diff --git a/CMakeLists.txt b/CMakeLists.txt index 40fac2ca2f..265e471dd2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -project(cura) +project(cura NONE) cmake_minimum_required(VERSION 2.8.12) include(GNUInstallDirs) @@ -17,48 +17,12 @@ set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'") configure_file(${CMAKE_SOURCE_DIR}/cura.desktop.in ${CMAKE_BINARY_DIR}/cura.desktop @ONLY) configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY) -# Macro needed to list all sub-directory of a directory. -# There is no function in cmake as far as I know. -# Found at: http://stackoverflow.com/a/7788165 -MACRO(SUBDIRLIST result curdir) - FILE(GLOB children RELATIVE ${curdir} ${curdir}/*) - SET(dirlist "") - FOREACH(child ${children}) - IF(IS_DIRECTORY ${curdir}/${child}) - STRING(REPLACE "/" "" child ${child}) - LIST(APPEND dirlist ${child}) - ENDIF() - ENDFOREACH() - SET(${result} ${dirlist}) -ENDMACRO() - if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "") + include(UraniumTranslationTools) # Extract Strings add_custom_target(extract-messages ${URANIUM_SCRIPTS_DIR}/extract-messages ${CMAKE_SOURCE_DIR} cura) - # Build Translations - find_package(Gettext) - if(GETTEXT_FOUND) - # translations target will convert .po files into .mo and .qm as needed. - # The files are checked for a _qt suffix and if it is found, converted to - # qm, otherwise they are converted to .po. - add_custom_target(translations ALL) - # copy-translations can be used to copy the built translation files from the - # build directory to the source resources directory. This is mostly a convenience - # during development, normally you want to simply use the install target to install - # the files along side the rest of the application. - - SUBDIRLIST(languages ${CMAKE_SOURCE_DIR}/resources/i18n/) - foreach(lang ${languages}) - file(GLOB po_files ${CMAKE_SOURCE_DIR}/resources/i18n/${lang}/*.po) - foreach(po_file ${po_files}) - string(REGEX REPLACE ".*/(.*).po" "${CMAKE_BINARY_DIR}/resources/i18n/${lang}/LC_MESSAGES/\\1.mo" mo_file ${po_file}) - add_custom_command(TARGET translations POST_BUILD COMMAND mkdir ARGS -p ${CMAKE_BINARY_DIR}/resources/i18n/${lang}/LC_MESSAGES/ COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} ARGS ${po_file} -o ${mo_file} -f) - endforeach() - endforeach() - install(DIRECTORY ${CMAKE_BINARY_DIR}/resources - DESTINATION ${CMAKE_INSTALL_DATADIR}/cura) - endif() + CREATE_TRANSLATION_TARGETS() endif() find_package(PythonInterp 3.4.0 REQUIRED) diff --git a/README.md b/README.md index b56a5ea345..9a86b6f8e0 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,10 @@ Please checkout [cura-build](https://github.com/Ultimaker/cura-build) Third party plugins ------------- -* [Print time calculator](https://github.com/nallath/PrintCostCalculator) -* [Post processing plugin](https://github.com/nallath/PostProcessingPlugin) -* [Barbarian Plugin](https://github.com/nallath/BarbarianPlugin) Simple scale tool for imperial to metric. +* [Print Cost Calculator](https://github.com/nallath/PrintCostCalculator): Calculates weight and monetary cost of your print. +* [Post Processing Plugin](https://github.com/nallath/PostProcessingPlugin): Allows for post-processing scripts to run on g-code. +* [Barbarian Plugin](https://github.com/nallath/BarbarianPlugin): Simple scale tool for imperial to metric. +* [X3G Writer](https://github.com/Ghostkeeper/X3GWriter): Adds support for exporting X3G files. Making profiles for other printers ---------------------------------- diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index a74a405044..91aa5a176d 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -67,6 +67,9 @@ class BuildVolume(SceneNode): self._disallowed_areas = [] self._disallowed_area_mesh = None + self._prime_tower_area = None + self._prime_tower_area_mesh = None + self.setCalculateBoundingBox(False) self._volume_aabb = None @@ -74,10 +77,16 @@ class BuildVolume(SceneNode): self._adhesion_type = None self._platform = Platform(self) - self._active_container_stack = None + self._global_container_stack = None Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) self._onGlobalContainerStackChanged() + self._active_extruder_stack = None + ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) + self._onActiveExtruderStackChanged() + + self._has_errors = False + def setWidth(self, width): if width: self._width = width @@ -106,6 +115,10 @@ class BuildVolume(SceneNode): if self._disallowed_area_mesh: renderer.queueNode(self, mesh = self._disallowed_area_mesh, shader = self._shader, transparent = True, backface_cull = True, sort = -9) + if self._prime_tower_area_mesh: + renderer.queueNode(self, mesh = self._prime_tower_area_mesh, shader = self._shader, transparent=True, + backface_cull=True, sort=-8) + return True ## Recalculates the build volume & disallowed areas. @@ -180,6 +193,24 @@ class BuildVolume(SceneNode): else: self._disallowed_area_mesh = None + if self._prime_tower_area: + mb = MeshBuilder() + color = Color(1.0, 0.0, 0.0, 0.5) + points = self._prime_tower_area.getPoints() + first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, + self._clamp(points[0][1], min_d, max_d)) + previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, + self._clamp(points[0][1], min_d, max_d)) + for point in points: + new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, + self._clamp(point[1], min_d, max_d)) + mb.addFace(first, previous_point, new_point, color=color) + previous_point = new_point + + self._prime_tower_area_mesh = mb.build() + else: + self._prime_tower_area_mesh = None + self._volume_aabb = AxisAlignedBox( minimum = Vector(min_w, min_h - 1.0, min_d), maximum = Vector(max_w, max_h - self._raft_thickness, max_d)) @@ -208,22 +239,22 @@ class BuildVolume(SceneNode): "@info:status", "The build volume height has been reduced due to the value of the" " \"Print Sequence\" setting to prevent the gantry from colliding" - " with printed models."), lifetime=10).show() + " with printed models.")).show() def getRaftThickness(self): return self._raft_thickness def _updateRaftThickness(self): old_raft_thickness = self._raft_thickness - self._adhesion_type = self._active_container_stack.getProperty("adhesion_type", "value") + self._adhesion_type = self._global_container_stack.getProperty("adhesion_type", "value") self._raft_thickness = 0.0 if self._adhesion_type == "raft": self._raft_thickness = ( - self._active_container_stack.getProperty("raft_base_thickness", "value") + - self._active_container_stack.getProperty("raft_interface_thickness", "value") + - self._active_container_stack.getProperty("raft_surface_layers", "value") * - self._active_container_stack.getProperty("raft_surface_thickness", "value") + - self._active_container_stack.getProperty("raft_airgap", "value")) + self._global_container_stack.getProperty("raft_base_thickness", "value") + + self._global_container_stack.getProperty("raft_interface_thickness", "value") + + self._global_container_stack.getProperty("raft_surface_layers", "value") * + self._global_container_stack.getProperty("raft_surface_thickness", "value") + + self._global_container_stack.getProperty("raft_airgap", "value")) # Rounding errors do not matter, we check if raft_thickness has changed at all if old_raft_thickness != self._raft_thickness: @@ -231,41 +262,52 @@ class BuildVolume(SceneNode): self.raftThicknessChanged.emit() def _onGlobalContainerStackChanged(self): - if self._active_container_stack: - self._active_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged) + if self._global_container_stack: + self._global_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged) - self._active_container_stack = Application.getInstance().getGlobalContainerStack() + self._global_container_stack = Application.getInstance().getGlobalContainerStack() - if self._active_container_stack: - self._active_container_stack.propertyChanged.connect(self._onSettingPropertyChanged) + if self._global_container_stack: + self._global_container_stack.propertyChanged.connect(self._onSettingPropertyChanged) - self._width = self._active_container_stack.getProperty("machine_width", "value") - if self._active_container_stack.getProperty("print_sequence", "value") == "one_at_a_time": - self._height = self._active_container_stack.getProperty("gantry_height", "value") - self._buildVolumeMessage() + self._width = self._global_container_stack.getProperty("machine_width", "value") + machine_height = self._global_container_stack.getProperty("machine_height", "value") + if self._global_container_stack.getProperty("print_sequence", "value") == "one_at_a_time": + self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height) + if self._height < machine_height: + self._buildVolumeMessage() else: - self._height = self._active_container_stack.getProperty("machine_height", "value") - self._depth = self._active_container_stack.getProperty("machine_depth", "value") + self._height = self._global_container_stack.getProperty("machine_height", "value") + self._depth = self._global_container_stack.getProperty("machine_depth", "value") self._updateDisallowedAreas() self._updateRaftThickness() self.rebuild() + def _onActiveExtruderStackChanged(self): + if self._active_extruder_stack: + self._active_extruder_stack.propertyChanged.disconnect(self._onSettingPropertyChanged) + self._active_extruder_stack = ExtruderManager.getInstance().getActiveExtruderStack() + if self._active_extruder_stack: + self._active_extruder_stack.propertyChanged.connect(self._onSettingPropertyChanged) + def _onSettingPropertyChanged(self, setting_key, property_name): if property_name != "value": return rebuild_me = False if setting_key == "print_sequence": + machine_height = self._global_container_stack.getProperty("machine_height", "value") if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time": - self._height = self._active_container_stack.getProperty("gantry_height", "value") - self._buildVolumeMessage() + self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height) + if self._height < machine_height: + self._buildVolumeMessage() else: - self._height = self._active_container_stack.getProperty("machine_height", "value") + self._height = self._global_container_stack.getProperty("machine_height", "value") rebuild_me = True - if setting_key in self._skirt_settings or setting_key in self._prime_settings: + if setting_key in self._skirt_settings or setting_key in self._prime_settings or setting_key in self._tower_settings or setting_key == "print_sequence": self._updateDisallowedAreas() rebuild_me = True @@ -276,20 +318,37 @@ class BuildVolume(SceneNode): if rebuild_me: self.rebuild() - def _updateDisallowedAreas(self): - if not self._active_container_stack: - return + def hasErrors(self): + return self._has_errors + def _updateDisallowedAreas(self): + if not self._global_container_stack: + return + self._has_errors = False # Reset. disallowed_areas = copy.deepcopy( - self._active_container_stack.getProperty("machine_disallowed_areas", "value")) + self._global_container_stack.getProperty("machine_disallowed_areas", "value")) areas = [] + machine_width = self._global_container_stack.getProperty("machine_width", "value") + machine_depth = self._global_container_stack.getProperty("machine_depth", "value") + self._prime_tower_area = None + # Add prime tower location as disallowed area. + if self._global_container_stack.getProperty("prime_tower_enable", "value") == True: + prime_tower_size = self._global_container_stack.getProperty("prime_tower_size", "value") + prime_tower_x = self._global_container_stack.getProperty("prime_tower_position_x", "value") - machine_width / 2 + prime_tower_y = - self._global_container_stack.getProperty("prime_tower_position_y", "value") + machine_depth / 2 + + self._prime_tower_area = Polygon([ + [prime_tower_x - prime_tower_size, prime_tower_y - prime_tower_size], + [prime_tower_x, prime_tower_y - prime_tower_size], + [prime_tower_x, prime_tower_y], + [prime_tower_x - prime_tower_size, prime_tower_y], + ]) + # Add extruder prime locations as disallowed areas. # Probably needs some rework after coordinate system change. extruder_manager = ExtruderManager.getInstance() - extruders = extruder_manager.getMachineExtruders(self._active_container_stack.getId()) - machine_width = self._active_container_stack.getProperty("machine_width", "value") - machine_depth = self._active_container_stack.getProperty("machine_depth", "value") + extruders = extruder_manager.getMachineExtruders(self._global_container_stack.getId()) for single_extruder in extruders: extruder_prime_pos_x = single_extruder.getProperty("extruder_prime_pos_x", "value") extruder_prime_pos_y = single_extruder.getProperty("extruder_prime_pos_y", "value") @@ -305,7 +364,7 @@ class BuildVolume(SceneNode): [prime_x - PRIME_CLEARANCE, prime_y + PRIME_CLEARANCE], ]) - bed_adhesion_size = self._getBedAdhesionSize(self._active_container_stack) + bed_adhesion_size = self._getBedAdhesionSize(self._global_container_stack) if disallowed_areas: # Extend every area already in the disallowed_areas with the skirt size. @@ -315,10 +374,13 @@ class BuildVolume(SceneNode): areas.append(poly) + if self._prime_tower_area: + self._prime_tower_area = self._prime_tower_area.getMinkowskiHull(Polygon(approximatedCircleVertices(bed_adhesion_size))) + # Add the skirt areas around the borders of the build plate. if bed_adhesion_size > 0: - half_machine_width = self._active_container_stack.getProperty("machine_width", "value") / 2 - half_machine_depth = self._active_container_stack.getProperty("machine_depth", "value") / 2 + half_machine_width = self._global_container_stack.getProperty("machine_width", "value") / 2 + half_machine_depth = self._global_container_stack.getProperty("machine_depth", "value") / 2 areas.append(Polygon(numpy.array([ [-half_machine_width, -half_machine_depth], @@ -348,12 +410,29 @@ class BuildVolume(SceneNode): [half_machine_width - bed_adhesion_size, -half_machine_depth + bed_adhesion_size] ], numpy.float32))) + # Check if the prime tower area intersects with any of the other areas. + # If this is the case, keep the polygon seperate, so it can be drawn in red. + # If not, add it back to disallowed area's, so it's rendered as normal. + collision = False + if self._prime_tower_area: + for area in areas: + if self._prime_tower_area.intersectsPolygon(area) is not None: + collision = True + break + if not collision: + areas.append(self._prime_tower_area) + self._prime_tower_area = None + self._has_errors = collision self._disallowed_areas = areas ## Convenience function to calculate the size of the bed adhesion in directions x, y. def _getBedAdhesionSize(self, container_stack): skirt_size = 0.0 + # If we are printing one at a time, we need to add the bed adhesion size to the disallowed areas of the objects + if container_stack.getProperty("print_sequence", "value") == "one_at_a_time": + return 0.1 # Return a very small value, so we do draw disallowed area's near the edges. + adhesion_type = container_stack.getProperty("adhesion_type", "value") if adhesion_type == "skirt": skirt_distance = container_stack.getProperty("skirt_gap", "value") @@ -378,3 +457,4 @@ class BuildVolume(SceneNode): _skirt_settings = ["adhesion_type", "skirt_gap", "skirt_line_count", "skirt_brim_line_width", "brim_width", "brim_line_count", "raft_margin", "draft_shield_enabled", "draft_shield_dist", "xy_offset"] _raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap"] _prime_settings = ["extruder_prime_pos_x", "extruder_prime_pos_y", "extruder_prime_pos_z"] + _tower_settings = ["prime_tower_enable", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y"] diff --git a/cura/ConvexHullDecorator.py b/cura/ConvexHullDecorator.py index 5185579633..770ed42a9f 100644 --- a/cura/ConvexHullDecorator.py +++ b/cura/ConvexHullDecorator.py @@ -56,6 +56,7 @@ class ConvexHullDecorator(SceneNodeDecorator): if self._global_stack and self._node: if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and not self._node.getParent().callDecoration("isGroup"): hull = hull.getMinkowskiHull(Polygon(numpy.array(self._global_stack.getProperty("machine_head_polygon", "value"), numpy.float32))) + hull = self._add2DAdhesionMargin(hull) return hull ## Get the convex hull of the node with the full head size @@ -229,17 +230,16 @@ class ConvexHullDecorator(SceneNodeDecorator): machine_head_coords = numpy.array( self._global_stack.getProperty("machine_head_with_fans_polygon", "value"), numpy.float32) - head_y_size = abs(machine_head_coords).min() # safe margin to take off in all directions if adhesion_type == "raft": - extra_margin = max(0, self._global_stack.getProperty("raft_margin", "value") - head_y_size) + extra_margin = max(0, self._global_stack.getProperty("raft_margin", "value")) elif adhesion_type == "brim": - extra_margin = max(0, self._global_stack.getProperty("brim_width", "value") - head_y_size) + extra_margin = max(0, self._global_stack.getProperty("brim_line_count", "value") * self._global_stack.getProperty("skirt_brim_line_width", "value")) elif adhesion_type == "skirt": extra_margin = max( 0, self._global_stack.getProperty("skirt_gap", "value") + - self._global_stack.getProperty("skirt_line_count", "value") * self._global_stack.getProperty("skirt_brim_line_width", "value") - - head_y_size) + self._global_stack.getProperty("skirt_line_count", "value") * self._global_stack.getProperty("skirt_brim_line_width", "value")) + # adjust head_and_fans with extra margin if extra_margin > 0: # In Cura 2.2+, there is a function to create this circle-like polygon. @@ -288,4 +288,4 @@ class ConvexHullDecorator(SceneNodeDecorator): _affected_settings = [ "adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap", "raft_margin", "print_sequence", - "skirt_gap", "skirt_line_count", "skirt_brim_line_width", "skirt_distance"] + "skirt_gap", "skirt_line_count", "skirt_brim_line_width", "skirt_distance", "brim_line_count"] diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 25a6d590e3..e93a23d01c 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -13,7 +13,6 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Mesh.ReadMeshJob import ReadMeshJob from UM.Logger import Logger from UM.Preferences import Preferences -from UM.Platform import Platform from UM.JobQueue import JobQueue from UM.SaveFile import SaveFile from UM.Scene.Selection import Selection @@ -24,6 +23,7 @@ from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.SetTransformOperation import SetTransformOperation +from UM.Operations.TranslateOperation import TranslateOperation from cura.SetParentOperation import SetParentOperation from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType @@ -37,7 +37,6 @@ from . import BuildVolume from . import CameraAnimation from . import PrintInformation from . import CuraActions -from . import MultiMaterialDecorator from . import ZOffsetDecorator from . import CuraSplashScreen from . import CameraImageProvider @@ -50,12 +49,12 @@ from PyQt5.QtGui import QColor, QIcon from PyQt5.QtWidgets import QMessageBox from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType -import platform import sys import os.path import numpy import copy import urllib + numpy.seterr(all="ignore") try: @@ -85,11 +84,12 @@ class CuraApplication(QtApplication): self._open_file_queue = [] # Files to open when plug-ins are loaded. # Need to do this before ContainerRegistry tries to load the machines - SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Any, default = True) - SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True) - SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True) - SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True) - SettingDefinition.addSupportedProperty("global_inherits_stack", DefinitionPropertyType.Function, default = "-1") + SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Any, default = True, read_only = True) + SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True, read_only = True) + SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True, read_only = True) + SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True, read_only = True) + SettingDefinition.addSupportedProperty("limit_to_extruder", DefinitionPropertyType.Function, default = "-1") + SettingDefinition.addSupportedProperty("resolve", DefinitionPropertyType.Function, default = None) SettingDefinition.addSettingType("extruder", None, str, Validator) SettingFunction.registerOperator("extruderValues", cura.Settings.ExtruderManager.getExtruderValues) @@ -180,8 +180,14 @@ class CuraApplication(QtApplication): ContainerRegistry.getInstance().addContainer(empty_material_container) empty_quality_container = copy.deepcopy(empty_container) empty_quality_container._id = "empty_quality" + empty_quality_container.setName("Not supported") + empty_quality_container.addMetaDataEntry("quality_type", "normal") empty_quality_container.addMetaDataEntry("type", "quality") ContainerRegistry.getInstance().addContainer(empty_quality_container) + empty_quality_changes_container = copy.deepcopy(empty_container) + empty_quality_changes_container._id = "empty_quality_changes" + empty_quality_changes_container.addMetaDataEntry("type", "quality_changes") + ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) ContainerRegistry.getInstance().load() @@ -248,7 +254,6 @@ class CuraApplication(QtApplication): blackmagic print_sequence infill_mesh - dual experimental """.replace("\n", ";").replace(" ", "")) @@ -309,7 +314,7 @@ class CuraApplication(QtApplication): path = None if instance_type == "material": path = Resources.getStoragePath(self.ResourceTypes.MaterialInstanceContainer, file_name) - elif instance_type == "quality": + elif instance_type == "quality" or instance_type == "quality_changes": path = Resources.getStoragePath(self.ResourceTypes.QualityInstanceContainer, file_name) elif instance_type == "user": path = Resources.getStoragePath(self.ResourceTypes.UserInstanceContainer, file_name) @@ -317,32 +322,36 @@ class CuraApplication(QtApplication): path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name) if path: + instance.setPath(path) with SaveFile(path, "wt", -1, "utf-8") as f: f.write(data) for stack in ContainerRegistry.getInstance().findContainerStacks(): - if not stack.isDirty(): - continue + self.saveStack(stack) - try: - data = stack.serialize() - except NotImplementedError: - continue - except Exception: - Logger.logException("e", "An exception occurred when serializing container %s", instance.getId()) - continue + def saveStack(self, stack): + if not stack.isDirty(): + return + try: + data = stack.serialize() + except NotImplementedError: + return + except Exception: + Logger.logException("e", "An exception occurred when serializing container %s", stack.getId()) + return - mime_type = ContainerRegistry.getMimeTypeForContainer(type(stack)) - file_name = urllib.parse.quote_plus(stack.getId()) + "." + mime_type.preferredSuffix - stack_type = stack.getMetaDataEntry("type", None) - path = None - if not stack_type or stack_type == "machine": - path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) - elif stack_type == "extruder_train": - path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) - if path: - with SaveFile(path, "wt", -1, "utf-8") as f: - f.write(data) + mime_type = ContainerRegistry.getMimeTypeForContainer(type(stack)) + file_name = urllib.parse.quote_plus(stack.getId()) + "." + mime_type.preferredSuffix + stack_type = stack.getMetaDataEntry("type", None) + path = None + if not stack_type or stack_type == "machine": + path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) + elif stack_type == "extruder_train": + path = Resources.getStoragePath(self.ResourceTypes.ExtruderStack, file_name) + if path: + stack.setPath(path) + with SaveFile(path, "wt", -1, "utf-8") as f: + f.write(data) @pyqtSlot(str, result = QUrl) @@ -477,6 +486,7 @@ class CuraApplication(QtApplication): qmlRegisterType(cura.Settings.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") qmlRegisterType(cura.Settings.MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") + qmlRegisterType(cura.Settings.QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel") qmlRegisterSingletonType(cura.Settings.ContainerManager, "Cura", 1, 0, "ContainerManager", cura.Settings.ContainerManager.createContainerManager) @@ -505,8 +515,6 @@ class CuraApplication(QtApplication): if self.getController().getActiveTool(): self._previous_active_tool = self.getController().getActiveTool().getPluginId() self.getController().setActiveTool(None) - else: - self._previous_active_tool = None def _onToolOperationStopped(self, event): if self._center_after_select: @@ -689,18 +697,17 @@ class CuraApplication(QtApplication): continue # Node that doesnt have a mesh and is not a group. if node.getParent() and node.getParent().callDecoration("isGroup"): continue # Grouped nodes don't need resetting as their parent (the group) is resetted) - nodes.append(node) if nodes: op = GroupedOperation() for node in nodes: + # Ensure that the object is above the build platform node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) - op.addOperation(SetTransformOperation(node, Vector(0,0,0))) - + op.addOperation(SetTransformOperation(node, Vector(0, node.getWorldPosition().y - node.getBoundingBox().bottom, 0))) op.push() - - ## Reset all transformations on nodes with mesh data. + + ## Reset all transformations on nodes with mesh data. @pyqtSlot() def resetAll(self): Logger.log("i", "Resetting all scene transformations") @@ -716,14 +723,17 @@ class CuraApplication(QtApplication): if nodes: op = GroupedOperation() - for node in nodes: # Ensure that the object is above the build platform node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator) - op.addOperation(SetTransformOperation(node, Vector(0,0,0), Quaternion(), Vector(1, 1, 1))) - + center_y = 0 + if node.callDecoration("isGroup"): + center_y = node.getWorldPosition().y - node.getBoundingBox().bottom + else: + center_y = node.getMeshData().getCenterPosition().y + op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0), Quaternion(), Vector(1, 1, 1))) op.push() - + ## Reload all mesh data on the screen from file. @pyqtSlot() def reloadAll(self): @@ -788,14 +798,19 @@ class CuraApplication(QtApplication): except Exception as e: Logger.log("d", "mergeSelected: Exception:", e) return - multi_material_decorator = MultiMaterialDecorator.MultiMaterialDecorator() - group_node.addDecorator(multi_material_decorator) - # Reset the position of each node - for node in group_node.getChildren(): - new_position = node.getMeshData().getCenterPosition() - new_position = new_position.scale(node.getScale()) - node.setPosition(new_position) - + + # Compute the center of the objects when their origins are aligned. + object_centers = [node.getMeshData().getCenterPosition().scale(node.getScale()) for node in group_node.getChildren()] + middle_x = sum([v.x for v in object_centers]) / len(object_centers) + middle_y = sum([v.y for v in object_centers]) / len(object_centers) + middle_z = sum([v.z for v in object_centers]) / len(object_centers) + offset = Vector(middle_x, middle_y, middle_z) + + # Move each node to the same position. + for center, node in zip(object_centers, group_node.getChildren()): + # Align the object and also apply the offset to center it inside the group. + node.setPosition(center - offset) + # Use the previously found center of the group bounding box as the new location of the group group_node.setPosition(group_node.getBoundingBox().center) @@ -921,3 +936,7 @@ class CuraApplication(QtApplication): self._additional_components[area_id].append(component) self.additionalComponentsChanged.emit(area_id) + + @pyqtSlot(str) + def log(self, msg): + Logger.log("d", msg) diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index c62113916d..d3da01e590 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -14,8 +14,9 @@ class LayerPolygon: SupportInfillType = 7 MoveCombingType = 8 MoveRetractionType = 9 + SupportInterfaceType = 10 - __jump_map = numpy.logical_or( numpy.arange(10) == NoneType, numpy.arange(10) >= MoveCombingType ) + __jump_map = numpy.logical_or(numpy.logical_or(numpy.arange(11) == NoneType, numpy.arange(11) == MoveCombingType), numpy.arange(11) == MoveRetractionType) def __init__(self, mesh, extruder, line_types, data, line_widths): self._mesh = mesh @@ -41,7 +42,7 @@ class LayerPolygon: # When type is used as index returns true if type == LayerPolygon.InfillType or type == LayerPolygon.SkinType or type == LayerPolygon.SupportInfillType # Should be generated in better way, not hardcoded. - self._isInfillOrSkinTypeMap = numpy.array([0, 0, 0, 1, 0, 0, 1, 1, 0, 0], dtype=numpy.bool) + self._isInfillOrSkinTypeMap = numpy.array([0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1], dtype=numpy.bool) self._build_cache_line_mesh_mask = None self._build_cache_needed_points = None @@ -178,10 +179,11 @@ class LayerPolygon: SkinType: Color(1.0, 1.0, 0.0, 1.0), SupportType: Color(0.0, 1.0, 1.0, 1.0), SkirtType: Color(0.0, 1.0, 1.0, 1.0), - InfillType: Color(1.0, 0.74, 0.0, 1.0), + InfillType: Color(1.0, 0.75, 0.0, 1.0), SupportInfillType: Color(0.0, 1.0, 1.0, 1.0), MoveCombingType: Color(0.0, 0.0, 1.0, 1.0), MoveRetractionType: Color(0.5, 0.5, 1.0, 1.0), + SupportInterfaceType: Color(0.25, 0.75, 1.0, 1.0), } # Should be generated in better way, not hardcoded. @@ -192,8 +194,9 @@ class LayerPolygon: [1.0, 1.0, 0.0, 1.0], [0.0, 1.0, 1.0, 1.0], [0.0, 1.0, 1.0, 1.0], - [1.0, 0.74, 0.0, 1.0], + [1.0, 0.75, 0.0, 1.0], [0.0, 1.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0], - [0.5, 0.5, 1.0, 1.0] + [0.5, 0.5, 1.0, 1.0], + [0.25, 0.75, 1.0, 1.0] ]) \ No newline at end of file diff --git a/cura/MultiMaterialDecorator.py b/cura/MultiMaterialDecorator.py deleted file mode 100644 index 5fee777309..0000000000 --- a/cura/MultiMaterialDecorator.py +++ /dev/null @@ -1,11 +0,0 @@ -from UM.Scene.SceneNodeDecorator import SceneNodeDecorator - -class MultiMaterialDecorator(SceneNodeDecorator): - def __init__(self): - super().__init__() - - def isMultiMaterial(self): - return True - - def __deepcopy__(self, memo): - return MultiMaterialDecorator() \ No newline at end of file diff --git a/cura/PlatformPhysics.py b/cura/PlatformPhysics.py index 56daaddc18..2a5bd4091c 100644 --- a/cura/PlatformPhysics.py +++ b/cura/PlatformPhysics.py @@ -15,6 +15,9 @@ from cura.ConvexHullDecorator import ConvexHullDecorator from . import PlatformPhysicsOperation from . import ZOffsetDecorator +import random # used for list shuffling + + class PlatformPhysics: def __init__(self, controller, volume): super().__init__() @@ -29,8 +32,11 @@ class PlatformPhysics: self._change_timer.setInterval(100) self._change_timer.setSingleShot(True) self._change_timer.timeout.connect(self._onChangeTimerFinished) + self._move_factor = 1.1 # By how much should we multiply overlap to calculate a new spot? + self._max_overlap_checks = 10 # How many times should we try to find a new spot per tick? Preferences.getInstance().addPreference("physics/automatic_push_free", True) + Preferences.getInstance().addPreference("physics/automatic_drop_down", True) def _onSceneChanged(self, source): self._change_timer.start() @@ -41,7 +47,16 @@ class PlatformPhysics: root = self._controller.getScene().getRoot() - for node in BreadthFirstIterator(root): + # Keep a list of nodes that are moving. We use this so that we don't move two intersecting objects in the + # same direction. + transformed_nodes = [] + + group_nodes = [] + # We try to shuffle all the nodes to prevent "locked" situations, where iteration B inverts iteration A. + # By shuffling the order of the nodes, this might happen a few times, but at some point it will resolve. + nodes = list(BreadthFirstIterator(root)) + random.shuffle(nodes) + for node in nodes: if node is root or type(node) is not SceneNode or node.getBoundingBox() is None: continue @@ -62,9 +77,12 @@ class PlatformPhysics: if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection: node._outside_buildarea = True + if node.callDecoration("isGroup"): + group_nodes.append(node) # Keep list of affected group_nodes + # Move it downwards if bottom is above platform move_vector = Vector() - if not (node.getParent() and node.getParent().callDecoration("isGroup")): #If an object is grouped, don't move it down + if Preferences.getInstance().getValue("physics/automatic_drop_down") and not (node.getParent() and node.getParent().callDecoration("isGroup")): #If an object is grouped, don't move it down z_offset = node.callDecoration("getZOffset") if node.getDecorator(ZOffsetDecorator.ZOffsetDecorator) else 0 move_vector = move_vector.set(y=-bbox.bottom + z_offset) @@ -91,27 +109,42 @@ class PlatformPhysics: if not other_node.callDecoration("getConvexHull") or not other_node.getBoundingBox(): continue - # Get the overlap distance for both convex hulls. If this returns None, there is no intersection. - head_hull = node.callDecoration("getConvexHullHead") - if head_hull: - overlap = head_hull.intersectsPolygon(other_node.callDecoration("getConvexHullHead")) - if not overlap: - other_head_hull = other_node.callDecoration("getConvexHullHead") - if other_head_hull: - overlap = node.callDecoration("getConvexHullHead").intersectsPolygon(other_head_hull) - else: - own_convex_hull = node.callDecoration("getConvexHull") - other_convex_hull = other_node.callDecoration("getConvexHull") - if own_convex_hull and other_convex_hull: - overlap = own_convex_hull.intersectsPolygon(other_convex_hull) - else: - # This can happen in some cases if the object is not yet done with being loaded. - # Simply waiting for the next tick seems to resolve this correctly. - overlap = None + if other_node in transformed_nodes: + continue # Other node is already moving, wait for next pass. + + overlap = (0, 0) # Start loop with no overlap + current_overlap_checks = 0 + # Continue to check the overlap until we no longer find one. + while overlap and current_overlap_checks < self._max_overlap_checks: + current_overlap_checks += 1 + head_hull = node.callDecoration("getConvexHullHead") + if head_hull: # One at a time intersection. + overlap = head_hull.translate(move_vector.x, move_vector.z).intersectsPolygon(other_node.callDecoration("getConvexHull")) + if not overlap: + other_head_hull = other_node.callDecoration("getConvexHullHead") + if other_head_hull: + overlap = node.callDecoration("getConvexHull").translate(move_vector.x, move_vector.z).intersectsPolygon(other_head_hull) + if overlap: + # Moving ensured that overlap was still there. Try anew! + move_vector = move_vector.set(x=move_vector.x + overlap[0] * self._move_factor, + z=move_vector.z + overlap[1] * self._move_factor) + else: + # Moving ensured that overlap was still there. Try anew! + move_vector = move_vector.set(x=move_vector.x + overlap[0] * self._move_factor, + z=move_vector.z + overlap[1] * self._move_factor) + else: + own_convex_hull = node.callDecoration("getConvexHull") + other_convex_hull = other_node.callDecoration("getConvexHull") + if own_convex_hull and other_convex_hull: + overlap = own_convex_hull.translate(move_vector.x, move_vector.z).intersectsPolygon(other_convex_hull) + if overlap: # Moving ensured that overlap was still there. Try anew! + move_vector = move_vector.set(x=move_vector.x + overlap[0] * self._move_factor, + z=move_vector.z + overlap[1] * self._move_factor) + else: + # This can happen in some cases if the object is not yet done with being loaded. + # Simply waiting for the next tick seems to resolve this correctly. + overlap = None - if overlap is None: - continue - move_vector = move_vector.set(x=overlap[0] * 1.1, z=overlap[1] * 1.1) convex_hull = node.callDecoration("getConvexHull") if convex_hull: if not convex_hull.isValid(): @@ -121,13 +154,19 @@ class PlatformPhysics: overlap = convex_hull.intersectsPolygon(area) if overlap is None: continue - node._outside_buildarea = True if not Vector.Null.equals(move_vector, epsilon=1e-5): + transformed_nodes.append(node) op = PlatformPhysicsOperation.PlatformPhysicsOperation(node, move_vector) op.push() + # Group nodes should override the _outside_buildarea property of their children. + for group_node in group_nodes: + for child_node in group_node.getAllChildren(): + child_node._outside_buildarea = group_node._outside_buildarea + + def _onToolOperationStarted(self, tool): self._enabled = False diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index b24fe11f18..300e76a192 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -1,10 +1,16 @@ +from UM.i18n import i18nCatalog from UM.OutputDevice.OutputDevice import OutputDevice from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt5.QtWidgets import QMessageBox +import UM.Settings.ContainerRegistry + from enum import IntEnum # For the connection state tracking. from UM.Logger import Logger - +from UM.Application import Application from UM.Signal import signalemitter +i18n_catalog = i18nCatalog("cura") + ## Printer output device adds extra interface options on top of output device. # # The assumption is made the printer is a FDM printer. @@ -19,6 +25,7 @@ class PrinterOutputDevice(QObject, OutputDevice): def __init__(self, device_id, parent = None): super().__init__(device_id = device_id, parent = parent) + self._container_registry = UM.Settings.ContainerRegistry.getInstance() self._target_bed_temperature = 0 self._bed_temperature = 0 self._num_extruders = 1 @@ -39,6 +46,8 @@ class PrinterOutputDevice(QObject, OutputDevice): self._error_text = "" self._accepts_commands = True + self._printer_state = "" + def requestWrite(self, node, file_name = None, filter_by_machine = False): raise NotImplementedError("requestWrite needs to be implemented") @@ -86,10 +95,21 @@ class PrinterOutputDevice(QObject, OutputDevice): acceptsCommandsChanged = pyqtSignal() + printerStateChanged = pyqtSignal() + + @pyqtProperty(str, notify=printerStateChanged) + def printerState(self): + return self._printer_state + @pyqtProperty(str, notify = jobStateChanged) def jobState(self): return self._job_state + def _updatePrinterState(self, printer_state): + if self._printer_state != printer_state: + self._printer_state = printer_state + self.printerStateChanged.emit() + def _updateJobState(self, job_state): if self._job_state != job_state: self._job_state = job_state @@ -145,8 +165,9 @@ class PrinterOutputDevice(QObject, OutputDevice): @pyqtSlot(int) def setTargetBedTemperature(self, temperature): self._setTargetBedTemperature(temperature) - self._target_bed_temperature = temperature - self.targetBedTemperatureChanged.emit() + if self._target_bed_temperature != temperature: + self._target_bed_temperature = temperature + self.targetBedTemperatureChanged.emit() ## Time the print has been printing. # Note that timeTotal - timeElapsed should give time remaining. @@ -207,8 +228,9 @@ class PrinterOutputDevice(QObject, OutputDevice): # This simply sets the bed temperature, but ensures that a signal is emitted. # /param temperature temperature of the bed. def _setBedTemperature(self, temperature): - self._bed_temperature = temperature - self.bedTemperatureChanged.emit() + if self._bed_temperature != temperature: + self._bed_temperature = temperature + self.bedTemperatureChanged.emit() ## Get the target bed temperature if connected printer (if any) @pyqtProperty(int, notify = targetBedTemperatureChanged) @@ -223,8 +245,10 @@ class PrinterOutputDevice(QObject, OutputDevice): @pyqtSlot(int, int) def setTargetHotendTemperature(self, index, temperature): self._setTargetHotendTemperature(index, temperature) - self._target_hotend_temperatures[index] = temperature - self.targetHotendTemperaturesChanged.emit() + + if self._target_hotend_temperatures[index] != temperature: + self._target_hotend_temperatures[index] = temperature + self.targetHotendTemperaturesChanged.emit() ## Implementation function of setTargetHotendTemperature. # /param index Index of the hotend to set the temperature of @@ -246,13 +270,29 @@ class PrinterOutputDevice(QObject, OutputDevice): # /param index Index of the hotend # /param temperature temperature of the hotend (in deg C) def _setHotendTemperature(self, index, temperature): - self._hotend_temperatures[index] = temperature - self.hotendTemperaturesChanged.emit() + if self._hotend_temperatures[index] != temperature: + self._hotend_temperatures[index] = temperature + self.hotendTemperaturesChanged.emit() @pyqtProperty("QVariantList", notify = materialIdChanged) def materialIds(self): return self._material_ids + @pyqtProperty("QVariantList", notify = materialIdChanged) + def materialNames(self): + result = [] + for material_id in self._material_ids: + if material_id is None: + result.append(i18n_catalog.i18nc("@item:material", "No material loaded")) + continue + + containers = self._container_registry.findInstanceContainers(type = "material", GUID = material_id) + if containers: + result.append(containers[0].getName()) + else: + result.append(i18n_catalog.i18nc("@item:material", "Unknown material")) + return result + ## Protected setter for the current material id. # /param index Index of the extruder # /param material_id id of the material @@ -262,7 +302,6 @@ class PrinterOutputDevice(QObject, OutputDevice): self._material_ids[index] = material_id self.materialIdChanged.emit(index, material_id) - @pyqtProperty("QVariantList", notify = hotendIdChanged) def hotendIds(self): return self._hotend_ids @@ -276,6 +315,11 @@ class PrinterOutputDevice(QObject, OutputDevice): self._hotend_ids[index] = hotend_id self.hotendIdChanged.emit(index, hotend_id) + ## Let the user decide if the hotends and/or material should be synced with the printer + # NB: the UX needs to be implemented by the plugin + def materialHotendChangedMessage(self, callback): + Logger.log("w", "materialHotendChangedMessage needs to be implemented, returning 'Yes'") + callback(QMessageBox.Yes) ## Attempt to establish connection def connect(self): @@ -292,8 +336,9 @@ class PrinterOutputDevice(QObject, OutputDevice): ## Set the connection state of this output device. # /param connection_state ConnectionState enum. def setConnectionState(self, connection_state): - self._connection_state = connection_state - self.connectionStateChanged.emit(self._id) + if self._connection_state != connection_state: + self._connection_state = connection_state + self.connectionStateChanged.emit(self._id) @pyqtProperty(str, notify = connectionTextChanged) def connectionText(self): @@ -329,7 +374,7 @@ class PrinterOutputDevice(QObject, OutputDevice): return self._head_z ## Update the saved position of the head - # This function should be called when a new position for the head is recieved. + # This function should be called when a new position for the head is received. def _updateHeadPosition(self, x, y ,z): position_changed = False if self._head_x != x: @@ -341,6 +386,7 @@ class PrinterOutputDevice(QObject, OutputDevice): if self._head_z != z: self._head_z = z position_changed = True + if position_changed: self.headPositionChanged.emit() diff --git a/cura/ProfileWriter.py b/cura/ProfileWriter.py index 6c719205ec..276e2b80a3 100644 --- a/cura/ProfileWriter.py +++ b/cura/ProfileWriter.py @@ -18,8 +18,8 @@ class ProfileWriter(PluginObject): # The profile writer may write its own file format to the specified file. # # \param path \type{string} The file to output to. - # \param profile \type{Profile} The profile to write to the file. + # \param profiles \type{Profile} or \type{List} The profile(s) to write to the file. # \return \code True \endcode if the writing was successful, or \code # False \endcode if it wasn't. - def write(self, path, node): + def write(self, path, profiles): raise NotImplementedError("Profile writer plugin was not correctly implemented. No write was specified.") diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 82be7c480f..e3a0d22299 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -14,6 +14,8 @@ import UM.Platform import UM.MimeTypeDatabase import UM.Logger +import cura.Settings + from UM.MimeTypeDatabase import MimeTypeNotFoundError from UM.i18n import i18nCatalog @@ -28,7 +30,9 @@ class ContainerManager(QObject): def __init__(self, parent = None): super().__init__(parent) - self._registry = UM.Settings.ContainerRegistry.getInstance() + self._container_registry = UM.Settings.ContainerRegistry.getInstance() + self._machine_manager = UM.Application.getInstance().getMachineManager() + self._container_name_filters = {} ## Create a duplicate of the specified container @@ -41,7 +45,7 @@ class ContainerManager(QObject): # \return The ID of the new container, or an empty string if duplication failed. @pyqtSlot(str, result = str) def duplicateContainer(self, container_id): - containers = self._registry.findContainers(None, id = container_id) + containers = self._container_registry.findContainers(None, id = container_id) if not containers: UM.Logger.log("w", "Could duplicate container %s because it was not found.", container_id) return "" @@ -49,7 +53,7 @@ class ContainerManager(QObject): container = containers[0] new_container = None - new_name = self._registry.uniqueName(container.getName()) + new_name = self._container_registry.uniqueName(container.getName()) # Only InstanceContainer has a duplicate method at the moment. # So fall back to serialize/deserialize when no duplicate method exists. if hasattr(container, "duplicate"): @@ -60,7 +64,7 @@ class ContainerManager(QObject): new_container.setName(new_name) if new_container: - self._registry.addContainer(new_container) + self._container_registry.addContainer(new_container) return new_container.getId() @@ -73,24 +77,24 @@ class ContainerManager(QObject): # \return True if successful, False if not. @pyqtSlot(str, str, str, result = bool) def renameContainer(self, container_id, new_id, new_name): - containers = self._registry.findContainers(None, id = container_id) + containers = self._container_registry.findContainers(None, id = container_id) if not containers: UM.Logger.log("w", "Could rename container %s because it was not found.", container_id) return False container = containers[0] # First, remove the container from the registry. This will clean up any files related to the container. - self._registry.removeContainer(container) + self._container_registry.removeContainer(container) # Ensure we have a unique name for the container - new_name = self._registry.uniqueName(new_name) + new_name = self._container_registry.uniqueName(new_name) # Then, update the name and ID of the container container.setName(new_name) container._id = new_id # TODO: Find a nicer way to set a new, unique ID # Finally, re-add the container so it will be properly serialized again. - self._registry.addContainer(container) + self._container_registry.addContainer(container) return True @@ -101,12 +105,12 @@ class ContainerManager(QObject): # \return True if the container was successfully removed, False if not. @pyqtSlot(str, result = bool) def removeContainer(self, container_id): - containers = self._registry.findContainers(None, id = container_id) + containers = self._container_registry.findContainers(None, id = container_id) if not containers: UM.Logger.log("w", "Could remove container %s because it was not found.", container_id) return False - self._registry.removeContainer(containers[0].getId()) + self._container_registry.removeContainer(containers[0].getId()) return True @@ -121,26 +125,25 @@ class ContainerManager(QObject): # \return True if successfully merged, False if not. @pyqtSlot(str, result = bool) def mergeContainers(self, merge_into_id, merge_id): - containers = self._registry.findContainers(None, id = merge_into_id) + containers = self._container_registry.findContainers(None, id = merge_into_id) if not containers: UM.Logger.log("w", "Could merge into container %s because it was not found.", merge_into_id) return False merge_into = containers[0] - containers = self._registry.findContainers(None, id = merge_id) + containers = self._container_registry.findContainers(None, id = merge_id) if not containers: UM.Logger.log("w", "Could not merge container %s because it was not found", merge_id) return False merge = containers[0] - if type(merge) != type(merge_into): + if not isinstance(merge, type(merge_into)): UM.Logger.log("w", "Cannot merge two containers of different types") return False - for key in merge.getAllKeys(): - merge_into.setProperty(key, "value", merge.getProperty(key, "value")) + self._performMerge(merge_into, merge) return True @@ -151,7 +154,7 @@ class ContainerManager(QObject): # \return True if successful, False if not. @pyqtSlot(str, result = bool) def clearContainer(self, container_id): - containers = self._registry.findContainers(None, id = container_id) + containers = self._container_registry.findContainers(None, id = container_id) if not containers: UM.Logger.log("w", "Could clear container %s because it was not found.", container_id) return False @@ -164,6 +167,19 @@ class ContainerManager(QObject): return True + @pyqtSlot(str, str, result=str) + def getContainerMetaDataEntry(self, container_id, entry_name): + containers = self._container_registry.findContainers(None, id=container_id) + if not containers: + UM.Logger.log("w", "Could not get metadata of container %s because it was not found.", container_id) + return "" + + result = containers[0].getMetaDataEntry(entry_name) + if result is not None: + return str(result) + else: + return "" + ## Set a metadata entry of the specified container. # # This will set the specified entry of the container's metadata to the specified @@ -178,9 +194,9 @@ class ContainerManager(QObject): # \return True if successful, False if not. @pyqtSlot(str, str, str, result = bool) def setContainerMetaDataEntry(self, container_id, entry_name, entry_value): - containers = UM.Settings.ContainerRegistry.getInstance().findContainers(None, id = container_id) + containers = self._container_registry.findContainers(None, id = container_id) if not containers: - UM.Logger.log("w", "Could set metadata of container %s because it was not found.", container_id) + UM.Logger.log("w", "Could not set metadata of container %s because it was not found.", container_id) return False container = containers[0] @@ -209,6 +225,24 @@ class ContainerManager(QObject): return True + ## Set the name of the specified container. + @pyqtSlot(str, str, result = bool) + def setContainerName(self, container_id, new_name): + containers = self._container_registry.findContainers(None, id = container_id) + if not containers: + UM.Logger.log("w", "Could not set name of container %s because it was not found.", container_id) + return False + + container = containers[0] + + if container.isReadOnly(): + UM.Logger.log("w", "Cannot set name of read-only container %s.", container_id) + return False + + container.setName(new_name) + + return True + ## Find instance containers matching certain criteria. # # This effectively forwards to ContainerRegistry::findInstanceContainers. @@ -219,11 +253,24 @@ class ContainerManager(QObject): @pyqtSlot("QVariantMap", result = "QVariantList") def findInstanceContainers(self, criteria): result = [] - for entry in self._registry.findInstanceContainers(**criteria): + for entry in self._container_registry.findInstanceContainers(**criteria): result.append(entry.getId()) return result + @pyqtSlot(str, result = bool) + def isContainerUsed(self, container_id): + UM.Logger.log("d", "Checking if container %s is currently used in the active stacks", container_id) + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + if container_id in [child.getId() for child in stack.getContainers()]: + UM.Logger.log("d", "The container is in use by %s", stack.getId()) + return True + return False + + @pyqtSlot(str, result = str) + def makeUniqueName(self, original_name): + return self._container_registry.uniqueName(original_name) + ## Get a list of string that can be used as name filters for a Qt File Dialog # # This will go through the list of available container types and generate a list of strings @@ -276,7 +323,7 @@ class ContainerManager(QObject): else: mime_type = self._container_name_filters[file_type]["mime"] - containers = UM.Settings.ContainerRegistry.getInstance().findContainers(None, id = container_id) + containers = self._container_registry.findContainers(None, id = container_id) if not containers: return { "status": "error", "message": "Container not found"} container = containers[0] @@ -302,6 +349,9 @@ class ContainerManager(QObject): except NotImplementedError: return { "status": "error", "message": "Unable to serialize container"} + if contents is None: + return {"status": "error", "message": "Serialization returned None. Unable to write to file"} + with UM.SaveFile(file_url, "w") as f: f.write(contents) @@ -334,7 +384,7 @@ class ContainerManager(QObject): return { "status": "error", "message": "Could not find a container to handle the specified file."} container_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_url))) - container_id = UM.Settings.ContainerRegistry.getInstance().uniqueName(container_id) + container_id = self._container_registry.uniqueName(container_id) container = container_type(container_id) @@ -346,10 +396,243 @@ class ContainerManager(QObject): container.setName(container_id) - UM.Settings.ContainerRegistry.getInstance().addContainer(container) + self._container_registry.addContainer(container) return { "status": "success", "message": "Successfully imported container {0}".format(container.getName()) } + ## Update the current active quality changes container with the settings from the user container. + # + # This will go through the active global stack and all active extruder stacks and merge the changes from the user + # container into the quality_changes container. After that, the user container is cleared. + # + # \return \type{bool} True if successful, False if not. + @pyqtSlot(result = bool) + def updateQualityChanges(self): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return False + + self._machine_manager.blurSettings.emit() + + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + # Find the quality_changes container for this stack and merge the contents of the top container into it. + quality_changes = stack.findContainer(type = "quality_changes") + if not quality_changes or quality_changes.isReadOnly(): + UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile in stack %s", stack.getId()) + continue + + self._performMerge(quality_changes, stack.getTop()) + + self._machine_manager.activeQualityChanged.emit() + + return True + + ## Clear the top-most (user) containers of the active stacks. + @pyqtSlot() + def clearUserContainers(self): + self._machine_manager.blurSettings.emit() + + # Go through global and extruder stacks and clear their topmost container (the user settings). + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + stack.getTop().clear() + + ## Create quality changes containers from the user containers in the active stacks. + # + # This will go through the global and extruder stacks and create quality_changes containers from + # the user containers in each stack. These then replace the quality_changes containers in the + # stack and clear the user settings. + # + # \return \type{bool} True if the operation was successfully, False if not. + @pyqtSlot(str, result = bool) + def createQualityChanges(self, base_name): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return False + + active_quality_name = self._machine_manager.activeQualityName + if active_quality_name == "": + UM.Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId()) + return False + + self._machine_manager.blurSettings.emit() + if base_name is None or base_name == "": + base_name = active_quality_name + unique_name = self._container_registry.uniqueName(base_name) + + # Go through the active stacks and create quality_changes containers from the user containers. + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + user_container = stack.getTop() + quality_container = stack.findContainer(type = "quality") + quality_changes_container = stack.findContainer(type = "quality_changes") + if not quality_container or not quality_changes_container: + UM.Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId()) + continue + + new_changes = self._createQualityChanges(quality_container, unique_name, stack.getId()) + self._performMerge(new_changes, user_container) + + self._container_registry.addContainer(new_changes) + stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_changes) + + self._machine_manager.activeQualityChanged.emit() + return True + + ## Remove all quality changes containers matching a specified name. + # + # This will search for quality_changes containers matching the supplied name and remove them. + # Note that if the machine specifies that qualities should be filtered by machine and/or material + # only the containers related to the active machine/material are removed. + # + # \param quality_name The name of the quality changes to remove. + # + # \return \type{bool} True if successful, False if not. + @pyqtSlot(str, result = bool) + def removeQualityChanges(self, quality_name): + UM.Logger.log("d", "Attempting to remove the quality change containers with name %s", quality_name) + containers_found = False + + if not quality_name: + return containers_found # Without a name we will never find a container to remove. + + # If the container that is being removed is the currently active quality, set another quality as the active quality + activate_quality = quality_name == self._machine_manager.activeQualityName + activate_quality_type = None + + for container in self._getFilteredContainers(name = quality_name, type = "quality_changes"): + containers_found = True + if activate_quality and not activate_quality_type: + activate_quality_type = container.getMetaDataEntry("quality") + self._container_registry.removeContainer(container.getId()) + + if not containers_found: + UM.Logger.log("d", "Unable to remove quality containers, as we did not find any by the name of %s", quality_name) + + elif activate_quality: + definition_id = "fdmprinter" if not self._machine_manager.filterQualityByMachine else self._machine_manager.activeDefinitionId + containers = self._container_registry.findInstanceContainers(type = "quality", definition = definition_id, quality_type = activate_quality_type) + if containers: + self._machine_manager.setActiveQuality(containers[0].getId()) + self._machine_manager.activeQualityChanged.emit() + + return containers_found + + ## Rename a set of quality changes containers. + # + # This will search for quality_changes containers matching the supplied name and rename them. + # Note that if the machine specifies that qualities should be filtered by machine and/or material + # only the containers related to the active machine/material are renamed. + # + # \param quality_name The name of the quality changes containers to rename. + # \param new_name The new name of the quality changes. + # + # \return True if successful, False if not. + @pyqtSlot(str, str, result = bool) + def renameQualityChanges(self, quality_name, new_name): + UM.Logger.log("d", "User requested QualityChanges container rename of %s to %s", quality_name, new_name) + if not quality_name or not new_name: + return False + + if quality_name == new_name: + UM.Logger.log("w", "Unable to rename %s to %s, because they are the same.", quality_name, new_name) + return True + + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return False + + self._machine_manager.blurSettings.emit() + + new_name = self._container_registry.uniqueName(new_name) + + container_registry = self._container_registry + for container in self._getFilteredContainers(name = quality_name, type = "quality_changes"): + stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) + container_registry.renameContainer(container.getId(), new_name, self._createUniqueId(stack_id, new_name)) + + self._machine_manager.activeQualityChanged.emit() + return True + + ## Duplicate a specified set of quality or quality_changes containers. + # + # This will search for containers matching the specified name. If the container is a "quality" type container, a new + # quality_changes container will be created with the specified quality as base. If the container is a "quality_changes" + # container, it is simply duplicated and renamed. + # + # \param quality_name The name of the quality to duplicate. + # + # \return A string containing the name of the duplicated containers, or an empty string if it failed. + @pyqtSlot(str, str, result = str) + def duplicateQualityOrQualityChanges(self, quality_name, base_name): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack or not quality_name: + return "" + UM.Logger.log("d", "Attempting to duplicate the quality %s", quality_name) + containers = self._container_registry.findInstanceContainers(name = quality_name) + if not containers: + UM.Logger.log("d", "Unable to duplicate the quality %s, because it doesn't exist.", quality_name) + return "" + + if base_name is None: + base_name = quality_name + + new_name = self._container_registry.uniqueName(base_name) + + container_type = containers[0].getMetaDataEntry("type") + if container_type == "quality": + for container in self._getFilteredContainers(name = quality_name, type = "quality"): + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + new_changes = self._createQualityChanges(container, new_name, stack.getId()) + self._container_registry.addContainer(new_changes) + elif container_type == "quality_changes": + for container in self._getFilteredContainers(name = quality_name, type = "quality_changes"): + stack_id = container.getMetaDataEntry("extruder", global_stack.getId()) + new_container = container.duplicate(self._createUniqueId(stack_id, new_name), new_name) + self._container_registry.addContainer(new_container) + else: + UM.Logger.log("w", "Unable to duplicate profile. It has the wrong type.") + return "" + + return new_name + + @pyqtSlot(str, result = str) + def duplicateMaterial(self, material_id): + containers = self._container_registry.findInstanceContainers(id=material_id) + if not containers: + UM.Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", material_id) + return "" + + # Ensure all settings are saved. + UM.Application.getInstance().saveSettings() + + # Create a new ID & container to hold the data. + new_id = self._container_registry.uniqueName(material_id) + container_type = type(containers[0]) # Could be either a XMLMaterialProfile or a InstanceContainer + duplicated_container = container_type(new_id) + + # Instead of duplicating we load the data from the basefile again. + # This ensures that the inheritance goes well and all "cut up" subclasses of the xmlMaterial profile + # are also correctly created. + with open(containers[0].getPath(), encoding="utf-8") as f: + duplicated_container.deserialize(f.read()) + duplicated_container.setDirty(True) + self._container_registry.addContainer(duplicated_container) + + # Factory function, used by QML + @staticmethod + def createContainerManager(engine, js_engine): + return ContainerManager() + + def _performMerge(self, merge_into, merge): + assert isinstance(merge, type(merge_into)) + + if merge == merge_into: + return + + for key in merge.getAllKeys(): + merge_into.setProperty(key, "value", merge.getProperty(key, "value")) + + merge.clear() + def _updateContainerNameFilters(self): self._container_name_filters = {} for plugin_id, container_type in UM.Settings.ContainerRegistry.getContainerTypes(): @@ -394,7 +677,88 @@ class ContainerManager(QObject): name_filter = "{0} ({1})".format(mime_type.comment, suffix_list) self._container_name_filters[name_filter] = entry - # Factory function, used by QML - @staticmethod - def createContainerManager(engine, js_engine): - return ContainerManager() + ## Return a generator that iterates over a set of containers that are filtered by machine and material when needed. + # + # \param kwargs Initial search criteria that the containers need to match. + # + # \return A generator that iterates over the list of containers matching the search criteria. + def _getFilteredContainers(self, **kwargs): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return False + + criteria = kwargs + + filter_by_material = False + + if global_stack.getMetaDataEntry("has_machine_quality"): + definition = global_stack.getBottom() + definition_id = definition.getMetaDataEntry("quality_definition", definition.getId()) + criteria["definition"] = definition_id + + filter_by_material = global_stack.getMetaDataEntry("has_materials") + + material_ids = [] + if filter_by_material: + for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + material_ids.append(stack.findContainer(type = "material").getId()) + + containers = self._container_registry.findInstanceContainers(**criteria) + for container in containers: + # If the machine specifies we should filter by material, exclude containers that do not match any active material. + if filter_by_material and container.getMetaDataEntry("material") not in material_ids: + continue + + yield container + + ## Creates a unique ID for a container by prefixing the name with the stack ID. + # + # This method creates a unique ID for a container by prefixing it with a specified stack ID. + # This is done to ensure we have an easily identified ID for quality changes, which have the + # same name across several stacks. + # + # \param stack_id The ID of the stack to prepend. + # \param container_name The name of the container that we are creating a unique ID for. + # + # \return Container name prefixed with stack ID, in lower case with spaces replaced by underscores. + def _createUniqueId(self, stack_id, container_name): + result = stack_id + "_" + container_name + result = result.lower() + result.replace(" ", "_") + return result + + ## Create a quality changes container for a specified quality container. + # + # \param quality_container The quality container to create a changes container for. + # \param new_name The name of the new quality_changes container. + # \param stack_id The ID of the container stack the new container "belongs to". It is used primarily to ensure a unique ID. + # + # \return A new quality_changes container with the specified container as base. + def _createQualityChanges(self, quality_container, new_name, stack_id): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + assert global_stack is not None + + # Create a new quality_changes container for the quality. + quality_changes = UM.Settings.InstanceContainer(self._createUniqueId(stack_id, new_name)) + quality_changes.setName(new_name) + quality_changes.addMetaDataEntry("type", "quality_changes") + quality_changes.addMetaDataEntry("quality", quality_container.getMetaDataEntry("quality_type")) + + # If we are creating a container for an extruder, ensure we add that to the container + if stack_id != global_stack.getId(): + quality_changes.addMetaDataEntry("extruder", stack_id) + + # If the machine specifies qualities should be filtered, ensure we match the current criteria. + if not global_stack.getMetaDataEntry("has_machine_quality"): + quality_changes.setDefinition(self._container_registry.findContainers(id = "fdmprinter")[0]) + else: + definition = global_stack.getBottom() + definition_id = definition.getMetaDataEntry("quality_definition", definition.getId()) + definition = self._container_registry.findContainers(id=definition_id)[0] + quality_changes.setDefinition(definition) + + if global_stack.getMetaDataEntry("has_materials"): + material = quality_container.getMetaDataEntry("material") + quality_changes.addMetaDataEntry("material", material) + + return quality_changes diff --git a/cura/Settings/ContainerSettingsModel.py b/cura/Settings/ContainerSettingsModel.py index f0fb91d471..5d7a252a4f 100644 --- a/cura/Settings/ContainerSettingsModel.py +++ b/cura/Settings/ContainerSettingsModel.py @@ -31,7 +31,7 @@ class ContainerSettingsModel(ListModel): self._update() def _update(self): - self.clear() + items = [] if len(self._container_ids) == 0: return @@ -64,14 +64,15 @@ class ContainerSettingsModel(ListModel): else: values.append("") - self.appendItem({ + items.append({ "key": key, "values": values, "label": definition.label, "unit": definition.unit, "category": category.label }) - self.sort(lambda k: (k["category"], k["key"])) + items.sort(key = lambda k: (k["category"], k["key"])) + self.setItems(items) ## Set the ids of the containers which have the settings this model should list. # Also makes sure the model updates when the containers have property changes diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 990143f7bb..87dec62f8d 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -58,12 +58,10 @@ class CuraContainerRegistry(ContainerRegistry): ## Exports an profile to a file # - # \param instance_id \type{str} the ID of the profile to export. + # \param instance_ids \type{list} the IDs of the profiles to export. # \param file_name \type{str} the full path and filename to export to. # \param file_type \type{str} the file type with the format " (*.)" - def exportProfile(self, instance_id, file_name, file_type): - Logger.log('d', 'exportProfile instance_id: '+str(instance_id)) - + def exportProfile(self, instance_ids, file_name, file_type): # Parse the fileType to deduce what plugin can save the file format. # fileType has the format " (*.)" split = file_type.rfind(" (*.") # Find where the description ends and the extension starts. @@ -82,16 +80,16 @@ class CuraContainerRegistry(ContainerRegistry): catalog.i18nc("@label", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_name)) if result == QMessageBox.No: return - - containers = ContainerRegistry.getInstance().findInstanceContainers(id=instance_id) - if not containers: - return - container = containers[0] + found_containers = [] + for instance_id in instance_ids: + containers = ContainerRegistry.getInstance().findInstanceContainers(id=instance_id) + if containers: + found_containers.append(containers[0]) profile_writer = self._findProfileWriter(extension, description) try: - success = profile_writer.write(file_name, container) + success = profile_writer.write(file_name, found_containers) except Exception as e: Logger.log("e", "Failed to export profile to %s: %s", file_name, str(e)) m = Message(catalog.i18nc("@info:status", "Failed to export profile to {0}: {1}", file_name, str(e)), lifetime = 0) @@ -130,6 +128,7 @@ class CuraContainerRegistry(ContainerRegistry): return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from {0}: {1}", file_name, "Invalid path")} plugin_registry = PluginRegistry.getInstance() + container_registry = ContainerRegistry.getInstance() for plugin_id, meta_data in self._getIOPlugins("profile_reader"): profile_reader = plugin_registry.getPluginObject(plugin_id) try: @@ -146,7 +145,11 @@ class CuraContainerRegistry(ContainerRegistry): return { "status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile.getName()) } else: for profile in profile_or_list: - self._configureProfile(profile, name_seed) + profile.setDirty(True) # Ensure the profiles are correctly saved + if profile.getId() != "": + container_registry.addContainer(profile) + else: + self._configureProfile(profile, name_seed) if len(profile_or_list) == 1: return {"status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile_or_list[0].getName())} @@ -160,7 +163,7 @@ class CuraContainerRegistry(ContainerRegistry): def _configureProfile(self, profile, name_seed): profile.setReadOnly(False) - new_name = self.createUniqueName("quality", "", name_seed, catalog.i18nc("@label", "Custom profile")) + new_name = self.createUniqueName("quality_changes", "", name_seed, catalog.i18nc("@label", "Custom profile")) profile.setName(new_name) profile._id = new_name @@ -170,6 +173,7 @@ class CuraContainerRegistry(ContainerRegistry): profile.addMetaDataEntry("material", self._activeMaterialId()) else: profile.setDefinition(ContainerRegistry.getInstance().findDefinitionContainers(id="fdmprinter")[0]) + ContainerRegistry.getInstance().addContainer(profile) ## Gets a list of profile writer plugins diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 10556096b0..ad6f21b945 100644 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -55,6 +55,13 @@ class ExtruderManager(QObject): map[position] = self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][position].getId() return map + @pyqtSlot(str, result = str) + def getQualityChangesIdByExtruderStackId(self, id): + for position in self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()]: + extruder = self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][position] + if extruder.getId() == id: + return extruder.findContainer(type = "quality_changes").getId() + ## The instance of the singleton pattern. # # It's None if the extruder manager hasn't been created yet. @@ -131,9 +138,9 @@ class ExtruderManager(QObject): # Make sure the next stack is a stack that contains only the machine definition if not extruder_train.getNextStack(): - shallowStack = UM.Settings.ContainerStack(machine_id + "_shallow") - shallowStack.addContainer(machine_definition) - extruder_train.setNextStack(shallowStack) + shallow_stack = UM.Settings.ContainerStack(machine_id + "_shallow") + shallow_stack.addContainer(machine_definition) + extruder_train.setNextStack(shallow_stack) changed = True if changed: self.extrudersChanged.emit(machine_id) @@ -153,7 +160,7 @@ class ExtruderManager(QObject): def createExtruderTrain(self, extruder_definition, machine_definition, position, machine_id): # Cache some things. container_registry = UM.Settings.ContainerRegistry.getInstance() - machine_definition_id = machine_definition.getId() + machine_definition_id = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(machine_definition) # Create a container stack for this extruder. extruder_stack_id = container_registry.uniqueName(extruder_definition.getId()) @@ -215,7 +222,7 @@ class ExtruderManager(QObject): search_criteria = { "type": "quality" } if machine_definition.getMetaDataEntry("has_machine_quality"): - search_criteria["definition"] = machine_definition.id + search_criteria["definition"] = machine_definition_id if machine_definition.getMetaDataEntry("has_materials") and material: search_criteria["material"] = material.id else: @@ -227,14 +234,17 @@ class ExtruderManager(QObject): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) if not containers and preferred_quality: - UM.Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality, machine_id) - search_criteria.pop("id", None) - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) + UM.Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality, machine_id) + search_criteria.pop("id", None) + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) if containers: quality = containers[0] container_stack.addContainer(quality) + empty_quality_changes = container_registry.findInstanceContainers(id = "empty_quality_changes")[0] + container_stack.addContainer(empty_quality_changes) + user_profile = container_registry.findInstanceContainers(type = "user", extruder = extruder_stack_id) if user_profile: # There was already a user profile, loaded from settings. user_profile = user_profile[0] @@ -248,9 +258,9 @@ class ExtruderManager(QObject): # Make sure the next stack is a stack that contains only the machine definition if not container_stack.getNextStack(): - shallowStack = UM.Settings.ContainerStack(machine_id + "_shallow") - shallowStack.addContainer(machine_definition) - container_stack.setNextStack(shallowStack) + shallow_stack = UM.Settings.ContainerStack(machine_id + "_shallow") + shallow_stack.addContainer(machine_definition) + container_stack.setNextStack(shallow_stack) container_registry.addContainer(container_stack) @@ -274,6 +284,20 @@ class ExtruderManager(QObject): for name in self._extruder_trains[machine_id]: yield self._extruder_trains[machine_id][name] + ## Returns a generator that will iterate over the global stack and per-extruder stacks. + # + # The first generated element is the global container stack. After that any extruder stacks are generated. + def getActiveGlobalAndExtruderStacks(self): + global_stack = UM.Application.getInstance().getGlobalContainerStack() + if not global_stack: + return + + yield global_stack + + global_id = global_stack.getId() + for name in self._extruder_trains[global_id]: + yield self._extruder_trains[global_id][name] + def __globalContainerStackChanged(self): self._addCurrentMachineExtruders() self.activeExtruderChanged.emit() @@ -313,6 +337,17 @@ class ExtruderManager(QObject): return result + ## Get all extruder values for a certain setting. + # + # This is exposed to qml for display purposes + # + # \param key The key of the setting to retieve values for. + # + # \return String representing the extruder values + @pyqtSlot(str, result="QList") + def getInstanceExtruderValues(self, key): + return ExtruderManager.getExtruderValues(key) + ## Get the value for a setting from a specific extruder. # # This is exposed to SettingFunction to use in value functions. diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 155f1a0df1..0ba6cdcfd6 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -46,6 +46,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): self.addRoleName(self.IndexRole, "index") self._add_global = False + self._simple_names = False self._active_extruder_stack = None @@ -70,6 +71,21 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): def addGlobal(self): return self._add_global + ## Set the simpleNames property. + def setSimpleNames(self, simple_names): + if simple_names != self._simple_names: + self._simple_names = simple_names + self.simpleNamesChanged.emit() + self._updateExtruders() + + ## Emitted when the simpleNames property changes. + simpleNamesChanged = pyqtSignal() + + ## Whether or not the model should show all definitions regardless of visibility. + @pyqtProperty(bool, fset = setSimpleNames, notify = simpleNamesChanged) + def simpleNames(self): + return self._simple_names + def _onActiveExtruderChanged(self): manager = ExtruderManager.getInstance() active_extruder_stack = manager.getActiveExtruderStack() @@ -97,9 +113,10 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): changed = False if self.rowCount() != 0: - self.clear() changed = True + items = [] + global_container_stack = UM.Application.getInstance().getGlobalContainerStack() if global_container_stack: if self._add_global: @@ -111,14 +128,14 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "color": color, "index": -1 } - self.appendItem(item) + items.append(item) changed = True manager = ExtruderManager.getInstance() for extruder in manager.getMachineExtruders(global_container_stack.getId()): extruder_name = extruder.getName() material = extruder.findContainer({ "type": "material" }) - if material: + if material and not self._simple_names: extruder_name = "%s (%s)" % (material.getName(), extruder_name) position = extruder.getMetaDataEntry("position", default = "0") # Get the position try: @@ -133,9 +150,10 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): "color": color, "index": position } - self.appendItem(item) + items.append(item) changed = True if changed: - self.sort(lambda item: item["index"]) + items.sort(key = lambda i: i["index"]) + self.setItems(items) self.modelChanged.emit() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 42784e4e38..5a91bc1706 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -7,6 +7,8 @@ from PyQt5.QtWidgets import QMessageBox from UM.Application import Application from UM.Preferences import Preferences from UM.Logger import Logger +from UM.Message import Message +from UM.Settings.SettingRelation import RelationType import UM.Settings @@ -17,6 +19,7 @@ from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") import time +import os class MachineManager(QObject): def __init__(self, parent = None): @@ -26,16 +29,17 @@ class MachineManager(QObject): self._global_container_stack = None Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + ## When the global container is changed, active material probably needs to be updated. + self.globalContainerChanged.connect(self.activeMaterialChanged) + self.globalContainerChanged.connect(self.activeVariantChanged) + self.globalContainerChanged.connect(self.activeQualityChanged) + self._active_stack_valid = None self._onGlobalContainerChanged() ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged) self._onActiveExtruderStackChanged() - ## When the global container is changed, active material probably needs to be updated. - self.globalContainerChanged.connect(self.activeMaterialChanged) - self.globalContainerChanged.connect(self.activeVariantChanged) - self.globalContainerChanged.connect(self.activeQualityChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeMaterialChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeVariantChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeQualityChanged) @@ -47,6 +51,7 @@ class MachineManager(QObject): self._empty_variant_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_variant")[0] self._empty_material_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_material")[0] self._empty_quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0] + self._empty_quality_changes_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality_changes")[0] Preferences.getInstance().addPreference("cura/active_machine", "") @@ -115,35 +120,10 @@ class MachineManager(QObject): if matching_extruder and matching_extruder.findContainer({"type": "variant"}).getName() != hotend_id: # Save the material that needs to be changed. Multiple changes will be handled by the callback. self._auto_hotends_changed[str(index)] = containers[0].getId() - Application.getInstance().messageBox(catalog.i18nc("@window:title", "Changes on the Printer"), - catalog.i18nc("@label", - "Do you want to change the materials and hotends to match the material in your printer?"), - catalog.i18nc("@label", - "The materials and / or hotends on your printer were changed. For best results always slice for the materials . hotends that are inserted in your printer."), - buttons=QMessageBox.Yes + QMessageBox.No, - icon=QMessageBox.Question, - callback=self._materialHotendChangedCallback) - - + self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) else: Logger.log("w", "No variant found for printer definition %s with id %s" % (self._global_container_stack.getBottom().getId(), hotend_id)) - def _autoUpdateHotends(self): - extruder_manager = ExtruderManager.getInstance() - for position in self._auto_hotends_changed: - hotend_id = self._auto_hotends_changed[position] - old_index = extruder_manager.activeExtruderIndex - - if old_index != int(position): - extruder_manager.setActiveExtruderIndex(int(position)) - else: - old_index = None - Logger.log("d", "Setting hotend variant of hotend %s to %s" % (position, hotend_id)) - self.setActiveVariant(hotend_id) - - if old_index is not None: - extruder_manager.setActiveExtruderIndex(old_index) - def _onMaterialIdChanged(self, index, material_id): if not self._global_container_stack: return @@ -164,10 +144,7 @@ class MachineManager(QObject): if matching_extruder and matching_extruder.findContainer({"type":"material"}).getMetaDataEntry("GUID") != material_id: # Save the material that needs to be changed. Multiple changes will be handled by the callback. self._auto_materials_changed[str(index)] = containers[0].getId() - Application.getInstance().messageBox(catalog.i18nc("@window:title", "Changes on the Printer"), catalog.i18nc("@label", "Do you want to change the materials and hotends to match the material in your printer?"), - catalog.i18nc("@label", "The materials and / or hotends on your printer were changed. For best results always slice for the materials and hotends that are inserted in your printer."), - buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._materialHotendChangedCallback) - + self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) else: Logger.log("w", "No material definition found for printer definition %s and GUID %s" % (definition_id, material_id)) @@ -196,107 +173,27 @@ class MachineManager(QObject): if old_index is not None: extruder_manager.setActiveExtruderIndex(old_index) - def _onGlobalPropertyChanged(self, key, property_name): - if property_name == "value": - ## We can get recursion issues. So we store a list of keys that we are still handling to prevent this. - if key in self._global_event_keys: - return - self._global_event_keys.add(key) - self.globalValueChanged.emit() + def _autoUpdateHotends(self): + extruder_manager = ExtruderManager.getInstance() + for position in self._auto_hotends_changed: + hotend_id = self._auto_hotends_changed[position] + old_index = extruder_manager.activeExtruderIndex - if self._active_container_stack and self._active_container_stack != self._global_container_stack: - # Make the global current settings mirror the stack values appropriate for this setting - if self._active_container_stack.getProperty("extruder_nr", "value") == int(self._active_container_stack.getProperty(key, "global_inherits_stack")): - - new_value = self._active_container_stack.getProperty(key, "value") - self._global_container_stack.getTop().setProperty(key, "value", new_value) - - # Global-only setting values should be set on all extruders and the global stack - if not self._global_container_stack.getProperty(key, "settable_per_extruder"): - extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) - target_stack_position = int(self._active_container_stack.getProperty(key, "global_inherits_stack")) - if target_stack_position == -1: # Prevent -1 from selecting wrong stack. - target_stack = self._active_container_stack - else: - target_stack = extruder_stacks[target_stack_position] - new_value = target_stack.getProperty(key, "value") - target_stack_has_user_value = target_stack.getTop().getInstance(key) != None - for extruder_stack in extruder_stacks: - if extruder_stack != target_stack: - if target_stack_has_user_value: - extruder_stack.getTop().setProperty(key, "value", new_value) - else: - # Remove from the value from the other stacks as well, unless the - # top value from the other stacklevels is different than the new value - for container in extruder_stack.getContainers(): - if container.__class__ == UM.Settings.InstanceContainer and container.getInstance(key) != None: - if container.getProperty(key, "value") != new_value: - # It could be that the setting needs to be removed instead of updated. - temp = extruder_stack - containers = extruder_stack.getContainers() - # Ensure we have the entire 'chain' - while temp.getNextStack(): - temp = temp.getNextStack() - containers.extend(temp.getContainers()) - instance_needs_removal = False - - if len(containers) > 1: - for index in range(1, len(containers)): - deeper_container = containers[index] - if deeper_container.getProperty(key, "value") is None: - continue # Deeper container does not have the value, so continue. - if deeper_container.getProperty(key, "value") == new_value: - # Removal will result in correct value, so do that. - # We do this to prevent the reset from showing up unneeded. - instance_needs_removal = True - break - else: - # Container has the value, but it's not the same. Stop looking. - break - if instance_needs_removal: - extruder_stack.getTop().removeInstance(key) - else: - extruder_stack.getTop().setProperty(key, "value", new_value) - else: - # Check if we really need to remove something. - if extruder_stack.getProperty(key, "value") != new_value: - extruder_stack.getTop().removeInstance(key) - break - if self._global_container_stack.getProperty(key, "value") != new_value: - self._global_container_stack.getTop().setProperty(key, "value", new_value) - self._global_event_keys.remove(key) - - if property_name == "global_inherits_stack": - if self._active_container_stack and self._active_container_stack != self._global_container_stack: - # Update the global user value when the "global_inherits_stack" function points to a different stack - extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())) - target_stack_position = int(self._active_container_stack.getProperty(key, "global_inherits_stack")) - if target_stack_position == -1: # Prevent -1 from selecting wrong stack. - target_stack = self._active_container_stack - else: - target_stack = extruder_stacks[target_stack_position] - - new_value = target_stack.getProperty(key, "value") - if self._global_container_stack.getProperty(key, "value") != new_value: - self._global_container_stack.getTop().setProperty(key, "value", new_value) - - if property_name == "validationState": - if self._active_stack_valid: - changed_validation_state = self._active_container_stack.getProperty(key, property_name) - if changed_validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError): - self._active_stack_valid = False - self.activeValidationChanged.emit() + if old_index != int(position): + extruder_manager.setActiveExtruderIndex(int(position)) else: - has_errors = self._checkStackForErrors(self._active_container_stack) - if not has_errors: - self._active_stack_valid = True - self.activeValidationChanged.emit() + old_index = None + Logger.log("d", "Setting hotend variant of hotend %s to %s" % (position, hotend_id)) + self.setActiveVariant(hotend_id) + + if old_index is not None: + extruder_manager.setActiveExtruderIndex(old_index) def _onGlobalContainerChanged(self): if self._global_container_stack: self._global_container_stack.nameChanged.disconnect(self._onMachineNameChanged) self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) - self._global_container_stack.propertyChanged.disconnect(self._onGlobalPropertyChanged) + self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged) material = self._global_container_stack.findContainer({"type": "material"}) material.nameChanged.disconnect(self._onMaterialNameChanged) @@ -313,7 +210,7 @@ class MachineManager(QObject): Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) self._global_container_stack.nameChanged.connect(self._onMachineNameChanged) self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) - self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) + self._global_container_stack.propertyChanged.connect(self._onPropertyChanged) material = self._global_container_stack.findContainer({"type": "material"}) material.nameChanged.connect(self._onMaterialNameChanged) @@ -324,11 +221,11 @@ class MachineManager(QObject): self.blurSettings.emit() # Ensure no-one has focus. if self._active_container_stack and self._active_container_stack != self._global_container_stack: self._active_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) - self._active_container_stack.propertyChanged.disconnect(self._onGlobalPropertyChanged) + self._active_container_stack.propertyChanged.disconnect(self._onPropertyChanged) self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack() if self._active_container_stack: self._active_container_stack.containersChanged.connect(self._onInstanceContainersChanged) - self._active_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged) + self._active_container_stack.propertyChanged.connect(self._onPropertyChanged) else: self._active_container_stack = self._global_container_stack self._active_stack_valid = not self._checkStackForErrors(self._active_container_stack) @@ -337,17 +234,6 @@ class MachineManager(QObject): def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") - if self._active_container_stack and self._active_container_stack != self._global_container_stack: - if int(self._active_container_stack.getProperty("extruder_nr", "value")) == 0: - global_container = self._global_container_stack.findContainer({"type": container_type}) - if global_container and global_container != container: - container_index = self._global_container_stack.getContainerIndex(global_container) - self._global_container_stack.replaceContainer(container_index, container) - - for key in container.getAllKeys(): - # Make sure the values in this profile are distributed to other stacks if necessary - self._onGlobalPropertyChanged(key, "value") - if container_type == "material": self.activeMaterialChanged.emit() elif container_type == "variant": @@ -355,6 +241,38 @@ class MachineManager(QObject): elif container_type == "quality": self.activeQualityChanged.emit() + def _onPropertyChanged(self, key, property_name): + if property_name == "value": + # If a setting is not settable per extruder, but "has enabled relations" that are settable per extruder + # we need to copy the value to global, so that the front-end displays the right settings. + if not self._active_container_stack.getProperty(key, "settable_per_extruder"): + relations = self._global_container_stack.getBottom()._getDefinition(key).relations + for relation in filter(lambda r: r.role == "enabled" and r.type == RelationType.RequiredByTarget, relations): + # Target setting is settable per extruder + if self._active_container_stack.getProperty(relation.target.key, "settable_per_extruder"): + new_value = self._global_container_stack.getProperty(key, "value") + stacks = [stack for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())] + for extruder_stack in stacks: + if extruder_stack.getProperty(key, "value") != new_value: + extruder_stack.getTop().setProperty(key, "value", new_value) + break + + if property_name == "validationState": + if self._active_stack_valid: + if self._active_container_stack.getProperty(key, "settable_per_extruder"): + changed_validation_state = self._active_container_stack.getProperty(key, property_name) + else: + changed_validation_state = self._global_container_stack.getProperty(key, property_name) + if changed_validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError): + self._active_stack_valid = False + self.activeValidationChanged.emit() + else: + if not self._checkStackForErrors(self._active_container_stack) and not self._checkStackForErrors(self._global_container_stack): + self._active_stack_valid = True + self.activeValidationChanged.emit() + + self.activeStackChanged.emit() + @pyqtSlot(str) def setActiveMachine(self, stack_id): containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = stack_id) @@ -374,7 +292,7 @@ class MachineManager(QObject): variant_instance_container = self._updateVariantContainer(definition) material_instance_container = self._updateMaterialContainer(definition, variant_instance_container) - quality_instance_container = self._updateQualityContainer(definition, material_instance_container) + quality_instance_container = self._updateQualityContainer(definition, variant_instance_container, material_instance_container) current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") current_settings_instance_container.addMetaDataEntry("machine", name) @@ -382,7 +300,6 @@ class MachineManager(QObject): current_settings_instance_container.setDefinition(definitions[0]) container_registry.addContainer(current_settings_instance_container) - # If a definition is found, its a list. Should only have one item. new_global_stack.addContainer(definition) if variant_instance_container: new_global_stack.addContainer(variant_instance_container) @@ -390,6 +307,8 @@ class MachineManager(QObject): new_global_stack.addContainer(material_instance_container) if quality_instance_container: new_global_stack.addContainer(quality_instance_container) + + new_global_stack.addContainer(self._empty_quality_changes_container) new_global_stack.addContainer(current_settings_instance_container) ExtruderManager.getInstance().addMachineExtruders(definition, new_global_stack.getId()) @@ -430,11 +349,29 @@ class MachineManager(QObject): ## Check if the global_container has instances in the user container @pyqtProperty(bool, notify = activeStackChanged) def hasUserSettings(self): - if not self._active_container_stack: + if not self._global_container_stack: return False - user_settings = self._active_container_stack.getTop().findInstances(**{}) - return len(user_settings) != 0 + if self._global_container_stack.getTop().findInstances(): + return True + + for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()): + if stack.getTop().findInstances(): + return True + + return False + + ## Delete a user setting from the global stack and all extruder stacks. + # \param key \type{str} the name of the key to delete + @pyqtSlot(str) + def clearUserSettingAllCurrentStacks(self, key): + if not self._global_container_stack: + return + + self._global_container_stack.getTop().removeInstance(key) + + for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()): + stack.getTop().removeInstance(key) ## Check if the global profile does not contain error states # Note that the _active_stack_valid is cached due to performance issues @@ -489,9 +426,47 @@ class MachineManager(QObject): return "" + @pyqtProperty("QVariantMap", notify = activeMaterialChanged) + def allActiveMaterialIds(self): + if not self._global_container_stack: + return {} + + result = {} + + for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + material_container = stack.findContainer(type = "material") + if not material_container: + continue + + result[stack.getId()] = material_container.getId() + + return result + + ## Get the Material ID associated with the currently active material + # \returns MaterialID (string) if found, empty string otherwise + @pyqtProperty(str, notify=activeQualityChanged) + def activeQualityMaterialId(self): + if self._active_container_stack: + quality = self._active_container_stack.findContainer({"type": "quality"}) + if quality: + material_id = quality.getMetaDataEntry("material") + if material_id: + # if the currently active machine inherits its qualities from a different machine + # definition, make sure to return a material that is relevant to that machine definition + definition_id = self.activeDefinitionId + quality_definition_id = self.activeQualityDefinitionId + if definition_id != quality_definition_id: + material_id = material_id.replace(definition_id, quality_definition_id, 1) + + return material_id + return "" + @pyqtProperty(str, notify=activeQualityChanged) def activeQualityName(self): if self._active_container_stack: + quality = self._active_container_stack.findContainer({"type": "quality_changes"}) + if quality and quality != self._empty_quality_changes_container: + return quality.getName() quality = self._active_container_stack.findContainer({"type": "quality"}) if quality: return quality.getName() @@ -499,12 +474,31 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self): - if self._active_container_stack: - quality = self._active_container_stack.findContainer({"type": "quality"}) + if self._global_container_stack: + quality = self._global_container_stack.findContainer({"type": "quality_changes"}) + if quality and quality != self._empty_quality_changes_container: + return quality.getId() + quality = self._global_container_stack.findContainer({"type": "quality"}) if quality: return quality.getId() return "" + @pyqtProperty(str, notify = activeQualityChanged) + def activeQualityType(self): + if self._global_container_stack: + quality = self._global_container_stack.findContainer(type = "quality") + if quality: + return quality.getMetaDataEntry("quality_type") + return "" + + @pyqtProperty(str, notify = activeQualityChanged) + def activeQualityChangesId(self): + if self._global_container_stack: + changes = self._global_container_stack.findContainer(type = "quality_changes") + if changes: + return changes.getId() + return "" + ## Check if a container is read_only @pyqtSlot(str, result = bool) def isReadOnly(self, container_id): @@ -526,142 +520,62 @@ class MachineManager(QObject): if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value: extruder_stack.getTop().setProperty(key, "value", new_value) - @pyqtSlot(result = str) - def newQualityContainerFromQualityAndUser(self): - new_container_id = self.duplicateContainer(self.activeQualityId) - if new_container_id == "": - return - self.blurSettings.emit() - self.updateQualityContainerFromUserContainer(new_container_id) - self.setActiveQuality(new_container_id) - return new_container_id - - @pyqtSlot(str, result=str) - def duplicateContainer(self, container_id): - if not self._active_container_stack: - return "" - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) - if containers: - new_name = self._createUniqueName("quality", "", containers[0].getName(), catalog.i18nc("@label", "Custom profile")) - - new_container = containers[0].duplicate(new_name, new_name) - - UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) - - return new_name - - return "" - - @pyqtSlot(str, str) - def renameQualityContainer(self, container_id, new_name): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") - if containers: - new_name = self._createUniqueName("quality", containers[0].getName(), new_name, - catalog.i18nc("@label", "Custom profile")) - - if containers[0].getName() == new_name: - # Nothing to do. - return - - # As we also want the id of the container to be changed (so that profile name is the name of the file - # on disk. We need to create a new instance and remove it (so the old file of the container is removed) - # If we don't do that, we might get duplicates & other weird issues. - new_container = UM.Settings.InstanceContainer("") - new_container.deserialize(containers[0].serialize()) - - # Actually set the name - new_container.setName(new_name) - new_container._id = new_name # Todo: Fix proper id change function for this. - - # Add the "new" container. - UM.Settings.ContainerRegistry.getInstance().addContainer(new_container) - - # Ensure that the renamed profile is saved -before- we remove the old profile. - Application.getInstance().saveSettings() - - # Actually set & remove new / old quality. - self.setActiveQuality(new_name) - self.removeQualityContainer(containers[0].getId()) - - @pyqtSlot(str) - def removeQualityContainer(self, container_id): - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) - if not containers or not self._active_container_stack: - return - - # If the container that is being removed is the currently active container, set another machine as the active container - activate_new_container = container_id == self.activeQualityId - - UM.Settings.ContainerRegistry.getInstance().removeContainer(container_id) - - if activate_new_container: - definition_id = "fdmprinter" if not self.filterQualityByMachine else self.activeDefinitionId - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition_id) - if containers: - self.setActiveQuality(containers[0].getId()) - self.activeQualityChanged.emit() - - @pyqtSlot(str) - @pyqtSlot() - def updateQualityContainerFromUserContainer(self, quality_id = None): - if not self._active_container_stack: - return - - if quality_id: - quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id, type = "quality") - if quality: - quality = quality[0] - else: - quality = self._active_container_stack.findContainer({"type": "quality"}) - - if not quality: - return - - user_settings = self._active_container_stack.getTop() - - for key in user_settings.getAllKeys(): - quality.setProperty(key, "value", user_settings.getProperty(key, "value")) - self.clearUserSettings() # As all users settings are noq a quality, remove them. - - @pyqtSlot(str) def setActiveMaterial(self, material_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = material_id) if not containers or not self._active_container_stack: return - - old_material = self._active_container_stack.findContainer({"type":"material"}) + Logger.log("d", "Attempting to change the active material to %s", material_id) + old_variant = self._active_container_stack.findContainer({"type": "variant"}) + old_material = self._active_container_stack.findContainer({"type": "material"}) old_quality = self._active_container_stack.findContainer({"type": "quality"}) - if old_material: - old_material.nameChanged.disconnect(self._onMaterialNameChanged) + old_quality_changes = self._active_container_stack.findContainer({"type": "quality_changes"}) + if not old_material: + Logger.log("w", "While trying to set the active material, no material was found to replace it.") + return + if old_quality_changes.getId() == "empty_quality_changes": #Don't want the empty one. + old_quality_changes = None + self.blurSettings.emit() + old_material.nameChanged.disconnect(self._onMaterialNameChanged) - material_index = self._active_container_stack.getContainerIndex(old_material) - self._active_container_stack.replaceContainer(material_index, containers[0]) + material_index = self._active_container_stack.getContainerIndex(old_material) + self._active_container_stack.replaceContainer(material_index, containers[0]) - containers[0].nameChanged.connect(self._onMaterialNameChanged) + containers[0].nameChanged.connect(self._onMaterialNameChanged) - preferred_quality_name = None - if old_quality: - preferred_quality_name = old_quality.getName() + if containers[0].getMetaDataEntry("compatible") == False: + message = Message(catalog.i18nc("@info:status", + "The selected material is imcompatible with the selected machine or configuration.")) + message.show() - self.setActiveQuality(self._updateQualityContainer(self._global_container_stack.getBottom(), containers[0], preferred_quality_name).id) + + if old_quality: + if old_quality_changes: + new_quality = self._updateQualityChangesContainer(old_quality.getMetaDataEntry("quality_type"), old_quality_changes.getMetaDataEntry("name")) + else: + new_quality = self._updateQualityContainer(self._global_container_stack.getBottom(), old_variant, containers[0], old_quality.getName()) else: - Logger.log("w", "While trying to set the active material, no material was found to replace.") + new_quality = self._updateQualityContainer(self._global_container_stack.getBottom(), old_variant, containers[0]) + + self.setActiveQuality(new_quality.getId()) @pyqtSlot(str) def setActiveVariant(self, variant_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = variant_id) if not containers or not self._active_container_stack: return + Logger.log("d", "Attempting to change the active variant to %s", variant_id) old_variant = self._active_container_stack.findContainer({"type": "variant"}) old_material = self._active_container_stack.findContainer({"type": "material"}) if old_variant: + self.blurSettings.emit() variant_index = self._active_container_stack.getContainerIndex(old_variant) self._active_container_stack.replaceContainer(variant_index, containers[0]) preferred_material = None if old_material: preferred_material_name = old_material.getName() + self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0], preferred_material_name).id) else: Logger.log("w", "While trying to set the active variant, no variant was found to replace.") @@ -669,32 +583,96 @@ class MachineManager(QObject): @pyqtSlot(str) def setActiveQuality(self, quality_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id) - if not containers or not self._active_container_stack: + if not containers or not self._global_container_stack: return - old_quality = self._active_container_stack.findContainer({"type": "quality"}) - if old_quality and old_quality != containers[0]: - old_quality.nameChanged.disconnect(self._onQualityNameChanged) + Logger.log("d", "Attempting to change the active quality to %s", quality_id) - quality_index = self._active_container_stack.getContainerIndex(old_quality) + self.blurSettings.emit() + quality_container = None + quality_changes_container = self._empty_quality_changes_container - self._active_container_stack.replaceContainer(quality_index, containers[0]) + container_type = containers[0].getMetaDataEntry("type") - containers[0].nameChanged.connect(self._onQualityNameChanged) - - if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: - # Ask the user if the user profile should be cleared or not (discarding the current settings) - # In Simple Mode we assume the user always wants to keep the (limited) current settings - details = catalog.i18nc("@label", "You made changes to the following setting(s):") - user_settings = self._active_container_stack.getTop().findInstances(**{}) - for setting in user_settings: - details = details + "\n " + setting.definition.label - - Application.getInstance().messageBox(catalog.i18nc("@window:title", "Switched profiles"), catalog.i18nc("@label", "Do you want to transfer your changed settings to this profile?"), - catalog.i18nc("@label", "If you transfer your settings they will override settings in the profile."), details, - buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._keepUserSettingsDialogCallback) + if container_type == "quality": + quality_container = containers[0] + elif container_type == "quality_changes": + quality_changes_container = containers[0] + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers( + quality_type = quality_changes_container.getMetaDataEntry("quality")) + if not containers: + Logger.log("e", "Could not find quality %s for changes %s, not changing quality", quality_changes_container.getMetaDataEntry("quality"), quality_changes_container.getId()) + return + quality_container = containers[0] else: - Logger.log("w", "While trying to set the active quality, no quality was found to replace.") + Logger.log("e", "Tried to set quality to a container that is not of the right type") + return + + quality_type = quality_container.getMetaDataEntry("quality_type") + if not quality_type: + quality_type = quality_changes_container.getName() + + for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): + extruder_id = stack.getId() if stack != self._global_container_stack else None + + criteria = { "quality_type": quality_type, "extruder": extruder_id } + + material = stack.findContainer(type = "material") + if material and material is not self._empty_material_container: + criteria["material"] = material.getId() + + if self._global_container_stack.getMetaDataEntry("has_machine_quality"): + criteria["definition"] = self.activeQualityDefinitionId + else: + criteria["definition"] = "fdmprinter" + + stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) + if not stack_quality: + criteria.pop("extruder") + stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) + if not stack_quality: + stack_quality = quality_container + else: + stack_quality = stack_quality[0] + else: + stack_quality = stack_quality[0] + + if quality_changes_container != self._empty_quality_changes_container: + stack_quality_changes = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = quality_changes_container.getName(), extruder = extruder_id)[0] + else: + stack_quality_changes = self._empty_quality_changes_container + + old_quality = stack.findContainer(type = "quality") + if old_quality: + old_quality.nameChanged.disconnect(self._onQualityNameChanged) + else: + Logger.log("w", "Could not find old quality while changing active quality.") + + old_changes = stack.findContainer(type = "quality_changes") + if old_changes: + old_changes.nameChanged.disconnect(self._onQualityNameChanged) + else: + Logger.log("w", "Could not find old quality_changes while changing active quality.") + + stack.replaceContainer(stack.getContainerIndex(old_quality), stack_quality) + stack.replaceContainer(stack.getContainerIndex(old_changes), stack_quality_changes) + + stack_quality.nameChanged.connect(self._onQualityNameChanged) + stack_quality_changes.nameChanged.connect(self._onQualityNameChanged) + + if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: + # Ask the user if the user profile should be cleared or not (discarding the current settings) + # In Simple Mode we assume the user always wants to keep the (limited) current settings + details = catalog.i18nc("@label", "You made changes to the following setting(s):") + user_settings = self._active_container_stack.getTop().findInstances(**{}) + for setting in user_settings: + details = details + "\n " + setting.definition.label + + Application.getInstance().messageBox(catalog.i18nc("@window:title", "Switched profiles"), catalog.i18nc("@label", "Do you want to transfer your changed settings to this profile?"), + catalog.i18nc("@label", "If you transfer your settings they will override settings in the profile."), details, + buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._keepUserSettingsDialogCallback) + + self.activeQualityChanged.emit() def _keepUserSettingsDialogCallback(self, button): if button == QMessageBox.Yes: @@ -702,7 +680,11 @@ class MachineManager(QObject): pass elif button == QMessageBox.No: # No, discard the settings in the user profile - self.clearUserSettings() + global_stack = Application.getInstance().getGlobalContainerStack() + for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()): + extruder.getTop().clear() + + global_stack.getTop().clear() @pyqtProperty(str, notify = activeVariantChanged) def activeVariantName(self): @@ -731,6 +713,61 @@ class MachineManager(QObject): return "" + ## Get the Definition ID to use to select quality profiles for the currently active machine + # \returns DefinitionID (string) if found, empty string otherwise + # \sa getQualityDefinitionId + @pyqtProperty(str, notify = globalContainerChanged) + def activeQualityDefinitionId(self): + if self._global_container_stack: + return self.getQualityDefinitionId(self._global_container_stack.getBottom()) + return "" + + ## Get the Definition ID to use to select quality profiles for machines of the specified definition + # This is normally the id of the definition itself, but machines can specify a different definition to inherit qualities from + # \param definition (DefinitionContainer) machine definition + # \returns DefinitionID (string) if found, empty string otherwise + def getQualityDefinitionId(self, definition): + definition_id = definition.getMetaDataEntry("quality_definition") + if not definition_id: + definition_id = definition.getId() + return definition_id + + ## Get the Variant ID to use to select quality profiles for the currently active variant + # \returns VariantID (string) if found, empty string otherwise + # \sa getQualityVariantId + @pyqtProperty(str, notify = activeVariantChanged) + def activeQualityVariantId(self): + if self._global_container_stack: + variant = self._global_container_stack.findContainer({"type": "variant"}) + if variant: + return self.getQualityVariantId(self._global_container_stack.getBottom(), variant) + return "" + + ## Get the Variant ID to use to select quality profiles for variants of the specified definitions + # This is normally the id of the variant itself, but machines can specify a different definition + # to inherit qualities from, which has consequences for the variant to use as well + # \param definition (DefinitionContainer) machine definition + # \param variant (DefinitionContainer) variant definition + # \returns VariantID (string) if found, empty string otherwise + def getQualityVariantId(self, definition, variant): + variant_id = variant.getId() + definition_id = definition.getId() + quality_definition_id = self.getQualityDefinitionId(definition) + + if definition_id != quality_definition_id: + variant_id = variant_id.replace(definition_id, quality_definition_id, 1) + return variant_id + + ## Gets how the active definition calls variants + # Caveat: per-definition-variant-title is currently not translated (though the fallback is) + @pyqtProperty(str, notify = globalContainerChanged) + def activeDefinitionVariantsName(self): + fallback_title = catalog.i18nc("@label", "Nozzle") + if self._global_container_stack: + return self._global_container_stack.getBottom().getMetaDataEntry("variants_name", fallback_title) + + return fallback_title + @pyqtSlot(str, str) def renameMachine(self, machine_id, new_name): containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id) @@ -825,10 +862,10 @@ class MachineManager(QObject): search_criteria = { "type": "material" } if definition.getMetaDataEntry("has_machine_materials"): - search_criteria["definition"] = definition.id + search_criteria["definition"] = self.getQualityDefinitionId(definition) if definition.getMetaDataEntry("has_variants") and variant_container: - search_criteria["variant"] = variant_container.id + search_criteria["variant"] = self.getQualityVariantId(definition, variant_container) else: search_criteria["definition"] = "fdmprinter" @@ -843,50 +880,120 @@ class MachineManager(QObject): if containers: return containers[0] - if "name" in search_criteria or "id" in search_criteria: + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) + if "variant" in search_criteria or "id" in search_criteria: # If a material by this name can not be found, try a wider set of search criteria - search_criteria.pop("name", None) + search_criteria.pop("variant", None) search_criteria.pop("id", None) - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) if containers: return containers[0] - + Logger.log("w", "Unable to find a material container with provided criteria, returning an empty one instead.") return self._empty_material_container - def _updateQualityContainer(self, definition, material_container = None, preferred_quality_name = None): + def _updateQualityContainer(self, definition, variant_container, material_container = None, preferred_quality_name = None): + container_registry = UM.Settings.ContainerRegistry.getInstance() search_criteria = { "type": "quality" } if definition.getMetaDataEntry("has_machine_quality"): - search_criteria["definition"] = definition.id + search_criteria["definition"] = self.getQualityDefinitionId(definition) if definition.getMetaDataEntry("has_materials") and material_container: search_criteria["material"] = material_container.id else: search_criteria["definition"] = "fdmprinter" - if preferred_quality_name: + if preferred_quality_name and preferred_quality_name != "empty": search_criteria["name"] = preferred_quality_name else: preferred_quality = definition.getMetaDataEntry("preferred_quality") if preferred_quality: search_criteria["id"] = preferred_quality - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) + containers = container_registry.findInstanceContainers(**search_criteria) if containers: return containers[0] + if "material" in search_criteria: + # First check if we can solve our material not found problem by checking if we can find quality containers + # that are assigned to the parents of this material profile. + try: + inherited_files = material_container.getInheritedFiles() + except AttributeError: # Material_container does not support inheritance. + inherited_files = [] + + if inherited_files: + for inherited_file in inherited_files: + # Extract the ID from the path we used to load the file. + search_criteria["material"] = os.path.basename(inherited_file).split(".")[0] + containers = container_registry.findInstanceContainers(**search_criteria) + if containers: + return containers[0] + # We still weren't able to find a quality for this specific material. + # Try to find qualities for a generic version of the material. + material_search_criteria = { "type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic"} + if definition.getMetaDataEntry("has_machine_quality"): + if material_container: + material_search_criteria["definition"] = material_container.getDefinition().id + + if definition.getMetaDataEntry("has_variants"): + material_search_criteria["variant"] = material_container.getMetaDataEntry("variant") + else: + material_search_criteria["definition"] = self.getQualityDefinitionId(definition) + + if definition.getMetaDataEntry("has_variants") and variant_container: + material_search_criteria["variant"] = self.getQualityVariantId(definition, variant_container) + else: + material_search_criteria["definition"] = "fdmprinter" + material_containers = container_registry.findInstanceContainers(**material_search_criteria) + if material_containers: + search_criteria["material"] = material_containers[0].getId() + + containers = container_registry.findInstanceContainers(**search_criteria) + if containers: + return containers[0] + if "name" in search_criteria or "id" in search_criteria: # If a quality by this name can not be found, try a wider set of search criteria search_criteria.pop("name", None) search_criteria.pop("id", None) - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) + containers = container_registry.findInstanceContainers(**search_criteria) if containers: return containers[0] + # Notify user that we were unable to find a matching quality + message = Message(catalog.i18nc("@info:status", "Unable to find a quality profile for this combination. Default settings will be used instead.")) + message.show() return self._empty_quality_container + ## Finds a quality-changes container to use if any other container + # changes. + # + # \param quality_type The quality type to find a quality-changes for. + # \param preferred_quality_changes_name The name of the quality-changes to + # pick, if any such quality-changes profile is available. + def _updateQualityChangesContainer(self, quality_type, preferred_quality_changes_name = None): + container_registry = UM.Settings.ContainerRegistry.getInstance() # Cache. + search_criteria = { "type": "quality_changes" } + + search_criteria["quality"] = quality_type + if preferred_quality_changes_name: + search_criteria["name"] = preferred_quality_changes_name + + # Try to search with the name in the criteria first, since we prefer to have the correct name. + containers = container_registry.findInstanceContainers(**search_criteria) + if containers: # Found one! + return containers[0] + + if "name" in search_criteria: + del search_criteria["name"] # Not found, then drop the name requirement (if we had one) and search again. + containers = container_registry.findInstanceContainers(**search_criteria) + if containers: + return containers[0] + + return self._empty_quality_changes_container # Didn't find anything with the required quality_type. + def _onMachineNameChanged(self): self.globalContainerChanged.emit() diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py new file mode 100644 index 0000000000..2d02d27f72 --- /dev/null +++ b/cura/Settings/QualitySettingsModel.py @@ -0,0 +1,194 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +import collections + +from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt + +import UM.Application +import UM.Logger +import UM.Qt +import UM.Settings + + +class QualitySettingsModel(UM.Qt.ListModel.ListModel): + KeyRole = Qt.UserRole + 1 + LabelRole = Qt.UserRole + 2 + UnitRole = Qt.UserRole + 3 + ProfileValueRole = Qt.UserRole + 4 + UserValueRole = Qt.UserRole + 5 + CategoryRole = Qt.UserRole + 6 + + def __init__(self, parent = None): + super().__init__(parent = parent) + + self._container_registry = UM.Settings.ContainerRegistry.getInstance() + + self._extruder_id = None + self._quality = None + self._material = None + + self.addRoleName(self.KeyRole, "key") + self.addRoleName(self.LabelRole, "label") + self.addRoleName(self.UnitRole, "unit") + self.addRoleName(self.ProfileValueRole, "profile_value") + self.addRoleName(self.UserValueRole, "user_value") + self.addRoleName(self.CategoryRole, "category") + + def setExtruderId(self, extruder_id): + if extruder_id != self._extruder_id: + self._extruder_id = extruder_id + self._update() + self.extruderIdChanged.emit() + + extruderIdChanged = pyqtSignal() + @pyqtProperty(str, fset = setExtruderId, notify = extruderIdChanged) + def extruderId(self): + return self._extruder_id + + def setQuality(self, quality): + if quality != self._quality: + self._quality = quality + self._update() + self.qualityChanged.emit() + + qualityChanged = pyqtSignal() + @pyqtProperty(str, fset = setQuality, notify = qualityChanged) + def quality(self): + return self._quality + + def setMaterial(self, material): + if material != self._material: + self._material = material + self._update() + self.materialChanged.emit() + + materialChanged = pyqtSignal() + @pyqtProperty(str, fset = setMaterial, notify = materialChanged) + def material(self): + return self._material + + def _update(self): + if not self._quality: + return + + items = [] + + settings = collections.OrderedDict() + definition_container = UM.Application.getInstance().getGlobalContainerStack().getBottom() + + containers = self._container_registry.findInstanceContainers(id = self._quality) + if not containers: + UM.Logger.log("w", "Could not find a quality container with id %s", self._quality) + return + + quality_container = None + quality_changes_container = None + + if containers[0].getMetaDataEntry("type") == "quality": + quality_container = containers[0] + else: + quality_changes_container = containers[0] + + criteria = { + "type": "quality", + "quality_type": quality_changes_container.getMetaDataEntry("quality"), + "definition": quality_changes_container.getDefinition().getId() + } + + if self._material: + criteria["material"] = self._material + + quality_container = self._container_registry.findInstanceContainers(**criteria) + if not quality_container: + UM.Logger.log("w", "Could not find a quality container matching quality changes %s", quality_changes_container.getId()) + return + quality_container = quality_container[0] + + quality_type = quality_container.getMetaDataEntry("quality_type") + definition_id = quality_container.getDefinition().getId() + + criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id} + + if self._material: + criteria["material"] = self._material + + criteria["extruder"] = self._extruder_id + + containers = self._container_registry.findInstanceContainers(**criteria) + if not containers: + # Try again, this time without extruder + new_criteria = criteria.copy() + new_criteria.pop("extruder") + containers = self._container_registry.findInstanceContainers(**new_criteria) + + if not containers: + # Try again, this time without material + criteria.pop("material") + containers = self._container_registry.findInstanceContainers(**criteria) + + if not containers: + # Try again, this time without material or extruder + criteria.pop("extruder") # "material" has already been popped + containers = self._container_registry.findInstanceContainers(**criteria) + + if not containers: + UM.Logger.log("Could not find any quality containers matching the search criteria %s" % str(criteria)) + return + + if quality_changes_container: + criteria = {"type": "quality_changes", "quality": quality_type, "definition": definition_id, "name": quality_changes_container.getName()} + if self._extruder_id != "": + criteria["extruder"] = self._extruder_id + else: + criteria["extruder"] = None + + changes = self._container_registry.findInstanceContainers(**criteria) + if changes: + containers.extend(changes) + + global_container_stack = UM.Application.getInstance().getGlobalContainerStack() + is_multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1 + + current_category = "" + for definition in definition_container.findDefinitions(): + if definition.type == "category": + current_category = definition.label + continue + + profile_value = None + for container in containers: + new_value = container.getProperty(definition.key, "value") + if new_value is not None: + profile_value = new_value + + user_value = None + if not self._extruder_id: + user_value = global_container_stack.getTop().getProperty(definition.key, "value") + else: + extruder_stack = self._container_registry.findContainerStacks(id = self._extruder_id) + if extruder_stack: + user_value = extruder_stack[0].getTop().getProperty(definition.key, "value") + + if profile_value is None and user_value is None: + continue + + if is_multi_extrusion: + settable_per_extruder = global_container_stack.getProperty(definition.key, "settable_per_extruder") + # If a setting is not settable per extruder (global) and we're looking at an extruder tab, don't show this value. + if self._extruder_id != "" and not settable_per_extruder: + continue + + # If a setting is settable per extruder (not global) and we're looking at global tab, don't show this value. + if self._extruder_id == "" and settable_per_extruder: + continue + items.append({ + "key": definition.key, + "label": definition.label, + "unit": definition.unit, + "profile_value": "" if profile_value is None else str(profile_value), # it is for display only + "user_value": "" if user_value is None else str(user_value), + "category": current_category + }) + + self.setItems(items) \ No newline at end of file diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index f547d283a4..8c10542069 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -30,7 +30,7 @@ class SettingOverrideDecorator(SceneNodeDecorator): self._stack.addContainer(self._instance) if cura.Settings.ExtruderManager.getInstance().extruderCount > 1: - self._extruder_stack = cura.Settings.ExtruderManager.getInstance().activeExtruderStackId + self._extruder_stack = cura.Settings.ExtruderManager.getInstance().getExtruderStack(0).getId() else: self._extruder_stack = None diff --git a/cura/Settings/__init__.py b/cura/Settings/__init__.py index da8f36c040..5daa00c84f 100644 --- a/cura/Settings/__init__.py +++ b/cura/Settings/__init__.py @@ -10,3 +10,4 @@ from .ExtrudersModel import ExtrudersModel from .MachineManager import MachineManager from .MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler from .SettingOverrideDecorator import SettingOverrideDecorator +from .QualitySettingsModel import QualitySettingsModel diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index 3d6ffd77c9..8041bbb171 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -1,3 +1,98 @@ +[2.3.0] + +*Speed improvements +The first thing you will notice is the speed. STL loading is now 10 to 20 times faster, layerview is significantly faster and slicing speed is slightly improved. + +*Multi Extrusion Support +Machines with multiple extruders are now supported. If you’ve got the Ultimaker Original with the dual extrusion upgrade kit, we’ve got you covered. + +*Custom Machine Support +The new custom machine plug-in allows you to change machine settings with ease. That means it’s now much easier to use Cura with custom machines. + +*Improved Position Tool +Place objects precisely where you want them by manually entering the values for the position. + +*Improved Grouping +It's now possible to transform objects that are already grouped. +Select an individual item in a group or merged object and edit as usual. Just Ctrl + Click and edit away. + +*Enhanced Profile Management +Profile management is improved. You can now easily see and track changes made to your profiles. + +*Improved Setting Visibility +Make multiple settings visible at once. The Visibility Overview setting indicates why a setting is not shown in the sidebar even if it is selected. + +*Improved time estimation +Time estimations are more accurate. Based on our test time estimations should be within 5% accuracy. + +*Optional G-code Machine Prefix +Disable the g-code prefix in Preferences. No more UM2_ on your printer display! + +*Print Weight Estimates +Cura now estimates print weight as well as length. + +*Automatic Import Configuration +Configurations from older installations of Cura 2.1 are automatically imported into the newest installation. + +*Slicing features +*Infill Improvements +We've introduced two new infill types: Tetrahedral and Cubic. They change along with the Z-axis for more uniform strength in all directions. Also, now you can change the density of the infill based on the distance from the top layers. You print get faster, use less material, and maintain the same object strength. + +*Set Acceleration and Jerk by Feature +You can now set Jerk and Acceleration by feature, (infill, walls, top/bottom, etc) for more precision. + +*Outer Wall Offset +Apply an offset to where the outer wall is printed for better surface quality when the outer wall line width is smaller than the nozzle size. + +*Enhanced Combing +The “No Skin” option allows you to comb over infill only to avoid scars on top surfaces. + +*Z Hop +Can’t avoid previously printed parts by horizontal moves? The Z Hop Only Over Printed Parts gives you the ability to Z Hop to avoid collisions for better surface quality. + +*Skin and Wall Overlap +The Skin Overlap setting allows you to overlap the skin lines with the walls for better adhesion. + +*Control Initial Layer Travel Speed +Set the travel speed of the initial layer(s) to reduce risk of extruder pulling the print from the bed. + +*Support Bottoms +This new feature duplicates the Support Roofs feature in the places where the support rests on the model. + +*Bug fixes & minor changes +Deleting grouped objects works as intended again. +Duplicating groups works as intended again. +Bridging works as intended again. +Rafts are no longer printed outside of build area. +Messages are now displayed 30 seconds instead of 10, making it less likely that certain messages are missed. +Drag and drop on the first run on windows works again. +You are now notified if you try to save to a locked SD card. +Combing is applied in more cases and results in better paths. +Infill thickness now supports Grid infill also for even multiples of the layer height. +Unretraction speeds are correct again. +Spiralize mode doesn’t spiralize the bottom layer any more. +Spiralize now spiralizes each part in a layer. +Support is no longer removed by unprintable thin parts of the model. +Support is now generated on each layer it’s supposed to. +Support doesn't go outside overhang areas any more. +Line distance is now the actual line distance. +Enabling raft doesn’t influence at which height the model is sliced any more. +Brim is now always printed just once. +Overlap Compensation works as intended again. +A raft now produces a reasonable amount of retractions. +No more string plume on top of one-at-a-time printed objects. +Engine log can be viewed even when slicing is finished. +Support roofs now only occur just below overhang. +Brim is now also generated under the support. +Compensate overlapping wall parts now also works for inner walls. +Bed Level and Checkup procedures for UMO+ can now be done without re-adding machine. +Undo and Redo now work correctly with multiple operations. +The last used folder is now remembered (instead of defaulting to home folder) +You can now adjust the speed at which the bed is lowered each layer. +Support roofs now only generate directly below the mesh. +Settings shared between skirt and brim now also activate when brim is selected. +Made it possible to add multiple Per Model Settings at once. + [2.1.3] *Material Profiles diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index 289c0a98a0..d5407f22c8 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -13,7 +13,7 @@ message Slice repeated ObjectList object_lists = 1; // The meshgroups to be printed one after another SettingList global_settings = 2; // The global settings used for the whole print job repeated Extruder extruders = 3; // The settings sent to each extruder object - repeated SettingExtruder global_inherits_stack = 4; //From which stack the setting would inherit if not defined in a stack. + repeated SettingExtruder limit_to_extruder = 4; //From which stack the setting would inherit if not defined in a stack. } message Extruder @@ -56,6 +56,7 @@ message Polygon { SupportInfillType = 7; MoveCombingType = 8; MoveRetractionType = 9; + SupportInterfaceType = 10; } Type type = 1; // Type of move bytes points = 2; // The points of the polygon, or two points if only a line segment (Currently only line segments are used) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index bae4e9d427..ec9b050cdd 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -127,7 +127,6 @@ class CuraEngineBackend(Backend): def close(self): # Terminate CuraEngine if it is still running at this point self._terminate() - super().close() ## Get the command that is used to call the engine. # This is useful for debugging and used to actually start the engine. @@ -197,7 +196,6 @@ class CuraEngineBackend(Backend): Logger.log("d", "Attempting to kill the engine process") if Application.getInstance().getCommandLineOption("external-backend", False): - self._createSocket() return if self._process is not None: @@ -206,8 +204,12 @@ 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)) + else: + # Process is none, but something did went wrong here. Try and re-create the socket + self._createSocket() ## Event handler to call when the job to initiate the slicing process is # completed. @@ -225,9 +227,19 @@ class CuraEngineBackend(Backend): if job.isCancelled() or job.getError() or job.getResult() == StartSliceJob.StartJobResult.Error: return + if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible: + if Application.getInstance().getPlatformActivity: + self._error_message = Message(catalog.i18nc("@info:status", + "The selected material is imcompatible with the selected machine or configuration.")) + self._error_message.show() + self.backendStateChange.emit(BackendState.Error) + else: + self.backendStateChange.emit(BackendState.NotStarted) + return + if job.getResult() == StartSliceJob.StartJobResult.SettingError: if Application.getInstance().getPlatformActivity: - self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) + self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. Please check your settings for errors.")) self._error_message.show() self.backendStateChange.emit(BackendState.Error) else: @@ -236,15 +248,18 @@ 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 models found.")) + self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit.")) self._error_message.show() self.backendStateChange.emit(BackendState.Error) else: self.backendStateChange.emit(BackendState.NotStarted) return - # Preparation completed, send it to the backend. self._socket.sendMessage(job.getSliceMessage()) + + # Notify the user that it's now up to the backend to do it's job + self.backendStateChange.emit(BackendState.Processing) + Logger.log("d", "Sending slice message took %s seconds", time() - self._slice_start_time ) ## Listener for when the scene has changed. @@ -374,8 +389,9 @@ class CuraEngineBackend(Backend): # # \param tool The tool that the user is using. def _onToolOperationStarted(self, tool): - self._terminate() # Do not continue slicing once a tool has started self._enabled = False # Do not reslice when a tool is doing it's 'thing' + self._terminate() # Do not continue slicing once a tool has started + ## Called when the user stops using some tool. # @@ -384,7 +400,7 @@ class CuraEngineBackend(Backend): # \param tool The tool that the user was using. def _onToolOperationStopped(self, tool): self._enabled = True # Tool stop, start listening for changes again. - + ## Called when the user changes the active view mode. def _onActiveViewChanged(self): if Application.getInstance().getController().getActiveView(): @@ -404,9 +420,10 @@ class CuraEngineBackend(Backend): # # We should reset our state and start listening for new connections. def _onBackendQuit(self): - if not self._restart and self._process: - Logger.log("d", "Backend quit with return code %s. Resetting process and socket.", self._process.wait()) - self._process = None + if not self._restart: + if self._process: + Logger.log("d", "Backend quit with return code %s. Resetting process and socket.", self._process.wait()) + self._process = None self._createSocket() ## Called when the global container stack changes diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index fc9fd05b44..b952fed8d5 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -24,6 +24,7 @@ class StartJobResult(IntEnum): Error = 2 SettingError = 3 NothingToSlice = 4 + MaterialIncompatible = 5 ## Formatter class that handles token expansion in start/end gcod @@ -78,6 +79,17 @@ class StartSliceJob(Job): self.setResult(StartJobResult.SettingError) return + if Application.getInstance().getBuildVolume().hasErrors(): + self.setResult(StartJobResult.SettingError) + return + + for extruder_stack in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(stack.getId()): + material = extruder_stack.findContainer({"type": "material"}) + if material: + if material.getMetaDataEntry("compatible") == False: + self.setResult(StartJobResult.MaterialIncompatible) + return + # Don't slice if there is a per object setting with an error value. for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is not SceneNode or not node.isSelectable(): @@ -203,7 +215,20 @@ class StartSliceJob(Job): keys = stack.getAllKeys() settings = {} for key in keys: - settings[key] = stack.getProperty(key, "value") + # Use resolvement value if available, or take the value + resolved_value = stack.getProperty(key, "resolve") + if resolved_value is not None: + # There is a resolvement value. Check if we need to use it. + user_container = stack.findContainer({"type": "user"}) + quality_changes_container = stack.findContainer({"type": "quality_changes"}) + if user_container.hasProperty(key,"value") or quality_changes_container.hasProperty(key,"value"): + # Normal case + settings[key] = stack.getProperty(key, "value") + else: + settings[key] = resolved_value + else: + # Normal case + settings[key] = stack.getProperty(key, "value") start_gcode = settings["machine_start_gcode"] settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode #Pre-compute material material_bed_temp_prepend and material_print_temp_prepend @@ -220,16 +245,16 @@ class StartSliceJob(Job): ## Sends for some settings which extruder they should fallback to if not # set. # - # This is only set for settings that have the global_inherits_stack + # This is only set for settings that have the limit_to_extruder # property. # # \param stack The global stack with all settings, from which to read the - # global_inherits_stack property. + # limit_to_extruder property. def _buildGlobalInheritsStackMessage(self, stack): for key in stack.getAllKeys(): - extruder = int(round(float(stack.getProperty(key, "global_inherits_stack")))) + extruder = int(round(float(stack.getProperty(key, "limit_to_extruder")))) if extruder >= 0: #Set to a specific extruder. - setting_extruder = self._slice_message.addRepeatedMessage("global_inherits_stack") + setting_extruder = self._slice_message.addRepeatedMessage("limit_to_extruder") setting_extruder.name = key setting_extruder.extruder = extruder diff --git a/plugins/CuraProfileReader/CuraProfileReader.py b/plugins/CuraProfileReader/CuraProfileReader.py index 261e68a26b..d1be5b59a8 100644 --- a/plugins/CuraProfileReader/CuraProfileReader.py +++ b/plugins/CuraProfileReader/CuraProfileReader.py @@ -1,12 +1,14 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. +import configparser -import os.path - +from UM import PluginRegistry from UM.Logger import Logger -from UM.Settings.InstanceContainer import InstanceContainer #The new profile to make. +from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make. from cura.ProfileReader import ProfileReader +import zipfile + ## A plugin that reads profile data from Cura profile files. # # It reads a profile from a .curaprofile file, and returns it as a profile @@ -24,19 +26,77 @@ class CuraProfileReader(ProfileReader): # not be read or didn't contain a valid profile, \code None \endcode is # returned. def read(self, file_name): - # Create an empty profile. - profile = InstanceContainer(os.path.basename(os.path.splitext(file_name)[0])) - profile.addMetaDataEntry("type", "quality") try: - with open(file_name) as f: # Open file for reading. - serialized = f.read() - except IOError as e: - Logger.log("e", "Unable to open file %s for reading: %s", file_name, str(e)) - return None - + with zipfile.ZipFile(file_name, "r") as archive: + results = [] + for profile_id in archive.namelist(): + with archive.open(profile_id) as f: + serialized = f.read() + profile = self._loadProfile(serialized.decode("utf-8"), profile_id) + if profile is not None: + results.append(profile) + return results + + except zipfile.BadZipFile: + # It must be an older profile from Cura 2.1. + with open(file_name, encoding="utf-8") as fhandle: + serialized = fhandle.read() + return [self._loadProfile(serialized, profile_id) for serialized, profile_id in self._upgradeProfile(serialized, file_name)] + + ## Convert a profile from an old Cura to this Cura if needed. + # + # \param serialized \type{str} The profile data to convert in the serialized on-disk format. + # \param profile_id \type{str} The name of the profile. + # \return \type{List[Tuple[str,str]]} List of serialized profile strings and matching profile names. + def _upgradeProfile(self, serialized, profile_id): + parser = configparser.ConfigParser(interpolation=None) + parser.read_string(serialized) + + if not "general" in parser: + Logger.log("w", "Missing required section 'general'.") + return [] + if not "version" in parser["general"]: + Logger.log("w", "Missing required 'version' property") + return [] + + version = int(parser["general"]["version"]) + if InstanceContainer.Version != version: + name = parser["general"]["name"] + return self._upgradeProfileVersion(serialized, name, version) + else: + return [(serialized, profile_id)] + + ## Load a profile from a serialized string. + # + # \param serialized \type{str} The profile data to read. + # \param profile_id \type{str} The name of the profile. + # \return \type{InstanceContainer|None} + def _loadProfile(self, serialized, profile_id): + # Create an empty profile. + profile = InstanceContainer(profile_id) + profile.addMetaDataEntry("type", "quality_changes") try: profile.deserialize(serialized) except Exception as e: # Parsing error. This is not a (valid) Cura profile then. Logger.log("e", "Error while trying to parse profile: %s", str(e)) return None - return profile \ No newline at end of file + return profile + + ## Upgrade a serialized profile to the current profile format. + # + # \param serialized \type{str} The profile data to convert. + # \param profile_id \type{str} The name of the profile. + # \param source_version \type{int} The profile version of 'serialized'. + # \return \type{List[Tuple[str,str]]} List of serialized profile strings and matching profile names. + def _upgradeProfileVersion(self, serialized, profile_id, source_version): + converter_plugins = PluginRegistry.getInstance().getAllMetaData(filter={"version_upgrade": {} }, active_only=True) + + source_format = ("profile", source_version) + profile_convert_funcs = [plugin["version_upgrade"][source_format][2] for plugin in converter_plugins + if source_format in plugin["version_upgrade"] and plugin["version_upgrade"][source_format][1] == InstanceContainer.Version] + + if not profile_convert_funcs: + return [] + + filenames, outputs = profile_convert_funcs[0](serialized, profile_id) + return list(zip(outputs, filenames)) diff --git a/plugins/CuraProfileWriter/CuraProfileWriter.py b/plugins/CuraProfileWriter/CuraProfileWriter.py index 86b4f7dc89..cd3681b86f 100644 --- a/plugins/CuraProfileWriter/CuraProfileWriter.py +++ b/plugins/CuraProfileWriter/CuraProfileWriter.py @@ -5,22 +5,31 @@ from UM.Logger import Logger from UM.SaveFile import SaveFile from cura.ProfileWriter import ProfileWriter - +import zipfile ## Writes profiles to Cura's own profile format with config files. class CuraProfileWriter(ProfileWriter): ## Writes a profile to the specified file path. # # \param path \type{string} The file to output to. - # \param profile \type{Profile} The profile to write to that file. + # \param profiles \type{Profile} \type{List} The profile(s) to write to that file. # \return \code True \endcode if the writing was successful, or \code # False \endcode if it wasn't. - def write(self, path, profile): - serialized = profile.serialize() + def write(self, path, profiles): + if type(profiles) != list: + profiles = [profiles] + + stream = open(path, "wb") # Open file for writing in binary. + archive = zipfile.ZipFile(stream, "w", compression=zipfile.ZIP_DEFLATED) try: - with SaveFile(path, "wt", -1, "utf-8") as f: # Open the specified file. - f.write(serialized) + # Open the specified file. + for profile in profiles: + serialized = profile.serialize() + profile_file = zipfile.ZipInfo(profile.getId()) + archive.writestr(profile_file, serialized) except Exception as e: Logger.log("e", "Failed to write profile to %s: %s", path, str(e)) return False + finally: + archive.close() return True diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index c2a932b68c..95d6659dd1 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -66,7 +66,10 @@ class GCodeWriter(MeshWriter): ## Create a new container with container 2 as base and container 1 written over it. def _createFlattenedContainerInstance(self, instance_container1, instance_container2): flat_container = InstanceContainer(instance_container2.getName()) - flat_container.setDefinition(instance_container2.getDefinition()) + if instance_container1.getDefinition(): + flat_container.setDefinition(instance_container1.getDefinition()) + else: + flat_container.setDefinition(instance_container2.getDefinition()) flat_container.setMetaData(instance_container2.getMetaData()) for key in instance_container2.getAllKeys(): @@ -89,17 +92,17 @@ class GCodeWriter(MeshWriter): prefix = ";SETTING_" + str(GCodeWriter.version) + " " # The prefix to put before each line. prefix_length = len(prefix) - container_with_profile = stack.findContainer({"type": "quality"}) + container_with_profile = stack.findContainer({"type": "quality_changes"}) if not container_with_profile: Logger.log("e", "No valid quality profile found, not writing settings to GCode!") return "" - flat_global_container = self._createFlattenedContainerInstance(stack.getTop(),container_with_profile) + flat_global_container = self._createFlattenedContainerInstance(stack.getTop(), container_with_profile) serialized = flat_global_container.serialize() data = {"global_quality": serialized} for extruder in ExtruderManager.getInstance().getMachineExtruders(stack.getId()): - extruder_quality = extruder.findContainer({"type": "quality"}) + extruder_quality = extruder.findContainer({"type": "quality_changes"}) if not extruder_quality: Logger.log("w", "No extruder quality profile found, not writing quality for extruder %s to file!", extruder.getId()) continue diff --git a/plugins/LayerView/LayerView.py b/plugins/LayerView/LayerView.py index f60d492ec7..fde186566f 100644 --- a/plugins/LayerView/LayerView.py +++ b/plugins/LayerView/LayerView.py @@ -12,9 +12,11 @@ from UM.Mesh.MeshBuilder import MeshBuilder from UM.Job import Job from UM.Preferences import Preferences from UM.Logger import Logger - +from UM.Scene.SceneNode import SceneNode from UM.View.RenderBatch import RenderBatch from UM.View.GL.OpenGL import OpenGL +from UM.Message import Message +from UM.Application import Application from cura.ConvexHullNode import ConvexHullNode @@ -33,7 +35,7 @@ class LayerView(View): def __init__(self): super().__init__() self._shader = None - self._selection_shader = None + self._ghost_shader = None self._num_layers = 0 self._layer_percentage = 0 # what percentage of layers need to be shown (Slider gives value between 0 - 100) self._proxy = LayerViewProxy.LayerViewProxy() @@ -45,6 +47,7 @@ class LayerView(View): self._top_layers_job = None self._activity = False self._old_max_layers = 0 + self._global_container_stack = None Preferences.getInstance().addPreference("view/top_layer_count", 5) Preferences.getInstance().addPreference("view/only_show_top_layers", False) @@ -54,6 +57,8 @@ class LayerView(View): self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers")) self._busy = False + self._wireprint_warning_message = Message(catalog.i18nc("@info:status", "Cura does not accurately display layers when Wire Printing is enabled")) + def getActivity(self): return self._activity @@ -84,9 +89,9 @@ class LayerView(View): scene = self.getController().getScene() renderer = self.getRenderer() - if not self._selection_shader: - self._selection_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader")) - self._selection_shader.setUniformValue("u_color", Color(32, 32, 32, 128)) + if not self._ghost_shader: + self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader")) + self._ghost_shader.setUniformValue("u_color", Color(0, 0, 0, 64)) for node in DepthFirstIterator(scene.getRoot()): # We do not want to render ConvexHullNode as it conflicts with the bottom layers. @@ -96,8 +101,13 @@ class LayerView(View): if not node.render(renderer): if node.getMeshData() and node.isVisible(): - if Selection.isSelected(node): - renderer.queueNode(node, transparent = True, shader = self._selection_shader) + renderer.queueNode(node, + shader = self._ghost_shader, + type = RenderBatch.RenderType.Transparent ) + + for node in DepthFirstIterator(scene.getRoot()): + if type(node) is SceneNode: + if node.getMeshData() and node.isVisible(): layer_data = node.callDecoration("getLayerData") if not layer_data: continue @@ -184,6 +194,33 @@ class LayerView(View): self.setLayer(self._current_layer_num - 1) return True + if event.type == Event.ViewActivateEvent: + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) + self._onGlobalStackChanged() + + elif event.type == Event.ViewDeactivateEvent: + self._wireprint_warning_message.hide() + Application.getInstance().globalContainerStackChanged.disconnect(self._onGlobalStackChanged) + if self._global_container_stack: + self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged) + + def _onGlobalStackChanged(self): + if self._global_container_stack: + self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged) + self._global_container_stack = Application.getInstance().getGlobalContainerStack() + if self._global_container_stack: + self._global_container_stack.propertyChanged.connect(self._onPropertyChanged) + self._onPropertyChanged("wireframe_enabled", "value") + else: + self._wireprint_warning_message.hide() + + def _onPropertyChanged(self, key, property_name): + if key == "wireframe_enabled" and property_name == "value": + if self._global_container_stack.getProperty("wireframe_enabled", "value"): + self._wireprint_warning_message.show() + else: + self._wireprint_warning_message.hide() + def _startUpdateTopLayers(self): if self._top_layers_job: self._top_layers_job.finished.disconnect(self._updateCurrentLayerMesh) diff --git a/plugins/LegacyProfileReader/DictionaryOfDoom.json b/plugins/LegacyProfileReader/DictionaryOfDoom.json index 471604ddbc..15ef792f83 100644 --- a/plugins/LegacyProfileReader/DictionaryOfDoom.json +++ b/plugins/LegacyProfileReader/DictionaryOfDoom.json @@ -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,11 +66,12 @@ "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))", - "ooze_shield_enabled": "ooze_shield" + "ooze_shield_enabled": "ooze_shield", + "skin_overlap": "fill_overlap" }, "defaults": { diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 19154c9c5a..a3e4e60b6a 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -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 \ No newline at end of file diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py new file mode 100644 index 0000000000..a37aa9c5cb --- /dev/null +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -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() \ No newline at end of file diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml new file mode 100644 index 0000000000..3c1839e07f --- /dev/null +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -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 + } + +} \ No newline at end of file diff --git a/plugins/MachineSettingsAction/__init__.py b/plugins/MachineSettingsAction/__init__.py new file mode 100644 index 0000000000..7d8b253d33 --- /dev/null +++ b/plugins/MachineSettingsAction/__init__.py @@ -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() } diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py index b4086291ca..56cec25db8 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py @@ -60,16 +60,16 @@ class PerObjectSettingVisibilityHandler(UM.Settings.Models.SettingVisibilityHand if definition: new_instance = SettingInstance(definition, settings) stack_nr = -1 - if definition.global_inherits_stack and self._stack.getProperty("machine_extruder_count", "value") > 1: + if definition.limit_to_extruder and self._stack.getProperty("machine_extruder_count", "value") > 1: #Obtain the value from the correct container stack. Only once, upon adding the setting. - stack_nr = str(int(round(float(self._stack.getProperty(item, "global_inherits_stack"))))) #Stack to get the setting from. Round it and remove the fractional part. + stack_nr = str(int(round(float(self._stack.getProperty(item, "limit_to_extruder"))))) #Stack to get the setting from. Round it and remove the fractional part. if stack_nr not in ExtruderManager.getInstance().extruderIds and self._stack.getProperty("extruder_nr", "value"): #Property not defined, but we have an extruder number. stack_nr = str(int(round(float(self._stack.getProperty("extruder_nr", "value"))))) - if stack_nr in ExtruderManager.getInstance().extruderIds: #We have either a global_inherits_stack or an extruder_nr. + if stack_nr in ExtruderManager.getInstance().extruderIds: #We have either a limit_to_extruder or an extruder_nr. stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = ExtruderManager.getInstance().extruderIds[stack_nr])[0] else: stack = UM.Application.getInstance().getGlobalContainerStack() - new_instance.setProperty("value", stack.getProperty(item, "value")) + new_instance.setProperty("value", stack.getRawProperty(item, "value")) new_instance.resetState() # Ensure that the state is not seen as a user state. settings.addInstance(new_instance) visibility_changed = True diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 72b5b7da95..ae6ccd277e 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -44,13 +44,11 @@ Item { model: Cura.ExtrudersModel { - id: extruders_model - onRowsInserted: extruderSelector.visible = extruders_model.rowCount() > 1 - onModelReset: extruderSelector.visible = extruders_model.rowCount() > 1 - onModelChanged: extruderSelector.color = extruders_model.getItem(extruderSelector.currentIndex).color + id: extrudersModel + onModelChanged: extruderSelector.color = extrudersModel.getItem(extruderSelector.currentIndex).color } - property string color: extruders_model.getItem(extruderSelector.currentIndex).color - visible: extruders_model.rowCount() > 1 + property string color: extrudersModel.getItem(extruderSelector.currentIndex).color + visible: machineExtruderCount.properties.value > 1 textRole: "name" width: UM.Theme.getSize("setting_control").width height: UM.Theme.getSize("section").height @@ -130,19 +128,19 @@ Item { onActivated: { - UM.ActiveTool.setProperty("SelectedActiveExtruder", extruders_model.getItem(index).id); - extruderSelector.color = extruders_model.getItem(index).color; + UM.ActiveTool.setProperty("SelectedActiveExtruder", extrudersModel.getItem(index).id); + extruderSelector.color = extrudersModel.getItem(index).color; } onModelChanged: updateCurrentIndex(); function updateCurrentIndex() { - for(var i = 0; i < extruders_model.rowCount(); ++i) + for(var i = 0; i < extrudersModel.rowCount(); ++i) { - if(extruders_model.getItem(i).id == UM.ActiveTool.properties.getValue("SelectedActiveExtruder")) + if(extrudersModel.getItem(i).id == UM.ActiveTool.properties.getValue("SelectedActiveExtruder")) { extruderSelector.currentIndex = i; - extruderSelector.color = extruders_model.getItem(i).color; + extruderSelector.color = extrudersModel.getItem(i).color; return; } } @@ -154,107 +152,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 + } } } } @@ -423,6 +428,16 @@ Item { ] } + UM.SettingPropertyProvider + { + id: machineExtruderCount + + containerStackId: Cura.MachineManager.activeMachineId + key: "machine_extruder_count" + watchedProperties: [ "value" ] + storeIndex: 0 + } + SystemPalette { id: palette; } Component diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index b5c4c0f22c..953f60a33d 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -7,6 +7,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Application import Application from UM.Preferences import Preferences from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator +from cura.Settings.ExtruderManager import ExtruderManager ## This tool allows the user to add & change settings per node in the scene. @@ -71,11 +72,20 @@ class PerObjectSettingsTool(Tool): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: self._multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1 + + # Ensure that all extruder data is reset if not self._multi_extrusion: - # Ensure that all extruder data is reset - root_node = Application.getInstance().getController().getScene().getRoot() - for node in DepthFirstIterator(root_node): - node.callDecoration("setActiveExtruder", global_container_stack.getId()) + default_stack_id = global_container_stack.getId() + else: + default_stack = ExtruderManager.getInstance().getExtruderStack(0) + if default_stack: + default_stack_id = default_stack.getId() + else: default_stack_id = global_container_stack.getId() + + root_node = Application.getInstance().getController().getScene().getRoot() + for node in DepthFirstIterator(root_node): + node.callDecoration("setActiveExtruder", default_stack_id) + self._updateEnabled() def _updateEnabled(self): diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index c6fc277234..f9dd0db85c 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -112,5 +112,5 @@ class RemovableDriveOutputDevice(OutputDevice): def _onActionTriggered(self, message, action): if action == "eject": - Application.getInstance().getOutputDeviceManager().getOutputDevicePlugin("RemovableDriveOutputDevice").ejectDevice(self) - + if Application.getInstance().getOutputDeviceManager().getOutputDevicePlugin("RemovableDriveOutputDevice").ejectDevice(self): + message.hide() \ No newline at end of file diff --git a/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py b/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py index 4e748230e9..90adac73b1 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py @@ -49,8 +49,9 @@ class RemovableDrivePlugin(OutputDevicePlugin): message = Message(catalog.i18nc("@info:status", "Ejected {0}. You can now safely remove the drive.").format(device.getName())) message.show() else: - message = Message(catalog.i18nc("@info:status", "Failed to eject {0}. Maybe it is still in use?").format(device.getName())) + message = Message(catalog.i18nc("@info:status", "Failed to eject {0}. Another program may be using the drive.").format(device.getName())) message.show() + return result def performEjectDevice(self, device): raise NotImplementedError() diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 047a03575d..ab9a75d1da 100644 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -1,6 +1,8 @@ # Copyright (c) 2015 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. +from cura.CuraApplication import CuraApplication + from UM.Extension import Extension from UM.Application import Application from UM.Preferences import Preferences @@ -18,6 +20,7 @@ import math import urllib.request import urllib.parse import ssl +import hashlib catalog = i18nCatalog("cura") @@ -43,9 +46,11 @@ class SliceInfoJob(Job): if Platform.isOSX(): kwoptions["context"] = ssl._create_unverified_context() + Logger.log("d", "Sending anonymous slice info to [%s]...", self.url) + try: f = urllib.request.urlopen(self.url, **kwoptions) - Logger.log("i", "Sent anonymous slice info to %s", self.url) + Logger.log("i", "Sent anonymous slice info.") f.close() except urllib.error.HTTPError as http_exception: Logger.log("e", "An HTTP error occurred while trying to send slice information: %s" % http_exception) @@ -56,7 +61,7 @@ class SliceInfoJob(Job): # The data is only sent when the user in question gave permission to do so. All data is anonymous and # no model files are being sent (Just a SHA256 hash of the model). class SliceInfo(Extension): - info_url = "https://stats.youmagine.com/curastats/slice" + info_url = "http://stats.youmagine.com/curastats/slice" def __init__(self): super().__init__() @@ -65,7 +70,7 @@ class SliceInfo(Extension): Preferences.getInstance().addPreference("info/asked_send_slice_info", False) if not Preferences.getInstance().getValue("info/asked_send_slice_info"): - self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura automatically sends slice info. You can disable this in preferences"), lifetime = 0, dismissable = False) + self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymised slicing statistics. You can disable this in preferences"), lifetime = 0, dismissable = False) self.send_slice_info_message.addAction("Dismiss", catalog.i18nc("@action:button", "Dismiss"), None, "") self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered) self.send_slice_info_message.show() @@ -80,6 +85,16 @@ class SliceInfo(Extension): Logger.log("d", "'info/send_slice_info' is turned off.") return # Do nothing, user does not want to send data + # Listing all files placed on the buildplate + modelhashes = [] + for node in DepthFirstIterator(CuraApplication.getInstance().getController().getScene().getRoot()): + if type(node) is not SceneNode or not node.getMeshData(): + continue + modelhashes.append(node.getMeshData().getHash()) + + # Creating md5sums and formatting them as discussed on JIRA + modelhash_formatted = ",".join(modelhashes) + global_container_stack = Application.getInstance().getGlobalContainerStack() # Get total material used (in mm^3) @@ -89,27 +104,6 @@ class SliceInfo(Extension): # TODO: Send material per extruder instead of mashing it on a pile material_used = math.pi * material_radius * material_radius * sum(print_information.materialLengths) #Volume of all materials used - # Get model information (bounding boxes, hashes and transformation matrix) - models_info = [] - for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()): - if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None: - if not getattr(node, "_outside_buildarea", False): - model_info = {} - model_info["hash"] = node.getMeshData().getHash() - model_info["bounding_box"] = {} - model_info["bounding_box"]["minimum"] = {} - model_info["bounding_box"]["minimum"]["x"] = node.getBoundingBox().minimum.x - model_info["bounding_box"]["minimum"]["y"] = node.getBoundingBox().minimum.y - model_info["bounding_box"]["minimum"]["z"] = node.getBoundingBox().minimum.z - - model_info["bounding_box"]["maximum"] = {} - model_info["bounding_box"]["maximum"]["x"] = node.getBoundingBox().maximum.x - model_info["bounding_box"]["maximum"]["y"] = node.getBoundingBox().maximum.y - model_info["bounding_box"]["maximum"]["z"] = node.getBoundingBox().maximum.z - model_info["transformation"] = str(node.getWorldTransformation().getData()) - - models_info.append(model_info) - # Bundle the collected data submitted_data = { "processor": platform.processor(), @@ -117,7 +111,7 @@ class SliceInfo(Extension): "platform": platform.platform(), "settings": global_container_stack.serialize(), # global_container with references on used containers "version": Application.getInstance().getVersion(), - "modelhash": "None", + "modelhash": modelhash_formatted, "printtime": print_information.currentPrintTime.getDisplayString(DurationFormat.Format.ISO8601), "filament": material_used, "language": Preferences.getInstance().getValue("general/language"), diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 3e3501a83f..fd9f106334 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -13,6 +13,7 @@ from UM.Settings.Validator import ValidatorState from UM.View.GL.OpenGL import OpenGL import cura.Settings +from cura.Settings.ExtruderManager import ExtruderManager import math @@ -45,16 +46,27 @@ class SolidView(View): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: + multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1 + + if multi_extrusion: + support_extruder_nr = global_container_stack.getProperty("support_extruder_nr", "value") + support_angle_stack = ExtruderManager.getInstance().getExtruderStack(support_extruder_nr) + if not support_angle_stack: + support_angle_stack = global_container_stack + else: + support_angle_stack = global_container_stack + if Preferences.getInstance().getValue("view/show_overhang"): - angle = global_container_stack.getProperty("support_angle", "value") - if angle is not None and global_container_stack.getProperty("support_angle", "validationState") == ValidatorState.Valid: + angle = support_angle_stack.getProperty("support_angle", "value") + # Make sure the overhang angle is valid before passing it to the shader + # Note: if the overhang angle is set to its default value, it does not need to get validated (validationState = None) + if angle is not None and global_container_stack.getProperty("support_angle", "validationState") in [None, ValidatorState.Valid]: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle))) else: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) #Overhang angle of 0 causes no area at all to be marked as overhang. else: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) - multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1 for node in DepthFirstIterator(scene.getRoot()): if not node.render(renderer): diff --git a/plugins/USBPrinting/FirmwareUpdateWindow.qml b/plugins/USBPrinting/FirmwareUpdateWindow.qml index d55541f36d..b42cff114f 100644 --- a/plugins/USBPrinting/FirmwareUpdateWindow.qml +++ b/plugins/USBPrinting/FirmwareUpdateWindow.qml @@ -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) + } } } diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index d0a459e561..4838fe9b96 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -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() @@ -139,7 +140,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): # \param gcode_list List with gcode (strings). def printGCode(self, gcode_list): if self._progress or self._connection_state != ConnectionState.connected: - self._error_message = Message(catalog.i18nc("@info:status", "Printer is busy or not connected. Unable to start a new job.")) + self._error_message = Message(catalog.i18nc("@info:status", "Unable to start a new job because the printer is busy or not connected.")) self._error_message.show() Logger.log("d", "Printer is busy or not connected, aborting print") self.writeError.emit(self) @@ -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,7 +184,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): if len(hex_file) == 0: Logger.log("e", "Unable to read provided hex file. Could not update firmware") - self._updateFirmware_completed() + self._updateFirmwareFailedMissingFirmware() return programmer = stk500v2.Stk500v2() @@ -198,30 +200,64 @@ class USBPrinterOutputDevice(PrinterOutputDevice): if not programmer.isConnected(): Logger.log("e", "Unable to connect with serial. Could not update firmware") - self._updateFirmware_completed() - return + self._updateFirmwareFailedCommunicationError() + return self._updating_firmware = True 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._updateFirmware_completed() + Logger.log("e", "Exception while trying to update firmware: <%s>" %(repr(e))) + self._updateFirmwareFailedUnknown() return programmer.close() - self._updateFirmware_completed() + self._updateFirmwareCompletedSucessfully() return - ## Private function which makes sure that firmware update process has completed/ended - def _updateFirmware_completed(self): + ## 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.resetFirmwareUpdate(update_has_finished = True) self.firmwareUpdateComplete.emit() - + return ## Upload new firmware to machine diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index d9a036c682..4dec2e3a06 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -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): @@ -96,10 +103,12 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension): self._firmware_view.show() - @pyqtSlot() - def updateAllFirmware(self): + @pyqtSlot(str) + def updateAllFirmware(self, file_name): + if file_name.startswith("file://"): + file_name = QUrl(file_name).toLocalFile() # File dialogs prepend the path with file://, which we don't need / want if not self._usb_output_devices: - Message(i18n_catalog.i18nc("@info","Cannot update firmware, there were no connected printers found.")).show() + Message(i18n_catalog.i18nc("@info", "Unable to update firmware because there are no printers connected.")).show() return for printer_connection in self._usb_output_devices: @@ -107,26 +116,26 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension): self.spawnFirmwareInterface("") for printer_connection in self._usb_output_devices: try: - self._usb_output_devices[printer_connection].updateFirmware(Resources.getPath(CuraApplication.ResourceTypes.Firmware, self._getDefaultFirmwareName())) + self._usb_output_devices[printer_connection].updateFirmware(file_name) 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 called '%s'" %(printer_connection, self._getDefaultFirmwareName())) + Logger.log("w", "No firmware found for printer %s called '%s'", printer_connection, file_name) Message(i18n_catalog.i18nc("@info", "Could not find firmware required for the printer at %s.") % printer_connection).show() self._firmware_view.close() continue - @pyqtSlot(str, result = bool) - def updateFirmwareBySerial(self, serial_port): + @pyqtSlot(str, str, result = bool) + def updateFirmwareBySerial(self, serial_port, file_name): if serial_port in self._usb_output_devices: self.spawnFirmwareInterface(self._usb_output_devices[serial_port].getSerialPort()) try: - self._usb_output_devices[serial_port].updateFirmware(Resources.getPath(CuraApplication.ResourceTypes.Firmware, self._getDefaultFirmwareName())) + self._usb_output_devices[serial_port].updateFirmware(file_name) except FileNotFoundError: self._firmware_view.close() - Logger.log("e", "Could not find firmware required for this machine called '%s'" %(self._getDefaultFirmwareName())) + Logger.log("e", "Could not find firmware required for this machine called '%s'", file_name) return False return True return False @@ -140,7 +149,8 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension): return USBPrinterOutputDeviceManager._instance - def _getDefaultFirmwareName(self): + @pyqtSlot(result = str) + def getDefaultFirmwareName(self): # Check if there is a valid global container stack global_container_stack = Application.getInstance().getGlobalContainerStack() if not global_container_stack: @@ -186,13 +196,13 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension): Logger.log("d", "Choosing basic firmware for machine %s.", machine_id) hex_file = machine_without_extras[machine_id] # Return "basic" firmware else: - Logger.log("e", "There is no firmware for machine %s.", machine_id) + Logger.log("w", "There is no firmware for machine %s.", machine_id) if hex_file: - return hex_file.format(baudrate=baudrate) + return Resources.getPath(CuraApplication.ResourceTypes.Firmware, hex_file.format(baudrate=baudrate)) else: - Logger.log("e", "Could not find any firmware for machine %s.", machine_id) - raise FileNotFoundError() + Logger.log("w", "Could not find any firmware for machine %s.", machine_id) + return "" ## Helper to identify serial ports (and scan for them) def _addRemovePorts(self, serial_ports): diff --git a/plugins/UltimakerMachineActions/BedLevelMachineAction.qml b/plugins/UltimakerMachineActions/BedLevelMachineAction.qml index 7f35637516..6c34212cf9 100644 --- a/plugins/UltimakerMachineActions/BedLevelMachineAction.qml +++ b/plugins/UltimakerMachineActions/BedLevelMachineAction.qml @@ -64,9 +64,7 @@ Cura.MachineAction { startBedLevelingButton.visible = false; bedlevelingButton.visible = true; - checkupMachineAction.heatupHotendStarted = false; - checkupMachineAction.heatupBedStarted = false; - manager.startCheck(); + manager.startBedLeveling(); } } diff --git a/plugins/UltimakerMachineActions/UMOUpgradeSelection.py b/plugins/UltimakerMachineActions/UMOUpgradeSelection.py index 5d00fd5e3a..b92dc30c68 100644 --- a/plugins/UltimakerMachineActions/UMOUpgradeSelection.py +++ b/plugins/UltimakerMachineActions/UMOUpgradeSelection.py @@ -20,31 +20,26 @@ 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() + variant = 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() \ No newline at end of file + 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) + return new_variant \ No newline at end of file diff --git a/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml b/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml index a1c607658d..abb7588a39 100644 --- a/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml +++ b/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml @@ -44,7 +44,7 @@ Cura.MachineAction 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"; } diff --git a/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.py b/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.py index 53476207fd..71d3f0b55b 100644 --- a/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.py +++ b/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.py @@ -1,9 +1,17 @@ from cura.MachineAction import MachineAction from UM.i18n import i18nCatalog +import cura.Settings.CuraContainerRegistry +import UM.Settings.DefinitionContainer catalog = i18nCatalog("cura") class UpgradeFirmwareMachineAction(MachineAction): def __init__(self): super().__init__("UpgradeFirmware", catalog.i18nc("@action", "Upgrade Firmware")) - self._qml_url = "UpgradeFirmwareMachineAction.qml" \ No newline at end of file + self._qml_url = "UpgradeFirmwareMachineAction.qml" + cura.Settings.CuraContainerRegistry.getInstance().containerAdded.connect(self._onContainerAdded) + + 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" and container.getMetaDataEntry("supports_usb_connection"): + UM.Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey()) diff --git a/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml b/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml index 0c9b80c010..153d8254ef 100644 --- a/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml +++ b/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml @@ -5,6 +5,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.1 +import QtQuick.Dialogs 1.2 // For filedialog import UM 1.2 as UM import Cura 1.0 as Cura @@ -44,34 +45,45 @@ Cura.MachineAction anchors.topMargin: UM.Theme.getSize("default_margin").height width: parent.width wrapMode: Text.WordWrap - text: catalog.i18nc("@label", "The firmware shipping with new Ultimakers works, but upgrades have been made to make better prints, and make calibration easier."); + text: catalog.i18nc("@label", "The firmware shipping with new printers works, but new versions tend to have more features and improvements."); } - Label - { - id: upgradeText2 - anchors.top: upgradeText1.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width - wrapMode: Text.WordWrap - text: catalog.i18nc("@label", "Cura requires these new features and thus your firmware will most likely need to be upgraded. You can do so now."); - } Row { - anchors.top: upgradeText2.bottom + anchors.top: upgradeText1.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.horizontalCenter: parent.horizontalCenter width: childrenRect.width spacing: UM.Theme.getSize("default_margin").width + property var firmwareName: Cura.USBPrinterManager.getDefaultFirmwareName() Button { - id: upgradeButton - text: catalog.i18nc("@action:button","Upgrade to Marlin Firmware"); + id: autoUpgradeButton + text: catalog.i18nc("@action:button", "Automatically upgrade Firmware"); + enabled: parent.firmwareName != "" onClicked: { - Cura.USBPrinterManager.updateAllFirmware() + Cura.USBPrinterManager.updateAllFirmware(parent.firmwareName) + } + } + Button + { + id: manualUpgradeButton + text: catalog.i18nc("@action:button", "Upload custom Firmware"); + onClicked: + { + customFirmwareDialog.open() } } } + + FileDialog + { + id: customFirmwareDialog + title: catalog.i18nc("@title:window", "Select custom firmware") + nameFilters: "Firmware image files (*.hex)" + selectExisting: true + onAccepted: Cura.USBPrinterManager.updateAllFirmware(fileUrl) + } } } \ No newline at end of file diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index 02113dbfc0..6510d34cb1 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -69,26 +69,33 @@ class MachineInstance: config.add_section("general") config.set("general", "name", self._name) config.set("general", "id", self._name) - config.set("general", "type", self._type_name) config.set("general", "version", "2") # Hard-code version 2, since if this number changes the programmer MUST change this entire function. import VersionUpgrade21to22 # Import here to prevent circular dependencies. has_machine_qualities = self._type_name in VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.machinesWithMachineQuality() type_name = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translatePrinter(self._type_name) - active_material = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateProfile(self._active_material_name) + active_material = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateMaterial(self._active_material_name) variant = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateVariant(self._variant_name, type_name) variant_materials = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateVariantForMaterials(self._variant_name, type_name) - active_profile = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateProfile(self._active_profile_name) - if has_machine_qualities: #This machine now has machine-quality profiles. - active_profile += "_" + active_material + "_" + variant - active_material += "_" + variant_materials #That means that the profile was split into multiple. - current_settings = "empty" #The profile didn't know the definition ID when it was upgraded, so it will have been invalid. Sorry, your current settings are lost now. + + #Convert to quality profile if we have one of the built-in profiles, otherwise convert to a quality-changes profile. + if self._active_profile_name in VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.builtInProfiles(): + active_quality = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateProfile(self._active_profile_name) + active_quality_changes = "empty_quality_changes" else: - current_settings = self._name + "_current_settings" + active_quality = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.getQualityFallback(type_name, variant, active_material) + if has_machine_qualities: #Then the profile will have split into multiple. + active_quality_changes = self._active_profile_name + "_" + active_material + "_" + variant + else: + active_quality_changes = self._active_profile_name + + if has_machine_qualities: #This machine now has machine-quality profiles. + active_material += "_" + variant_materials #That means that the profile was split into multiple. containers = [ - current_settings, - active_profile, + "", #The current profile doesn't know the definition ID when it was upgraded, only the instance ID, so it will be invalid. Sorry, your current settings are lost now. + active_quality_changes, + active_quality, active_material, variant, type_name diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py index 781410997b..a09ac4f3d7 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py @@ -80,7 +80,7 @@ class Profile: import VersionUpgrade21to22 # Import here to prevent circular dependencies. if self._name == "Current settings": - self._filename += "_current_settings" #This resolves a duplicate ID arising from how Cura 2.1 stores its current settings. + return None, None #Can't upgrade these, because the new current profile needs to specify the definition ID and the old file only had the machine instance, not the definition. config = configparser.ConfigParser(interpolation = None) @@ -94,12 +94,10 @@ class Profile: config.set("general", "definition", "fdmprinter") #In this case, the machine definition is unknown, and it might now have machine-specific profiles, in which case this will fail. config.add_section("metadata") - if self._type: - config.set("metadata", "type", self._type) - else: - config.set("metadata", "type", "quality") + config.set("metadata", "quality", "normal") #This feature doesn't exist in 2.1 yet, so we don't know the actual quality type. For now, always base it on normal. + config.set("metadata", "type", "quality_changes") if self._weight: - config.set("metadata", "weight", self._weight) + config.set("metadata", "weight", str(self._weight)) if self._machine_variant_name: if self._machine_type_id: config.set("metadata", "variant", VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateVariant(self._machine_variant_name, self._machine_type_id)) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py index 3dfb88638f..286667f5b0 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py @@ -23,29 +23,105 @@ from . import Profile # To upgrade profiles. # may have changed in later versions than 2.2. _machines_with_machine_quality = { "ultimaker2plus": { - "materials": { "generic_abs", "generic_cpe", "generic_pla", "generic_pva" }, + "materials": { "generic_abs", "generic_cpe", "generic_pla", "generic_pva", "generic_cpe_plus", "generic_nylon", "generic_pc", "generic_tpu" }, "variants": { "0.25 mm", "0.4 mm", "0.6 mm", "0.8 mm" } }, "ultimaker2_extended_plus": { - "materials": { "generic_abs", "generic_cpe", "generic_pla", "generic_pva" }, + "materials": { "generic_abs", "generic_cpe", "generic_pla", "generic_pva", "generic_cpe_plus", "generic_nylon", "generic_pc", "generic_tpu" }, "variants": { "0.25 mm", "0.4 mm", "0.6 mm", "0.8 mm" } } } +## How to translate material names from the old version to the new. +_material_translations = { + "PLA": "generic_pla", + "ABS": "generic_abs", + "CPE": "generic_cpe", + "CPE+": "generic_cpe_plus", + "Nylon": "generic_nylon", + "PC": "generic_pc", + "TPU": "generic_tpu", +} + +## How to translate material names for in the profile names. +_material_translations_profiles = { + "PLA": "pla", + "ABS": "abs", + "CPE": "cpe", + "CPE+": "cpep", + "Nylon": "nylon", + "PC": "pc", + "TPU": "tpu", +} + ## How to translate printer names from the old version to the new. _printer_translations = { "ultimaker2plus": "ultimaker2_plus" } +_printer_translations_profiles = { + "ultimaker2plus": "um2p", #Does NOT get included in PLA profiles! + "ultimaker2_extended_plus": "um2ep" #Has no profiles for CPE+, Nylon, PC and TPU! +} + ## How to translate profile names from the old version to the new. +# +# This must have an entry for every built-in profile, since it also services +# as a set for which profiles were built-in. _profile_translations = { - "PLA": "generic_pla", - "ABS": "generic_abs", - "CPE": "generic_cpe", "Low Quality": "low", "Normal Quality": "normal", "High Quality": "high", - "Ulti Quality": "high" #This one doesn't have an equivalent. Map it to high. + "Ulti Quality": "high", #This one doesn't have an equivalent. Map it to high. + "abs_0.25_normal": "um2p_abs_0.25_normal", + "abs_0.4_fast": "um2p_abs_0.4_fast", + "abs_0.4_high": "um2p_abs_0.4_high", + "abs_0.4_normal": "um2p_abs_0.4_normal", + "abs_0.6_normal": "um2p_abs_0.6_normal", + "abs_0.8_normal": "um2p_abs_0.8_normal", + "cpe_0.25_normal": "um2p_cpe_0.25_normal", + "cpe_0.4_fast": "um2p_cpe_0.4_fast", + "cpe_0.4_high": "um2p_cpe_0.4_high", + "cpe_0.4_normal": "um2p_cpe_0.4_normal", + "cpe_0.6_normal": "um2p_cpe_0.6_normal", + "cpe_0.8_normal": "um2p_cpe_0.8_normal", + "cpep_0.4_draft": "um2p_cpep_0.4_draft", + "cpep_0.4_normal": "um2p_cpep_0.4_normal", + "cpep_0.6_draft": "um2p_cpep_0.6_draft", + "cpep_0.6_normal": "um2p_cpep_0.6_normal", + "cpep_0.8_draft": "um2p_cpep_0.8_draft", + "cpep_0.8_normal": "um2p_cpep_0.8_normal", + "nylon_0.25_high": "um2p_nylon_0.25_high", + "nylon_0.25_normal": "um2p_nylon_0.25_normal", + "nylon_0.4_fast": "um2p_nylon_0.4_fast", + "nylon_0.4_normal": "um2p_nylon_0.4_normal", + "nylon_0.6_fast": "um2p_nylon_0.6_fast", + "nylon_0.6_normal": "um2p_nylon_0.6_normal", + "nylon_0.8_draft": "um2p_nylon_0.8_draft", + "nylon_0.8_normal": "um2p_nylon_0.8_normal", + "pc_0.25_high": "um2p_pc_0.25_high", + "pc_0.25_normal": "um2p_pc_0.25_normal", + "pc_0.4_fast": "um2p_pc_0.4_fast", + "pc_0.4_normal": "um2p_pc_0.4_normal", + "pc_0.6_fast": "um2p_pc_0.6_fast", + "pc_0.6_normal": "um2p_pc_0.6_normal", + "pc_0.8_draft": "um2p_pc_0.8_draft", + "pc_0.8_normal": "um2p_pc_0.8_normal", + "pla_0.25_normal": "pla_0.25_normal", #Note that the PLA profiles don't get the um2p_ prefix, though they are for UM2+. + "pla_0.4_fast": "pla_0.4_fast", + "pla_0.4_high": "pla_0.4_high", + "pla_0.4_normal": "pla_0.4_normal", + "pla_0.6_normal": "pla_0.6_normal", + "pla_0.8_normal": "pla_0.8_normal", + "tpu_0.25_high": "um2p_tpu_0.25_high", + "tpu_0.4_normal": "um2p_tpu_0.4_normal", + "tpu_0.6_fast": "um2p_tpu_0.6_fast" +} + +## Settings that are no longer in the new version. +_removed_settings = { + "fill_perimeter_gaps", + "support_area_smoothing" } ## How to translate setting names from the old version to the new. @@ -67,6 +143,54 @@ _setting_name_translations = { "support_roof_pattern": "support_interface_pattern" } +## Custom profiles become quality_changes. This dictates which quality to base +# the quality_changes profile on. +# +# Which quality profile to base the quality_changes on depends on the machine, +# material and nozzle. +# +# If a current configuration is missing, fall back to "normal". +_quality_fallbacks = { + "ultimaker2_plus": { + "ultimaker2_plus_0.25": { + "generic_abs": "um2p_abs_0.25_normal", + "generic_cpe": "um2p_cpe_0.25_normal", + #No CPE+. + "generic_nylon": "um2p_nylon_0.25_normal", + "generic_pc": "um2p_pc_0.25_normal", + "generic_pla": "pla_0.25_normal", + "generic_tpu": "um2p_tpu_0.25_high" + }, + "ultimaker2_plus_0.4": { + "generic_abs": "um2p_abs_0.4_normal", + "generic_cpe": "um2p_cpe_0.4_normal", + "generic_cpep": "um2p_cpep_0.4_normal", + "generic_nylon": "um2p_nylon_0.4_normal", + "generic_pc": "um2p_pc_0.4_normal", + "generic_pla": "pla_0.4_normal", + "generic_tpu": "um2p_tpu_0.4_normal" + }, + "ultimaker2_plus_0.6": { + "generic_abs": "um2p_abs_0.6_normal", + "generic_cpe": "um2p_cpe_0.6_normal", + "generic_cpep": "um2p_cpep_0.6_normal", + "generic_nylon": "um2p_nylon_0.6_normal", + "generic_pc": "um2p_pc_0.6_normal", + "generic_pla": "pla_0.6_normal", + "generic_tpu": "um2p_tpu_0.6_fast", + }, + "ultimaker2_plus_0.8": { + "generic_abs": "um2p_abs_0.8_normal", + "generic_cpe": "um2p_cpe_0.8_normal", + "generic_cpep": "um2p_cpep_0.8_normal", + "generic_nylon": "um2p_nylon_0.8_normal", + "generic_pc": "um2p_pc_0.8_normal", + "generic_pla": "pla_0.8_normal", + #No TPU. + } + } +} + ## How to translate variants of specific machines from the old version to the # new. _variant_translations = { @@ -84,6 +208,14 @@ _variant_translations = { } } +## How to translate variant names for in the profile names. +_variant_translations_profiles = { + "0.25 mm": "0.25", + "0.4 mm": "0.4", + "0.6 mm": "0.6", + "0.8 mm": "0.8" +} + ## Cura 2.2's material profiles use a different naming scheme for variants. # # Getting pretty stressed out by this sort of thing... @@ -118,6 +250,33 @@ class VersionUpgrade21to22(VersionUpgrade): parser.read_string(serialised) return int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. + ## Gets the fallback quality to use for a specific machine-variant-material + # combination. + # + # For custom profiles we fall back onto this quality profile, since we + # don't know which quality profile it was based on. + # + # \param machine The machine ID of the user's configuration in 2.2. + # \param variant The variant ID of the user's configuration in 2.2. + # \param material The material ID of the user's configuration in 2.2. + @staticmethod + def getQualityFallback(machine, variant, material): + if machine not in _quality_fallbacks: + return "normal" + if variant not in _quality_fallbacks[machine]: + return "normal" + if material not in _quality_fallbacks[machine][variant]: + return "normal" + return _quality_fallbacks[machine][variant][material] + + ## Gets the set of built-in profile names in Cura 2.1. + # + # This is required to test if profiles should be converted to a quality + # profile or a quality-changes profile. + @staticmethod + def builtInProfiles(): + return _profile_translations.keys() + ## Gets a set of the machines which now have per-material quality profiles. # # \return A set of machine identifiers. @@ -142,7 +301,7 @@ class VersionUpgrade21to22(VersionUpgrade): ## Converts preferences from format version 2 to version 3. # # \param serialised The serialised preferences file in version 2. - # \param filename THe supposed file name of the preferences file, without + # \param filename The supposed file name of the preferences file, without # extension. # \return A tuple containing the new filename and the serialised # preferences in version 3, or None if the input was not of the correct @@ -166,6 +325,28 @@ class VersionUpgrade21to22(VersionUpgrade): return filename, None return profile.export() + ## Translates a material name for the change from Cura 2.1 to 2.2. + # + # \param material A material name in Cura 2.1. + # \return The name of the corresponding material in Cura 2.2. + @staticmethod + def translateMaterial(material): + if material in _material_translations: + return _material_translations[material] + return material + + ## Translates a material name for the change from Cura 2.1 to 2.2 in + # quality profile names. + # + # \param material A material name in Cura 2.1. + # \return The name of the corresponding material in the quality profiles + # in Cura 2.2. + @staticmethod + def translateMaterialForProfiles(material): + if material in _material_translations_profiles: + return _material_translations_profiles[material] + return material + ## Translates a printer name that might have changed since the last # version. # @@ -177,6 +358,17 @@ class VersionUpgrade21to22(VersionUpgrade): return _printer_translations[printer] return printer #Doesn't need to be translated. + ## Translates a printer name for the change from Cura 2.1 to 2.2 in quality + # profile names. + # + # \param printer A printer name in 2.1. + # \return The name of the corresponding printer in Cura 2.2. + @staticmethod + def translatePrinterForProfile(printer): + if printer in _printer_translations_profiles: + return _printer_translations_profiles[printer] + return printer + ## Translates a built-in profile name that might have changed since the # last version. # @@ -199,13 +391,15 @@ class VersionUpgrade21to22(VersionUpgrade): @staticmethod def translateSettings(settings): for key, value in settings.items(): - if key == "fill_perimeter_gaps": #Setting is removed. + if key in _removed_settings: del settings[key] elif key == "retraction_combing": #Combing was made into an enum instead of a boolean. settings[key] = "off" if (value == "False") else "all" elif key in _setting_name_translations: del settings[key] settings[_setting_name_translations[key]] = value + if "infill_overlap" in settings: # New setting, added in 2.3 + settings["skin_overlap"] = settings["infill_overlap"] return settings ## Translates a setting name for the change from Cura 2.1 to 2.2. @@ -242,4 +436,16 @@ class VersionUpgrade21to22(VersionUpgrade): def translateVariantForMaterials(variant, machine): if machine in _variant_translations_materials and variant in _variant_translations_materials[machine]: return _variant_translations_materials[machine][variant] + return variant + + ## Translates a variant name for the change from Cura 2.1 to 2.2 in quality + # profiles. + # + # \param variant The name of the variant in Cura 2.1. + # \return The name of the corresponding variant for in quality profiles in + # Cura 2.2. + @staticmethod + def translateVariantForProfiles(variant): + if variant in _variant_translations_profiles: + return _variant_translations_profiles[variant] return variant \ No newline at end of file diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 84b78c1d6a..bf3f34b667 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -7,7 +7,10 @@ import io import xml.etree.ElementTree as ET import uuid +from UM.Resources import Resources from UM.Logger import Logger +from UM.Util import parseBool +from cura.CuraApplication import CuraApplication import UM.Dictionary @@ -17,66 +20,70 @@ import UM.Settings class XmlMaterialProfile(UM.Settings.InstanceContainer): def __init__(self, container_id, *args, **kwargs): super().__init__(container_id, *args, **kwargs) + self._inherited_files = [] - ## 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) - - new_id = self.getMetaDataEntry("brand") + "_" + new_id + "_" + self.getDefinition().getId() - variant = self.getMetaDataEntry("variant") - if variant: - variant_containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = variant) - if variant_containers: - new_id += "_" + variant_containers[0].getName().replace(" ", "_") - - 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 + def getInheritedFiles(self): + return self._inherited_files ## Overridden from InstanceContainer def setReadOnly(self, read_only): super().setReadOnly(read_only) - for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(GUID = self.getMetaDataEntry("GUID")): - container._read_only = read_only + basefile = self.getMetaDataEntry("base_file", self._id) # if basefile is self.id, this is a basefile. + for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile): + container._read_only = read_only # prevent loop instead of calling setReadOnly ## Overridden from InstanceContainer + # set the meta data for all machine / variant combinations def setMetaDataEntry(self, key, value): if self.isReadOnly(): return + if self.getMetaDataEntry(key, None) == value: + # Prevent loop caused by for loop. + return super().setMetaDataEntry(key, value) - if key == "material": - self.setName(value) + basefile = self.getMetaDataEntry("base_file", self._id) #if basefile is self.id, this is a basefile. + # Update all containers that share GUID and basefile + for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile): + container.setMetaDataEntry(key, value) - for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(GUID = self.getMetaDataEntry("GUID")): - container.setMetaData(copy.deepcopy(self._metadata)) - if key == "material": - container.setName(value) - - ## Overridden from InstanceContainer - def setProperty(self, key, property_name, property_value, container = None): + ## Overridden from InstanceContainer, similar to setMetaDataEntry. + # without this function the setName would only set the name of the specific nozzle / material / machine combination container + # The function is a bit tricky. It will not set the name of all containers if it has the correct name itself. + def setName(self, new_name): if self.isReadOnly(): return - super().setProperty(key, property_name, property_value) + # Not only is this faster, it also prevents a major loop that causes a stack overflow. + if self.getName() == new_name: + return - for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(GUID = self.getMetaDataEntry("GUID")): - container._dirty = True + super().setName(new_name) + + basefile = self.getMetaDataEntry("base_file", self._id) # if basefile is self.id, this is a basefile. + # Update the basefile as well, this is actually what we're trying to do + # Update all containers that share GUID and basefile + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile) + for container in containers: + container.setName(new_name) ## Overridden from InstanceContainer + # def setProperty(self, key, property_name, property_value, container = None): + # if self.isReadOnly(): + # return + # + # super().setProperty(key, property_name, property_value) + # + # basefile = self.getMetaDataEntry("base_file", self._id) #if basefile is self.id, this is a basefile. + # for container in UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile): + # if not container.isReadOnly(): + # container.setDirty(True) + + ## Overridden from InstanceContainer + # base file: global settings + supported machines + # machine / variant combination: only changes for itself. def serialize(self): registry = UM.Settings.ContainerRegistry.getInstance() @@ -85,7 +92,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): # Since we create an instance of XmlMaterialProfile for each machine and nozzle in the profile, # we should only serialize the "base" material definition, since that can then take care of # serializing the machine/nozzle specific profiles. - raise NotImplementedError("Cannot serialize non-root XML materials") + raise NotImplementedError("Ignoring serializing non-root XML materials, the data is contained in the base material") builder = ET.TreeBuilder() @@ -118,11 +125,19 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): builder.data(metadata.pop("color_name", "")) builder.end("color") + builder.start("label") + builder.data(self._name) + builder.end("label") + builder.end("name") ## End Name Block for key, value in metadata.items(): builder.start(key) + # Normally value is a string. + # Nones get handled well. + if isinstance(value, bool): + value = str(value) # parseBool in deserialize expects 'True'. builder.data(value) builder.end(key) @@ -215,19 +230,130 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): _indent(root) stream = io.StringIO() tree = ET.ElementTree(root) - tree.write(stream, "unicode", True) + tree.write(stream, encoding="unicode", xml_declaration=True) return stream.getvalue() + # Recursively resolve loading inherited files + def _resolveInheritance(self, file_name): + xml = self._loadFile(file_name) + + inherits = xml.find("./um:inherits", self.__namespaces) + if inherits is not None: + inherited = self._resolveInheritance(inherits.text) + xml = self._mergeXML(inherited, xml) + + return xml + + def _loadFile(self, file_name): + path = Resources.getPath(CuraApplication.getInstance().ResourceTypes.MaterialInstanceContainer, file_name + ".xml.fdm_material") + + with open(path, encoding="utf-8") as f: + contents = f.read() + + self._inherited_files.append(path) + return ET.fromstring(contents) + + # The XML material profile can have specific settings for machines. + # Some machines share profiles, so they are only created once. + # This function duplicates those elements so that each machine tag only has one identifier. + def _expandMachinesXML(self, element): + settings_element = element.find("./um:settings", self.__namespaces) + machines = settings_element.iterfind("./um:machine", self.__namespaces) + machines_to_add = [] + machines_to_remove = [] + for machine in machines: + identifiers = list(machine.iterfind("./um:machine_identifier", self.__namespaces)) + has_multiple_identifiers = len(identifiers) > 1 + if has_multiple_identifiers: + # Multiple identifiers found. We need to create a new machine element and copy all it's settings there. + for identifier in identifiers: + new_machine = copy.deepcopy(machine) + # Create list of identifiers that need to be removed from the copied element. + other_identifiers = [self._createKey(other_identifier) for other_identifier in identifiers if other_identifier is not identifier] + # As we can only remove by exact object reference, we need to look through the identifiers of copied machine. + new_machine_identifiers = list(new_machine.iterfind("./um:machine_identifier", self.__namespaces)) + for new_machine_identifier in new_machine_identifiers: + key = self._createKey(new_machine_identifier) + # Key was in identifiers to remove, so this element needs to be purged + if key in other_identifiers: + new_machine.remove(new_machine_identifier) + machines_to_add.append(new_machine) + machines_to_remove.append(machine) + else: + pass # Machine only has one identifier. Nothing to do. + # Remove & add all required machines. + for machine_to_remove in machines_to_remove: + settings_element.remove(machine_to_remove) + for machine_to_add in machines_to_add: + settings_element.append(machine_to_add) + return element + + def _mergeXML(self, first, second): + result = copy.deepcopy(first) + self._combineElement(self._expandMachinesXML(result), self._expandMachinesXML(second)) + return result + + def _createKey(self, element): + key = element.tag.split("}")[-1] + if "key" in element.attrib: + key += " key:" + element.attrib["key"] + if "manufacturer" in element.attrib: + key += " manufacturer:" + element.attrib["manufacturer"] + if "product" in element.attrib: + key += " product:" + element.attrib["product"] + if key == "machine": + for item in element: + if "machine_identifier" in item.tag: + key += " " + item.attrib["product"] + return key + + # Recursively merges XML elements. Updates either the text or children if another element is found in first. + # If it does not exist, copies it from second. + def _combineElement(self, first, second): + # Create a mapping from tag name to element. + + mapping = {} + for element in first: + key = self._createKey(element) + mapping[key] = element + for element in second: + key = self._createKey(element) + if len(element): # Check if element has children. + try: + if "setting" in element.tag and not "settings" in element.tag: + # Setting can have points in it. In that case, delete all values and override them. + for child in list(mapping[key]): + mapping[key].remove(child) + for child in element: + mapping[key].append(child) + else: + self._combineElement(mapping[key], element) # Multiple elements, handle those. + except KeyError: + mapping[key] = element + first.append(element) + else: + try: + mapping[key].text = element.text + except KeyError: # Not in the mapping, so simply add it + mapping[key] = element + first.append(element) + ## Overridden from InstanceContainer def deserialize(self, serialized): data = ET.fromstring(serialized) self.addMetaDataEntry("type", "material") + self.addMetaDataEntry("base_file", self.id) # TODO: Add material verfication self.addMetaDataEntry("status", "unknown") + inherits = data.find("./um:inherits", self.__namespaces) + if inherits is not None: + inherited = self._resolveInheritance(inherits.text) + data = self._mergeXML(inherited, data) + metadata = data.iterfind("./um:metadata/*", self.__namespaces) for entry in metadata: tag_name = _tag_without_namespace(entry) @@ -236,8 +362,12 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): brand = entry.find("./um:brand", self.__namespaces) material = entry.find("./um:material", self.__namespaces) color = entry.find("./um:color", self.__namespaces) + label = entry.find("./um:label", self.__namespaces) - self.setName(material.text) + if label is not None: + self.setName(label.text) + else: + self.setName(self._profile_name(material.text, color.text)) self.addMetaDataEntry("brand", brand.text) self.addMetaDataEntry("material", material.text) @@ -266,6 +396,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): self.setDefinition(UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0]) + global_compatibility = True global_setting_values = {} settings = data.iterfind("./um:settings/um:setting", self.__namespaces) for entry in settings: @@ -273,6 +404,9 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): if key in self.__material_property_setting_map: self.setProperty(self.__material_property_setting_map[key], "value", entry.text, self._definition) global_setting_values[self.__material_property_setting_map[key]] = entry.text + elif key in self.__unmapped_settings: + if key == "hardware compatible": + global_compatibility = parseBool(entry.text) else: Logger.log("d", "Unsupported material setting %s", key) @@ -280,12 +414,16 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): machines = data.iterfind("./um:settings/um:machine", self.__namespaces) for machine in machines: + machine_compatibility = global_compatibility machine_setting_values = {} settings = machine.iterfind("./um:setting", self.__namespaces) for entry in settings: key = entry.get("key") if key in self.__material_property_setting_map: machine_setting_values[self.__material_property_setting_map[key]] = entry.text + elif key in self.__unmapped_settings: + if key == "hardware compatible": + machine_compatibility = parseBool(entry.text) else: Logger.log("d", "Unsupported material setting %s", key) @@ -293,8 +431,8 @@ 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) - continue + # Lets try again with some naive heuristics. + machine_id = identifier.get("product").replace(" ", "").lower() definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = machine_id) if not definitions: @@ -303,21 +441,22 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): definition = definitions[0] - new_material = XmlMaterialProfile(self.id + "_" + machine_id) - new_material.setName(self.getName()) - new_material.setMetaData(copy.deepcopy(self.getMetaData())) - new_material.setDefinition(definition) - new_material.addMetaDataEntry("base_file", self.id) + if machine_compatibility: + new_material = XmlMaterialProfile(self.id + "_" + machine_id) + new_material.setName(self.getName()) + new_material.setMetaData(copy.deepcopy(self.getMetaData())) + new_material.setDefinition(definition) - for key, value in global_setting_values.items(): - new_material.setProperty(key, "value", value, definition) + for key, value in global_setting_values.items(): + new_material.setProperty(key, "value", value, definition) - for key, value in machine_setting_values.items(): - new_material.setProperty(key, "value", value, definition) + for key, value in machine_setting_values.items(): + new_material.setProperty(key, "value", value, definition) - new_material._dirty = False + new_material._dirty = False + + UM.Settings.ContainerRegistry.getInstance().addContainer(new_material) - UM.Settings.ContainerRegistry.getInstance().addContainer(new_material) hotends = machine.iterfind("./um:hotend", self.__namespaces) for hotend in hotends: @@ -334,13 +473,25 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): Logger.log("d", "No variants found with ID or name %s for machine %s", hotend_id, definition.id) continue + hotend_compatibility = machine_compatibility + hotend_setting_values = {} + settings = hotend.iterfind("./um:setting", self.__namespaces) + for entry in settings: + key = entry.get("key") + if key in self.__material_property_setting_map: + hotend_setting_values[self.__material_property_setting_map[key]] = entry.text + elif key in self.__unmapped_settings: + if key == "hardware compatible": + hotend_compatibility = parseBool(entry.text) + else: + Logger.log("d", "Unsupported material setting %s", key) + new_hotend_material = XmlMaterialProfile(self.id + "_" + machine_id + "_" + hotend_id.replace(" ", "_")) new_hotend_material.setName(self.getName()) new_hotend_material.setMetaData(copy.deepcopy(self.getMetaData())) new_hotend_material.setDefinition(definition) - new_hotend_material.addMetaDataEntry("base_file", self.id) - new_hotend_material.addMetaDataEntry("variant", variant_containers[0].id) + new_hotend_material.addMetaDataEntry("compatible", hotend_compatibility) for key, value in global_setting_values.items(): new_hotend_material.setProperty(key, "value", value, definition) @@ -348,17 +499,20 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): for key, value in machine_setting_values.items(): new_hotend_material.setProperty(key, "value", value, definition) - settings = hotend.iterfind("./um:setting", self.__namespaces) - for entry in settings: - key = entry.get("key") - if key in self.__material_property_setting_map: - new_hotend_material.setProperty(self.__material_property_setting_map[key], "value", entry.text, definition) - else: - Logger.log("d", "Unsupported material setting %s", key) + for key, value in hotend_setting_values.items(): + new_hotend_material.setProperty(key, "value", value, definition) new_hotend_material._dirty = False UM.Settings.ContainerRegistry.getInstance().addContainer(new_hotend_material) + if not global_compatibility: + # Change the type of this container so it is not shown as an option in menus. + # This uses InstanceContainer.setMetaDataEntry because otherwise all containers that + # share this basefile are also updated. + dirty = self.isDirty() + super().setMetaDataEntry("type", "incompatible_material") + super().setDirty(dirty) # reset dirty flag after setMetaDataEntry + def _addSettingElement(self, builder, instance): try: key = UM.Dictionary.findKey(self.__material_property_setting_map, instance.definition.key) @@ -369,24 +523,34 @@ 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", + "retraction speed": "retraction_speed" } + __unmapped_settings = [ + "hardware compatible" + ] # 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" } diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 4c90ae9ecd..b594ed1653 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Prusa i3 Hephestos" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/s\n; -- end of START GCODE --" }, diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index e49e7163e8..68f06e390f 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Hephestos 2" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nM104 S{material_print_temperature} ; Heat up extruder while leveling\nM800 ; Custom GCODE to fire start print procedure\nM109 S{material_print_temperature} ; Makes sure the temperature is correct before printing\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" }, "machine_width": { "default_value": 210 }, diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index 867f5f37aa..7a3b3f27fd 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Prusa i3 Hephestos XL" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/s\n; -- end of START GCODE --" }, diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index b8d4cbf015..a0290a4063 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Witbox" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/s\n; -- end of START GCODE --" }, diff --git a/resources/definitions/bq_witbox_2.def.json b/resources/definitions/bq_witbox_2.def.json index e47d082d0f..ac13c2144c 100644 --- a/resources/definitions/bq_witbox_2.def.json +++ b/resources/definitions/bq_witbox_2.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Witbox 2" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" }, diff --git a/resources/definitions/custom.def.json b/resources/definitions/custom.def.json new file mode 100644 index 0000000000..7ae1d1bd28 --- /dev/null +++ b/resources/definitions/custom.def.json @@ -0,0 +1,15 @@ +{ + "id": "custom", + "version": 2, + "name": "Custom FDM printer", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Ultimaker", + "manufacturer": "Custom", + "category": "Custom", + "file_formats": "text/x-gcode", + "has_materials": true, + "first_start_actions": ["MachineSettingsAction"] + } +} diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index 7c594e3eda..16f18d3b2e 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -177,8 +177,7 @@ "minimum_value_warning": "machine_nozzle_offset_x", "maximum_value": "machine_width", "settable_per_mesh": false, - "settable_per_extruder": true, - "enabled": false + "settable_per_extruder": true }, "extruder_prime_pos_y": { @@ -190,8 +189,7 @@ "minimum_value_warning": "machine_nozzle_offset_y", "maximum_value_warning": "machine_depth", "settable_per_mesh": false, - "settable_per_extruder": true, - "enabled": false + "settable_per_extruder": true } } } diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index f2d51c5020..eae6593fb8 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -10,12 +10,14 @@ "manufacturer": "Ultimaker", "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", "visible": false, - "preferred_material": "pla", - "preferred_quality": "normal", + "has_materials": true, + "preferred_material": "*generic_pla*", + "preferred_quality": "*normal*", "machine_extruder_trains": { "0": "fdmextruder" - } + }, + "supports_usb_connection": true }, "settings": { @@ -27,6 +29,16 @@ "icon": "category_machine", "children": { + "machine_name": + { + "label": "Machine Type", + "description": "The name of your 3D printer model.", + "default_value": "Unknown", + "type": "str", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false + }, "machine_show_variants": { "label": "Show machine variants", @@ -402,7 +414,7 @@ "description": "The maximum speed of the filament.", "unit": "mm/s", "type": "float", - "default_value": 25, + "default_value": 299792458000, "settable_per_mesh": false, "settable_per_extruder": false, "settable_per_meshgroup": false @@ -642,6 +654,7 @@ "type": "float", "enabled": "support_enable", "value": "line_width", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -654,7 +667,8 @@ "minimum_value": "0.0001", "maximum_value_warning": "machine_nozzle_size * 2", "type": "float", - "enabled": "extruderValue(support_extruder_nr, 'support_interface_enable')", + "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable')", + "limit_to_extruder": "support_interface_extruder_nr", "value": "line_width", "settable_per_mesh": false, "settable_per_extruder": true @@ -1099,6 +1113,7 @@ "description": "The temperature used for the heated build plate. Set at 0 to pre-heat the printer manually.", "unit": "°C", "type": "float", + "resolve": "sum(extruderValues('material_bed_temperature')) / len(extruderValues('material_bed_temperature'))", "default_value": 60, "minimum_value": "-273.15", "maximum_value_warning": "260", @@ -1158,7 +1173,7 @@ "default_value": 25, "minimum_value": "0", "maximum_value": "machine_max_feedrate_e", - "maximum_value_warning": "100", + "maximum_value_warning": "25", "enabled": "retraction_enable", "settable_per_mesh": false, "settable_per_extruder": true, @@ -1171,7 +1186,7 @@ "default_value": 25, "minimum_value": "0", "maximum_value": "machine_max_feedrate_e", - "maximum_value_warning": "100", + "maximum_value_warning": "25", "enabled": "retraction_enable", "value": "retraction_speed", "settable_per_mesh": false, @@ -1185,7 +1200,7 @@ "default_value": 25, "minimum_value": "0", "maximum_value": "machine_max_feedrate_e", - "maximum_value_warning": "100", + "maximum_value_warning": "25", "enabled": "retraction_enable", "value": "retraction_speed", "settable_per_mesh": false, @@ -1455,6 +1470,7 @@ "value": "speed_print", "enabled": "support_enable", "settable_per_mesh": false, + "limit_to_extruder": "support_extruder_nr", "settable_per_extruder": true, "children": { @@ -1470,6 +1486,7 @@ "maximum_value_warning": "150", "value": "speed_support", "enabled": "support_enable", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -1483,7 +1500,8 @@ "minimum_value": "0.1", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)", "maximum_value_warning": "150", - "enabled": "extruderValue(support_extruder_nr, 'support_interface_enable') and support_enable", + "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", + "limit_to_extruder": "support_interface_extruder_nr", "value": "speed_support / 1.5", "settable_per_mesh": false, "settable_per_extruder": true @@ -1574,7 +1592,8 @@ "value": "speed_layer_0", "enabled": "adhesion_type == \"skirt\" or adhesion_type == \"brim\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "max_feedrate_z_override": { @@ -1724,6 +1743,7 @@ "value": "acceleration_print", "enabled": "acceleration_enabled and support_enable", "settable_per_mesh": false, + "limit_to_extruder": "support_extruder_nr", "settable_per_extruder": true, "children": { "acceleration_support_infill": { @@ -1737,6 +1757,7 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "enabled": "acceleration_enabled and support_enable", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -1750,7 +1771,8 @@ "minimum_value": "0.1", "minimum_value_warning": "100", "maximum_value_warning": "10000", - "enabled": "acceleration_enabled and extruderValue(support_extruder_nr, 'support_interface_enable') and support_enable", + "enabled": "acceleration_enabled and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", + "limit_to_extruder": "support_interface_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true } @@ -1839,11 +1861,10 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "enabled": "acceleration_enabled", - "settable_per_mesh": false + "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr" }, - - "jerk_enabled": { "label": "Enable Jerk Control", "description": "Enables adjusting the jerk of print head when the velocity in the X or Y axis changes. Increasing the jerk can reduce printing time at the cost of print quality.", @@ -1944,6 +1965,7 @@ "enabled": "jerk_enabled and support_enable", "settable_per_mesh": false, "settable_per_extruder": true, + "limit_to_extruder": "support_extruder_nr", "children": { "jerk_support_infill": { "label": "Support Infill Jerk", @@ -1956,6 +1978,7 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "enabled": "jerk_enabled and support_enable", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -1969,7 +1992,8 @@ "minimum_value": "0.1", "minimum_value_warning": "5", "maximum_value_warning": "50", - "enabled": "jerk_enabled and extruderValue(support_extruder_nr, 'support_interface_enable') and support_enable", + "enabled": "jerk_enabled and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", + "limit_to_extruder": "support_interface_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true } @@ -2058,7 +2082,8 @@ "maximum_value_warning": "50", "value": "jerk_layer_0", "enabled": "jerk_enabled", - "settable_per_mesh": false + "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr" } } }, @@ -2288,7 +2313,7 @@ "minimum_value": "0", "maximum_value": "90", "default_value": 50, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_interface_extruder_nr if support_interface_enable else support_infill_extruder_nr", "enabled": "support_enable", "settable_per_mesh": true }, @@ -2307,7 +2332,7 @@ }, "default_value": "zigzag", "enabled": "support_enable", - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -2318,6 +2343,7 @@ "type": "bool", "default_value": true, "enabled": "support_enable and (support_pattern == 'zigzag')", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -2331,6 +2357,7 @@ "maximum_value_warning": "100", "default_value": 15, "enabled": "support_enable", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true, "children": { @@ -2344,6 +2371,7 @@ "default_value": 2.66, "enabled": "support_enable", "value": "(support_line_width * 100) / support_infill_rate * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true } @@ -2358,7 +2386,7 @@ "minimum_value": "0", "maximum_value_warning": "10", "default_value": 0.1, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_interface_extruder_nr if support_interface_enable else support_infill_extruder_nr", "enabled": "support_enable", "settable_per_mesh": true, "children": @@ -2374,7 +2402,7 @@ "type": "float", "enabled": "support_enable", "value": "extruderValue(support_extruder_nr, 'support_z_distance')", - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_interface_extruder_nr if support_interface_enable else support_infill_extruder_nr", "settable_per_mesh": true }, "support_bottom_distance": @@ -2386,7 +2414,7 @@ "maximum_value_warning": "10", "default_value": 0.1, "value": "extruderValue(support_extruder_nr, 'support_z_distance') if support_type == 'everywhere' else 0", - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_interface_extruder_nr if support_interface_enable else support_infill_extruder_nr", "type": "float", "enabled": "support_enable and support_type == 'everywhere'", "settable_per_mesh": true @@ -2402,7 +2430,7 @@ "minimum_value": "0", "maximum_value_warning": "10", "default_value": 0.7, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_infill_extruder_nr", "enabled": "support_enable", "settable_per_mesh": true }, @@ -2415,7 +2443,7 @@ "z_overrides_xy": "Z overrides X/Y" }, "default_value": "z_overrides_xy", - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_infill_extruder_nr", "enabled": "support_enable", "settable_per_mesh": true }, @@ -2428,8 +2456,8 @@ "maximum_value_warning": "10", "default_value": 0.2, "value": "machine_nozzle_size / 2", - "global_inherits_stack": "support_extruder_nr", - "enabled": "support_enable and extruderValue(support_extruder_nr, 'support_xy_overrides_z') == 'z_overrides_xy'", + "limit_to_extruder": "support_infill_extruder_nr", + "enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_xy_overrides_z') == 'z_overrides_xy'", "settable_per_mesh": true }, "support_bottom_stair_step_height": @@ -2439,7 +2467,7 @@ "unit": "mm", "type": "float", "default_value": 0.3, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_interface_extruder_nr if support_interface_enable else support_infill_extruder_nr", "minimum_value": "0", "maximum_value_warning": "1.0", "enabled": "support_enable", @@ -2452,7 +2480,7 @@ "unit": "mm", "type": "float", "default_value": 2.0, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_infill_extruder_nr", "minimum_value_warning": "0", "maximum_value_warning": "10", "enabled": "support_enable", @@ -2465,32 +2493,19 @@ "unit": "mm", "type": "float", "default_value": 0.2, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_infill_extruder_nr", "minimum_value_warning": "-0.5", "maximum_value_warning": "5.0", "enabled": "support_enable", "settable_per_mesh": true }, - "support_area_smoothing": - { - "label": "Support Area Smoothing", - "description": "Maximum distance in the X/Y directions of a line segment which is to be smoothed out. Ragged lines are introduced by the join distance and support bridge, which cause the machine to resonate. Smoothing the support areas won't cause them to break with the constraints, except it might change the overhang.", - "unit": "mm", - "type": "float", - "default_value": 0.6, - "global_inherits_stack": "support_extruder_nr", - "minimum_value": "0", - "maximum_value_warning": "1.0", - "enabled": "support_enable", - "settable_per_mesh": true - }, "support_interface_enable": { "label": "Enable Support Interface", "description": "Generate a dense interface between the model and the support. This will create a skin at the top of the support on which the model is printed and at the bottom of the support, where it rests on the model.", "type": "bool", "default_value": false, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_interface_extruder_nr", "enabled": "support_enable", "settable_per_mesh": true }, @@ -2502,9 +2517,9 @@ "type": "float", "default_value": 1, "minimum_value": "0", - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_interface_extruder_nr", "maximum_value_warning": "10", - "enabled": "extruderValue(support_extruder_nr, 'support_interface_enable') and support_enable", + "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", "settable_per_mesh": true, "children": { @@ -2515,11 +2530,11 @@ "unit": "mm", "type": "float", "default_value": 1, - "value": "extruderValue(support_extruder_nr, 'support_interface_height')", + "value": "extruderValue(support_interface_extruder_nr, 'support_interface_height')", "minimum_value": "0", - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_interface_extruder_nr", "maximum_value_warning": "10", - "enabled": "extruderValue(support_extruder_nr, 'support_interface_enable') and support_enable", + "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", "settable_per_mesh": true }, "support_bottom_height": @@ -2529,16 +2544,29 @@ "unit": "mm", "type": "float", "default_value": 1, - "value": "extruderValue(support_extruder_nr, 'support_interface_height')", + "value": "extruderValue(support_interface_extruder_nr, 'support_interface_height')", "minimum_value": "0", - "minimum_value_warning": "extruderValue(support_extruder_nr, 'support_bottom_stair_step_height')", - "global_inherits_stack": "support_extruder_nr", + "minimum_value_warning": "extruderValue(support_interface_extruder_nr, 'support_bottom_stair_step_height')", + "limit_to_extruder": "support_interface_extruder_nr", "maximum_value_warning": "10", - "enabled": "extruderValue(support_extruder_nr, 'support_interface_enable') and support_enable", + "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", "settable_per_mesh": true } } }, + "support_interface_skip_height": + { + "label": "Support Interface Resolution", + "description": "When checking where there's model above the support, take steps of the given height. Lower values will slice slower, while higher values may cause normal support to be printed in some places where there should have been support interface.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "support_interface_height", + "limit_to_extruder": "support_interface_extruder_nr", + "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", + "settable_per_mesh": true + }, "support_interface_density": { "label": "Support Interface Density", @@ -2548,8 +2576,8 @@ "default_value": 100, "minimum_value": "0", "maximum_value_warning": "100", - "global_inherits_stack": "support_extruder_nr", - "enabled": "extruderValue(support_extruder_nr, 'support_interface_enable') and support_enable", + "limit_to_extruder": "support_interface_extruder_nr", + "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", "settable_per_mesh": false, "settable_per_extruder": true, "children": @@ -2563,8 +2591,8 @@ "default_value": 0.4, "minimum_value": "0", "value": "0 if support_interface_density == 0 else (support_interface_line_width * 100) / support_interface_density * (2 if support_interface_pattern == \"grid\" else (3 if support_interface_pattern == \"triangles\" else 1))", - "global_inherits_stack": "support_extruder_nr", - "enabled": "extruderValue(support_extruder_nr, 'support_interface_enable') and support_enable", + "limit_to_extruder": "support_interface_extruder_nr", + "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", "settable_per_mesh": false, "settable_per_extruder": true } @@ -2584,8 +2612,8 @@ "zigzag": "Zig Zag" }, "default_value": "concentric", - "global_inherits_stack": "support_extruder_nr", - "enabled": "extruderValue(support_extruder_nr, 'support_interface_enable') and support_enable", + "limit_to_extruder": "support_interface_extruder_nr", + "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -2595,7 +2623,7 @@ "description": "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. Near the overhang the towers' diameter decreases, forming a roof.", "type": "bool", "default_value": true, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_infill_extruder_nr", "enabled": "support_enable", "settable_per_mesh": true }, @@ -2606,10 +2634,10 @@ "unit": "mm", "type": "float", "default_value": 3.0, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_infill_extruder_nr", "minimum_value": "0", "maximum_value_warning": "10", - "enabled": "support_enable and extruderValue(support_extruder_nr, 'support_use_towers')", + "enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_use_towers')", "settable_per_mesh": true }, "support_minimal_diameter": @@ -2619,11 +2647,11 @@ "unit": "mm", "type": "float", "default_value": 3.0, - "global_inherits_stack": "support_extruder_nr", + "limit_to_extruder": "support_infill_extruder_nr", "minimum_value": "0", "maximum_value_warning": "10", - "maximum_value": "extruderValue(support_extruder_nr, 'support_tower_diameter')", - "enabled": "support_enable and extruderValue(support_extruder_nr, 'support_use_towers')", + "maximum_value": "extruderValue(support_infill_extruder_nr, 'support_tower_diameter')", + "enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_use_towers')", "settable_per_mesh": true }, "support_tower_roof_angle": @@ -2635,8 +2663,8 @@ "minimum_value": "0", "maximum_value": "90", "default_value": 65, - "global_inherits_stack": "support_extruder_nr", - "enabled": "support_enable and extruderValue(support_extruder_nr, 'support_use_towers')", + "limit_to_extruder": "support_infill_extruder_nr", + "enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_use_towers')", "settable_per_mesh": true } } @@ -2687,6 +2715,7 @@ "raft": "Raft" }, "default_value": "brim", + "resolve": "'raft' if 'raft' in extruderValues('adhesion_type') else ('brim' if 'brim' in extruderValues('adhesion_type') else 'skirt')", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -2700,7 +2729,8 @@ "maximum_value_warning": "10", "enabled": "adhesion_type == \"skirt\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "skirt_gap": { @@ -2713,7 +2743,8 @@ "maximum_value_warning": "100", "enabled": "adhesion_type == \"skirt\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "skirt_brim_minimal_length": { @@ -2741,6 +2772,7 @@ "enabled": "adhesion_type == \"brim\"", "settable_per_mesh": false, "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr", "children": { "brim_line_count": @@ -2754,7 +2786,8 @@ "value": "math.ceil(brim_width / skirt_brim_line_width)", "enabled": "adhesion_type == \"brim\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" } } }, @@ -2766,7 +2799,8 @@ "default_value": true, "enabled": "adhesion_type == \"brim\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_margin": { @@ -2777,7 +2811,8 @@ "default_value": 15, "minimum_value_warning": "0", "maximum_value_warning": "10", - "enabled": "adhesion_type == \"raft\"" + "enabled": "adhesion_type == \"raft\"", + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_airgap": { @@ -2790,7 +2825,8 @@ "maximum_value_warning": "1.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "layer_0_z_overlap": { "label": "Initial Layer Z Overlap", @@ -2803,7 +2839,8 @@ "maximum_value_warning": "layer_height", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_surface_layers": { @@ -2815,7 +2852,8 @@ "maximum_value_warning": "20", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_surface_thickness": { @@ -2829,7 +2867,8 @@ "maximum_value_warning": "2.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_surface_line_width": { @@ -2843,7 +2882,8 @@ "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_surface_line_spacing": { @@ -2857,7 +2897,8 @@ "enabled": "adhesion_type == \"raft\"", "value": "raft_surface_line_width", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_interface_thickness": { @@ -2871,7 +2912,8 @@ "maximum_value_warning": "5.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_interface_line_width": { @@ -2885,7 +2927,8 @@ "maximum_value_warning": "machine_nozzle_size * 2", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_interface_line_spacing": { @@ -2899,7 +2942,8 @@ "maximum_value_warning": "15.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_base_thickness": { @@ -2913,7 +2957,8 @@ "maximum_value_warning": "5.0", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_base_line_width": { @@ -2927,7 +2972,8 @@ "maximum_value_warning": "machine_nozzle_size * 3", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_base_line_spacing": { @@ -2941,7 +2987,8 @@ "maximum_value_warning": "100", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_speed": { @@ -2957,6 +3004,7 @@ "value": "speed_print / 60 * 30", "settable_per_mesh": false, "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr", "children": { "raft_surface_speed": @@ -2972,7 +3020,8 @@ "enabled": "adhesion_type == \"raft\"", "value": "raft_speed", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_interface_speed": { @@ -2987,7 +3036,8 @@ "maximum_value_warning": "150", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_base_speed": { @@ -3002,13 +3052,11 @@ "enabled": "adhesion_type == \"raft\"", "value": "0.75 * raft_speed", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" } } }, - - - "raft_acceleration": { "label": "Raft Print Acceleration", "description": "The acceleration with which the raft is printed.", @@ -3021,6 +3069,7 @@ "value": "acceleration_print", "enabled": "adhesion_type == \"raft\" and acceleration_enabled", "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr", "children": { "raft_surface_acceleration": { "label": "Raft Top Print Acceleration", @@ -3033,7 +3082,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "enabled": "adhesion_type == \"raft\" and acceleration_enabled", - "settable_per_mesh": false + "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_interface_acceleration": { "label": "Raft Middle Print Acceleration", @@ -3046,7 +3096,8 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "enabled": "adhesion_type == \"raft\" and acceleration_enabled", - "settable_per_mesh": false + "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_base_acceleration": { "label": "Raft Base Print Acceleration", @@ -3059,13 +3110,11 @@ "minimum_value_warning": "100", "maximum_value_warning": "10000", "enabled": "adhesion_type == \"raft\" and acceleration_enabled", - "settable_per_mesh": false + "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr" } } }, - - - "raft_jerk": { "label": "Raft Print Jerk", "description": "The jerk with which the raft is printed.", @@ -3078,6 +3127,7 @@ "value": "jerk_print", "enabled": "adhesion_type == \"raft\" and jerk_enabled", "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr", "children": { "raft_surface_jerk": { "label": "Raft Top Print Jerk", @@ -3090,7 +3140,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "100", "enabled": "adhesion_type == \"raft\" and jerk_enabled", - "settable_per_mesh": false + "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_interface_jerk": { "label": "Raft Middle Print Jerk", @@ -3103,7 +3154,8 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "enabled": "adhesion_type == \"raft\" and jerk_enabled", - "settable_per_mesh": false + "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_base_jerk": { "label": "Raft Base Print Jerk", @@ -3116,12 +3168,11 @@ "minimum_value_warning": "5", "maximum_value_warning": "50", "enabled": "adhesion_type == \"raft\" and jerk_enabled", - "settable_per_mesh": false + "settable_per_mesh": false, + "limit_to_extruder": "adhesion_extruder_nr" } } }, - - "raft_fan_speed": { "label": "Raft Fan Speed", "description": "The fan speed for the raft.", @@ -3133,6 +3184,7 @@ "settable_per_mesh": false, "settable_per_extruder": true, "enabled": "adhesion_type == \"raft\"", + "limit_to_extruder": "adhesion_extruder_nr", "children": { "raft_surface_fan_speed": @@ -3147,7 +3199,8 @@ "value": "raft_fan_speed", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_interface_fan_speed": { @@ -3161,7 +3214,8 @@ "value": "raft_fan_speed", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" }, "raft_base_fan_speed": { @@ -3175,7 +3229,8 @@ "value": "raft_fan_speed", "enabled": "adhesion_type == \"raft\"", "settable_per_mesh": false, - "settable_per_extruder": true + "settable_per_extruder": true, + "limit_to_extruder": "adhesion_extruder_nr" } } } @@ -3187,6 +3242,7 @@ "type": "category", "icon": "category_dual", "description": "Settings used for printing with multiple extruders.", + "enabled": "machine_extruder_count > 1", "children": { "adhesion_extruder_nr": @@ -3238,7 +3294,7 @@ "type": "extruder", "default_value": "0", "value": "support_extruder_nr", - "enabled": "support_enable and machine_extruder_count > 1 and extruderValue(support_extruder_nr, 'support_interface_enable')", + "enabled": "support_enable and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false } @@ -3249,7 +3305,9 @@ "label": "Enable Prime Tower", "description": "Print a tower next to the print which serves to prime the material after each nozzle switch.", "type": "bool", + "enabled": "machine_extruder_count > 1", "default_value": false, + "resolve": "max(extruderValues('prime_tower_enable'))", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3263,6 +3321,7 @@ "default_value": 15, "value": "15 if prime_tower_enable else 0", "minimum_value": "0", + "maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)", "maximum_value_warning": "20", "settable_per_mesh": false, "settable_per_extruder": false @@ -3277,6 +3336,8 @@ "default_value": 200, "minimum_value_warning": "-1000", "maximum_value_warning": "1000", + "maximum_value": "machine_width - 0.5 * prime_tower_size", + "minimum_value": "0.5 * prime_tower_size", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3290,6 +3351,8 @@ "default_value": 200, "minimum_value_warning": "-1000", "maximum_value_warning": "1000", + "maximum_value": "machine_depth - 0.5 * prime_tower_size", + "minimum_value": "0.5 * prime_tower_size", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3481,7 +3544,7 @@ }, "experimental": { - "label": "Experimental Modes", + "label": "Experimental", "type": "category", "icon": "category_experimental", "description": "experimental!", @@ -3643,6 +3706,7 @@ "maximum_value": "90", "default_value": 30, "enabled": "support_conical_enabled and support_enable", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": true }, "support_conical_min_width": @@ -3656,6 +3720,7 @@ "maximum_value_warning": "100.0", "type": "float", "enabled": "support_conical_enabled and support_enable", + "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": true }, "magic_fuzzy_skin_enabled": @@ -3726,6 +3791,7 @@ "type": "float", "unit": "mm", "default_value": 3, + "value": "machine_nozzle_head_distance", "minimum_value": "0.0001", "maximum_value_warning": "20", "enabled": "wireframe_enabled", diff --git a/resources/definitions/grr_neo.def.json b/resources/definitions/grr_neo.def.json index e4b871303b..e2a4d47b78 100644 --- a/resources/definitions/grr_neo.def.json +++ b/resources/definitions/grr_neo.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "German RepRap Neo" }, "machine_width": { "default_value": 150 }, diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index 9ba8d0d44b..48c3ace5d9 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "Innovo INVENTOR" }, "machine_width": { "default_value": 340 }, @@ -27,7 +28,7 @@ "default_value": true }, "machine_center_is_zero": { - "default_value": false + "default_value": true }, "machine_nozzle_size": { "default_value": 0.4 @@ -56,7 +57,7 @@ "default_value": "G28 ; Home extruder\nM107 ; Turn off fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\n{IF_BED}M190 S{BED}\n{IF_EXT0}M104 T0 S{TEMP0}\n{IF_EXT0}M109 T0 S{TEMP0}\n{IF_EXT1}M104 T1 S{TEMP1}\n{IF_EXT1}M109 T1 S{TEMP1}\nG32 S3 ; auto level\nG92 E0 ; Reset extruder position" }, "machine_end_gcode": { - "default_value": "M104 S0\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors" + "default_value": "M104 S0 ; turn off extruders\nM140 S0 ; heated bed heater off\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors" }, "layer_height": { "default_value": 0.15 @@ -65,10 +66,10 @@ "default_value": 0.8 }, "top_bottom_thickness": { - "default_value": 0.3 + "default_value": 1.2 }, "material_print_temperature": { - "default_value": 215 + "default_value": 205 }, "material_bed_temperature": { "default_value": 60 @@ -77,23 +78,30 @@ "default_value": 1.75 }, "speed_print": { - "default_value": 60 + "default_value": 50 + }, + "speed_wall_0": { + "default_value": 25 + }, + "speed_wall_x": { + "default_value": 40 }, "speed_infill": { - "default_value": 100 + "default_value": 80 }, "speed_topbottom": { "default_value": 30 }, + "speed_support_interface": + { + "default_value": 20 + }, "speed_travel": { "default_value": 150 }, "speed_layer_0": { "default_value": 30.0, "minimum_value": 0.1 - }, - "infill_overlap": { - "default_value": 10.0 } } -} \ No newline at end of file +} diff --git a/resources/definitions/m180.def.json b/resources/definitions/m180.def.json index bb027d33bc..04859d87b9 100644 --- a/resources/definitions/m180.def.json +++ b/resources/definitions/m180.def.json @@ -12,6 +12,7 @@ }, "overrides": { + "machine_name": { "default_value": "Malyan M180" }, "machine_width": { "default_value": 230 }, diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json index 4d3f6e06b7..4e066ddff2 100644 --- a/resources/definitions/maker_starter.def.json +++ b/resources/definitions/maker_starter.def.json @@ -13,6 +13,7 @@ }, "overrides": { + "machine_name": { "default_value": "3DMaker Starter" }, "machine_width": { "default_value": 210 }, @@ -145,7 +146,7 @@ "adhesion_type": { "default_value": "Raft" }, - "skirt_minimal_length": { + "skirt_brim_minimal_length": { "default_value": 100 }, "raft_base_line_spacing": { diff --git a/resources/definitions/mankati_fullscale_xt_plus.def.json b/resources/definitions/mankati_fullscale_xt_plus.def.json index 72c8ebdd86..65ed223f9e 100644 --- a/resources/definitions/mankati_fullscale_xt_plus.def.json +++ b/resources/definitions/mankati_fullscale_xt_plus.def.json @@ -12,6 +12,7 @@ "platform": "mankati_fullscale_xt_plus_platform.stl" }, "overrides": { + "machine_name": { "default_value": "Mankati Fullscale XT Plus" }, "machine_width": { "default_value": 260 }, "machine_depth": { "default_value": 260 }, "machine_height": { "default_value": 300 }, diff --git a/resources/definitions/mendel90.def.json b/resources/definitions/mendel90.def.json index 8d9a6d99a1..cce0c3133a 100644 --- a/resources/definitions/mendel90.def.json +++ b/resources/definitions/mendel90.def.json @@ -19,6 +19,7 @@ ], "overrides": { + "machine_name": { "default_value": "Mendel90" }, "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nG92 E0 ;zero the extruded length\nM107 ;start with the fan off\nG1 X90 Y200 F6000 ;go to the middle of the front\nG1 Z0.05 ;close to the bed\nG1 Z0.3 ;lift Z\n" }, diff --git a/resources/definitions/printrbot_simple.def.json b/resources/definitions/printrbot_simple.def.json index a1963fe20e..3d082af89d 100644 --- a/resources/definitions/printrbot_simple.def.json +++ b/resources/definitions/printrbot_simple.def.json @@ -8,16 +8,18 @@ "author": "Calvindog717", "manufacturer": "PrintrBot", "category": "Other", + "platform": "printrbot_simple_metal_platform.stl", "file_formats": "text/x-gcode" }, "overrides": { + "machine_name": { "default_value": "Printrbot Simple" }, "machine_heated_bed": { "default_value": false }, "machine_width": { "default_value": 150 }, "machine_height": { "default_value": 150 }, "machine_depth": { "default_value": 140 }, "machine_center_is_zero": { "default_value": false }, - "machine_nozzle_size": { "default_value": 0.3 }, + "machine_nozzle_size": { "default_value": 0.4 }, "material_diameter": { "default_value": 1.75 }, "machine_nozzle_heat_up_speed": { "default_value": 2 }, "machine_nozzle_cool_down_speed": { "default_value": 2 }, @@ -33,10 +35,10 @@ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG29 ; auto bed-levelling\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;home X/Y\nG28 Z0 ;home Z\nG92 E0 ;zero the extruded length\nG29 ;initiate auto bed leveling sequence\nG92 X132.4 Y20 ;correct bed origin (G29 changes it)" }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nM106 S0 ;fan off\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit\nG1 Z+1 E-5 F9000 ;move Z up a bit and retract even more\nG28 X0 Y0 ;home X/Y, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" } } } diff --git a/resources/definitions/prusa_i3.def.json b/resources/definitions/prusa_i3.def.json index 12e7054694..3b1adc5f00 100644 --- a/resources/definitions/prusa_i3.def.json +++ b/resources/definitions/prusa_i3.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "Prusa i3" }, "machine_heated_bed": { "default_value": true }, diff --git a/resources/definitions/prusa_i3_mk2.def.json b/resources/definitions/prusa_i3_mk2.def.json new file mode 100644 index 0000000000..e0c4475362 --- /dev/null +++ b/resources/definitions/prusa_i3_mk2.def.json @@ -0,0 +1,53 @@ +{ + "id": "prusa_i3_mk2", + "version": 2, + "name": "Prusa i3 Mk2", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Apsu", + "manufacturer": "Prusa Research", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2", + "platform": "prusai3_platform.stl", + "has_materials": true + }, + + "overrides": { + "machine_name": { "default_value": "Prusa i3 Mk2" }, + "machine_heated_bed": { "default_value": true }, + "machine_width": { "default_value": 250 }, + "machine_height": { "default_value": 200 }, + "machine_depth": { "default_value": 210 }, + "machine_center_is_zero": { "default_value": false }, + "material_diameter": { "default_value": 1.75 }, + "material_bed_temperature": { "default_value": 55 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "layer_height": { "default_value": 0.1 }, + "layer_height_0": { "default_value": 0.15 }, + "retraction_amount": { "default_value": 0.8 }, + "retraction_speed": { "default_value": 35 }, + "retraction_retract_speed": { "default_value": 35 }, + "retraction_prime_speed": { "default_value": 35 }, + "adhesion_type": { "default_value": "skirt" }, + "machine_nozzle_heat_up_speed": { "default_value": 2 }, + "machine_nozzle_cool_down_speed": { "default_value": 2 }, + "machine_head_with_fans_polygon": { "default_value": [[-31,31],[34,31],[34,-40],[-31,-40]] }, + "gantry_height": { "default_value": 28 }, + "machine_max_feedrate_z": { "default_value": 12 }, + "machine_max_feedrate_e": { "default_value": 120 }, + "machine_max_acceleration_z": { "default_value": 500 }, + "machine_acceleration": { "default_value": 1000 }, + "machine_max_jerk_xy": { "default_value": 10 }, + "machine_max_jerk_z": { "default_value": 0.2 }, + "machine_max_jerk_e": { "default_value": 2.5 }, + "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, + "machine_start_gcode": { + "default_value": "G21 ; set units to millimeters\nG90 ; use absolute positioning\nM82 ; absolute extrusion mode\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nM104 S{material_print_temperature} ; set extruder temp\nM140 S{material_bed_temperature} ; set bed temp\nM190 S{material_bed_temperature} ; wait for bed temp\nM109 S{material_print_temperature} ; wait for extruder temp\nG92 E0.0 ; reset extruder distance position\nG1 Y-3.0 F1000.0 ; go outside print area\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E21.5 F1000.0 ; intro line\nG92 E0.0 ; reset extruder distance position" + }, + "machine_end_gcode": { + "default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y210; home X axis and push Y forward\nM84 ; disable motors" + } + } +} diff --git a/resources/definitions/prusa_i3_xl.def.json b/resources/definitions/prusa_i3_xl.def.json index 819a93b860..7dcd6aceaf 100644 --- a/resources/definitions/prusa_i3_xl.def.json +++ b/resources/definitions/prusa_i3_xl.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "Prusa i3 xl" }, "machine_heated_bed": { "default_value": true }, diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json index fb8112a582..7266c12a38 100644 --- a/resources/definitions/rigidbot.def.json +++ b/resources/definitions/rigidbot.def.json @@ -13,6 +13,7 @@ }, "overrides": { + "machine_name": { "default_value": "RigidBot" }, "machine_width": { "default_value": 254 }, diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json index 7026df646b..9ada143fbc 100644 --- a/resources/definitions/rigidbot_big.def.json +++ b/resources/definitions/rigidbot_big.def.json @@ -13,6 +13,7 @@ }, "overrides": { + "machine_name": { "default_value": "RigidBotBig" }, "machine_width": { "default_value": 400 }, diff --git a/resources/definitions/ultimaker.def.json b/resources/definitions/ultimaker.def.json index dc52b00dcc..0a3729c766 100644 --- a/resources/definitions/ultimaker.def.json +++ b/resources/definitions/ultimaker.def.json @@ -9,6 +9,9 @@ "visible": false }, "overrides": { + "machine_max_feedrate_e": { + "default_value": 45 + }, "material_print_temperature": { "minimum_value": "0" }, diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json index 81723ae10d..79c89ab068 100644 --- a/resources/definitions/ultimaker2.def.json +++ b/resources/definitions/ultimaker2.def.json @@ -14,9 +14,11 @@ "platform": "ultimaker2_platform.obj", "platform_texture": "Ultimaker2backplate.png", "platform_offset": [9, 0, 0], + "has_materials": false, "supported_actions":["UpgradeFirmware"] }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2" }, "machine_start_gcode" : { "default_value": "", "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nG1 X10 Y0 F4000;move X/Y to min endstops\\nG28 Z0 ;move Z to bottom endstops\\nG1 Z15.0 F9000 ;move the platform to 15mm\\nG92 E0 ;zero the extruded length\\nG1 F200 E10 ;extrude 10 mm of feed stock\\nG92 E0 ;zero the extruded length again\\nG1 F9000\\n;Put printing message on LCD screen\\nM117 Printing...\"" diff --git a/resources/definitions/ultimaker2_extended.def.json b/resources/definitions/ultimaker2_extended.def.json index 889046694c..803e9fe896 100644 --- a/resources/definitions/ultimaker2_extended.def.json +++ b/resources/definitions/ultimaker2_extended.def.json @@ -16,6 +16,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2 Extended" }, "machine_height": { "default_value": 305 } diff --git a/resources/definitions/ultimaker2_extended_plus.def.json b/resources/definitions/ultimaker2_extended_plus.def.json index ea97033878..4490b67957 100644 --- a/resources/definitions/ultimaker2_extended_plus.def.json +++ b/resources/definitions/ultimaker2_extended_plus.def.json @@ -7,6 +7,7 @@ "author": "Ultimaker", "manufacturer": "Ultimaker", "category": "Ultimaker", + "quality_definition": "ultimaker2_plus", "weight": 2, "file_formats": "text/x-gcode", "platform": "ultimaker2_platform.obj", @@ -15,17 +16,9 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2 Extended+" }, "machine_height": { "default_value": 305 - }, - "machine_show_variants": { - "default_value": true - }, - "machine_nozzle_head_distance": { - "default_value": 5 - }, - "machine_nozzle_expansion_angle": { - "default_value": 45 } } } diff --git a/resources/definitions/ultimaker2_go.def.json b/resources/definitions/ultimaker2_go.def.json index 107d413296..5d4c898ade 100644 --- a/resources/definitions/ultimaker2_go.def.json +++ b/resources/definitions/ultimaker2_go.def.json @@ -17,6 +17,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2 Go" }, "machine_width": { "default_value": 120 }, diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index 4c7279b178..87c158782c 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -11,9 +11,7 @@ "file_formats": "text/x-gcode", "platform": "ultimaker2_platform.obj", "platform_texture": "Ultimaker2Plusbackplate.png", - "preferred_variant": "ultimaker2_plus_0.4", - "preferred_material": "*pla*", - "preferred_quality": "*normal*", + "preferred_variant": "*0.4*", "has_variants": true, "has_materials": true, "has_machine_materials": true, @@ -22,6 +20,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2+" }, "speed_infill": { "value": "speed_print" }, diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json index 3dd4766afa..03b3b50a08 100644 --- a/resources/definitions/ultimaker_original.def.json +++ b/resources/definitions/ultimaker_original.def.json @@ -13,13 +13,12 @@ "icon": "icon_ultimaker.png", "platform": "ultimaker_platform.stl", "has_materials": true, - "preferred_material": "*pla*", - "preferred_quality": "*normal*", "first_start_actions": ["UMOUpgradeSelection", "UMOCheckup", "BedLevel"], "supported_actions": ["UMOUpgradeSelection", "UMOCheckup", "BedLevel", "UpgradeFirmware"] }, "overrides": { + "machine_name": { "default_value": "Ultimaker Original" }, "machine_width": { "default_value": 205 }, diff --git a/resources/definitions/ultimaker_original_dual.def.json b/resources/definitions/ultimaker_original_dual.def.json index 04c8aadcc9..48d2436b92 100644 --- a/resources/definitions/ultimaker_original_dual.def.json +++ b/resources/definitions/ultimaker_original_dual.def.json @@ -13,18 +13,17 @@ "icon": "icon_ultimaker.png", "platform": "ultimaker_platform.stl", "has_materials": true, - "preferred_material": "*pla*", - "preferred_quality": "*normal*", "machine_extruder_trains": { - "0": "ultimaker_original_dual_left", - "1": "ultimaker_original_dual_right" + "0": "ultimaker_original_dual_1st", + "1": "ultimaker_original_dual_2nd" }, "first_start_actions": ["UMOUpgradeSelection", "UMOCheckup", "BedLevel"], "supported_actions": ["UMOUpgradeSelection", "UMOCheckup", "BedLevel", "UpgradeFirmware"] }, "overrides": { + "machine_name": { "default_value": "Ultimaker Original" }, "machine_width": { "default_value": 205 }, @@ -65,12 +64,22 @@ "default_value": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nT1 ;Switch to the 2nd extruder\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F200 E-{switch_extruder_retraction_amount}\nT0 ;Switch to the 1st extruder\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." }, "machine_end_gcode": { - "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + "default_value": "M104 T0 S0 ;1st extruder heater off\nM104 T1 S0 ;2nd extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" }, - "machine_extruder_count": { "default_value": 2 }, - "print_sequence": {"enabled": false} + "machine_extruder_count": { + "default_value": 2 + }, + "print_sequence": { + "enabled": false + }, + "prime_tower_position_x": { + "default_value": 185 + }, + "prime_tower_position_y": { + "default_value": 160 + } } } diff --git a/resources/definitions/ultimaker_original_plus.def.json b/resources/definitions/ultimaker_original_plus.def.json index 2c83070add..89cc7aa67a 100644 --- a/resources/definitions/ultimaker_original_plus.def.json +++ b/resources/definitions/ultimaker_original_plus.def.json @@ -17,6 +17,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker Original+" }, "machine_heated_bed": { "default_value": true }, diff --git a/resources/definitions/uniqbot_one.def.json b/resources/definitions/uniqbot_one.def.json index 1342e065a2..a3ab5cc779 100644 --- a/resources/definitions/uniqbot_one.def.json +++ b/resources/definitions/uniqbot_one.def.json @@ -12,6 +12,7 @@ }, "overrides": { + "machine_name": { "default_value": "Uniqbot" }, "machine_heated_bed": { "default_value": false }, diff --git a/resources/extruders/ultimaker_original_dual_1st.def.json b/resources/extruders/ultimaker_original_dual_1st.def.json new file mode 100644 index 0000000000..058dbf3028 --- /dev/null +++ b/resources/extruders/ultimaker_original_dual_1st.def.json @@ -0,0 +1,26 @@ +{ + "id": "ultimaker_original_dual_1st", + "version": 2, + "name": "1st Extruder", + "inherits": "fdmextruder", + "metadata": { + "machine": "ultimaker_original_dual", + "position": "0" + }, + + "overrides": { + "extruder_nr": { + "default_value": 0, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { "default_value": 0.0 }, + "machine_nozzle_offset_y": { "default_value": 0.0 }, + + "machine_extruder_start_pos_abs": { "default_value": true }, + "machine_extruder_start_pos_x": { "value": "prime_tower_position_x" }, + "machine_extruder_start_pos_y": { "value": "prime_tower_position_y" }, + "machine_extruder_end_pos_abs": { "default_value": true }, + "machine_extruder_end_pos_x": { "value": "prime_tower_position_x" }, + "machine_extruder_end_pos_y": { "value": "prime_tower_position_y" } + } +} diff --git a/resources/extruders/ultimaker_original_dual_2nd.def.json b/resources/extruders/ultimaker_original_dual_2nd.def.json new file mode 100644 index 0000000000..4b600d0281 --- /dev/null +++ b/resources/extruders/ultimaker_original_dual_2nd.def.json @@ -0,0 +1,26 @@ +{ + "id": "ultimaker_original_dual_2nd", + "version": 2, + "name": "2nd Extruder", + "inherits": "fdmextruder", + "metadata": { + "machine": "ultimaker_original_dual", + "position": "1" + }, + + "overrides": { + "extruder_nr": { + "default_value": 1, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { "default_value": 0.0 }, + "machine_nozzle_offset_y": { "default_value": 21.6 }, + + "machine_extruder_start_pos_abs": { "default_value": true }, + "machine_extruder_start_pos_x": { "value": "prime_tower_position_x" }, + "machine_extruder_start_pos_y": { "value": "prime_tower_position_y" }, + "machine_extruder_end_pos_abs": { "default_value": true }, + "machine_extruder_end_pos_x": { "value": "prime_tower_position_x" }, + "machine_extruder_end_pos_y": { "value": "prime_tower_position_y" } + } +} diff --git a/resources/extruders/ultimaker_original_dual_left.def.json b/resources/extruders/ultimaker_original_dual_left.def.json deleted file mode 100644 index 51268dd8b7..0000000000 --- a/resources/extruders/ultimaker_original_dual_left.def.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "id": "ultimaker_original_dual_left", - "version": 2, - "name": "Left Extruder", - "inherits": "fdmextruder", - "metadata": { - "machine": "ultimaker_original_dual", - "position": "0" - }, - - "overrides": { - "extruder_nr": { - "default_value": 0, - "maximum_value": "1" - }, - "machine_nozzle_offset_x": { "default_value": 0.0 }, - "machine_nozzle_offset_y": { "default_value": 0.0 } - } -} diff --git a/resources/extruders/ultimaker_original_dual_right.def.json b/resources/extruders/ultimaker_original_dual_right.def.json deleted file mode 100644 index 9a0cd089fe..0000000000 --- a/resources/extruders/ultimaker_original_dual_right.def.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "id": "ultimaker_original_dual_right", - "version": 2, - "name": "Right Extruder", - "inherits": "fdmextruder", - "metadata": { - "machine": "ultimaker_original_dual", - "position": "1" - }, - - "overrides": { - "extruder_nr": { - "default_value": 1, - "maximum_value": "1" - }, - "machine_nozzle_offset_x": { "default_value": 0.0 }, - "machine_nozzle_offset_y": { "default_value": 21.6 } - } -} diff --git a/resources/i18n/cura.pot b/resources/i18n/cura.pot index d54d173ad3..fddd237b88 100644 --- a/resources/i18n/cura.pot +++ b/resources/i18n/cura.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-04-01 13:45+0200\n" +"POT-Creation-Date: 2016-09-13 17:49+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,6 +17,23 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/__init__.py:12 +msgctxt "@label" +msgid "Machine Settings action" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "" +"Provides a way to change machine settings (such as build volume, nozzle " +"size, etc)" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:19 +msgctxt "@action" +msgid "Machine Settings" +msgstr "" + #: /home/ruben/Projects/Cura/plugins/XRayView/__init__.py:12 msgctxt "@label" msgid "X-Ray View" @@ -48,7 +65,7 @@ msgid "GCode File" msgstr "" #: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/__init__.py:12 -#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:16 +#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18 msgctxt "@label" msgid "Changelog" msgstr "" @@ -58,7 +75,7 @@ msgctxt "@info:whatsthis" msgid "Shows changes since latest checked version." msgstr "" -#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.py:34 +#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.py:35 msgctxt "@item:inmenu" msgid "Show Changelog" msgstr "" @@ -74,71 +91,84 @@ msgid "" "Accepts G-Code and sends them to a printer. Plugin can also update firmware." msgstr "" -#: /home/ruben/Projects/Cura/plugins/USBPrinting/PrinterConnection.py:35 +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:27 msgctxt "@item:inmenu" msgid "USB printing" msgstr "" -#: /home/ruben/Projects/Cura/plugins/USBPrinting/PrinterConnection.py:36 +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:28 msgctxt "@action:button" -msgid "Print with USB" +msgid "Print via USB" msgstr "" -#: /home/ruben/Projects/Cura/plugins/USBPrinting/PrinterConnection.py:37 +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:29 msgctxt "@info:tooltip" -msgid "Print with USB" +msgid "Print via USB" msgstr "" -#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterManager.py:49 -msgctxt "@title:menu" -msgid "Firmware" +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:31 +msgctxt "@info:status" +msgid "Connected via USB" msgstr "" -#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterManager.py:50 -msgctxt "@item:inmenu" -msgid "Update Firmware" +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:143 +msgctxt "@info:status" +msgid "Unable to start a new job because the printer is busy or not connected." msgstr "" -#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterManager.py:101 +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDeviceManager.py:111 msgctxt "@info" -msgid "Cannot update firmware, there were no connected printers found." +msgid "Unable to update firmware because there are no printers connected." msgstr "" -#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:21 +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDeviceManager.py:125 +#, python-format +msgctxt "@info" +msgid "Could not find firmware required for the printer at %s." +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:20 msgctxt "@action:button" msgid "Save to Removable Drive" msgstr "" -#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:22 +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:21 #, python-brace-format msgctxt "@item:inlistbox" msgid "Save to Removable Drive {0}" msgstr "" -#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:66 +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:74 #, python-brace-format msgctxt "@info:progress" msgid "Saving to Removable Drive {0}" msgstr "" -#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:94 +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:84 +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:87 +#, python-brace-format +msgctxt "@info:status" +msgid "Could not save to {0}: {1}" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:102 #, python-brace-format msgctxt "@info:status" msgid "Saved to Removable Drive {0} as {1}" msgstr "" -#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:95 +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:103 msgctxt "@action:button" msgid "Eject" msgstr "" -#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:95 +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:103 #, python-brace-format msgctxt "@action" msgid "Eject removable device {0}" msgstr "" -#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:100 +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:108 #, python-brace-format msgctxt "@info:status" msgid "Could not save to removable drive {0}: {1}" @@ -163,7 +193,7 @@ msgstr "" #: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py:52 #, python-brace-format msgctxt "@info:status" -msgid "Failed to eject {0}. Maybe it is still in use?" +msgid "Failed to eject {0}. Another program may be using the drive." msgstr "" #: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py:69 @@ -171,6 +201,20 @@ msgctxt "@item:intext" msgid "Removable Drive" msgstr "" +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "" + #: /home/ruben/Projects/Cura/plugins/AutoSave/__init__.py:12 msgctxt "@label" msgid "Auto Save" @@ -191,17 +235,28 @@ msgctxt "@info:whatsthis" msgid "Submits anonymous slice info. Can be disabled through preferences." msgstr "" -#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:35 +#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:73 msgctxt "@info" msgid "" -"Cura automatically sends slice info. You can disable this in preferences" +"Cura collects anonymised slicing statistics. You can disable this in " +"preferences" msgstr "" -#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:36 +#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:74 msgctxt "@action:button" msgid "Dismiss" msgstr "" +#: /home/ruben/Projects/Cura/plugins/XmlMaterialProfile/__init__.py:13 +msgctxt "@label" +msgid "Material Profiles" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/XmlMaterialProfile/__init__.py:16 +msgctxt "@info:whatsthis" +msgid "Provides capabilities to read and write XML-based material profiles." +msgstr "" + #: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:12 msgctxt "@label" msgid "Legacy Cura Profile Reader" @@ -247,14 +302,19 @@ msgctxt "@item:inlistbox" msgid "Layers" msgstr "" -#: /home/ruben/Projects/Cura/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py:12 +#: /home/ruben/Projects/Cura/plugins/LayerView/LayerView.py:58 +msgctxt "@info:status" +msgid "Cura does not accurately display layers when Wire Printing is enabled" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py:14 msgctxt "@label" msgid "Version Upgrade 2.1 to 2.2" msgstr "" -#: /home/ruben/Projects/Cura/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py:15 +#: /home/ruben/Projects/Cura/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py:17 msgctxt "@info:whatsthis" -msgid "Upgrades preferences and settings from Cura 2.1 to Cura 2.2." +msgid "Upgrades configurations from Cura 2.1 to Cura 2.2." msgstr "" #: /home/ruben/Projects/Cura/plugins/ImageReader/__init__.py:12 @@ -292,9 +352,18 @@ msgctxt "@item:inlistbox" msgid "GIF Image" msgstr "" -#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:135 +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:232 msgctxt "@info:status" -msgid "Unable to slice. Please check your setting values for errors." +msgid "" +"Unable to slice with the current settings. Please check your settings for " +"errors." +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:241 +msgctxt "@info:status" +msgid "" +"Nothing to slice because none of the models fit the build volume. Please " +"scale or rotate models to fit." msgstr "" #: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/__init__.py:13 @@ -307,30 +376,30 @@ msgctxt "@info:whatsthis" msgid "Provides the link to the CuraEngine slicing backend." msgstr "" -#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py:42 -#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py:155 +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:45 +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:180 msgctxt "@info:status" msgid "Processing Layers" msgstr "" -#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:12 +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:14 msgctxt "@label" -msgid "Per Object Settings Tool" +msgid "Per Model Settings Tool" msgstr "" -#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:15 +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:17 msgctxt "@info:whatsthis" -msgid "Provides the Per Object Settings." +msgid "Provides the Per Model Settings." msgstr "" -#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:19 +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:21 msgctxt "@label" -msgid "Per Object Settings" +msgid "Per Model Settings" msgstr "" -#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:20 +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:22 msgctxt "@info:tooltip" -msgid "Configure Per Object Settings" +msgid "Configure Per Model Settings" msgstr "" #: /home/ruben/Projects/Cura/plugins/3MFReader/__init__.py:12 @@ -379,6 +448,38 @@ msgctxt "@item:inlistbox" msgid "Cura Profile" msgstr "" +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/__init__.py:15 +msgctxt "@label" +msgid "Ultimaker machine actions" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/__init__.py:18 +msgctxt "@info:whatsthis" +msgid "" +"Provides machine actions for Ultimaker machines (such as bed leveling " +"wizard, selecting upgrades, etc)" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelection.py:12 +msgctxt "@action" +msgid "Select upgrades" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.py:10 +msgctxt "@action" +msgid "Upgrade Firmware" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py:13 +msgctxt "@action" +msgid "Checkup" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.py:13 +msgctxt "@action" +msgid "Level build plate" +msgstr "" + #: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:12 msgctxt "@label" msgid "Cura Profile Reader" @@ -389,95 +490,350 @@ msgctxt "@info:whatsthis" msgid "Provides support for importing Cura profiles." msgstr "" -#: /home/ruben/Projects/Cura/cura/CrashHandler.py:26 +#: /home/ruben/Projects/Cura/cura/PrinterOutputDevice.py:286 +msgctxt "@item:material" +msgid "No material loaded" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/PrinterOutputDevice.py:293 +msgctxt "@item:material" +msgid "Unknown material" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:342 +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:79 +msgctxt "@title:window" +msgid "File Already Exists" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:343 +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:80 +#, python-brace-format +msgctxt "@label" +msgid "" +"The file {0} already exists. Are you sure you want to " +"overwrite it?" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:548 +msgctxt "@info:status" +msgid "" +"The selected material is imcompatible with the selected machine or " +"configuration." +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:666 +msgctxt "@label" +msgid "You made changes to the following setting(s):" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:671 +msgctxt "@window:title" +msgid "Switched profiles" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:671 +msgctxt "@label" +msgid "Do you want to transfer your changed settings to this profile?" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:672 +msgctxt "@label" +msgid "" +"If you transfer your settings they will override settings in the profile." +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:765 +msgctxt "@label" +msgid "Nozzle" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:966 +msgctxt "@info:status" +msgid "" +"Unable to find a quality profile for this combination. Default settings will " +"be used instead." +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:95 +#, python-brace-format +msgctxt "@info:status" +msgid "" +"Failed to export profile to {0}: {1}" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:100 +#, python-brace-format +msgctxt "@info:status" +msgid "" +"Failed to export profile to {0}: Writer plugin reported " +"failure." +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:103 +#, python-brace-format +msgctxt "@info:status" +msgid "Exported profile to {0}" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:128 +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:139 +#, python-brace-format +msgctxt "@info:status" +msgid "" +"Failed to import profile from {0}: {1}" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:145 +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:155 +#, python-brace-format +msgctxt "@info:status" +msgid "Successfully imported profile {0}" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:158 +#, python-brace-format +msgctxt "@info:status" +msgid "Successfully imported profiles {0}" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:161 +#, python-brace-format +msgctxt "@info:status" +msgid "Profile {0} has an unknown file type." +msgstr "" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:166 +msgctxt "@label" +msgid "Custom profile" +msgstr "" + +#: /home/ruben/Projects/Cura/cura/BuildVolume.py:240 +msgctxt "@info:status" +msgid "" +"The build volume height has been reduced due to the value of the \"Print " +"Sequence\" setting to prevent the gantry from colliding with printed models." +msgstr "" + +#: /home/ruben/Projects/Cura/cura/CrashHandler.py:42 msgctxt "@title:window" msgid "Oops!" msgstr "" -#: /home/ruben/Projects/Cura/cura/CrashHandler.py:32 +#: /home/ruben/Projects/Cura/cura/CrashHandler.py:48 msgctxt "@label" msgid "" -"

An uncaught exception has occurred!

Please use the information " -"below to post a bug report at http://github.com/Ultimaker/Cura/issues

" +"

A fatal exception has occurred that we could not recover from!

Please use the information below to post a bug report at http://github.com/Ultimaker/Cura/" +"issues

" msgstr "" -#: /home/ruben/Projects/Cura/cura/CrashHandler.py:52 +#: /home/ruben/Projects/Cura/cura/CrashHandler.py:68 msgctxt "@action:button" msgid "Open Web Page" msgstr "" -#: /home/ruben/Projects/Cura/cura/CuraApplication.py:168 +#: /home/ruben/Projects/Cura/cura/CuraApplication.py:167 +msgctxt "@info:progress" +msgid "Loading machines..." +msgstr "" + +#: /home/ruben/Projects/Cura/cura/CuraApplication.py:390 msgctxt "@info:progress" msgid "Setting up scene..." msgstr "" -#: /home/ruben/Projects/Cura/cura/CuraApplication.py:202 +#: /home/ruben/Projects/Cura/cura/CuraApplication.py:424 msgctxt "@info:progress" msgid "Loading interface..." msgstr "" -#: /home/ruben/Projects/Cura/cura/CuraApplication.py:273 +#: /home/ruben/Projects/Cura/cura/CuraApplication.py:536 #, python-format msgctxt "@info" msgid "%(width).1f x %(depth).1f x %(height).1f mm" msgstr "" -#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:37 -#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:81 -#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:74 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:27 +msgctxt "@title" +msgid "Machine Settings" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:38 +msgctxt "@label" +msgid "Please enter the correct settings for your printer below:" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:63 +msgctxt "@label" +msgid "Printer Settings" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:74 +msgctxt "@label" +msgid "X (Width)" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:85 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:101 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:117 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:190 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:206 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:222 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:238 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:258 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:278 +msgctxt "@label" +msgid "mm" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:90 +msgctxt "@label" +msgid "Y (Depth)" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:106 +msgctxt "@label" +msgid "Z (Height)" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:126 +msgctxt "@option:check" +msgid "Heated Bed" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:133 +msgctxt "@option:check" +msgid "Machine Center is Zero" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:145 +msgctxt "@label" +msgid "GCode Flavor" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:168 +msgctxt "@label" +msgid "Printhead Settings" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:179 +msgctxt "@label" +msgid "X min" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:195 +msgctxt "@label" +msgid "Y min" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:211 +msgctxt "@label" +msgid "X max" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:227 +msgctxt "@label" +msgid "Y max" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:247 +msgctxt "@label" +msgid "Gantry height" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:267 +msgctxt "@label" +msgid "Nozzle size" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:296 +msgctxt "@label" +msgid "Start Gcode" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:318 +msgctxt "@label" +msgid "End Gcode" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:39 +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:105 +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:423 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:120 +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:77 #: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:38 msgctxt "@action:button" msgid "Close" msgstr "" -#: /home/ruben/Projects/Cura/plugins/USBPrinting/ControlWindow.qml:17 -msgctxt "@title:window" -msgid "Print with USB" -msgstr "" - -#: /home/ruben/Projects/Cura/plugins/USBPrinting/ControlWindow.qml:28 -msgctxt "@label" -msgid "Extruder Temperature %1" -msgstr "" - -#: /home/ruben/Projects/Cura/plugins/USBPrinting/ControlWindow.qml:33 -msgctxt "@label" -msgid "Bed Temperature %1" -msgstr "" - -#: /home/ruben/Projects/Cura/plugins/USBPrinting/ControlWindow.qml:60 -msgctxt "@action:button" -msgid "Print" -msgstr "" - -#: /home/ruben/Projects/Cura/plugins/USBPrinting/ControlWindow.qml:67 -#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:191 -#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:273 -msgctxt "@action:button" -msgid "Cancel" -msgstr "" - #: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:20 msgctxt "@title:window" msgid "Firmware Update" msgstr "" -#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:38 -msgctxt "@label" -msgid "Starting firmware update, this may take a while." -msgstr "" - -#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:43 +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:40 msgctxt "@label" msgid "Firmware update completed." msgstr "" -#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:48 +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:45 +msgctxt "@label" +msgid "Starting firmware update, this may take a while." +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:50 msgctxt "@label" msgid "Updating firmware." msgstr "" +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:59 +msgctxt "@label" +msgid "Firmware update failed due to an unknown error." +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:62 +msgctxt "@label" +msgid "Firmware update failed due to an communication error." +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:65 +msgctxt "@label" +msgid "Firmware update failed due to an input/output error." +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:68 +msgctxt "@label" +msgid "Firmware update failed due to missing firmware." +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:71 +msgctxt "@label" +msgid "Unknown error code: %1" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:17 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:48 +msgctxt "@label" +msgid "Scripts" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:146 +msgctxt "@label" +msgid "Active Scripts" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:434 +msgctxt "@label" +msgid "Done" +msgstr "" + #: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:21 msgctxt "@title:window" msgid "Convert Image..." @@ -557,653 +913,43 @@ msgctxt "@action:button" msgid "OK" msgstr "" -#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:95 +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:191 msgctxt "@action:button" -msgid "Add Setting" +msgid "Cancel" msgstr "" -#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:135 +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:34 +msgctxt "@label" +msgid "Print model with" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:274 +msgctxt "@action:button" +msgid "Select settings" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:314 msgctxt "@title:window" -msgid "Pick a Setting to Customize" +msgid "Select Settings to Customize for this model" msgstr "" -#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:146 +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:338 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:91 msgctxt "@label:textbox" msgid "Filter..." msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/AddMachineWizard.qml:18 -msgctxt "@title:window" -msgid "Add Printer" +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:362 +msgctxt "@label:checkbox" +msgid "Show all" msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/AddMachineWizard.qml:25 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/AddMachine.qml:63 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:27 msgctxt "@title" -msgid "Add Printer" +msgid "Build Plate Leveling" msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:195 -msgctxt "@label" -msgid "00h 00min" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:215 -msgctxt "@label" -msgid "0.0 m" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:215 -msgctxt "@label" -msgid "%1 m" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:15 -msgctxt "@title:window" -msgid "About Cura" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:54 -msgctxt "@label" -msgid "End-to-end solution for fused filament 3D printing." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:66 -msgctxt "@info:credit" -msgid "" -"Cura has been developed by Ultimaker B.V. in cooperation with the community." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:96 -msgctxt "@label:listbox" -msgid "Setup" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:250 -msgctxt "@title:tab" -msgid "Simple" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:251 -msgctxt "@title:tab" -msgid "Advanced" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:14 -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:515 -msgctxt "@title:tab" -msgid "General" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:51 -msgctxt "@label" -msgid "Language:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:62 -msgctxt "@item:inlistbox" -msgid "English" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:63 -msgctxt "@item:inlistbox" -msgid "Finnish" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:64 -msgctxt "@item:inlistbox" -msgid "French" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:65 -msgctxt "@item:inlistbox" -msgid "German" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:66 -msgctxt "@item:inlistbox" -msgid "Italian" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:67 -msgctxt "@item:inlistbox" -msgid "Dutch" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:68 -msgctxt "@item:inlistbox" -msgid "Spanish" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:106 -msgctxt "@label" -msgid "" -"You will need to restart the application for language changes to have effect." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:114 -msgctxt "@info:tooltip" -msgid "" -"Should objects on the platform be moved so that they no longer intersect." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:119 -msgctxt "@option:check" -msgid "Ensure objects are kept apart" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:128 -msgctxt "@info:tooltip" -msgid "" -"Should opened files be scaled to the build volume if they are too large?" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:133 -msgctxt "@option:check" -msgid "Scale large files" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:142 -msgctxt "@info:tooltip" -msgid "" -"Should anonymous data about your print be sent to Ultimaker? Note, no " -"models, IP addresses or other personally identifiable information is sent or " -"stored." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/GeneralPage.qml:147 -msgctxt "@option:check" -msgid "Send (anonymous) print information" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:51 -msgctxt "@action:inmenu" -msgid "Toggle Fu&ll Screen" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:58 -msgctxt "@action:inmenu menubar:edit" -msgid "&Undo" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:66 -msgctxt "@action:inmenu menubar:edit" -msgid "&Redo" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:74 -msgctxt "@action:inmenu menubar:file" -msgid "&Quit" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:82 -msgctxt "@action:inmenu menubar:settings" -msgid "&Preferences..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:89 -msgctxt "@action:inmenu menubar:printer" -msgid "&Add Printer..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:95 -msgctxt "@action:inmenu menubar:printer" -msgid "Manage Pr&inters..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:102 -msgctxt "@action:inmenu menubar:profile" -msgid "&Add Profile..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:108 -msgctxt "@action:inmenu menubar:profile" -msgid "Manage Profiles..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:115 -msgctxt "@action:inmenu menubar:help" -msgid "Show Online &Documentation" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:122 -msgctxt "@action:inmenu menubar:help" -msgid "Report a &Bug" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:129 -msgctxt "@action:inmenu menubar:help" -msgid "&About..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:136 -msgctxt "@action:inmenu menubar:edit" -msgid "Delete &Selection" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:145 -msgctxt "@action:inmenu" -msgid "Delete Object" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:153 -msgctxt "@action:inmenu" -msgid "Ce&nter Object on Platform" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:159 -msgctxt "@action:inmenu menubar:edit" -msgid "&Group Objects" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:167 -msgctxt "@action:inmenu menubar:edit" -msgid "Ungroup Objects" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:175 -msgctxt "@action:inmenu menubar:edit" -msgid "&Merge Objects" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:183 -msgctxt "@action:inmenu" -msgid "&Duplicate Object" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:190 -msgctxt "@action:inmenu menubar:edit" -msgid "&Clear Build Platform" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:199 -msgctxt "@action:inmenu menubar:file" -msgid "Re&load All Objects" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:206 -msgctxt "@action:inmenu menubar:edit" -msgid "Reset All Object Positions" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:212 -msgctxt "@action:inmenu menubar:edit" -msgid "Reset All Object &Transformations" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:218 -msgctxt "@action:inmenu menubar:file" -msgid "&Open File..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:226 -msgctxt "@action:inmenu menubar:help" -msgid "Show Engine &Log..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:24 -msgctxt "@label:PrintjobStatus" -msgid "Please load a 3d model" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:26 -msgctxt "@label:PrintjobStatus" -msgid "Preparing to slice..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:29 -msgctxt "@label:PrintjobStatus" -msgid "Slicing..." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:31 -msgctxt "@label:PrintjobStatus" -msgid "Ready to " -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:123 -msgctxt "@info:tooltip" -msgid "Select the active output device" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/ProfileSetup.qml:29 -msgctxt "@label" -msgid "Profile:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:16 -msgctxt "@title:window" -msgid "Cura" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:53 -msgctxt "@title:menu menubar:toplevel" -msgid "&File" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:62 -msgctxt "@title:menu menubar:file" -msgid "Open &Recent" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:92 -msgctxt "@action:inmenu menubar:file" -msgid "&Save Selection to File" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:100 -msgctxt "@title:menu menubar:file" -msgid "Save &All" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:128 -msgctxt "@title:menu menubar:toplevel" -msgid "&Edit" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:145 -msgctxt "@title:menu menubar:toplevel" -msgid "&View" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:167 -msgctxt "@title:menu menubar:toplevel" -msgid "&Printer" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:213 -msgctxt "@title:menu menubar:toplevel" -msgid "P&rofile" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:252 -msgctxt "@title:menu menubar:toplevel" -msgid "E&xtensions" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:285 -msgctxt "@title:menu menubar:toplevel" -msgid "&Settings" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:293 -msgctxt "@title:menu menubar:toplevel" -msgid "&Help" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:378 -msgctxt "@action:button" -msgid "Open File" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:422 -msgctxt "@action:button" -msgid "View Mode" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:518 -msgctxt "@title:tab" -msgid "View" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:665 -msgctxt "@title:window" -msgid "Open file" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:36 -msgctxt "@label" -msgid "Infill:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:146 -msgctxt "@label" -msgid "Hollow" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:150 -msgctxt "@label" -msgid "No (0%) infill will leave your model hollow at the cost of low strength" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:154 -msgctxt "@label" -msgid "Light" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:158 -msgctxt "@label" -msgid "Light (20%) infill will give your model an average strength" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:162 -msgctxt "@label" -msgid "Dense" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:166 -msgctxt "@label" -msgid "Dense (50%) infill will give your model an above average strength" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:170 -msgctxt "@label" -msgid "Solid" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:174 -msgctxt "@label" -msgid "Solid (100%) infill will make your model completely solid" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:193 -msgctxt "@label:listbox" -msgid "Helpers:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:213 -msgctxt "@option:check" -msgid "Generate Brim" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:228 -msgctxt "@label" -msgid "" -"Enable printing a brim. This will add a single-layer-thick flat area around " -"your object which is easy to cut off afterwards." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:246 -msgctxt "@option:check" -msgid "Generate Support Structure" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:261 -msgctxt "@label" -msgid "" -"Enable printing support structures. This will build up supporting structures " -"below the model to prevent the model from sagging or printing in mid air." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15 -msgctxt "@title:window" -msgid "Engine Log" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/ViewPage.qml:16 -msgctxt "@title:window" -msgid "View" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/ViewPage.qml:33 -msgctxt "@info:tooltip" -msgid "" -"Highlight unsupported areas of the model in red. Without support these areas " -"will nog print properly." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/ViewPage.qml:42 -msgctxt "@option:check" -msgid "Display overhang" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/ViewPage.qml:49 -msgctxt "@info:tooltip" -msgid "" -"Moves the camera so the object is in the center of the view when an object " -"is selected" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/ViewPage.qml:54 -msgctxt "@action:button" -msgid "Center camera when item is selected" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:29 -msgctxt "@label:listbox" -msgid "Print Job" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:50 -msgctxt "@label:listbox" -msgid "Printer:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:107 -msgctxt "@label" -msgid "Nozzle:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:171 -msgctxt "@label" -msgid "Material:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:72 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/AddMachine.qml:242 -msgctxt "@title" -msgid "Check Printer" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:84 -msgctxt "@label" -msgid "" -"It's a good idea to do a few sanity checks on your Ultimaker. You can skip " -"this step if you know your machine is functional" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:100 -msgctxt "@action:button" -msgid "Start Printer Check" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:116 -msgctxt "@action:button" -msgid "Skip Printer Check" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:136 -msgctxt "@label" -msgid "Connection: " -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:145 -msgctxt "@info:status" -msgid "Done" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:145 -msgctxt "@info:status" -msgid "Incomplete" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:155 -msgctxt "@label" -msgid "Min endstop X: " -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:164 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:183 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:202 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:357 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:368 -msgctxt "@info:status" -msgid "Works" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:164 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:183 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:202 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:221 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:277 -msgctxt "@info:status" -msgid "Not checked" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:174 -msgctxt "@label" -msgid "Min endstop Y: " -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:193 -msgctxt "@label" -msgid "Min endstop Z: " -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:212 -msgctxt "@label" -msgid "Nozzle temperature check: " -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:236 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:292 -msgctxt "@action:button" -msgid "Start Heating" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:241 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:297 -msgctxt "@info:progress" -msgid "Checking" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:267 -msgctxt "@label" -msgid "bed temperature check:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:324 -msgctxt "@label" -msgid "Everything is in order! You're done with your CheckUp." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/SelectUpgradedPartsUM2.qml:48 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:31 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/AddMachine.qml:233 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/AddMachine.qml:236 -msgctxt "@title" -msgid "Select Upgraded Parts" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/SelectUpgradedPartsUM2.qml:59 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:42 -msgctxt "@label" -msgid "" -"To assist you in having better default settings for your Ultimaker. Cura " -"would like to know which upgrades you have in your machine:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/SelectUpgradedPartsUM2.qml:74 -msgctxt "@option:check" -msgid "Olsson Block" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/Bedleveling.qml:46 -msgctxt "@title" -msgid "Bed Leveling" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/Bedleveling.qml:58 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:38 msgctxt "@label" msgid "" "To make sure your prints will come out great, you can now adjust your " @@ -1211,60 +957,30 @@ msgid "" "the different positions that can be adjusted." msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/Bedleveling.qml:67 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:47 msgctxt "@label" msgid "" -"For every postition; 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." +"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." msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/Bedleveling.qml:82 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:62 +msgctxt "@action:button" +msgid "Start Build Plate Leveling" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:74 msgctxt "@action:button" msgid "Move to Next Position" msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/Bedleveling.qml:122 -msgctxt "@action:button" -msgid "Skip Bedleveling" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/Bedleveling.qml:147 -msgctxt "@label" -msgid "Everything is in order! You're done with bedleveling." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:57 -msgctxt "@option:check" -msgid "Extruder driver ugrades" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:63 -msgctxt "@option:check" -msgid "Heated printer bed" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:74 -msgctxt "@option:check" -msgid "Heated printer bed (self built)" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:90 -msgctxt "@label" -msgid "" -"If you bought your Ultimaker after october 2012 you will have the Extruder " -"drive upgrade. If you do not have this upgrade, it is highly recommended to " -"improve reliability. This upgrade can be bought from the Ultimaker webshop " -"or found on thingiverse as thing:26094" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:22 -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/AddMachine.qml:239 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:27 msgctxt "@title" msgid "Upgrade Firmware" msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:33 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:38 msgctxt "@label" msgid "" "Firmware is the piece of software running directly on your 3D printer. This " @@ -1272,48 +988,1309 @@ msgid "" "makes your printer work." msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:43 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:48 msgctxt "@label" msgid "" -"The firmware shipping with new Ultimakers works, but upgrades have been made " -"to make better prints, and make calibration easier." +"The firmware shipping with new printers works, but new versions tend to have " +"more features and improvements." msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:53 -msgctxt "@label" -msgid "" -"Cura requires these new features and thus your firmware will most likely " -"need to be upgraded. You can do so now." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:64 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:62 msgctxt "@action:button" -msgid "Upgrade to Marlin Firmware" +msgid "Automatically upgrade Firmware" msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:73 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:72 msgctxt "@action:button" -msgid "Skip Upgrade" +msgid "Upload custom Firmware" msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/AddMachine.qml:72 -msgctxt "@label" -msgid "Please select the type of printer:" +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:83 +msgctxt "@title:window" +msgid "Select custom firmware" msgstr "" -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/AddMachine.qml:198 -msgctxt "@label" -msgid "" -"This printer name has already been used. Please choose a different printer " -"name." -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/AddMachine.qml:208 -msgctxt "@label:textbox" -msgid "Printer Name:" -msgstr "" - -#: /home/ruben/Projects/Cura/resources/qml/WizardPages/AddMachine.qml:245 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:25 msgctxt "@title" -msgid "Bed Levelling" +msgid "Select Printer Upgrades" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:37 +msgctxt "@label" +msgid "Please select any upgrades made to this Ultimaker Original" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:45 +msgctxt "@label" +msgid "Heated Build Plate (official kit or self-built)" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:27 +msgctxt "@title" +msgid "Check Printer" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:39 +msgctxt "@label" +msgid "" +"It's a good idea to do a few sanity checks on your Ultimaker. You can skip " +"this step if you know your machine is functional" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:53 +msgctxt "@action:button" +msgid "Start Printer Check" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:80 +msgctxt "@label" +msgid "Connection: " +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89 +msgctxt "@info:status" +msgid "Connected" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89 +msgctxt "@info:status" +msgid "Not connected" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:99 +msgctxt "@label" +msgid "Min endstop X: " +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151 +msgctxt "@info:status" +msgid "Works" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:173 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234 +msgctxt "@info:status" +msgid "Not checked" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:120 +msgctxt "@label" +msgid "Min endstop Y: " +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:141 +msgctxt "@label" +msgid "Min endstop Z: " +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:163 +msgctxt "@label" +msgid "Nozzle temperature check: " +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248 +msgctxt "@action:button" +msgid "Stop Heating" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248 +msgctxt "@action:button" +msgid "Start Heating" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:223 +msgctxt "@label" +msgid "Build plate temperature check:" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234 +msgctxt "@info:status" +msgid "Checked" +msgstr "" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:284 +msgctxt "@label" +msgid "Everything is in order! You're done with your CheckUp." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:84 +msgctxt "@label:MonitorStatus" +msgid "Not connected to a printer" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:86 +msgctxt "@label:MonitorStatus" +msgid "Printer does not accept commands" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:92 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:189 +msgctxt "@label:MonitorStatus" +msgid "In maintenance. Please check the printer" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:97 +msgctxt "@label:MonitorStatus" +msgid "Lost connection with the printer" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:99 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:179 +msgctxt "@label:MonitorStatus" +msgid "Printing..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:101 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:181 +msgctxt "@label:MonitorStatus" +msgid "Paused" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:103 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:183 +msgctxt "@label:MonitorStatus" +msgid "Preparing..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:105 +msgctxt "@label:MonitorStatus" +msgid "Please remove the print" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:209 +msgctxt "@label:" +msgid "Resume" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:213 +msgctxt "@label:" +msgid "Pause" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:242 +msgctxt "@label:" +msgid "Abort Print" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:252 +msgctxt "@window:title" +msgid "Abort print" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:254 +msgctxt "@label" +msgid "Are you sure you want to abort the print?" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:47 +msgctxt "@label" +msgid "Display Name" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:57 +msgctxt "@label" +msgid "Brand" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:67 +msgctxt "@label" +msgid "Material Type" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:76 +msgctxt "@label" +msgid "Color" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:110 +msgctxt "@label" +msgid "Properties" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:112 +msgctxt "@label" +msgid "Density" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:125 +msgctxt "@label" +msgid "Diameter" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:138 +msgctxt "@label" +msgid "Filament Cost" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:147 +msgctxt "@label" +msgid "Filament weight" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:157 +msgctxt "@label" +msgid "Filament length" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:166 +msgctxt "@label" +msgid "Cost per Meter (Approx.)" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:171 +msgctxt "@label" +msgid "%1/m" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:177 +msgctxt "@label" +msgid "Description" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:190 +msgctxt "@label" +msgid "Adhesion Information" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:208 +msgctxt "@label" +msgid "Print settings" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:14 +msgctxt "@title:tab" +msgid "Setting Visibility" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:44 +msgctxt "@label:textbox" +msgid "Check all" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:26 +msgctxt "@title:column" +msgid "Setting" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:32 +msgctxt "@title:column" +msgid "Profile" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:38 +msgctxt "@title:column" +msgid "Current" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:45 +msgctxt "@title:column" +msgid "Unit" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:14 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:430 +msgctxt "@title:tab" +msgid "General" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:72 +msgctxt "@label" +msgid "Interface" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:81 +msgctxt "@label" +msgid "Language:" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:93 +msgctxt "@item:inlistbox" +msgid "English" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:94 +msgctxt "@item:inlistbox" +msgid "Finnish" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:95 +msgctxt "@item:inlistbox" +msgid "French" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:96 +msgctxt "@item:inlistbox" +msgid "German" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:97 +msgctxt "@item:inlistbox" +msgid "Italian" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:98 +msgctxt "@item:inlistbox" +msgid "Dutch" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:99 +msgctxt "@item:inlistbox" +msgid "Spanish" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:137 +msgctxt "@label" +msgid "" +"You will need to restart the application for language changes to have effect." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:152 +msgctxt "@label" +msgid "Viewport behavior" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:160 +msgctxt "@info:tooltip" +msgid "" +"Highlight unsupported areas of the model in red. Without support these areas " +"will not print properly." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:169 +msgctxt "@option:check" +msgid "Display overhang" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:176 +msgctxt "@info:tooltip" +msgid "" +"Moves the camera so the model is in the center of the view when an model is " +"selected" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:181 +msgctxt "@action:button" +msgid "Center camera when item is selected" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:190 +msgctxt "@info:tooltip" +msgid "" +"Should models on the platform be moved so that they no longer intersect?" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:195 +msgctxt "@option:check" +msgid "Ensure models are kept apart" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:203 +msgctxt "@info:tooltip" +msgid "Should models on the platform be moved down to touch the build plate?" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:208 +msgctxt "@option:check" +msgid "Automatically drop models to the build plate" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:217 +msgctxt "@info:tooltip" +msgid "" +"Display 5 top layers in layer view or only the top-most layer. Rendering 5 " +"layers takes longer, but may show more information." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:222 +msgctxt "@action:button" +msgid "Display five top layers in layer view" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:240 +msgctxt "@info:tooltip" +msgid "Should only the top layers be displayed in layerview?" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:245 +msgctxt "@option:check" +msgid "Only display top layer(s) in layer view" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:261 +msgctxt "@label" +msgid "Opening files" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:267 +msgctxt "@info:tooltip" +msgid "Should models be scaled to the build volume if they are too large?" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:272 +msgctxt "@option:check" +msgid "Scale large models" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:281 +msgctxt "@info:tooltip" +msgid "" +"An model may appear extremely small if its unit is for example in meters " +"rather than millimeters. Should these models be scaled up?" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:286 +msgctxt "@option:check" +msgid "Scale extremely small models" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:295 +msgctxt "@info:tooltip" +msgid "" +"Should a prefix based on the printer name be added to the print job name " +"automatically?" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:300 +msgctxt "@option:check" +msgid "Add machine prefix to job name" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:317 +msgctxt "@label" +msgid "Privacy" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:324 +msgctxt "@info:tooltip" +msgid "Should Cura check for updates when the program is started?" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:329 +msgctxt "@option:check" +msgid "Check for updates on start" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:339 +msgctxt "@info:tooltip" +msgid "" +"Should anonymous data about your print be sent to Ultimaker? Note, no " +"models, IP addresses or other personally identifiable information is sent or " +"stored." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:344 +msgctxt "@option:check" +msgid "Send (anonymous) print information" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:15 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:435 +msgctxt "@title:tab" +msgid "Printers" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:37 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:71 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:127 +msgctxt "@action:button" +msgid "Activate" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:44 +msgctxt "@action:button" +msgid "Add" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:50 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:111 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:152 +msgctxt "@action:button" +msgid "Remove" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:57 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:118 +msgctxt "@action:button" +msgid "Rename" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:146 +msgctxt "@label" +msgid "Printer type:" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:154 +msgctxt "@label" +msgid "Connection:" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:159 +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:21 +msgctxt "@info:status" +msgid "The printer is not connected." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:165 +msgctxt "@label" +msgid "State:" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:185 +msgctxt "@label:MonitorStatus" +msgid "Waiting for someone to clear the build plate" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:191 +msgctxt "@label:MonitorStatus" +msgid "Aborting print..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:194 +msgctxt "@label:MonitorStatus" +msgid "Waiting for a printjob" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:15 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:439 +msgctxt "@title:tab" +msgid "Profiles" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:49 +msgctxt "@label" +msgid "Protected profiles" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:49 +msgctxt "@label" +msgid "Custom profiles" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:80 +msgctxt "@label" +msgid "Create" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:96 +msgctxt "@label" +msgid "Duplicate" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:129 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:159 +msgctxt "@action:button" +msgid "Import" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:135 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:166 +msgctxt "@action:button" +msgid "Export" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:142 +msgctxt "@label %1 is printer name" +msgid "Printer: %1" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:181 +msgctxt "@action:button" +msgid "Update profile with current settings" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:189 +msgctxt "@action:button" +msgid "Discard current settings" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:206 +msgctxt "@action:label" +msgid "" +"This profile uses the defaults specified by the printer, so it has no " +"settings in the list below." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:213 +msgctxt "@action:label" +msgid "Your current settings match the selected profile." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:229 +msgctxt "@title:tab" +msgid "Global Settings" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:271 +msgctxt "@title:window" +msgid "Rename Profile" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:284 +msgctxt "@title:window" +msgid "Create Profile" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:298 +msgctxt "@title:window" +msgid "Duplicate Profile" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:312 +msgctxt "@window:title" +msgid "Import Profile" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:320 +msgctxt "@title:window" +msgid "Import Profile" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:348 +msgctxt "@title:window" +msgid "Export Profile" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:15 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:437 +msgctxt "@title:tab" +msgid "Materials" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:106 +msgctxt "" +"@action:label %1 is printer name, %2 is how this printer names variants, %3 " +"is variant name" +msgid "Printer: %1, %2: %3" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:110 +msgctxt "@action:label %1 is printer name" +msgid "Printer: %1" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:134 +msgctxt "@action:button" +msgid "Duplicate" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:189 +msgctxt "@action:button" +msgid "Edit" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:256 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:264 +msgctxt "@title:window" +msgid "Import Material" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:265 +msgctxt "@info:status" +msgid "" +"Could not import material %1: %2" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:269 +msgctxt "@info:status" +msgid "Successfully imported material %1" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:287 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:302 +msgctxt "@title:window" +msgid "Export Material" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:306 +msgctxt "@info:status" +msgid "" +"Failed to export material to %1: %2" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:312 +msgctxt "@info:status" +msgid "Successfully exported material to %1" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:18 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:701 +msgctxt "@title:window" +msgid "Add Printer" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:183 +msgctxt "@action:button" +msgid "Add Printer" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:176 +msgctxt "@label" +msgid "00h 00min" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:212 +msgctxt "@label" +msgid "%1 m / ~ %2 g" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:15 +msgctxt "@title:window" +msgid "About Cura" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:57 +msgctxt "@label" +msgid "End-to-end solution for fused filament 3D printing." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:69 +msgctxt "@info:credit" +msgid "" +"Cura has been developed by Ultimaker B.V. in cooperation with the community." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:189 +msgctxt "@action:menu" +msgid "Copy value to all extruders" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:203 +msgctxt "@action:menu" +msgid "Hide this setting" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:209 +msgctxt "@action:menu" +msgid "Configure setting visiblity..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:75 +msgctxt "@label" +msgid "" +"Some hidden settings use values different from their normal calculated " +"value.\n" +"\n" +"Click to make these settings visible." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:59 +msgctxt "@label" +msgid "Affects" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:64 +msgctxt "@label" +msgid "Affected By" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:155 +msgctxt "@label" +msgid "" +"This setting is always shared between all extruders. Changing it here will " +"change the value for all extruders" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:158 +msgctxt "@label" +msgid "The value is resolved from per-extruder values " +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:186 +msgctxt "@label" +msgid "" +"This setting has a value that is different from the profile.\n" +"\n" +"Click to restore the value of the profile." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:262 +msgctxt "@label" +msgid "" +"This setting is normally calculated, but it currently has an absolute value " +"set.\n" +"\n" +"Click to restore the calculated value." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:190 +msgctxt "@label:listbox" +msgid "Print Setup" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:261 +msgctxt "@label" +msgid "Printer Monitor" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:382 +msgctxt "@title:tab" +msgid "Simple" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:383 +msgctxt "@title:tab" +msgid "Advanced" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:18 +#: /home/ruben/Projects/Cura/resources/qml/Menus/NozzleMenu.qml:18 +msgctxt "@title:menuitem %1 is the value from the printer" +msgid "Automatic: %1" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12 +msgctxt "@title:menu menubar:toplevel" +msgid "&View" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:13 +msgctxt "@title:menu menubar:file" +msgid "Open &Recent" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:31 +msgctxt "@label" +msgid "Temperatures" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:39 +msgctxt "@label" +msgid "Hotend" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:49 +msgctxt "@label" +msgid "Build plate" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:57 +msgctxt "@label" +msgid "Active print" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:62 +msgctxt "@label" +msgid "Job Name" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:68 +msgctxt "@label" +msgid "Printing Time" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:74 +msgctxt "@label" +msgid "Estimated time left" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:62 +msgctxt "@action:inmenu" +msgid "Toggle Fu&ll Screen" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:69 +msgctxt "@action:inmenu menubar:edit" +msgid "&Undo" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:79 +msgctxt "@action:inmenu menubar:edit" +msgid "&Redo" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:89 +msgctxt "@action:inmenu menubar:file" +msgid "&Quit" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:97 +msgctxt "@action:inmenu" +msgid "Configure Cura..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:104 +msgctxt "@action:inmenu menubar:printer" +msgid "&Add Printer..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:110 +msgctxt "@action:inmenu menubar:printer" +msgid "Manage Pr&inters..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:117 +msgctxt "@action:inmenu" +msgid "Manage Materials..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:125 +msgctxt "@action:inmenu menubar:profile" +msgid "&Update profile with current settings" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:133 +msgctxt "@action:inmenu menubar:profile" +msgid "&Discard current settings" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141 +msgctxt "@action:inmenu menubar:profile" +msgid "&Create profile from current settings..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:147 +msgctxt "@action:inmenu menubar:profile" +msgid "Manage Profiles..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:154 +msgctxt "@action:inmenu menubar:help" +msgid "Show Online &Documentation" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:162 +msgctxt "@action:inmenu menubar:help" +msgid "Report a &Bug" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:170 +msgctxt "@action:inmenu menubar:help" +msgid "&About..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:177 +msgctxt "@action:inmenu menubar:edit" +msgid "Delete &Selection" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:187 +msgctxt "@action:inmenu" +msgid "Delete Model" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:195 +msgctxt "@action:inmenu" +msgid "Ce&nter Model on Platform" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:201 +msgctxt "@action:inmenu menubar:edit" +msgid "&Group Models" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:211 +msgctxt "@action:inmenu menubar:edit" +msgid "Ungroup Models" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:221 +msgctxt "@action:inmenu menubar:edit" +msgid "&Merge Models" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:231 +msgctxt "@action:inmenu" +msgid "&Duplicate Model" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:238 +msgctxt "@action:inmenu menubar:edit" +msgid "&Select All Models" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:248 +msgctxt "@action:inmenu menubar:edit" +msgid "&Clear Build Plate" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:258 +msgctxt "@action:inmenu menubar:file" +msgid "Re&load All Models" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:266 +msgctxt "@action:inmenu menubar:edit" +msgid "Reset All Model Positions" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:273 +msgctxt "@action:inmenu menubar:edit" +msgid "Reset All Model &Transformations" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:280 +msgctxt "@action:inmenu menubar:file" +msgid "&Open File..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:288 +msgctxt "@action:inmenu menubar:help" +msgid "Show Engine &Log..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:296 +msgctxt "@action:inmenu menubar:help" +msgid "Show Configuration Folder" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:303 +msgctxt "@action:menu" +msgid "Configure setting visibility..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:24 +msgctxt "@label:PrintjobStatus" +msgid "Please load a 3d model" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:30 +msgctxt "@label:PrintjobStatus" +msgid "Preparing to slice..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:32 +msgctxt "@label:PrintjobStatus" +msgid "Slicing..." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:34 +msgctxt "@label:PrintjobStatus %1 is target operation" +msgid "Ready to %1" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:36 +msgctxt "@label:PrintjobStatus" +msgid "Unable to Slice" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:175 +msgctxt "@info:tooltip" +msgid "Select the active output device" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:19 +msgctxt "@title:window" +msgid "Cura" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:69 +msgctxt "@title:menu menubar:toplevel" +msgid "&File" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:81 +msgctxt "@action:inmenu menubar:file" +msgid "&Save Selection to File" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:89 +msgctxt "@title:menu menubar:file" +msgid "Save &All" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:116 +msgctxt "@title:menu menubar:toplevel" +msgid "&Edit" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:132 +msgctxt "@title:menu" +msgid "&View" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:137 +msgctxt "@title:menu" +msgid "&Settings" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:139 +msgctxt "@title:menu menubar:toplevel" +msgid "&Printer" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:149 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:161 +msgctxt "@title:menu" +msgid "&Material" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:150 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:162 +msgctxt "@title:menu" +msgid "&Profile" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:154 +msgctxt "@action:inmenu" +msgid "Set as Active Extruder" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:172 +msgctxt "@title:menu menubar:toplevel" +msgid "E&xtensions" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:205 +msgctxt "@title:menu menubar:toplevel" +msgid "P&references" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:213 +msgctxt "@title:menu menubar:toplevel" +msgid "&Help" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:291 +msgctxt "@action:button" +msgid "Open File" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:364 +msgctxt "@action:button" +msgid "View Mode" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:433 +msgctxt "@title:tab" +msgid "Settings" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:642 +msgctxt "@title:window" +msgid "Open file" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:38 +msgctxt "@label" +msgid "Infill:" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:169 +msgctxt "@label" +msgid "Hollow" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:173 +msgctxt "@label" +msgid "No (0%) infill will leave your model hollow at the cost of low strength" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:177 +msgctxt "@label" +msgid "Light" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:181 +msgctxt "@label" +msgid "Light (20%) infill will give your model an average strength" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:185 +msgctxt "@label" +msgid "Dense" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:189 +msgctxt "@label" +msgid "Dense (50%) infill will give your model an above average strength" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:193 +msgctxt "@label" +msgid "Solid" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:197 +msgctxt "@label" +msgid "Solid (100%) infill will make your model completely solid" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:219 +msgctxt "@label" +msgid "Helper Parts:" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:233 +msgctxt "@option:check" +msgid "Print Build Plate Adhesion" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:263 +msgctxt "@label" +msgid "" +"Enable printing a brim or raft. This will add a flat area around or under " +"your object which is easy to cut off afterwards." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:295 +msgctxt "@option:check" +msgid "Print Support Structure" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:312 +msgctxt "@label" +msgid "" +"Enable printing support structures. This will build up supporting structures " +"below the model to prevent the model from sagging or printing in mid air." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:355 +msgctxt "@label" +msgid "" +"Select which extruder to use for support. This will build up supporting " +"structures below the model to prevent the model from sagging or printing in " +"mid air." +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:381 +msgctxt "@label" +msgid "Don't print support" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:386 +msgctxt "@label" +msgid "Print support using %1" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:407 +msgctxt "@label" +msgid "" +"Need help improving your prints? Read the Ultimaker " +"Troubleshooting Guides" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15 +msgctxt "@title:window" +msgid "Engine Log" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:41 +msgctxt "@label:listbox" +msgid "Printer:" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:189 +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:197 +msgctxt "@label" +msgid "Material" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:276 +msgctxt "@label" +msgid "Profile:" +msgstr "" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:313 +msgctxt "@tooltip" +msgid "" +"Some setting values are different from the values stored in the profile.\n" +"\n" +"Click to open the profile manager." msgstr "" diff --git a/resources/i18n/en/cura.po b/resources/i18n/en/cura.po index d8cb6123ed..3e711b9674 100644 --- a/resources/i18n/en/cura.po +++ b/resources/i18n/en/cura.po @@ -1,1320 +1,2389 @@ -# English translations for PACKAGE package. -# Copyright (C) 2016 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Automatically generated, 2016. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-01-18 11:54+0100\n" -"PO-Revision-Date: 2016-01-26 08:37+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: en\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: /home/tamara/2.1/Cura/cura/CrashHandler.py:26 -msgctxt "@title:window" -msgid "Oops!" -msgstr "Oops!" - -#: /home/tamara/2.1/Cura/cura/CrashHandler.py:32 -msgctxt "@label" -msgid "" -"

An uncaught exception has occurred!

Please use the information " -"below to post a bug report at http://github.com/Ultimaker/Cura/issues

" -msgstr "

An uncaught exception has occurred!

Please use the information below to post a bug report at http://github.com/Ultimaker/Cura/issues

" - -#: /home/tamara/2.1/Cura/cura/CrashHandler.py:52 -msgctxt "@action:button" -msgid "Open Web Page" -msgstr "Open Web Page" - -#: /home/tamara/2.1/Cura/cura/CuraApplication.py:158 -msgctxt "@info:progress" -msgid "Setting up scene..." -msgstr "Setting up scene..." - -#: /home/tamara/2.1/Cura/cura/CuraApplication.py:192 -msgctxt "@info:progress" -msgid "Loading interface..." -msgstr "Loading interface..." - -#: /home/tamara/2.1/Cura/cura/CuraApplication.py:253 -#, python-format -msgctxt "@info" -msgid "%(width).1f x %(depth).1f x %(height).1f mm" -msgstr "%(width).1f x %(depth).1f x %(height).1f mm" - -#: /home/tamara/2.1/Cura/plugins/CuraProfileReader/__init__.py:12 -msgctxt "@label" -msgid "Cura Profile Reader" -msgstr "Cura Profile Reader" - -#: /home/tamara/2.1/Cura/plugins/CuraProfileReader/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Provides support for importing Cura profiles." -msgstr "Provides support for importing Cura profiles." - -#: /home/tamara/2.1/Cura/plugins/CuraProfileReader/__init__.py:21 -#: /home/tamara/2.1/Cura/plugins/CuraProfileWriter/__init__.py:21 -msgctxt "@item:inlistbox" -msgid "Cura Profile" -msgstr "Cura Profile" - -#: /home/tamara/2.1/Cura/plugins/XRayView/__init__.py:12 -msgctxt "@label" -msgid "X-Ray View" -msgstr "X-Ray View" - -#: /home/tamara/2.1/Cura/plugins/XRayView/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Provides the X-Ray view." -msgstr "Provides the X-Ray view." - -#: /home/tamara/2.1/Cura/plugins/XRayView/__init__.py:19 -msgctxt "@item:inlistbox" -msgid "X-Ray" -msgstr "X-Ray" - -#: /home/tamara/2.1/Cura/plugins/3MFReader/__init__.py:12 -msgctxt "@label" -msgid "3MF Reader" -msgstr "3MF Reader" - -#: /home/tamara/2.1/Cura/plugins/3MFReader/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Provides support for reading 3MF files." -msgstr "Provides support for reading 3MF files." - -#: /home/tamara/2.1/Cura/plugins/3MFReader/__init__.py:21 -msgctxt "@item:inlistbox" -msgid "3MF File" -msgstr "3MF File" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:20 -msgctxt "@action:button" -msgid "Save to Removable Drive" -msgstr "Save to Removable Drive" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:21 -#, python-brace-format -msgctxt "@item:inlistbox" -msgid "Save to Removable Drive {0}" -msgstr "Save to Removable Drive {0}" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:57 -#, python-brace-format -msgctxt "@info:progress" -msgid "Saving to Removable Drive {0}" -msgstr "Saving to Removable Drive {0}" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:85 -#, python-brace-format -msgctxt "@info:status" -msgid "Saved to Removable Drive {0} as {1}" -msgstr "Saved to Removable Drive {0} as {1}" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:86 -msgctxt "@action:button" -msgid "Eject" -msgstr "Eject" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:86 -#, python-brace-format -msgctxt "@action" -msgid "Eject removable device {0}" -msgstr "Eject removable device {0}" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:91 -#, python-brace-format -msgctxt "@info:status" -msgid "Could not save to removable drive {0}: {1}" -msgstr "Could not save to removable drive {0}: {1}" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py:58 -msgctxt "@item:intext" -msgid "Removable Drive" -msgstr "Removable Drive" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py:46 -#, python-brace-format -msgctxt "@info:status" -msgid "Ejected {0}. You can now safely remove the drive." -msgstr "Ejected {0}. You can now safely remove the drive." - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py:49 -#, python-brace-format -msgctxt "@info:status" -msgid "Failed to eject {0}. Maybe it is still in use?" -msgstr "Failed to eject {0}. Is it still in use?" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/__init__.py:12 -msgctxt "@label" -msgid "Removable Drive Output Device Plugin" -msgstr "Removable Drive Output Device Plugin" - -#: /home/tamara/2.1/Cura/plugins/RemovableDriveOutputDevice/__init__.py:14 -msgctxt "@info:whatsthis" -msgid "Provides removable drive hotplugging and writing support" -msgstr "Provides removable drive hot plugging and writing support" - -#: /home/tamara/2.1/Cura/plugins/ChangeLogPlugin/ChangeLog.py:34 -msgctxt "@item:inmenu" -msgid "Show Changelog" -msgstr "Show Changelog" - -#: /home/tamara/2.1/Cura/plugins/ChangeLogPlugin/__init__.py:12 -msgctxt "@label" -msgid "Changelog" -msgstr "Changelog" - -#: /home/tamara/2.1/Cura/plugins/ChangeLogPlugin/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Shows changes since latest checked version" -msgstr "Shows changes since latest checked version" - -#: /home/tamara/2.1/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:124 -msgctxt "@info:status" -msgid "Unable to slice. Please check your setting values for errors." -msgstr "Unable to slice. Please check your setting values for errors." - -#: /home/tamara/2.1/Cura/plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py:30 -#: /home/tamara/2.1/Cura/plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py:120 -msgctxt "@info:status" -msgid "Processing Layers" -msgstr "Processing Layers" - -#: /home/tamara/2.1/Cura/plugins/CuraEngineBackend/__init__.py:13 -msgctxt "@label" -msgid "CuraEngine Backend" -msgstr "CuraEngine Backend" - -#: /home/tamara/2.1/Cura/plugins/CuraEngineBackend/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Provides the link to the CuraEngine slicing backend" -msgstr "Provides the link to the CuraEngine slicing backend" - -#: /home/tamara/2.1/Cura/plugins/GCodeWriter/__init__.py:12 -msgctxt "@label" -msgid "GCode Writer" -msgstr "GCode Writer" - -#: /home/tamara/2.1/Cura/plugins/GCodeWriter/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Writes GCode to a file" -msgstr "Writes GCode to a file" - -#: /home/tamara/2.1/Cura/plugins/GCodeWriter/__init__.py:22 -msgctxt "@item:inlistbox" -msgid "GCode File" -msgstr "GCode File" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/USBPrinterManager.py:49 -msgctxt "@title:menu" -msgid "Firmware" -msgstr "Firmware" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/USBPrinterManager.py:50 -msgctxt "@item:inmenu" -msgid "Update Firmware" -msgstr "Update Firmware" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/USBPrinterManager.py:101 -msgctxt "@info" -msgid "Cannot update firmware, there were no connected printers found." -msgstr "Cannot update firmware, no connected printers were found." - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/PrinterConnection.py:35 -msgctxt "@item:inmenu" -msgid "USB printing" -msgstr "USB printing" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/PrinterConnection.py:36 -msgctxt "@action:button" -msgid "Print with USB" -msgstr "Print with USB" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/PrinterConnection.py:37 -msgctxt "@info:tooltip" -msgid "Print with USB" -msgstr "Print with USB" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/__init__.py:13 -msgctxt "@label" -msgid "USB printing" -msgstr "USB printing" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/__init__.py:17 -msgctxt "@info:whatsthis" -msgid "" -"Accepts G-Code and sends them to a printer. Plugin can also update firmware." -msgstr "Accepts G-Code and sends them to a printer. Plugin can also update firmware." - -#: /home/tamara/2.1/Cura/plugins/SliceInfoPlugin/SliceInfo.py:35 -msgctxt "@info" -msgid "" -"Cura automatically sends slice info. You can disable this in preferences" -msgstr "Cura automatically sends slice info. You can disable this in preferences" - -#: /home/tamara/2.1/Cura/plugins/SliceInfoPlugin/SliceInfo.py:36 -msgctxt "@action:button" -msgid "Dismiss" -msgstr "Dismiss" - -#: /home/tamara/2.1/Cura/plugins/SliceInfoPlugin/__init__.py:10 -msgctxt "@label" -msgid "Slice info" -msgstr "Slice info" - -#: /home/tamara/2.1/Cura/plugins/SliceInfoPlugin/__init__.py:13 -msgctxt "@info:whatsthis" -msgid "Submits anonymous slice info. Can be disabled through preferences." -msgstr "Submits anonymous slice info. Can be disabled through preferences." - -#: /home/tamara/2.1/Cura/plugins/CuraProfileWriter/__init__.py:12 -msgctxt "@label" -msgid "Cura Profile Writer" -msgstr "Cura Profile Writer" - -#: /home/tamara/2.1/Cura/plugins/CuraProfileWriter/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Provides support for exporting Cura profiles." -msgstr "Provides support for exporting Cura profiles." - -#: /home/tamara/2.1/Cura/plugins/ImageReader/__init__.py:12 -msgctxt "@label" -msgid "Image Reader" -msgstr "Image Reader" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Enables ability to generate printable geometry from 2D image files." -msgstr "Enables ability to generate printable geometry from 2D image files." - -#: /home/tamara/2.1/Cura/plugins/ImageReader/__init__.py:21 -msgctxt "@item:inlistbox" -msgid "JPG Image" -msgstr "JPG Image" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/__init__.py:25 -msgctxt "@item:inlistbox" -msgid "JPEG Image" -msgstr "JPEG Image" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/__init__.py:29 -msgctxt "@item:inlistbox" -msgid "PNG Image" -msgstr "PNG Image" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/__init__.py:33 -msgctxt "@item:inlistbox" -msgid "BMP Image" -msgstr "BMP Image" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/__init__.py:37 -msgctxt "@item:inlistbox" -msgid "GIF Image" -msgstr "GIF Image" - -#: /home/tamara/2.1/Cura/plugins/GCodeProfileReader/__init__.py:12 -msgctxt "@label" -msgid "GCode Profile Reader" -msgstr "GCode Profile Reader" - -#: /home/tamara/2.1/Cura/plugins/GCodeProfileReader/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Provides support for importing profiles from g-code files." -msgstr "Provides support for importing profiles from g-code files." - -#: /home/tamara/2.1/Cura/plugins/GCodeProfileReader/__init__.py:21 -msgctxt "@item:inlistbox" -msgid "G-code File" -msgstr "G-code File" - -#: /home/tamara/2.1/Cura/plugins/SolidView/__init__.py:12 -msgctxt "@label" -msgid "Solid View" -msgstr "Solid View" - -#: /home/tamara/2.1/Cura/plugins/SolidView/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Provides a normal solid mesh view." -msgstr "Provides a normal solid mesh view." - -#: /home/tamara/2.1/Cura/plugins/SolidView/__init__.py:19 -msgctxt "@item:inmenu" -msgid "Solid" -msgstr "Solid" - -#: /home/tamara/2.1/Cura/plugins/LayerView/__init__.py:13 -msgctxt "@label" -msgid "Layer View" -msgstr "Layer View" - -#: /home/tamara/2.1/Cura/plugins/LayerView/__init__.py:16 -msgctxt "@info:whatsthis" -msgid "Provides the Layer view." -msgstr "Provides the Layer view." - -#: /home/tamara/2.1/Cura/plugins/LayerView/__init__.py:20 -msgctxt "@item:inlistbox" -msgid "Layers" -msgstr "Layers" - -#: /home/tamara/2.1/Cura/plugins/AutoSave/__init__.py:12 -msgctxt "@label" -msgid "Auto Save" -msgstr "Auto Save" - -#: /home/tamara/2.1/Cura/plugins/AutoSave/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Automatically saves Preferences, Machines and Profiles after changes." -msgstr "Automatically saves Preferences, Machines and Profiles after changes." - -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/__init__.py:12 -msgctxt "@label" -msgid "Per Object Settings Tool" -msgstr "Per Object Settings Tool" - -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Provides the Per Object Settings." -msgstr "Provides the Per Object Settings." - -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/__init__.py:19 -msgctxt "@label" -msgid "Per Object Settings" -msgstr "Per Object Settings" - -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/__init__.py:20 -msgctxt "@info:tooltip" -msgid "Configure Per Object Settings" -msgstr "Configure Per Object Settings" - -#: /home/tamara/2.1/Cura/plugins/LegacyProfileReader/__init__.py:12 -msgctxt "@label" -msgid "Legacy Cura Profile Reader" -msgstr "Legacy Cura Profile Reader" - -#: /home/tamara/2.1/Cura/plugins/LegacyProfileReader/__init__.py:15 -msgctxt "@info:whatsthis" -msgid "Provides support for importing profiles from legacy Cura versions." -msgstr "Provides support for importing profiles from legacy Cura versions." - -#: /home/tamara/2.1/Cura/plugins/LegacyProfileReader/__init__.py:21 -msgctxt "@item:inlistbox" -msgid "Cura 15.04 profiles" -msgstr "Cura 15.04 profiles" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:20 -msgctxt "@title:window" -msgid "Firmware Update" -msgstr "Firmware Update" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:38 -msgctxt "@label" -msgid "Starting firmware update, this may take a while." -msgstr "Starting firmware update, this may take some time." - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:43 -msgctxt "@label" -msgid "Firmware update completed." -msgstr "Firmware update completed." - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:48 -msgctxt "@label" -msgid "Updating firmware." -msgstr "Updating firmware." - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:80 -#: /home/tamara/2.1/Cura/resources/qml/EngineLog.qml:38 -#: /home/tamara/2.1/Cura/resources/qml/AboutDialog.qml:74 -msgctxt "@action:button" -msgid "Close" -msgstr "Close" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/ControlWindow.qml:17 -msgctxt "@title:window" -msgid "Print with USB" -msgstr "Print with USB" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/ControlWindow.qml:28 -msgctxt "@label" -msgid "Extruder Temperature %1" -msgstr "Extruder Temperature %1" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/ControlWindow.qml:33 -msgctxt "@label" -msgid "Bed Temperature %1" -msgstr "Bed Temperature %1" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/ControlWindow.qml:60 -msgctxt "@action:button" -msgid "Print" -msgstr "Print" - -#: /home/tamara/2.1/Cura/plugins/USBPrinting/ControlWindow.qml:67 -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:200 -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:303 -#: /home/tamara/2.1/Cura/resources/qml/LoadProfileDialog.qml:58 -msgctxt "@action:button" -msgid "Cancel" -msgstr "Cancel" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:24 -msgctxt "@title:window" -msgid "Convert Image..." -msgstr "Convert Image..." - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:38 -msgctxt "@info:tooltip" -msgid "The maximum distance of each pixel from \"Base.\"" -msgstr "The maximum distance of each pixel from \"Base.\"" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:44 -msgctxt "@action:label" -msgid "Height (mm)" -msgstr "Height (mm)" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:62 -msgctxt "@info:tooltip" -msgid "The base height from the build plate in millimeters." -msgstr "The base height from the build plate in millimetres." - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:68 -msgctxt "@action:label" -msgid "Base (mm)" -msgstr "Base (mm)" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:86 -msgctxt "@info:tooltip" -msgid "The width in millimeters on the build plate." -msgstr "The width in millimetres on the build plate." - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:92 -msgctxt "@action:label" -msgid "Width (mm)" -msgstr "Width (mm)" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:111 -msgctxt "@info:tooltip" -msgid "The depth in millimeters on the build plate" -msgstr "The depth in millimetres on the build plate" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:117 -msgctxt "@action:label" -msgid "Depth (mm)" -msgstr "Depth (mm)" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:135 -msgctxt "@info:tooltip" -msgid "" -"By default, white pixels represent high points on the mesh and black pixels " -"represent low points on the mesh. Change this option to reverse the behavior " -"such that black pixels represent high points on the mesh and white pixels " -"represent low points on the mesh." -msgstr "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behaviour such that black pixels represent high points on the mesh and white pixels represent low points on the mesh." - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:149 -msgctxt "@item:inlistbox" -msgid "Lighter is higher" -msgstr "Lighter is higher" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:149 -msgctxt "@item:inlistbox" -msgid "Darker is higher" -msgstr "Darker is higher" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:159 -msgctxt "@info:tooltip" -msgid "The amount of smoothing to apply to the image." -msgstr "The amount of smoothing to apply to the image." - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:165 -msgctxt "@action:label" -msgid "Smoothing" -msgstr "Smoothing" - -#: /home/tamara/2.1/Cura/plugins/ImageReader/ConfigUI.qml:193 -msgctxt "@action:button" -msgid "OK" -msgstr "OK" - -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:31 -msgctxt "@label" -msgid "" -"Per Object Settings behavior may be unexpected when 'Print sequence' is set " -"to 'All at Once'." -msgstr "Per Object Settings behaviour may be unexpected when 'Print sequence' is set to 'All at Once'." - -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:42 -msgctxt "@label" -msgid "Object profile" -msgstr "Object profile" - -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:126 -msgctxt "@action:button" -msgid "Add Setting" -msgstr "Add Setting" - -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:166 -msgctxt "@title:window" -msgid "Pick a Setting to Customize" -msgstr "Pick a Setting to Customise" - -#: /home/tamara/2.1/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:177 -msgctxt "@label:textbox" -msgid "Filter..." -msgstr "Filter..." - -#: /home/tamara/2.1/Cura/resources/qml/JobSpecs.qml:198 -msgctxt "@label" -msgid "00h 00min" -msgstr "00h 00min" - -#: /home/tamara/2.1/Cura/resources/qml/JobSpecs.qml:218 -msgctxt "@label" -msgid "0.0 m" -msgstr "0.0 m" - -#: /home/tamara/2.1/Cura/resources/qml/JobSpecs.qml:218 -msgctxt "@label" -msgid "%1 m" -msgstr "%1 m" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarHeader.qml:29 -msgctxt "@label:listbox" -msgid "Print Job" -msgstr "Print Job" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarHeader.qml:50 -msgctxt "@label:listbox" -msgid "Printer:" -msgstr "Printer:" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarHeader.qml:107 -msgctxt "@label" -msgid "Nozzle:" -msgstr "Nozzle:" - -#: /home/tamara/2.1/Cura/resources/qml/Sidebar.qml:89 -msgctxt "@label:listbox" -msgid "Setup" -msgstr "Setup" - -#: /home/tamara/2.1/Cura/resources/qml/Sidebar.qml:215 -msgctxt "@title:tab" -msgid "Simple" -msgstr "Simple" - -#: /home/tamara/2.1/Cura/resources/qml/Sidebar.qml:216 -msgctxt "@title:tab" -msgid "Advanced" -msgstr "Advanced" - -#: /home/tamara/2.1/Cura/resources/qml/AddMachineWizard.qml:18 -msgctxt "@title:window" -msgid "Add Printer" -msgstr "Add Printer" - -#: /home/tamara/2.1/Cura/resources/qml/AddMachineWizard.qml:25 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/AddMachine.qml:99 -msgctxt "@title" -msgid "Add Printer" -msgstr "Add Printer" - -#: /home/tamara/2.1/Cura/resources/qml/LoadProfileDialog.qml:15 -msgctxt "@title:window" -msgid "Load profile" -msgstr "Load profile" - -#: /home/tamara/2.1/Cura/resources/qml/LoadProfileDialog.qml:24 -msgctxt "@label" -msgid "" -"Selecting this profile overwrites some of your customised settings. Do you " -"want to merge the new settings into your current profile or do you want to " -"load a clean copy of the profile?" -msgstr "Selecting this profile overwrites some of your customised settings. Do you want to merge the new settings into your current profile or do you want to load a clean copy of the profile?" - -#: /home/tamara/2.1/Cura/resources/qml/LoadProfileDialog.qml:38 -msgctxt "@label" -msgid "Show details." -msgstr "Show details." - -#: /home/tamara/2.1/Cura/resources/qml/LoadProfileDialog.qml:50 -msgctxt "@action:button" -msgid "Merge settings" -msgstr "Merge settings" - -#: /home/tamara/2.1/Cura/resources/qml/LoadProfileDialog.qml:54 -msgctxt "@action:button" -msgid "Reset profile" -msgstr "Reset profile" - -#: /home/tamara/2.1/Cura/resources/qml/ProfileSetup.qml:28 -msgctxt "@label" -msgid "Profile:" -msgstr "Profile:" - -#: /home/tamara/2.1/Cura/resources/qml/EngineLog.qml:15 -msgctxt "@title:window" -msgid "Engine Log" -msgstr "Engine Log" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:50 -msgctxt "@action:inmenu" -msgid "Toggle Fu&ll Screen" -msgstr "Toggle Fu&ll Screen" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:57 -msgctxt "@action:inmenu menubar:edit" -msgid "&Undo" -msgstr "&Undo" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:65 -msgctxt "@action:inmenu menubar:edit" -msgid "&Redo" -msgstr "&Redo" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:73 -msgctxt "@action:inmenu menubar:file" -msgid "&Quit" -msgstr "&Quit" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:81 -msgctxt "@action:inmenu menubar:settings" -msgid "&Preferences..." -msgstr "&Preferences..." - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:88 -msgctxt "@action:inmenu menubar:printer" -msgid "&Add Printer..." -msgstr "&Add Printer..." - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:94 -msgctxt "@action:inmenu menubar:printer" -msgid "Manage Pr&inters..." -msgstr "Manage Pr&inters..." - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:101 -msgctxt "@action:inmenu menubar:profile" -msgid "Manage Profiles..." -msgstr "Manage Profiles..." - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:108 -msgctxt "@action:inmenu menubar:help" -msgid "Show Online &Documentation" -msgstr "Show Online &Documentation" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:115 -msgctxt "@action:inmenu menubar:help" -msgid "Report a &Bug" -msgstr "Report a &Bug" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:122 -msgctxt "@action:inmenu menubar:help" -msgid "&About..." -msgstr "&About..." - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:129 -msgctxt "@action:inmenu menubar:edit" -msgid "Delete &Selection" -msgstr "Delete &Selection" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:137 -msgctxt "@action:inmenu" -msgid "Delete Object" -msgstr "Delete Object" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:144 -msgctxt "@action:inmenu" -msgid "Ce&nter Object on Platform" -msgstr "Ce&ntre Object on Platform" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:150 -msgctxt "@action:inmenu menubar:edit" -msgid "&Group Objects" -msgstr "&Group Objects" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:158 -msgctxt "@action:inmenu menubar:edit" -msgid "Ungroup Objects" -msgstr "Ungroup Objects" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:166 -msgctxt "@action:inmenu menubar:edit" -msgid "&Merge Objects" -msgstr "&Merge Objects" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:174 -msgctxt "@action:inmenu" -msgid "&Duplicate Object" -msgstr "&Duplicate Object" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:181 -msgctxt "@action:inmenu menubar:edit" -msgid "&Clear Build Platform" -msgstr "&Clear Build Platform" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:189 -msgctxt "@action:inmenu menubar:file" -msgid "Re&load All Objects" -msgstr "Re&load All Objects" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:196 -msgctxt "@action:inmenu menubar:edit" -msgid "Reset All Object Positions" -msgstr "Reset All Object Positions" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:202 -msgctxt "@action:inmenu menubar:edit" -msgid "Reset All Object &Transformations" -msgstr "Reset All Object &Transformations" - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:208 -msgctxt "@action:inmenu menubar:file" -msgid "&Open File..." -msgstr "&Open File..." - -#: /home/tamara/2.1/Cura/resources/qml/Actions.qml:216 -msgctxt "@action:inmenu menubar:help" -msgid "Show Engine &Log..." -msgstr "Show Engine &Log..." - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:135 -msgctxt "@label" -msgid "Infill:" -msgstr "Infill:" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:237 -msgctxt "@label" -msgid "Hollow" -msgstr "Hollow" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:239 -msgctxt "@label" -msgid "No (0%) infill will leave your model hollow at the cost of low strength" -msgstr "No (0%) infill will leave your model hollow at the cost of low strength" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:243 -msgctxt "@label" -msgid "Light" -msgstr "Light" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:245 -msgctxt "@label" -msgid "Light (20%) infill will give your model an average strength" -msgstr "Light (20%) infill will give your model an average strength" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:249 -msgctxt "@label" -msgid "Dense" -msgstr "Dense" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:251 -msgctxt "@label" -msgid "Dense (50%) infill will give your model an above average strength" -msgstr "Dense (50%) infill will give your model an above average strength" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:255 -msgctxt "@label" -msgid "Solid" -msgstr "Solid" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:257 -msgctxt "@label" -msgid "Solid (100%) infill will make your model completely solid" -msgstr "Solid (100%) infill will make your model completely solid" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:276 -msgctxt "@label:listbox" -msgid "Helpers:" -msgstr "Helpers:" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:296 -msgctxt "@option:check" -msgid "Generate Brim" -msgstr "Generate Brim" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:312 -msgctxt "@label" -msgid "" -"Enable printing a brim. This will add a single-layer-thick flat area around " -"your object which is easy to cut off afterwards." -msgstr "Enable printing a brim. This will add a single-layer-thick flat area around your object which is easy to cut off afterwards." - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:330 -msgctxt "@option:check" -msgid "Generate Support Structure" -msgstr "Generate Support Structure" - -#: /home/tamara/2.1/Cura/resources/qml/SidebarSimple.qml:346 -msgctxt "@label" -msgid "" -"Enable printing support structures. This will build up supporting structures " -"below the model to prevent the model from sagging or printing in mid air." -msgstr "Enable printing support structures. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air." - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:14 -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:492 -msgctxt "@title:tab" -msgid "General" -msgstr "General" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:51 -msgctxt "@label" -msgid "Language:" -msgstr "Language:" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:64 -msgctxt "@item:inlistbox" -msgid "English" -msgstr "English" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:65 -msgctxt "@item:inlistbox" -msgid "Finnish" -msgstr "Finnish" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:66 -msgctxt "@item:inlistbox" -msgid "French" -msgstr "French" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:67 -msgctxt "@item:inlistbox" -msgid "German" -msgstr "German" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:69 -msgctxt "@item:inlistbox" -msgid "Polish" -msgstr "Polish" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:109 -msgctxt "@label" -msgid "" -"You will need to restart the application for language changes to have effect." -msgstr "You will need to restart the application for language changes to have effect." - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:117 -msgctxt "@info:tooltip" -msgid "" -"Should objects on the platform be moved so that they no longer intersect." -msgstr "Should objects on the platform be moved so that they no longer intersect." - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:122 -msgctxt "@option:check" -msgid "Ensure objects are kept apart" -msgstr "Ensure objects are kept apart" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:131 -msgctxt "@info:tooltip" -msgid "" -"Should opened files be scaled to the build volume if they are too large?" -msgstr "Should opened files be scaled to the build volume if they are too large?" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:136 -msgctxt "@option:check" -msgid "Scale large files" -msgstr "Scale large files" - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:145 -msgctxt "@info:tooltip" -msgid "" -"Should anonymous data about your print be sent to Ultimaker? Note, no " -"models, IP addresses or other personally identifiable information is sent or " -"stored." -msgstr "Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored." - -#: /home/tamara/2.1/Cura/resources/qml/GeneralPage.qml:150 -msgctxt "@option:check" -msgid "Send (anonymous) print information" -msgstr "Send (anonymous) print information" - -#: /home/tamara/2.1/Cura/resources/qml/ViewPage.qml:16 -msgctxt "@title:window" -msgid "View" -msgstr "View" - -#: /home/tamara/2.1/Cura/resources/qml/ViewPage.qml:33 -msgctxt "@info:tooltip" -msgid "" -"Highlight unsupported areas of the model in red. Without support these areas " -"will nog print properly." -msgstr "Highlight unsupported areas of the model in red. Without support these areas will not print properly." - -#: /home/tamara/2.1/Cura/resources/qml/ViewPage.qml:42 -msgctxt "@option:check" -msgid "Display overhang" -msgstr "Display overhang" - -#: /home/tamara/2.1/Cura/resources/qml/ViewPage.qml:49 -msgctxt "@info:tooltip" -msgid "" -"Moves the camera so the object is in the center of the view when an object " -"is selected" -msgstr "Moves the camera so the object is in the centre of the view when an object is selected" - -#: /home/tamara/2.1/Cura/resources/qml/ViewPage.qml:54 -msgctxt "@action:button" -msgid "Center camera when item is selected" -msgstr "Centre camera when item is selected" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:72 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/AddMachine.qml:275 -msgctxt "@title" -msgid "Check Printer" -msgstr "Check Printer" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:84 -msgctxt "@label" -msgid "" -"It's a good idea to do a few sanity checks on your Ultimaker. You can skip " -"this step if you know your machine is functional" -msgstr "It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:100 -msgctxt "@action:button" -msgid "Start Printer Check" -msgstr "Start Printer Check" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:116 -msgctxt "@action:button" -msgid "Skip Printer Check" -msgstr "Skip Printer Check" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:136 -msgctxt "@label" -msgid "Connection: " -msgstr "Connection: " - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:145 -msgctxt "@info:status" -msgid "Done" -msgstr "Done" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:145 -msgctxt "@info:status" -msgid "Incomplete" -msgstr "Incomplete" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:155 -msgctxt "@label" -msgid "Min endstop X: " -msgstr "Min endstop X: " - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:164 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:183 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:202 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:357 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:368 -msgctxt "@info:status" -msgid "Works" -msgstr "Works" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:164 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:183 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:202 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:221 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:277 -msgctxt "@info:status" -msgid "Not checked" -msgstr "Not checked" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:174 -msgctxt "@label" -msgid "Min endstop Y: " -msgstr "Min endstop Y: " - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:193 -msgctxt "@label" -msgid "Min endstop Z: " -msgstr "Min endstop Z: " - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:212 -msgctxt "@label" -msgid "Nozzle temperature check: " -msgstr "Nozzle temperature check: " - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:236 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:292 -msgctxt "@action:button" -msgid "Start Heating" -msgstr "Start Heating" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:241 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:297 -msgctxt "@info:progress" -msgid "Checking" -msgstr "Checking" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:267 -msgctxt "@label" -msgid "bed temperature check:" -msgstr "bed temperature check:" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UltimakerCheckup.qml:324 -msgctxt "@label" -msgid "Everything is in order! You're done with your CheckUp." -msgstr "Everything is in order! You're done with your CheckUp." - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:31 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/AddMachine.qml:269 -msgctxt "@title" -msgid "Select Upgraded Parts" -msgstr "Select Upgraded Parts" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:42 -msgctxt "@label" -msgid "" -"To assist you in having better default settings for your Ultimaker. Cura " -"would like to know which upgrades you have in your machine:" -msgstr "To assist you in having better default settings for your Ultimaker. Cura would like to know which upgrades you have in your machine:" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:57 -msgctxt "@option:check" -msgid "Extruder driver ugrades" -msgstr "Extruder driver upgrades" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:63 -msgctxt "@option:check" -msgid "Heated printer bed" -msgstr "Heated printer bed" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:74 -msgctxt "@option:check" -msgid "Heated printer bed (self built)" -msgstr "Heated printer bed (self built)" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/SelectUpgradedParts.qml:90 -msgctxt "@label" -msgid "" -"If you bought your Ultimaker after october 2012 you will have the Extruder " -"drive upgrade. If you do not have this upgrade, it is highly recommended to " -"improve reliability. This upgrade can be bought from the Ultimaker webshop " -"or found on thingiverse as thing:26094" -msgstr "If you bought your Ultimaker after October 2012 you will have the Extruder drive upgrade. If you do not have this upgrade, it is highly recommended to improve reliability. This upgrade can be bought from the Ultimaker web shop or found on Thingiverse as thing:26094" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/AddMachine.qml:108 -msgctxt "@label" -msgid "Please select the type of printer:" -msgstr "Please select the type of printer:" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/AddMachine.qml:235 -msgctxt "@label" -msgid "" -"This printer name has already been used. Please choose a different printer " -"name." -msgstr "This printer name has already been used. Please choose a different printer name." - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/AddMachine.qml:245 -msgctxt "@label:textbox" -msgid "Printer Name:" -msgstr "Printer Name:" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/AddMachine.qml:272 -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:22 -msgctxt "@title" -msgid "Upgrade Firmware" -msgstr "Upgrade Firmware" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/AddMachine.qml:278 -msgctxt "@title" -msgid "Bed Levelling" -msgstr "Bed Levelling" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/Bedleveling.qml:41 -msgctxt "@title" -msgid "Bed Leveling" -msgstr "Bed Leveling" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/Bedleveling.qml:53 -msgctxt "@label" -msgid "" -"To make sure your prints will come out great, you can now adjust your " -"buildplate. When you click 'Move to Next Position' the nozzle will move to " -"the different positions that can be adjusted." -msgstr "You can now adjust the build plate to make sure your prints come out great. When you click 'Move to Next Position’, the nozzle will move to the different positions that can be adjusted." - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/Bedleveling.qml:62 -msgctxt "@label" -msgid "" -"For every postition; 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." -msgstr "For every position; insert a piece of paper under the nozzle and adjust the print bed height. The print bed height is correct when the paper is gripped slightly by the tip of the nozzle." - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/Bedleveling.qml:77 -msgctxt "@action:button" -msgid "Move to Next Position" -msgstr "Move to Next Position" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/Bedleveling.qml:109 -msgctxt "@action:button" -msgid "Skip Bedleveling" -msgstr "Skip Bed Levelling" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/Bedleveling.qml:123 -msgctxt "@label" -msgid "Everything is in order! You're done with bedleveling." -msgstr "Everything is ready! You're done with bed levelling." - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:33 -msgctxt "@label" -msgid "" -"Firmware is the piece of software running directly on your 3D printer. This " -"firmware controls the step motors, regulates the temperature and ultimately " -"makes your printer work." -msgstr "Firmware is the piece of software running directly on your 3D printer. This firmware controls the step motors, regulates the temperature and ultimately makes your printer work." - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:43 -msgctxt "@label" -msgid "" -"The firmware shipping with new Ultimakers works, but upgrades have been made " -"to make better prints, and make calibration easier." -msgstr "The firmware shipping with new Ultimakers works, but upgrades have been made to make better prints, and make calibration easier." - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:53 -msgctxt "@label" -msgid "" -"Cura requires these new features and thus your firmware will most likely " -"need to be upgraded. You can do so now." -msgstr "Cura requires these new features and thus your firmware will most likely need to be upgraded. You can do this now." - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:64 -msgctxt "@action:button" -msgid "Upgrade to Marlin Firmware" -msgstr "Upgrade to Marlin Firmware" - -#: /home/tamara/2.1/Cura/resources/qml/WizardPages/UpgradeFirmware.qml:73 -msgctxt "@action:button" -msgid "Skip Upgrade" -msgstr "Skip Upgrade" - -#: /home/tamara/2.1/Cura/resources/qml/SaveButton.qml:23 -msgctxt "@label:PrintjobStatus" -msgid "Please load a 3d model" -msgstr "Please load a 3D model" - -#: /home/tamara/2.1/Cura/resources/qml/SaveButton.qml:25 -msgctxt "@label:PrintjobStatus" -msgid "Preparing to slice..." -msgstr "Preparing to slice..." - -#: /home/tamara/2.1/Cura/resources/qml/SaveButton.qml:28 -msgctxt "@label:PrintjobStatus" -msgid "Slicing..." -msgstr "Slicing..." - -#: /home/tamara/2.1/Cura/resources/qml/SaveButton.qml:30 -msgctxt "@label:PrintjobStatus" -msgid "Ready to " -msgstr "Ready to " - -#: /home/tamara/2.1/Cura/resources/qml/SaveButton.qml:122 -msgctxt "@info:tooltip" -msgid "Select the active output device" -msgstr "Select the active output device" - -#: /home/tamara/2.1/Cura/resources/qml/AboutDialog.qml:15 -msgctxt "@title:window" -msgid "About Cura" -msgstr "About Cura" - -#: /home/tamara/2.1/Cura/resources/qml/AboutDialog.qml:54 -msgctxt "@label" -msgid "End-to-end solution for fused filament 3D printing." -msgstr "End-to-end solution for fused filament 3D printing." - -#: /home/tamara/2.1/Cura/resources/qml/AboutDialog.qml:66 -msgctxt "@info:credit" -msgid "" -"Cura has been developed by Ultimaker B.V. in cooperation with the community." -msgstr "Cura has been developed by Ultimaker B.V. in cooperation with the community." - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:16 -msgctxt "@title:window" -msgid "Cura" -msgstr "Cura" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:53 -msgctxt "@title:menu menubar:toplevel" -msgid "&File" -msgstr "&File" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:62 -msgctxt "@title:menu menubar:file" -msgid "Open &Recent" -msgstr "Open &Recent" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:92 -msgctxt "@action:inmenu menubar:file" -msgid "&Save Selection to File" -msgstr "&Save Selection to File" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:100 -msgctxt "@title:menu menubar:file" -msgid "Save &All" -msgstr "Save &All" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:128 -msgctxt "@title:menu menubar:toplevel" -msgid "&Edit" -msgstr "&Edit" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:145 -msgctxt "@title:menu menubar:toplevel" -msgid "&View" -msgstr "&View" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:167 -msgctxt "@title:menu menubar:toplevel" -msgid "&Printer" -msgstr "&Printer" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:213 -msgctxt "@title:menu menubar:toplevel" -msgid "P&rofile" -msgstr "P&rofile" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:240 -msgctxt "@title:menu menubar:toplevel" -msgid "E&xtensions" -msgstr "E&xtensions" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:273 -msgctxt "@title:menu menubar:toplevel" -msgid "&Settings" -msgstr "&Settings" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:281 -msgctxt "@title:menu menubar:toplevel" -msgid "&Help" -msgstr "&Help" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:366 -msgctxt "@action:button" -msgid "Open File" -msgstr "Open File" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:410 -msgctxt "@action:button" -msgid "View Mode" -msgstr "View Mode" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:495 -msgctxt "@title:tab" -msgid "View" -msgstr "View" - -#: /home/tamara/2.1/Cura/resources/qml/Cura.qml:644 -msgctxt "@title:window" -msgid "Open file" -msgstr "Open file" +# English translations for PACKAGE package. +# Copyright (C) 2016 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Automatically generated, 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-09-13 17:49+0200\n" +"PO-Revision-Date: 2016-09-13 17:49+0200\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/__init__.py:12 +msgctxt "@label" +msgid "Machine Settings action" +msgstr "Machine Settings action" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "" +"Provides a way to change machine settings (such as build volume, nozzle " +"size, etc)" +msgstr "" +"Provides a way to change machine settings (such as build volume, nozzle " +"size, etc)" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:19 +msgctxt "@action" +msgid "Machine Settings" +msgstr "Machine Settings" + +#: /home/ruben/Projects/Cura/plugins/XRayView/__init__.py:12 +msgctxt "@label" +msgid "X-Ray View" +msgstr "X-Ray View" + +#: /home/ruben/Projects/Cura/plugins/XRayView/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Provides the X-Ray view." +msgstr "Provides the X-Ray view." + +#: /home/ruben/Projects/Cura/plugins/XRayView/__init__.py:19 +msgctxt "@item:inlistbox" +msgid "X-Ray" +msgstr "X-Ray" + +#: /home/ruben/Projects/Cura/plugins/GCodeWriter/__init__.py:12 +msgctxt "@label" +msgid "GCode Writer" +msgstr "GCode Writer" + +#: /home/ruben/Projects/Cura/plugins/GCodeWriter/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Writes GCode to a file." +msgstr "Writes GCode to a file." + +#: /home/ruben/Projects/Cura/plugins/GCodeWriter/__init__.py:22 +msgctxt "@item:inlistbox" +msgid "GCode File" +msgstr "GCode File" + +#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/__init__.py:12 +#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18 +msgctxt "@label" +msgid "Changelog" +msgstr "Changelog" + +#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Shows changes since latest checked version." +msgstr "Shows changes since latest checked version." + +#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.py:35 +msgctxt "@item:inmenu" +msgid "Show Changelog" +msgstr "Show Changelog" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/__init__.py:13 +msgctxt "@label" +msgid "USB printing" +msgstr "USB printing" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/__init__.py:17 +msgctxt "@info:whatsthis" +msgid "" +"Accepts G-Code and sends them to a printer. Plugin can also update firmware." +msgstr "" +"Accepts G-Code and sends them to a printer. Plugin can also update firmware." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:27 +msgctxt "@item:inmenu" +msgid "USB printing" +msgstr "USB printing" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:28 +msgctxt "@action:button" +msgid "Print via USB" +msgstr "Print via USB" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:29 +msgctxt "@info:tooltip" +msgid "Print via USB" +msgstr "Print via USB" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:31 +msgctxt "@info:status" +msgid "Connected via USB" +msgstr "Connected via USB" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:143 +msgctxt "@info:status" +msgid "Unable to start a new job because the printer is busy or not connected." +msgstr "" +"Unable to start a new job because the printer is busy or not connected." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDeviceManager.py:111 +msgctxt "@info" +msgid "Unable to update firmware because there are no printers connected." +msgstr "Unable to update firmware because there are no printers connected." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDeviceManager.py:125 +#, python-format +msgctxt "@info" +msgid "Could not find firmware required for the printer at %s." +msgstr "Could not find firmware required for the printer at %s." + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:20 +msgctxt "@action:button" +msgid "Save to Removable Drive" +msgstr "Save to Removable Drive" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:21 +#, python-brace-format +msgctxt "@item:inlistbox" +msgid "Save to Removable Drive {0}" +msgstr "Save to Removable Drive {0}" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:74 +#, python-brace-format +msgctxt "@info:progress" +msgid "Saving to Removable Drive {0}" +msgstr "Saving to Removable Drive {0}" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:84 +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:87 +#, python-brace-format +msgctxt "@info:status" +msgid "Could not save to {0}: {1}" +msgstr "Could not save to {0}: {1}" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:102 +#, python-brace-format +msgctxt "@info:status" +msgid "Saved to Removable Drive {0} as {1}" +msgstr "Saved to Removable Drive {0} as {1}" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:103 +msgctxt "@action:button" +msgid "Eject" +msgstr "Eject" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:103 +#, python-brace-format +msgctxt "@action" +msgid "Eject removable device {0}" +msgstr "Eject removable device {0}" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:108 +#, python-brace-format +msgctxt "@info:status" +msgid "Could not save to removable drive {0}: {1}" +msgstr "Could not save to removable drive {0}: {1}" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/__init__.py:12 +msgctxt "@label" +msgid "Removable Drive Output Device Plugin" +msgstr "Removable Drive Output Device Plugin" + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/__init__.py:14 +msgctxt "@info:whatsthis" +msgid "Provides removable drive hotplugging and writing support." +msgstr "Provides removable drive hotplugging and writing support." + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py:49 +#, python-brace-format +msgctxt "@info:status" +msgid "Ejected {0}. You can now safely remove the drive." +msgstr "Ejected {0}. You can now safely remove the drive." + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py:52 +#, python-brace-format +msgctxt "@info:status" +msgid "Failed to eject {0}. Another program may be using the drive." +msgstr "Failed to eject {0}. Another program may be using the drive." + +#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py:69 +msgctxt "@item:intext" +msgid "Removable Drive" +msgstr "Removable Drive" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "Modify G-Code" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Post Processing" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Extension that allows for user created scripts for post processing" + +#: /home/ruben/Projects/Cura/plugins/AutoSave/__init__.py:12 +msgctxt "@label" +msgid "Auto Save" +msgstr "Auto Save" + +#: /home/ruben/Projects/Cura/plugins/AutoSave/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Automatically saves Preferences, Machines and Profiles after changes." +msgstr "Automatically saves Preferences, Machines and Profiles after changes." + +#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/__init__.py:10 +msgctxt "@label" +msgid "Slice info" +msgstr "Slice info" + +#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/__init__.py:13 +msgctxt "@info:whatsthis" +msgid "Submits anonymous slice info. Can be disabled through preferences." +msgstr "Submits anonymous slice info. Can be disabled through preferences." + +#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:73 +msgctxt "@info" +msgid "" +"Cura collects anonymised slicing statistics. You can disable this in " +"preferences" +msgstr "" +"Cura collects anonymised slicing statistics. You can disable this in " +"preferences" + +#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:74 +msgctxt "@action:button" +msgid "Dismiss" +msgstr "Dismiss" + +#: /home/ruben/Projects/Cura/plugins/XmlMaterialProfile/__init__.py:13 +msgctxt "@label" +msgid "Material Profiles" +msgstr "Material Profiles" + +#: /home/ruben/Projects/Cura/plugins/XmlMaterialProfile/__init__.py:16 +msgctxt "@info:whatsthis" +msgid "Provides capabilities to read and write XML-based material profiles." +msgstr "Provides capabilities to read and write XML-based material profiles." + +#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:12 +msgctxt "@label" +msgid "Legacy Cura Profile Reader" +msgstr "Legacy Cura Profile Reader" + +#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Provides support for importing profiles from legacy Cura versions." +msgstr "Provides support for importing profiles from legacy Cura versions." + +#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:21 +msgctxt "@item:inlistbox" +msgid "Cura 15.04 profiles" +msgstr "Cura 15.04 profiles" + +#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:12 +msgctxt "@label" +msgid "GCode Profile Reader" +msgstr "GCode Profile Reader" + +#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Provides support for importing profiles from g-code files." +msgstr "Provides support for importing profiles from g-code files." + +#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:21 +msgctxt "@item:inlistbox" +msgid "G-code File" +msgstr "G-code File" + +#: /home/ruben/Projects/Cura/plugins/LayerView/__init__.py:13 +msgctxt "@label" +msgid "Layer View" +msgstr "Layer View" + +#: /home/ruben/Projects/Cura/plugins/LayerView/__init__.py:16 +msgctxt "@info:whatsthis" +msgid "Provides the Layer view." +msgstr "Provides the Layer view." + +#: /home/ruben/Projects/Cura/plugins/LayerView/__init__.py:20 +msgctxt "@item:inlistbox" +msgid "Layers" +msgstr "Layers" + +#: /home/ruben/Projects/Cura/plugins/LayerView/LayerView.py:58 +msgctxt "@info:status" +msgid "Cura does not accurately display layers when Wire Printing is enabled" +msgstr "Cura does not accurately display layers when Wire Printing is enabled" + +#: /home/ruben/Projects/Cura/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py:14 +msgctxt "@label" +msgid "Version Upgrade 2.1 to 2.2" +msgstr "Version Upgrade 2.1 to 2.2" + +#: /home/ruben/Projects/Cura/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py:17 +msgctxt "@info:whatsthis" +msgid "Upgrades configurations from Cura 2.1 to Cura 2.2." +msgstr "Upgrades configurations from Cura 2.1 to Cura 2.2." + +#: /home/ruben/Projects/Cura/plugins/ImageReader/__init__.py:12 +msgctxt "@label" +msgid "Image Reader" +msgstr "Image Reader" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Enables ability to generate printable geometry from 2D image files." +msgstr "Enables ability to generate printable geometry from 2D image files." + +#: /home/ruben/Projects/Cura/plugins/ImageReader/__init__.py:21 +msgctxt "@item:inlistbox" +msgid "JPG Image" +msgstr "JPG Image" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/__init__.py:25 +msgctxt "@item:inlistbox" +msgid "JPEG Image" +msgstr "JPEG Image" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/__init__.py:29 +msgctxt "@item:inlistbox" +msgid "PNG Image" +msgstr "PNG Image" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/__init__.py:33 +msgctxt "@item:inlistbox" +msgid "BMP Image" +msgstr "BMP Image" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/__init__.py:37 +msgctxt "@item:inlistbox" +msgid "GIF Image" +msgstr "GIF Image" + +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:232 +msgctxt "@info:status" +msgid "" +"Unable to slice with the current settings. Please check your settings for " +"errors." +msgstr "" +"Unable to slice with the current settings. Please check your settings for " +"errors." + +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:241 +msgctxt "@info:status" +msgid "" +"Nothing to slice because none of the models fit the build volume. Please " +"scale or rotate models to fit." +msgstr "" +"Nothing to slice because none of the models fit the build volume. Please " +"scale or rotate models to fit." + +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/__init__.py:13 +msgctxt "@label" +msgid "CuraEngine Backend" +msgstr "CuraEngine Backend" + +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Provides the link to the CuraEngine slicing backend." +msgstr "Provides the link to the CuraEngine slicing backend." + +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:45 +#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:180 +msgctxt "@info:status" +msgid "Processing Layers" +msgstr "Processing Layers" + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:14 +msgctxt "@label" +msgid "Per Model Settings Tool" +msgstr "Per Model Settings Tool" + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:17 +msgctxt "@info:whatsthis" +msgid "Provides the Per Model Settings." +msgstr "Provides the Per Model Settings." + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:21 +msgctxt "@label" +msgid "Per Model Settings" +msgstr "Per Model Settings" + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/__init__.py:22 +msgctxt "@info:tooltip" +msgid "Configure Per Model Settings" +msgstr "Configure Per Model Settings" + +#: /home/ruben/Projects/Cura/plugins/3MFReader/__init__.py:12 +msgctxt "@label" +msgid "3MF Reader" +msgstr "3MF Reader" + +#: /home/ruben/Projects/Cura/plugins/3MFReader/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Provides support for reading 3MF files." +msgstr "Provides support for reading 3MF files." + +#: /home/ruben/Projects/Cura/plugins/3MFReader/__init__.py:21 +msgctxt "@item:inlistbox" +msgid "3MF File" +msgstr "3MF File" + +#: /home/ruben/Projects/Cura/plugins/SolidView/__init__.py:12 +msgctxt "@label" +msgid "Solid View" +msgstr "Solid View" + +#: /home/ruben/Projects/Cura/plugins/SolidView/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Provides a normal solid mesh view." +msgstr "Provides a normal solid mesh view." + +#: /home/ruben/Projects/Cura/plugins/SolidView/__init__.py:19 +msgctxt "@item:inmenu" +msgid "Solid" +msgstr "Solid" + +#: /home/ruben/Projects/Cura/plugins/CuraProfileWriter/__init__.py:12 +msgctxt "@label" +msgid "Cura Profile Writer" +msgstr "Cura Profile Writer" + +#: /home/ruben/Projects/Cura/plugins/CuraProfileWriter/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Provides support for exporting Cura profiles." +msgstr "Provides support for exporting Cura profiles." + +#: /home/ruben/Projects/Cura/plugins/CuraProfileWriter/__init__.py:21 +#: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:21 +msgctxt "@item:inlistbox" +msgid "Cura Profile" +msgstr "Cura Profile" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/__init__.py:15 +msgctxt "@label" +msgid "Ultimaker machine actions" +msgstr "Ultimaker machine actions" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/__init__.py:18 +msgctxt "@info:whatsthis" +msgid "" +"Provides machine actions for Ultimaker machines (such as bed leveling " +"wizard, selecting upgrades, etc)" +msgstr "" +"Provides machine actions for Ultimaker machines (such as bed leveling " +"wizard, selecting upgrades, etc)" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelection.py:12 +msgctxt "@action" +msgid "Select upgrades" +msgstr "Select upgrades" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.py:10 +msgctxt "@action" +msgid "Upgrade Firmware" +msgstr "Upgrade Firmware" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py:13 +msgctxt "@action" +msgid "Checkup" +msgstr "Checkup" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.py:13 +msgctxt "@action" +msgid "Level build plate" +msgstr "Level build plate" + +#: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:12 +msgctxt "@label" +msgid "Cura Profile Reader" +msgstr "Cura Profile Reader" + +#: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:15 +msgctxt "@info:whatsthis" +msgid "Provides support for importing Cura profiles." +msgstr "Provides support for importing Cura profiles." + +#: /home/ruben/Projects/Cura/cura/PrinterOutputDevice.py:286 +msgctxt "@item:material" +msgid "No material loaded" +msgstr "No material loaded" + +#: /home/ruben/Projects/Cura/cura/PrinterOutputDevice.py:293 +msgctxt "@item:material" +msgid "Unknown material" +msgstr "Unknown material" + +#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:342 +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:79 +msgctxt "@title:window" +msgid "File Already Exists" +msgstr "File Already Exists" + +#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:343 +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:80 +#, python-brace-format +msgctxt "@label" +msgid "" +"The file {0} already exists. Are you sure you want to " +"overwrite it?" +msgstr "" +"The file {0} already exists. Are you sure you want to " +"overwrite it?" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:548 +msgctxt "@info:status" +msgid "" +"The selected material is imcompatible with the selected machine or " +"configuration." +msgstr "" +"The selected material is imcompatible with the selected machine or " +"configuration." + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:666 +msgctxt "@label" +msgid "You made changes to the following setting(s):" +msgstr "You made changes to the following setting(s):" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:671 +msgctxt "@window:title" +msgid "Switched profiles" +msgstr "Switched profiles" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:671 +msgctxt "@label" +msgid "Do you want to transfer your changed settings to this profile?" +msgstr "Do you want to transfer your changed settings to this profile?" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:672 +msgctxt "@label" +msgid "" +"If you transfer your settings they will override settings in the profile." +msgstr "" +"If you transfer your settings they will override settings in the profile." + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:765 +msgctxt "@label" +msgid "Nozzle" +msgstr "Nozzle" + +#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:966 +msgctxt "@info:status" +msgid "" +"Unable to find a quality profile for this combination. Default settings will " +"be used instead." +msgstr "" +"Unable to find a quality profile for this combination. Default settings will " +"be used instead." + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:95 +#, python-brace-format +msgctxt "@info:status" +msgid "" +"Failed to export profile to {0}: {1}" +msgstr "" +"Failed to export profile to {0}: {1}" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:100 +#, python-brace-format +msgctxt "@info:status" +msgid "" +"Failed to export profile to {0}: Writer plugin reported " +"failure." +msgstr "" +"Failed to export profile to {0}: Writer plugin reported " +"failure." + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:103 +#, python-brace-format +msgctxt "@info:status" +msgid "Exported profile to {0}" +msgstr "Exported profile to {0}" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:128 +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:139 +#, python-brace-format +msgctxt "@info:status" +msgid "" +"Failed to import profile from {0}: {1}" +msgstr "" +"Failed to import profile from {0}: {1}" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:145 +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:155 +#, python-brace-format +msgctxt "@info:status" +msgid "Successfully imported profile {0}" +msgstr "Successfully imported profile {0}" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:158 +#, python-brace-format +msgctxt "@info:status" +msgid "Successfully imported profiles {0}" +msgstr "Successfully imported profiles {0}" + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:161 +#, python-brace-format +msgctxt "@info:status" +msgid "Profile {0} has an unknown file type." +msgstr "Profile {0} has an unknown file type." + +#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:166 +msgctxt "@label" +msgid "Custom profile" +msgstr "Custom profile" + +#: /home/ruben/Projects/Cura/cura/BuildVolume.py:240 +msgctxt "@info:status" +msgid "" +"The build volume height has been reduced due to the value of the \"Print " +"Sequence\" setting to prevent the gantry from colliding with printed models." +msgstr "" +"The build volume height has been reduced due to the value of the \"Print " +"Sequence\" setting to prevent the gantry from colliding with printed models." + +#: /home/ruben/Projects/Cura/cura/CrashHandler.py:42 +msgctxt "@title:window" +msgid "Oops!" +msgstr "Oops!" + +#: /home/ruben/Projects/Cura/cura/CrashHandler.py:48 +msgctxt "@label" +msgid "" +"

A fatal exception has occurred that we could not recover from!

Please use the information below to post a bug report at http://github.com/Ultimaker/Cura/" +"issues

" +msgstr "" +"

A fatal exception has occurred that we could not recover from!

Please use the information below to post a bug report at http://github.com/Ultimaker/Cura/" +"issues

" + +#: /home/ruben/Projects/Cura/cura/CrashHandler.py:68 +msgctxt "@action:button" +msgid "Open Web Page" +msgstr "Open Web Page" + +#: /home/ruben/Projects/Cura/cura/CuraApplication.py:167 +msgctxt "@info:progress" +msgid "Loading machines..." +msgstr "Loading machines..." + +#: /home/ruben/Projects/Cura/cura/CuraApplication.py:390 +msgctxt "@info:progress" +msgid "Setting up scene..." +msgstr "Setting up scene..." + +#: /home/ruben/Projects/Cura/cura/CuraApplication.py:424 +msgctxt "@info:progress" +msgid "Loading interface..." +msgstr "Loading interface..." + +#: /home/ruben/Projects/Cura/cura/CuraApplication.py:536 +#, python-format +msgctxt "@info" +msgid "%(width).1f x %(depth).1f x %(height).1f mm" +msgstr "%(width).1f x %(depth).1f x %(height).1f mm" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:27 +msgctxt "@title" +msgid "Machine Settings" +msgstr "Machine Settings" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:38 +msgctxt "@label" +msgid "Please enter the correct settings for your printer below:" +msgstr "Please enter the correct settings for your printer below:" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:63 +msgctxt "@label" +msgid "Printer Settings" +msgstr "Printer Settings" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:74 +msgctxt "@label" +msgid "X (Width)" +msgstr "X (Width)" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:85 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:101 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:117 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:190 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:206 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:222 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:238 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:258 +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:278 +msgctxt "@label" +msgid "mm" +msgstr "mm" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:90 +msgctxt "@label" +msgid "Y (Depth)" +msgstr "Y (Depth)" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:106 +msgctxt "@label" +msgid "Z (Height)" +msgstr "Z (Height)" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:126 +msgctxt "@option:check" +msgid "Heated Bed" +msgstr "Heated Bed" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:133 +msgctxt "@option:check" +msgid "Machine Center is Zero" +msgstr "Machine Center is Zero" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:145 +msgctxt "@label" +msgid "GCode Flavor" +msgstr "GCode Flavor" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:168 +msgctxt "@label" +msgid "Printhead Settings" +msgstr "Printhead Settings" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:179 +msgctxt "@label" +msgid "X min" +msgstr "X min" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:195 +msgctxt "@label" +msgid "Y min" +msgstr "Y min" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:211 +msgctxt "@label" +msgid "X max" +msgstr "X max" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:227 +msgctxt "@label" +msgid "Y max" +msgstr "Y max" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:247 +msgctxt "@label" +msgid "Gantry height" +msgstr "Gantry height" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:267 +msgctxt "@label" +msgid "Nozzle size" +msgstr "Nozzle size" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:296 +msgctxt "@label" +msgid "Start Gcode" +msgstr "Start Gcode" + +#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:318 +msgctxt "@label" +msgid "End Gcode" +msgstr "End Gcode" + +#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:39 +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:105 +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:423 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:120 +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:77 +#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:38 +msgctxt "@action:button" +msgid "Close" +msgstr "Close" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:20 +msgctxt "@title:window" +msgid "Firmware Update" +msgstr "Firmware Update" + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:40 +msgctxt "@label" +msgid "Firmware update completed." +msgstr "Firmware update completed." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:45 +msgctxt "@label" +msgid "Starting firmware update, this may take a while." +msgstr "Starting firmware update, this may take a while." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:50 +msgctxt "@label" +msgid "Updating firmware." +msgstr "Updating firmware." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:59 +msgctxt "@label" +msgid "Firmware update failed due to an unknown error." +msgstr "Firmware update failed due to an unknown error." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:62 +msgctxt "@label" +msgid "Firmware update failed due to an communication error." +msgstr "Firmware update failed due to an communication error." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:65 +msgctxt "@label" +msgid "Firmware update failed due to an input/output error." +msgstr "Firmware update failed due to an input/output error." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:68 +msgctxt "@label" +msgid "Firmware update failed due to missing firmware." +msgstr "Firmware update failed due to missing firmware." + +#: /home/ruben/Projects/Cura/plugins/USBPrinting/FirmwareUpdateWindow.qml:71 +msgctxt "@label" +msgid "Unknown error code: %1" +msgstr "Unknown error code: %1" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:17 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Post Processing Plugin" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:48 +msgctxt "@label" +msgid "Scripts" +msgstr "Scripts" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:146 +msgctxt "@label" +msgid "Active Scripts" +msgstr "Active Scripts" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:434 +msgctxt "@label" +msgid "Done" +msgstr "Done" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:21 +msgctxt "@title:window" +msgid "Convert Image..." +msgstr "Convert Image..." + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:35 +msgctxt "@info:tooltip" +msgid "The maximum distance of each pixel from \"Base.\"" +msgstr "The maximum distance of each pixel from \"Base.\"" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:40 +msgctxt "@action:label" +msgid "Height (mm)" +msgstr "Height (mm)" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:58 +msgctxt "@info:tooltip" +msgid "The base height from the build plate in millimeters." +msgstr "The base height from the build plate in millimeters." + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:63 +msgctxt "@action:label" +msgid "Base (mm)" +msgstr "Base (mm)" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:81 +msgctxt "@info:tooltip" +msgid "The width in millimeters on the build plate." +msgstr "The width in millimeters on the build plate." + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:86 +msgctxt "@action:label" +msgid "Width (mm)" +msgstr "Width (mm)" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:105 +msgctxt "@info:tooltip" +msgid "The depth in millimeters on the build plate" +msgstr "The depth in millimeters on the build plate" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:110 +msgctxt "@action:label" +msgid "Depth (mm)" +msgstr "Depth (mm)" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:128 +msgctxt "@info:tooltip" +msgid "" +"By default, white pixels represent high points on the mesh and black pixels " +"represent low points on the mesh. Change this option to reverse the behavior " +"such that black pixels represent high points on the mesh and white pixels " +"represent low points on the mesh." +msgstr "" +"By default, white pixels represent high points on the mesh and black pixels " +"represent low points on the mesh. Change this option to reverse the behavior " +"such that black pixels represent high points on the mesh and white pixels " +"represent low points on the mesh." + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:141 +msgctxt "@item:inlistbox" +msgid "Lighter is higher" +msgstr "Lighter is higher" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:141 +msgctxt "@item:inlistbox" +msgid "Darker is higher" +msgstr "Darker is higher" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:151 +msgctxt "@info:tooltip" +msgid "The amount of smoothing to apply to the image." +msgstr "The amount of smoothing to apply to the image." + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:156 +msgctxt "@action:label" +msgid "Smoothing" +msgstr "Smoothing" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:184 +msgctxt "@action:button" +msgid "OK" +msgstr "OK" + +#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:191 +msgctxt "@action:button" +msgid "Cancel" +msgstr "Cancel" + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:34 +msgctxt "@label" +msgid "Print model with" +msgstr "Print model with" + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:274 +msgctxt "@action:button" +msgid "Select settings" +msgstr "Select settings" + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:314 +msgctxt "@title:window" +msgid "Select Settings to Customize for this model" +msgstr "Select Settings to Customize for this model" + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:338 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:91 +msgctxt "@label:textbox" +msgid "Filter..." +msgstr "Filter..." + +#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:362 +msgctxt "@label:checkbox" +msgid "Show all" +msgstr "Show all" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:27 +msgctxt "@title" +msgid "Build Plate Leveling" +msgstr "Build Plate Leveling" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:38 +msgctxt "@label" +msgid "" +"To make sure your prints will come out great, you can now adjust your " +"buildplate. When you click 'Move to Next Position' the nozzle will move to " +"the different positions that can be adjusted." +msgstr "" +"To make sure your prints will come out great, you can now adjust your " +"buildplate. When you click 'Move to Next Position' the nozzle will move to " +"the different positions that can be adjusted." + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:47 +msgctxt "@label" +msgid "" +"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." +msgstr "" +"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." + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:62 +msgctxt "@action:button" +msgid "Start Build Plate Leveling" +msgstr "Start Build Plate Leveling" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:74 +msgctxt "@action:button" +msgid "Move to Next Position" +msgstr "Move to Next Position" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:27 +msgctxt "@title" +msgid "Upgrade Firmware" +msgstr "Upgrade Firmware" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:38 +msgctxt "@label" +msgid "" +"Firmware is the piece of software running directly on your 3D printer. This " +"firmware controls the step motors, regulates the temperature and ultimately " +"makes your printer work." +msgstr "" +"Firmware is the piece of software running directly on your 3D printer. This " +"firmware controls the step motors, regulates the temperature and ultimately " +"makes your printer work." + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:48 +msgctxt "@label" +msgid "" +"The firmware shipping with new printers works, but new versions tend to have " +"more features and improvements." +msgstr "" +"The firmware shipping with new printers works, but new versions tend to have " +"more features and improvements." + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:62 +msgctxt "@action:button" +msgid "Automatically upgrade Firmware" +msgstr "Automatically upgrade Firmware" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:72 +msgctxt "@action:button" +msgid "Upload custom Firmware" +msgstr "Upload custom Firmware" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UpgradeFirmwareMachineAction.qml:83 +msgctxt "@title:window" +msgid "Select custom firmware" +msgstr "Select custom firmware" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:25 +msgctxt "@title" +msgid "Select Printer Upgrades" +msgstr "Select Printer Upgrades" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:37 +msgctxt "@label" +msgid "Please select any upgrades made to this Ultimaker Original" +msgstr "Please select any upgrades made to this Ultimaker Original" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:45 +msgctxt "@label" +msgid "Heated Build Plate (official kit or self-built)" +msgstr "Heated Build Plate (official kit or self-built)" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:27 +msgctxt "@title" +msgid "Check Printer" +msgstr "Check Printer" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:39 +msgctxt "@label" +msgid "" +"It's a good idea to do a few sanity checks on your Ultimaker. You can skip " +"this step if you know your machine is functional" +msgstr "" +"It's a good idea to do a few sanity checks on your Ultimaker. You can skip " +"this step if you know your machine is functional" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:53 +msgctxt "@action:button" +msgid "Start Printer Check" +msgstr "Start Printer Check" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:80 +msgctxt "@label" +msgid "Connection: " +msgstr "Connection: " + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89 +msgctxt "@info:status" +msgid "Connected" +msgstr "Connected" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89 +msgctxt "@info:status" +msgid "Not connected" +msgstr "Not connected" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:99 +msgctxt "@label" +msgid "Min endstop X: " +msgstr "Min endstop X: " + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151 +msgctxt "@info:status" +msgid "Works" +msgstr "Works" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:173 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234 +msgctxt "@info:status" +msgid "Not checked" +msgstr "Not checked" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:120 +msgctxt "@label" +msgid "Min endstop Y: " +msgstr "Min endstop Y: " + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:141 +msgctxt "@label" +msgid "Min endstop Z: " +msgstr "Min endstop Z: " + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:163 +msgctxt "@label" +msgid "Nozzle temperature check: " +msgstr "Nozzle temperature check: " + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248 +msgctxt "@action:button" +msgid "Stop Heating" +msgstr "Stop Heating" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187 +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248 +msgctxt "@action:button" +msgid "Start Heating" +msgstr "Start Heating" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:223 +msgctxt "@label" +msgid "Build plate temperature check:" +msgstr "Build plate temperature check:" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234 +msgctxt "@info:status" +msgid "Checked" +msgstr "Checked" + +#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:284 +msgctxt "@label" +msgid "Everything is in order! You're done with your CheckUp." +msgstr "Everything is in order! You're done with your CheckUp." + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:84 +msgctxt "@label:MonitorStatus" +msgid "Not connected to a printer" +msgstr "Not connected to a printer" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:86 +msgctxt "@label:MonitorStatus" +msgid "Printer does not accept commands" +msgstr "Printer does not accept commands" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:92 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:189 +msgctxt "@label:MonitorStatus" +msgid "In maintenance. Please check the printer" +msgstr "In maintenance. Please check the printer" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:97 +msgctxt "@label:MonitorStatus" +msgid "Lost connection with the printer" +msgstr "Lost connection with the printer" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:99 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:179 +msgctxt "@label:MonitorStatus" +msgid "Printing..." +msgstr "Printing..." + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:101 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:181 +msgctxt "@label:MonitorStatus" +msgid "Paused" +msgstr "Paused" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:103 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:183 +msgctxt "@label:MonitorStatus" +msgid "Preparing..." +msgstr "Preparing..." + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:105 +msgctxt "@label:MonitorStatus" +msgid "Please remove the print" +msgstr "Please remove the print" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:209 +msgctxt "@label:" +msgid "Resume" +msgstr "Resume" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:213 +msgctxt "@label:" +msgid "Pause" +msgstr "Pause" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:242 +msgctxt "@label:" +msgid "Abort Print" +msgstr "Abort Print" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:252 +msgctxt "@window:title" +msgid "Abort print" +msgstr "Abort print" + +#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:254 +msgctxt "@label" +msgid "Are you sure you want to abort the print?" +msgstr "Are you sure you want to abort the print?" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:47 +msgctxt "@label" +msgid "Display Name" +msgstr "Display Name" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:57 +msgctxt "@label" +msgid "Brand" +msgstr "Brand" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:67 +msgctxt "@label" +msgid "Material Type" +msgstr "Material Type" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:76 +msgctxt "@label" +msgid "Color" +msgstr "Color" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:110 +msgctxt "@label" +msgid "Properties" +msgstr "Properties" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:112 +msgctxt "@label" +msgid "Density" +msgstr "Density" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:125 +msgctxt "@label" +msgid "Diameter" +msgstr "Diameter" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:138 +msgctxt "@label" +msgid "Filament Cost" +msgstr "Filament Cost" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:147 +msgctxt "@label" +msgid "Filament weight" +msgstr "Filament weight" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:157 +msgctxt "@label" +msgid "Filament length" +msgstr "Filament length" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:166 +msgctxt "@label" +msgid "Cost per Meter (Approx.)" +msgstr "Cost per Meter (Approx.)" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:171 +msgctxt "@label" +msgid "%1/m" +msgstr "%1/m" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:177 +msgctxt "@label" +msgid "Description" +msgstr "Description" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:190 +msgctxt "@label" +msgid "Adhesion Information" +msgstr "Adhesion Information" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:208 +msgctxt "@label" +msgid "Print settings" +msgstr "Print settings" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:14 +msgctxt "@title:tab" +msgid "Setting Visibility" +msgstr "Setting Visibility" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:44 +msgctxt "@label:textbox" +msgid "Check all" +msgstr "Check all" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:26 +msgctxt "@title:column" +msgid "Setting" +msgstr "Setting" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:32 +msgctxt "@title:column" +msgid "Profile" +msgstr "Profile" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:38 +msgctxt "@title:column" +msgid "Current" +msgstr "Current" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:45 +msgctxt "@title:column" +msgid "Unit" +msgstr "Unit" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:14 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:430 +msgctxt "@title:tab" +msgid "General" +msgstr "General" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:72 +msgctxt "@label" +msgid "Interface" +msgstr "Interface" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:81 +msgctxt "@label" +msgid "Language:" +msgstr "Language:" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:93 +msgctxt "@item:inlistbox" +msgid "English" +msgstr "English" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:94 +msgctxt "@item:inlistbox" +msgid "Finnish" +msgstr "Finnish" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:95 +msgctxt "@item:inlistbox" +msgid "French" +msgstr "French" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:96 +msgctxt "@item:inlistbox" +msgid "German" +msgstr "German" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:97 +msgctxt "@item:inlistbox" +msgid "Italian" +msgstr "Italian" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:98 +msgctxt "@item:inlistbox" +msgid "Dutch" +msgstr "Dutch" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:99 +msgctxt "@item:inlistbox" +msgid "Spanish" +msgstr "Spanish" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:137 +msgctxt "@label" +msgid "" +"You will need to restart the application for language changes to have effect." +msgstr "" +"You will need to restart the application for language changes to have effect." + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:152 +msgctxt "@label" +msgid "Viewport behavior" +msgstr "Viewport behavior" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:160 +msgctxt "@info:tooltip" +msgid "" +"Highlight unsupported areas of the model in red. Without support these areas " +"will not print properly." +msgstr "" +"Highlight unsupported areas of the model in red. Without support these areas " +"will not print properly." + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:169 +msgctxt "@option:check" +msgid "Display overhang" +msgstr "Display overhang" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:176 +msgctxt "@info:tooltip" +msgid "" +"Moves the camera so the model is in the center of the view when an model is " +"selected" +msgstr "" +"Moves the camera so the model is in the center of the view when an model is " +"selected" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:181 +msgctxt "@action:button" +msgid "Center camera when item is selected" +msgstr "Center camera when item is selected" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:190 +msgctxt "@info:tooltip" +msgid "" +"Should models on the platform be moved so that they no longer intersect?" +msgstr "" +"Should models on the platform be moved so that they no longer intersect?" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:195 +msgctxt "@option:check" +msgid "Ensure models are kept apart" +msgstr "Ensure models are kept apart" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:203 +msgctxt "@info:tooltip" +msgid "Should models on the platform be moved down to touch the build plate?" +msgstr "Should models on the platform be moved down to touch the build plate?" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:208 +msgctxt "@option:check" +msgid "Automatically drop models to the build plate" +msgstr "Automatically drop models to the build plate" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:217 +msgctxt "@info:tooltip" +msgid "" +"Display 5 top layers in layer view or only the top-most layer. Rendering 5 " +"layers takes longer, but may show more information." +msgstr "" +"Display 5 top layers in layer view or only the top-most layer. Rendering 5 " +"layers takes longer, but may show more information." + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:222 +msgctxt "@action:button" +msgid "Display five top layers in layer view" +msgstr "Display five top layers in layer view" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:240 +msgctxt "@info:tooltip" +msgid "Should only the top layers be displayed in layerview?" +msgstr "Should only the top layers be displayed in layerview?" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:245 +msgctxt "@option:check" +msgid "Only display top layer(s) in layer view" +msgstr "Only display top layer(s) in layer view" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:261 +msgctxt "@label" +msgid "Opening files" +msgstr "Opening files" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:267 +msgctxt "@info:tooltip" +msgid "Should models be scaled to the build volume if they are too large?" +msgstr "Should models be scaled to the build volume if they are too large?" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:272 +msgctxt "@option:check" +msgid "Scale large models" +msgstr "Scale large models" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:281 +msgctxt "@info:tooltip" +msgid "" +"An model may appear extremely small if its unit is for example in meters " +"rather than millimeters. Should these models be scaled up?" +msgstr "" +"An model may appear extremely small if its unit is for example in meters " +"rather than millimeters. Should these models be scaled up?" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:286 +msgctxt "@option:check" +msgid "Scale extremely small models" +msgstr "Scale extremely small models" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:295 +msgctxt "@info:tooltip" +msgid "" +"Should a prefix based on the printer name be added to the print job name " +"automatically?" +msgstr "" +"Should a prefix based on the printer name be added to the print job name " +"automatically?" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:300 +msgctxt "@option:check" +msgid "Add machine prefix to job name" +msgstr "Add machine prefix to job name" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:317 +msgctxt "@label" +msgid "Privacy" +msgstr "Privacy" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:324 +msgctxt "@info:tooltip" +msgid "Should Cura check for updates when the program is started?" +msgstr "Should Cura check for updates when the program is started?" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:329 +msgctxt "@option:check" +msgid "Check for updates on start" +msgstr "Check for updates on start" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:339 +msgctxt "@info:tooltip" +msgid "" +"Should anonymous data about your print be sent to Ultimaker? Note, no " +"models, IP addresses or other personally identifiable information is sent or " +"stored." +msgstr "" +"Should anonymous data about your print be sent to Ultimaker? Note, no " +"models, IP addresses or other personally identifiable information is sent or " +"stored." + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:344 +msgctxt "@option:check" +msgid "Send (anonymous) print information" +msgstr "Send (anonymous) print information" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:15 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:435 +msgctxt "@title:tab" +msgid "Printers" +msgstr "Printers" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:37 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:71 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:127 +msgctxt "@action:button" +msgid "Activate" +msgstr "Activate" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:44 +msgctxt "@action:button" +msgid "Add" +msgstr "Add" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:50 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:111 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:152 +msgctxt "@action:button" +msgid "Remove" +msgstr "Remove" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:57 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:118 +msgctxt "@action:button" +msgid "Rename" +msgstr "Rename" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:146 +msgctxt "@label" +msgid "Printer type:" +msgstr "Printer type:" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:154 +msgctxt "@label" +msgid "Connection:" +msgstr "Connection:" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:159 +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:21 +msgctxt "@info:status" +msgid "The printer is not connected." +msgstr "The printer is not connected." + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:165 +msgctxt "@label" +msgid "State:" +msgstr "State:" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:185 +msgctxt "@label:MonitorStatus" +msgid "Waiting for someone to clear the build plate" +msgstr "Waiting for someone to clear the build plate" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:191 +msgctxt "@label:MonitorStatus" +msgid "Aborting print..." +msgstr "Aborting print..." + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:194 +msgctxt "@label:MonitorStatus" +msgid "Waiting for a printjob" +msgstr "Waiting for a printjob" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:15 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:439 +msgctxt "@title:tab" +msgid "Profiles" +msgstr "Profiles" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:49 +msgctxt "@label" +msgid "Protected profiles" +msgstr "Protected profiles" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:49 +msgctxt "@label" +msgid "Custom profiles" +msgstr "Custom profiles" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:80 +msgctxt "@label" +msgid "Create" +msgstr "Create" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:96 +msgctxt "@label" +msgid "Duplicate" +msgstr "Duplicate" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:129 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:159 +msgctxt "@action:button" +msgid "Import" +msgstr "Import" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:135 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:166 +msgctxt "@action:button" +msgid "Export" +msgstr "Export" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:142 +msgctxt "@label %1 is printer name" +msgid "Printer: %1" +msgstr "Printer: %1" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:181 +msgctxt "@action:button" +msgid "Update profile with current settings" +msgstr "Update profile with current settings" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:189 +msgctxt "@action:button" +msgid "Discard current settings" +msgstr "Discard current settings" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:206 +msgctxt "@action:label" +msgid "" +"This profile uses the defaults specified by the printer, so it has no " +"settings in the list below." +msgstr "" +"This profile uses the defaults specified by the printer, so it has no " +"settings in the list below." + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:213 +msgctxt "@action:label" +msgid "Your current settings match the selected profile." +msgstr "Your current settings match the selected profile." + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:229 +msgctxt "@title:tab" +msgid "Global Settings" +msgstr "Global Settings" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:271 +msgctxt "@title:window" +msgid "Rename Profile" +msgstr "Rename Profile" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:284 +msgctxt "@title:window" +msgid "Create Profile" +msgstr "Create Profile" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:298 +msgctxt "@title:window" +msgid "Duplicate Profile" +msgstr "Duplicate Profile" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:312 +msgctxt "@window:title" +msgid "Import Profile" +msgstr "Import Profile" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:320 +msgctxt "@title:window" +msgid "Import Profile" +msgstr "Import Profile" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:348 +msgctxt "@title:window" +msgid "Export Profile" +msgstr "Export Profile" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:15 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:437 +msgctxt "@title:tab" +msgid "Materials" +msgstr "Materials" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:106 +msgctxt "" +"@action:label %1 is printer name, %2 is how this printer names variants, %3 " +"is variant name" +msgid "Printer: %1, %2: %3" +msgstr "Printer: %1, %2: %3" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:110 +msgctxt "@action:label %1 is printer name" +msgid "Printer: %1" +msgstr "Printer: %1" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:134 +msgctxt "@action:button" +msgid "Duplicate" +msgstr "Duplicate" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:189 +msgctxt "@action:button" +msgid "Edit" +msgstr "Edit" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:256 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:264 +msgctxt "@title:window" +msgid "Import Material" +msgstr "Import Material" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:265 +msgctxt "@info:status" +msgid "" +"Could not import material %1: %2" +msgstr "" +"Could not import material %1: %2" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:269 +msgctxt "@info:status" +msgid "Successfully imported material %1" +msgstr "Successfully imported material %1" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:287 +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:302 +msgctxt "@title:window" +msgid "Export Material" +msgstr "Export Material" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:306 +msgctxt "@info:status" +msgid "" +"Failed to export material to %1: %2" +msgstr "" +"Failed to export material to %1: %2" + +#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:312 +msgctxt "@info:status" +msgid "Successfully exported material to %1" +msgstr "Successfully exported material to %1" + +#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:18 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:701 +msgctxt "@title:window" +msgid "Add Printer" +msgstr "Add Printer" + +#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:183 +msgctxt "@action:button" +msgid "Add Printer" +msgstr "Add Printer" + +#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:176 +msgctxt "@label" +msgid "00h 00min" +msgstr "00h 00min" + +#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:212 +msgctxt "@label" +msgid "%1 m / ~ %2 g" +msgstr "%1 m / ~ %2 g" + +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:15 +msgctxt "@title:window" +msgid "About Cura" +msgstr "About Cura" + +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:57 +msgctxt "@label" +msgid "End-to-end solution for fused filament 3D printing." +msgstr "End-to-end solution for fused filament 3D printing." + +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:69 +msgctxt "@info:credit" +msgid "" +"Cura has been developed by Ultimaker B.V. in cooperation with the community." +msgstr "" +"Cura has been developed by Ultimaker B.V. in cooperation with the community." + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:189 +msgctxt "@action:menu" +msgid "Copy value to all extruders" +msgstr "Copy value to all extruders" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:203 +msgctxt "@action:menu" +msgid "Hide this setting" +msgstr "Hide this setting" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:209 +msgctxt "@action:menu" +msgid "Configure setting visiblity..." +msgstr "Configure setting visiblity..." + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:75 +msgctxt "@label" +msgid "" +"Some hidden settings use values different from their normal calculated " +"value.\n" +"\n" +"Click to make these settings visible." +msgstr "" +"Some hidden settings use values different from their normal calculated " +"value.\n" +"\n" +"Click to make these settings visible." + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:59 +msgctxt "@label" +msgid "Affects" +msgstr "Affects" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:64 +msgctxt "@label" +msgid "Affected By" +msgstr "Affected By" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:155 +msgctxt "@label" +msgid "" +"This setting is always shared between all extruders. Changing it here will " +"change the value for all extruders" +msgstr "" +"This setting is always shared between all extruders. Changing it here will " +"change the value for all extruders" + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:158 +msgctxt "@label" +msgid "The value is resolved from per-extruder values " +msgstr "The value is resolved from per-extruder values " + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:186 +msgctxt "@label" +msgid "" +"This setting has a value that is different from the profile.\n" +"\n" +"Click to restore the value of the profile." +msgstr "" +"This setting has a value that is different from the profile.\n" +"\n" +"Click to restore the value of the profile." + +#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:262 +msgctxt "@label" +msgid "" +"This setting is normally calculated, but it currently has an absolute value " +"set.\n" +"\n" +"Click to restore the calculated value." +msgstr "" +"This setting is normally calculated, but it currently has an absolute value " +"set.\n" +"\n" +"Click to restore the calculated value." + +#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:190 +msgctxt "@label:listbox" +msgid "Print Setup" +msgstr "Print Setup" + +#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:261 +msgctxt "@label" +msgid "Printer Monitor" +msgstr "Printer Monitor" + +#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:382 +msgctxt "@title:tab" +msgid "Simple" +msgstr "Simple" + +#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:383 +msgctxt "@title:tab" +msgid "Advanced" +msgstr "Advanced" + +#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:18 +#: /home/ruben/Projects/Cura/resources/qml/Menus/NozzleMenu.qml:18 +msgctxt "@title:menuitem %1 is the value from the printer" +msgid "Automatic: %1" +msgstr "Automatic: %1" + +#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12 +msgctxt "@title:menu menubar:toplevel" +msgid "&View" +msgstr "&View" + +#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:13 +msgctxt "@title:menu menubar:file" +msgid "Open &Recent" +msgstr "Open &Recent" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:31 +msgctxt "@label" +msgid "Temperatures" +msgstr "Temperatures" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:39 +msgctxt "@label" +msgid "Hotend" +msgstr "Hotend" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:49 +msgctxt "@label" +msgid "Build plate" +msgstr "Build plate" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:57 +msgctxt "@label" +msgid "Active print" +msgstr "Active print" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:62 +msgctxt "@label" +msgid "Job Name" +msgstr "Job Name" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:68 +msgctxt "@label" +msgid "Printing Time" +msgstr "Printing Time" + +#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:74 +msgctxt "@label" +msgid "Estimated time left" +msgstr "Estimated time left" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:62 +msgctxt "@action:inmenu" +msgid "Toggle Fu&ll Screen" +msgstr "Toggle Fu&ll Screen" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:69 +msgctxt "@action:inmenu menubar:edit" +msgid "&Undo" +msgstr "&Undo" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:79 +msgctxt "@action:inmenu menubar:edit" +msgid "&Redo" +msgstr "&Redo" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:89 +msgctxt "@action:inmenu menubar:file" +msgid "&Quit" +msgstr "&Quit" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:97 +msgctxt "@action:inmenu" +msgid "Configure Cura..." +msgstr "Configure Cura..." + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:104 +msgctxt "@action:inmenu menubar:printer" +msgid "&Add Printer..." +msgstr "&Add Printer..." + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:110 +msgctxt "@action:inmenu menubar:printer" +msgid "Manage Pr&inters..." +msgstr "Manage Pr&inters..." + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:117 +msgctxt "@action:inmenu" +msgid "Manage Materials..." +msgstr "Manage Materials..." + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:125 +msgctxt "@action:inmenu menubar:profile" +msgid "&Update profile with current settings" +msgstr "&Update profile with current settings" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:133 +msgctxt "@action:inmenu menubar:profile" +msgid "&Discard current settings" +msgstr "&Discard current settings" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141 +msgctxt "@action:inmenu menubar:profile" +msgid "&Create profile from current settings..." +msgstr "&Create profile from current settings..." + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:147 +msgctxt "@action:inmenu menubar:profile" +msgid "Manage Profiles..." +msgstr "Manage Profiles..." + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:154 +msgctxt "@action:inmenu menubar:help" +msgid "Show Online &Documentation" +msgstr "Show Online &Documentation" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:162 +msgctxt "@action:inmenu menubar:help" +msgid "Report a &Bug" +msgstr "Report a &Bug" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:170 +msgctxt "@action:inmenu menubar:help" +msgid "&About..." +msgstr "&About..." + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:177 +msgctxt "@action:inmenu menubar:edit" +msgid "Delete &Selection" +msgstr "Delete &Selection" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:187 +msgctxt "@action:inmenu" +msgid "Delete Model" +msgstr "Delete Model" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:195 +msgctxt "@action:inmenu" +msgid "Ce&nter Model on Platform" +msgstr "Ce&nter Model on Platform" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:201 +msgctxt "@action:inmenu menubar:edit" +msgid "&Group Models" +msgstr "&Group Models" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:211 +msgctxt "@action:inmenu menubar:edit" +msgid "Ungroup Models" +msgstr "Ungroup Models" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:221 +msgctxt "@action:inmenu menubar:edit" +msgid "&Merge Models" +msgstr "&Merge Models" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:231 +msgctxt "@action:inmenu" +msgid "&Duplicate Model" +msgstr "&Duplicate Model" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:238 +msgctxt "@action:inmenu menubar:edit" +msgid "&Select All Models" +msgstr "&Select All Models" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:248 +msgctxt "@action:inmenu menubar:edit" +msgid "&Clear Build Plate" +msgstr "&Clear Build Plate" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:258 +msgctxt "@action:inmenu menubar:file" +msgid "Re&load All Models" +msgstr "Re&load All Models" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:266 +msgctxt "@action:inmenu menubar:edit" +msgid "Reset All Model Positions" +msgstr "Reset All Model Positions" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:273 +msgctxt "@action:inmenu menubar:edit" +msgid "Reset All Model &Transformations" +msgstr "Reset All Model &Transformations" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:280 +msgctxt "@action:inmenu menubar:file" +msgid "&Open File..." +msgstr "&Open File..." + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:288 +msgctxt "@action:inmenu menubar:help" +msgid "Show Engine &Log..." +msgstr "Show Engine &Log..." + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:296 +msgctxt "@action:inmenu menubar:help" +msgid "Show Configuration Folder" +msgstr "Show Configuration Folder" + +#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:303 +msgctxt "@action:menu" +msgid "Configure setting visibility..." +msgstr "Configure setting visibility..." + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:24 +msgctxt "@label:PrintjobStatus" +msgid "Please load a 3d model" +msgstr "Please load a 3d model" + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:30 +msgctxt "@label:PrintjobStatus" +msgid "Preparing to slice..." +msgstr "Preparing to slice..." + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:32 +msgctxt "@label:PrintjobStatus" +msgid "Slicing..." +msgstr "Slicing..." + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:34 +msgctxt "@label:PrintjobStatus %1 is target operation" +msgid "Ready to %1" +msgstr "Ready to %1" + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:36 +msgctxt "@label:PrintjobStatus" +msgid "Unable to Slice" +msgstr "Unable to Slice" + +#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:175 +msgctxt "@info:tooltip" +msgid "Select the active output device" +msgstr "Select the active output device" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:19 +msgctxt "@title:window" +msgid "Cura" +msgstr "Cura" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:69 +msgctxt "@title:menu menubar:toplevel" +msgid "&File" +msgstr "&File" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:81 +msgctxt "@action:inmenu menubar:file" +msgid "&Save Selection to File" +msgstr "&Save Selection to File" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:89 +msgctxt "@title:menu menubar:file" +msgid "Save &All" +msgstr "Save &All" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:116 +msgctxt "@title:menu menubar:toplevel" +msgid "&Edit" +msgstr "&Edit" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:132 +msgctxt "@title:menu" +msgid "&View" +msgstr "&View" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:137 +msgctxt "@title:menu" +msgid "&Settings" +msgstr "&Settings" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:139 +msgctxt "@title:menu menubar:toplevel" +msgid "&Printer" +msgstr "&Printer" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:149 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:161 +msgctxt "@title:menu" +msgid "&Material" +msgstr "&Material" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:150 +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:162 +msgctxt "@title:menu" +msgid "&Profile" +msgstr "&Profile" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:154 +msgctxt "@action:inmenu" +msgid "Set as Active Extruder" +msgstr "Set as Active Extruder" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:172 +msgctxt "@title:menu menubar:toplevel" +msgid "E&xtensions" +msgstr "E&xtensions" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:205 +msgctxt "@title:menu menubar:toplevel" +msgid "P&references" +msgstr "P&references" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:213 +msgctxt "@title:menu menubar:toplevel" +msgid "&Help" +msgstr "&Help" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:291 +msgctxt "@action:button" +msgid "Open File" +msgstr "Open File" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:364 +msgctxt "@action:button" +msgid "View Mode" +msgstr "View Mode" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:433 +msgctxt "@title:tab" +msgid "Settings" +msgstr "Settings" + +#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:642 +msgctxt "@title:window" +msgid "Open file" +msgstr "Open file" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:38 +msgctxt "@label" +msgid "Infill:" +msgstr "Infill:" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:169 +msgctxt "@label" +msgid "Hollow" +msgstr "Hollow" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:173 +msgctxt "@label" +msgid "No (0%) infill will leave your model hollow at the cost of low strength" +msgstr "" +"No (0%) infill will leave your model hollow at the cost of low strength" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:177 +msgctxt "@label" +msgid "Light" +msgstr "Light" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:181 +msgctxt "@label" +msgid "Light (20%) infill will give your model an average strength" +msgstr "Light (20%) infill will give your model an average strength" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:185 +msgctxt "@label" +msgid "Dense" +msgstr "Dense" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:189 +msgctxt "@label" +msgid "Dense (50%) infill will give your model an above average strength" +msgstr "Dense (50%) infill will give your model an above average strength" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:193 +msgctxt "@label" +msgid "Solid" +msgstr "Solid" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:197 +msgctxt "@label" +msgid "Solid (100%) infill will make your model completely solid" +msgstr "Solid (100%) infill will make your model completely solid" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:219 +msgctxt "@label" +msgid "Helper Parts:" +msgstr "Helper Parts:" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:233 +msgctxt "@option:check" +msgid "Print Build Plate Adhesion" +msgstr "Print Build Plate Adhesion" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:263 +msgctxt "@label" +msgid "" +"Enable printing a brim or raft. This will add a flat area around or under " +"your object which is easy to cut off afterwards." +msgstr "" +"Enable printing a brim or raft. This will add a flat area around or under " +"your object which is easy to cut off afterwards." + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:295 +msgctxt "@option:check" +msgid "Print Support Structure" +msgstr "Print Support Structure" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:312 +msgctxt "@label" +msgid "" +"Enable printing support structures. This will build up supporting structures " +"below the model to prevent the model from sagging or printing in mid air." +msgstr "" +"Enable printing support structures. This will build up supporting structures " +"below the model to prevent the model from sagging or printing in mid air." + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:355 +msgctxt "@label" +msgid "" +"Select which extruder to use for support. This will build up supporting " +"structures below the model to prevent the model from sagging or printing in " +"mid air." +msgstr "" +"Select which extruder to use for support. This will build up supporting " +"structures below the model to prevent the model from sagging or printing in " +"mid air." + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:381 +msgctxt "@label" +msgid "Don't print support" +msgstr "Don't print support" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:386 +msgctxt "@label" +msgid "Print support using %1" +msgstr "Print support using %1" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:407 +msgctxt "@label" +msgid "" +"Need help improving your prints? Read the Ultimaker " +"Troubleshooting Guides" +msgstr "" +"Need help improving your prints? Read the Ultimaker " +"Troubleshooting Guides" + +#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15 +msgctxt "@title:window" +msgid "Engine Log" +msgstr "Engine Log" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:41 +msgctxt "@label:listbox" +msgid "Printer:" +msgstr "Printer:" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:189 +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:197 +msgctxt "@label" +msgid "Material" +msgstr "Material" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:276 +msgctxt "@label" +msgid "Profile:" +msgstr "Profile:" + +#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:313 +msgctxt "@tooltip" +msgid "" +"Some setting values are different from the values stored in the profile.\n" +"\n" +"Click to open the profile manager." +msgstr "" +"Some setting values are different from the values stored in the profile.\n" +"\n" +"Click to open the profile manager." diff --git a/resources/i18n/en/fdmprinter.json.po b/resources/i18n/en/fdmprinter.json.po index 4578306bfb..ae0bef18b2 100644 --- a/resources/i18n/en/fdmprinter.json.po +++ b/resources/i18n/en/fdmprinter.json.po @@ -1,2498 +1,2809 @@ -msgid "" -msgstr "" -"Project-Id-Version: Uranium json setting files\n" -"Report-Msgid-Bugs-To: http://github.com/ultimaker/uranium\n" -"POT-Creation-Date: 2016-01-18 11:54+0000\n" -"PO-Revision-Date: 2016-01-26 08:37+0100\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Language: en\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: fdmprinter.json -msgctxt "machine label" -msgid "Machine" -msgstr "Machine" - -#: fdmprinter.json -msgctxt "machine_nozzle_size label" -msgid "Nozzle Diameter" -msgstr "Nozzle Diameter" - -#: fdmprinter.json -msgctxt "machine_nozzle_size description" -msgid "The inner diameter of the nozzle." -msgstr "The inner diameter of the nozzle." - -#: fdmprinter.json -msgctxt "resolution label" -msgid "Quality" -msgstr "Quality" - -#: fdmprinter.json -msgctxt "layer_height label" -msgid "Layer Height" -msgstr "Layer Height" - -#: fdmprinter.json -msgctxt "layer_height description" -msgid "" -"The height of each layer, in mm. Normal quality prints are 0.1mm, high " -"quality is 0.06mm. You can go up to 0.25mm with an Ultimaker for very fast " -"prints at low quality. For most purposes, layer heights between 0.1 and " -"0.2mm give a good tradeoff of speed and surface finish." -msgstr "The height of each layer, in mm. Normal quality prints are 0.1 mm, high quality is 0.06 mm. You can go up to 0.25 mm with an Ultimaker for very fast prints at low quality. For most purposes, layer heights between 0.1 and 0.2 mm give a good trade-off between speed and surface finish." - -#: fdmprinter.json -msgctxt "layer_height_0 label" -msgid "Initial Layer Height" -msgstr "Initial Layer Height" - -#: fdmprinter.json -msgctxt "layer_height_0 description" -msgid "" -"The layer height of the bottom layer. A thicker bottom layer makes sticking " -"to the bed easier." -msgstr "The layer height of the bottom layer. A thicker bottom layer makes adhesion to the bed easier." - -#: fdmprinter.json -msgctxt "line_width label" -msgid "Line Width" -msgstr "Line Width" - -#: fdmprinter.json -msgctxt "line_width description" -msgid "" -"Width of a single line. Each line will be printed with this width in mind. " -"Generally the width of each line should correspond to the width of your " -"nozzle, but for the outer wall and top/bottom surface smaller line widths " -"may be chosen, for higher quality." -msgstr "Width of a single line. Each line will be printed with this width in mind. Generally, the width of each line should correspond to the width of your nozzle, but smaller line widths may be chosen for the outer wall and top/bottom surface for higher quality there." - -#: fdmprinter.json -msgctxt "wall_line_width label" -msgid "Wall Line Width" -msgstr "Wall Line Width" - -#: fdmprinter.json -msgctxt "wall_line_width description" -msgid "" -"Width of a single shell line. Each line of the shell will be printed with " -"this width in mind." -msgstr "Width of a single shell line. Each line of the shell will be printed to obtain this width." - -#: fdmprinter.json -msgctxt "wall_line_width_0 label" -msgid "Outer Wall Line Width" -msgstr "Outer Wall Line Width" - -#: fdmprinter.json -msgctxt "wall_line_width_0 description" -msgid "" -"Width of the outermost shell line. By printing a thinner outermost wall line " -"you can print higher details with a larger nozzle." -msgstr "Width of the outermost shell line. By printing a thinner outermost wall line, you can print a higher level of detail with a larger nozzle." - -#: fdmprinter.json -msgctxt "wall_line_width_x label" -msgid "Other Walls Line Width" -msgstr "Other Walls Line Width" - -#: fdmprinter.json -msgctxt "wall_line_width_x description" -msgid "" -"Width of a single shell line for all shell lines except the outermost one." -msgstr "Width of a single shell line for all shell lines except the outermost one." - -#: fdmprinter.json -msgctxt "skirt_line_width label" -msgid "Skirt line width" -msgstr "Skirt line width" - -#: fdmprinter.json -msgctxt "skirt_line_width description" -msgid "Width of a single skirt line." -msgstr "Width of a single skirt line." - -#: fdmprinter.json -msgctxt "skin_line_width label" -msgid "Top/bottom line width" -msgstr "Top/bottom line width" - -#: fdmprinter.json -msgctxt "skin_line_width description" -msgid "" -"Width of a single top/bottom printed line, used to fill up the top/bottom " -"areas of a print." -msgstr "Width of a single top/bottom printed line, used to fill up the top/bottom areas of a print." - -#: fdmprinter.json -msgctxt "infill_line_width label" -msgid "Infill line width" -msgstr "Infill line width" - -#: fdmprinter.json -msgctxt "infill_line_width description" -msgid "Width of the inner infill printed lines." -msgstr "Width of the inner infill printed lines." - -#: fdmprinter.json -msgctxt "support_line_width label" -msgid "Support line width" -msgstr "Support line width" - -#: fdmprinter.json -msgctxt "support_line_width description" -msgid "Width of the printed support structures lines." -msgstr "Width of the printed support structures lines." - -#: fdmprinter.json -msgctxt "support_roof_line_width label" -msgid "Support Roof line width" -msgstr "Support Roof line width" - -#: fdmprinter.json -msgctxt "support_roof_line_width description" -msgid "" -"Width of a single support roof line, used to fill the top of the support." -msgstr "Width of a single support roof line, used to fill the top of the support." - -#: fdmprinter.json -msgctxt "shell label" -msgid "Shell" -msgstr "Shell" - -#: fdmprinter.json -msgctxt "shell_thickness label" -msgid "Shell Thickness" -msgstr "Shell Thickness" - -#: fdmprinter.json -msgctxt "shell_thickness description" -msgid "" -"The thickness of the outside shell in the horizontal and vertical direction. " -"This is used in combination with the nozzle size to define the number of " -"perimeter lines and the thickness of those perimeter lines. This is also " -"used to define the number of solid top and bottom layers." -msgstr "The thickness of the outside shell in the horizontal and vertical direction. This is used in combination with the nozzle size to define the number of perimeter lines and the thickness of those perimeter lines. This is also used to define the number of solid top and bottom layers." - -#: fdmprinter.json -msgctxt "wall_thickness label" -msgid "Wall Thickness" -msgstr "Wall Thickness" - -#: fdmprinter.json -msgctxt "wall_thickness description" -msgid "" -"The thickness of the outside walls in the horizontal direction. This is used " -"in combination with the nozzle size to define the number of perimeter lines " -"and the thickness of those perimeter lines." -msgstr "The thickness of the outside walls in the horizontal direction. This is used in combination with the nozzle size to define the number of perimeter lines and the thickness of those perimeter lines." - -#: fdmprinter.json -msgctxt "wall_line_count label" -msgid "Wall Line Count" -msgstr "Wall Line Count" - -#: fdmprinter.json -msgctxt "wall_line_count description" -msgid "" -"Number of shell lines. These lines are called perimeter lines in other tools " -"and impact the strength and structural integrity of your print." -msgstr "Number of shell lines. These lines are called perimeter lines in other tools and affect the strength and structural integrity of your print." - -#: fdmprinter.json -msgctxt "alternate_extra_perimeter label" -msgid "Alternate Extra Wall" -msgstr "Alternate Extra Wall" - -#: fdmprinter.json -msgctxt "alternate_extra_perimeter description" -msgid "" -"Make an extra wall at every second layer, so that infill will be caught " -"between an extra wall above and one below. This results in a better cohesion " -"between infill and walls, but might have an impact on the surface quality." -msgstr "Make an extra wall at every second layer, so that infill will be caught between an extra wall above and one below. This results in better cohesion between infill and walls, but could affect the surface quality." - -#: fdmprinter.json -msgctxt "top_bottom_thickness label" -msgid "Bottom/Top Thickness" -msgstr "Bottom/Top Thickness" - -#: fdmprinter.json -msgctxt "top_bottom_thickness description" -msgid "" -"This controls the thickness of the bottom and top layers. The number of " -"solid layers put down is calculated from the layer thickness and this value. " -"Having this value a multiple of the layer thickness makes sense. Keep it " -"near your wall thickness to make an evenly strong part." -msgstr "This controls the thickness of the bottom and top layers. The number of solid layers put down is calculated from the layer thickness and this value. It is logical to make this value a multiple of the layer thickness. Keep it close to your wall thickness to make a uniformly strong part." - -#: fdmprinter.json -msgctxt "top_thickness label" -msgid "Top Thickness" -msgstr "Top Thickness" - -#: fdmprinter.json -msgctxt "top_thickness description" -msgid "" -"This controls the thickness of the top layers. The number of solid layers " -"printed is calculated from the layer thickness and this value. Having this " -"value be a multiple of the layer thickness makes sense. Keep it near your " -"wall thickness to make an evenly strong part." -msgstr "This controls the thickness of the top layers. The number of solid layers printed is calculated from the layer thickness and this value. It is logical to make this value a multiple of the layer thickness. Keep it close to your wall thickness to make a uniformly strong part." - -#: fdmprinter.json -msgctxt "top_layers label" -msgid "Top Layers" -msgstr "Top Layers" - -#: fdmprinter.json -msgctxt "top_layers description" -msgid "This controls the number of top layers." -msgstr "This controls the number of top layers." - -#: fdmprinter.json -msgctxt "bottom_thickness label" -msgid "Bottom Thickness" -msgstr "Bottom Thickness" - -#: fdmprinter.json -msgctxt "bottom_thickness description" -msgid "" -"This controls the thickness of the bottom layers. The number of solid layers " -"printed is calculated from the layer thickness and this value. Having this " -"value be a multiple of the layer thickness makes sense. And keep it near to " -"your wall thickness to make an evenly strong part." -msgstr "This controls the thickness of the bottom layers. The number of solid layers printed is calculated from the layer thickness and this value. It is logical to make this value a multiple of the layer thickness. Keep it close to your wall thickness to make a uniformly strong part." - -#: fdmprinter.json -msgctxt "bottom_layers label" -msgid "Bottom Layers" -msgstr "Bottom Layers" - -#: fdmprinter.json -msgctxt "bottom_layers description" -msgid "This controls the amount of bottom layers." -msgstr "This controls the number of bottom layers." - -#: fdmprinter.json -msgctxt "remove_overlapping_walls_enabled label" -msgid "Remove Overlapping Wall Parts" -msgstr "Remove Overlapping Wall Parts" - -#: fdmprinter.json -msgctxt "remove_overlapping_walls_enabled description" -msgid "" -"Remove parts of a wall which share an overlap which would result in " -"overextrusion in some places. These overlaps occur in thin pieces in a model " -"and sharp corners." -msgstr "Remove parts of a wall that share an overlap that would result in over-extrusion in some places. These overlaps occur in thin parts and sharp corners in models." - -#: fdmprinter.json -msgctxt "remove_overlapping_walls_0_enabled label" -msgid "Remove Overlapping Outer Wall Parts" -msgstr "Remove Overlapping Outer Wall Parts" - -#: fdmprinter.json -msgctxt "remove_overlapping_walls_0_enabled description" -msgid "" -"Remove parts of an outer wall which share an overlap which would result in " -"overextrusion in some places. These overlaps occur in thin pieces in a model " -"and sharp corners." -msgstr "Remove parts of an outer wall that share an overlap that would result in over-extrusion in some places. These overlaps occur in thin parts and sharp corners in models." - -#: fdmprinter.json -msgctxt "remove_overlapping_walls_x_enabled label" -msgid "Remove Overlapping Other Wall Parts" -msgstr "Remove Overlapping Other Wall Parts" - -#: fdmprinter.json -msgctxt "remove_overlapping_walls_x_enabled description" -msgid "" -"Remove parts of an inner wall which share an overlap which would result in " -"overextrusion in some places. These overlaps occur in thin pieces in a model " -"and sharp corners." -msgstr "Remove parts of an inner wall that share an overlap that would result in over-extrusion in some places. These overlaps occur in thin parts and sharp corners in models." - -#: fdmprinter.json -msgctxt "travel_compensate_overlapping_walls_enabled label" -msgid "Compensate Wall Overlaps" -msgstr "Compensate Wall Overlaps" - -#: fdmprinter.json -msgctxt "travel_compensate_overlapping_walls_enabled description" -msgid "" -"Compensate the flow for parts of a wall being laid down where there already " -"is a piece of a wall. These overlaps occur in thin pieces in a model. Gcode " -"generation might be slowed down considerably." -msgstr "Compensate the flow for parts of a wall being laid down where there already is a piece of a wall. These overlaps occur in thin pieces in models. Gcode generation could be slowed down considerably." - -#: fdmprinter.json -msgctxt "fill_perimeter_gaps label" -msgid "Fill Gaps Between Walls" -msgstr "Fill Gaps Between Walls" - -#: fdmprinter.json -msgctxt "fill_perimeter_gaps description" -msgid "" -"Fill the gaps created by walls where they would otherwise be overlapping. " -"This will also fill thin walls. Optionally only the gaps occurring within " -"the top and bottom skin can be filled." -msgstr "Fill the gaps created by walls where they would otherwise be overlapping. This will also fill thin walls. Optionally only the gaps occurring within the top and bottom skin can be filled." - -#: fdmprinter.json -msgctxt "fill_perimeter_gaps option nowhere" -msgid "Nowhere" -msgstr "Nowhere" - -#: fdmprinter.json -msgctxt "fill_perimeter_gaps option everywhere" -msgid "Everywhere" -msgstr "Everywhere" - -#: fdmprinter.json -msgctxt "fill_perimeter_gaps option skin" -msgid "Skin" -msgstr "Skin" - -#: fdmprinter.json -msgctxt "top_bottom_pattern label" -msgid "Bottom/Top Pattern" -msgstr "Bottom/Top Pattern" - -#: fdmprinter.json -msgctxt "top_bottom_pattern description" -msgid "" -"Pattern of the top/bottom solid fill. This is normally done with lines to " -"get the best possible finish, but in some cases a concentric fill gives a " -"nicer end result." -msgstr "Pattern of the top/bottom solid fill. This is normally done with lines to get the best possible finish, but in some cases a concentric fill gives a better end result." - -#: fdmprinter.json -msgctxt "top_bottom_pattern option lines" -msgid "Lines" -msgstr "Lines" - -#: fdmprinter.json -msgctxt "top_bottom_pattern option concentric" -msgid "Concentric" -msgstr "Concentric" - -#: fdmprinter.json -msgctxt "top_bottom_pattern option zigzag" -msgid "Zig Zag" -msgstr "Zig Zag" - -#: fdmprinter.json -msgctxt "skin_no_small_gaps_heuristic label" -msgid "Ignore small Z gaps" -msgstr "Ignore small Z gaps" - -#: fdmprinter.json -msgctxt "skin_no_small_gaps_heuristic description" -msgid "" -"When the model has small vertical gaps, about 5% extra computation time can " -"be spent on generating top and bottom skin in these narrow spaces. In such a " -"case set this setting to false." -msgstr "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such a case, set this setting to ‘false’." - -#: fdmprinter.json -msgctxt "skin_alternate_rotation label" -msgid "Alternate Skin Rotation" -msgstr "Alternate Skin Rotation" - -#: fdmprinter.json -msgctxt "skin_alternate_rotation description" -msgid "" -"Alternate between diagonal skin fill and horizontal + vertical skin fill. " -"Although the diagonal directions can print quicker, this option can improve " -"the printing quality by reducing the pillowing effect." -msgstr "Alternate between diagonal skin fill and horizontal + vertical skin fill. Although the diagonal directions can print more quickly, this option can improve printing quality by reducing the pillowing effect." - -#: fdmprinter.json -msgctxt "skin_outline_count label" -msgid "Extra Skin Wall Count" -msgstr "Extra Skin Wall Count" - -#: fdmprinter.json -msgctxt "skin_outline_count description" -msgid "" -"Number of lines around skin regions. Using one or two skin perimeter lines " -"can greatly improve roofs which would start in the middle of infill cells." -msgstr "Number of lines around skin regions. Using one or two skin perimeter lines can greatly improve roofs that would start in the middle of infill cells." - -#: fdmprinter.json -msgctxt "xy_offset label" -msgid "Horizontal expansion" -msgstr "Horizontal expansion" - -#: fdmprinter.json -msgctxt "xy_offset description" -msgid "" -"Amount of offset applied to all polygons in each layer. Positive values can " -"compensate for too big holes; negative values can compensate for too small " -"holes." -msgstr "Amount of offset applied to all polygons in each layer. Positive values can compensate for too big holes; negative values can compensate for too small holes." - -#: fdmprinter.json -msgctxt "z_seam_type label" -msgid "Z Seam Alignment" -msgstr "Z Seam Alignment" - -#: fdmprinter.json -msgctxt "z_seam_type description" -msgid "" -"Starting point of each path in a layer. When paths in consecutive layers " -"start at the same point a vertical seam may show on the print. When aligning " -"these at the back, the seam is easiest to remove. When placed randomly the " -"inaccuracies at the paths' start will be less noticeable. When taking the " -"shortest path the print will be quicker." -msgstr "Starting point of each path in a layer. When paths in consecutive layers start at the same point, a vertical seam may show on the print. The seams are easiest to remove when they are aligned at the back. The inaccuracies at the paths' start will be less noticeable when placed randomly. The print will be quicker when taking the shortest path." - -#: fdmprinter.json -msgctxt "z_seam_type option back" -msgid "Back" -msgstr "Back" - -#: fdmprinter.json -msgctxt "z_seam_type option shortest" -msgid "Shortest" -msgstr "Shortest" - -#: fdmprinter.json -msgctxt "z_seam_type option random" -msgid "Random" -msgstr "Random" - -#: fdmprinter.json -msgctxt "infill label" -msgid "Infill" -msgstr "Infill" - -#: fdmprinter.json -msgctxt "infill_sparse_density label" -msgid "Infill Density" -msgstr "Infill Density" - -#: fdmprinter.json -msgctxt "infill_sparse_density description" -msgid "" -"This controls how densely filled the insides of your print will be. For a " -"solid part use 100%, for a hollow part use 0%. A value around 20% is usually " -"enough. This setting won't affect the outside of the print and only adjusts " -"how strong the part becomes." -msgstr "This controls how densely the insides of your print will be filled. For a solid part use 100%, for a hollow part use 0%. A value around 20% is usually enough. This setting won't affect the outside of the print and only adjusts how strong the part will be." - -#: fdmprinter.json -msgctxt "infill_line_distance label" -msgid "Line distance" -msgstr "Line distance" - -#: fdmprinter.json -msgctxt "infill_line_distance description" -msgid "Distance between the printed infill lines." -msgstr "Distance between the printed infill lines." - -#: fdmprinter.json -msgctxt "infill_pattern label" -msgid "Infill Pattern" -msgstr "Infill Pattern" - -#: fdmprinter.json -msgctxt "infill_pattern description" -msgid "" -"Cura defaults to switching between grid and line infill, but with this " -"setting visible you can control this yourself. The line infill swaps " -"direction on alternate layers of infill, while the grid prints the full " -"cross-hatching on each layer of infill." -msgstr "Cura defaults to switching between grid and line infill, but when this setting is visible, you can control this yourself. The line infill swaps direction on alternate layers of infill, while the grid prints the full cross-hatching on each layer of infill." - -#: fdmprinter.json -msgctxt "infill_pattern option grid" -msgid "Grid" -msgstr "Grid" - -#: fdmprinter.json -msgctxt "infill_pattern option lines" -msgid "Lines" -msgstr "Lines" - -#: fdmprinter.json -msgctxt "infill_pattern option triangles" -msgid "Triangles" -msgstr "Triangles" - -#: fdmprinter.json -msgctxt "infill_pattern option concentric" -msgid "Concentric" -msgstr "Concentric" - -#: fdmprinter.json -msgctxt "infill_pattern option zigzag" -msgid "Zig Zag" -msgstr "Zig Zag" - -#: fdmprinter.json -msgctxt "infill_overlap label" -msgid "Infill Overlap" -msgstr "Infill Overlap" - -#: fdmprinter.json -msgctxt "infill_overlap description" -msgid "" -"The amount of overlap between the infill and the walls. A slight overlap " -"allows the walls to connect firmly to the infill." -msgstr "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill." - -#: fdmprinter.json -msgctxt "infill_wipe_dist label" -msgid "Infill Wipe Distance" -msgstr "Infill Wipe Distance" - -#: fdmprinter.json -msgctxt "infill_wipe_dist description" -msgid "" -"Distance of a travel move inserted after every infill line, to make the " -"infill stick to the walls better. This option is similar to infill overlap, " -"but without extrusion and only on one end of the infill line." -msgstr "Distance of a travel move inserted after every infill line, to make the infill stick to the walls better. This option is similar to infill overlap, but without extrusion and only at one end of the infill line." - -#: fdmprinter.json -msgctxt "infill_sparse_thickness label" -msgid "Infill Thickness" -msgstr "Infill Thickness" - -#: fdmprinter.json -msgctxt "infill_sparse_thickness description" -msgid "" -"The thickness of the sparse infill. This is rounded to a multiple of the " -"layerheight and used to print the sparse-infill in fewer, thicker layers to " -"save printing time." -msgstr "The thickness of the sparse infill. This is rounded to a multiple of the layer height and used to print the sparse-infill in fewer, thicker layers to save printing time." - -#: fdmprinter.json -msgctxt "infill_before_walls label" -msgid "Infill Before Walls" -msgstr "Infill Before Walls" - -#: fdmprinter.json -msgctxt "infill_before_walls description" -msgid "" -"Print the infill before printing the walls. Printing the walls first may " -"lead to more accurate walls, but overhangs print worse. Printing the infill " -"first leads to sturdier walls, but the infill pattern might sometimes show " -"through the surface." -msgstr "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but worse overhang prints. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface." - -#: fdmprinter.json -msgctxt "material label" -msgid "Material" -msgstr "Material" - -#: fdmprinter.json -msgctxt "material_flow_dependent_temperature label" -msgid "Auto Temperature" -msgstr "Auto Temperature" - -#: fdmprinter.json -msgctxt "material_flow_dependent_temperature description" -msgid "" -"Change the temperature for each layer automatically with the average flow " -"speed of that layer." -msgstr "Change the temperature for each layer automatically with the average flow speed of that layer." - -#: fdmprinter.json -msgctxt "material_print_temperature label" -msgid "Printing Temperature" -msgstr "Printing Temperature" - -#: fdmprinter.json -msgctxt "material_print_temperature description" -msgid "" -"The temperature used for printing. Set at 0 to pre-heat yourself. For PLA a " -"value of 210C is usually used.\n" -"For ABS a value of 230C or higher is required." -msgstr "The temperature used for printing. Set to 0 for manual pre-heating. For PLA a value of 210C is usually used.\nFor ABS a value of 230C or higher is required." - -#: fdmprinter.json -msgctxt "material_flow_temp_graph label" -msgid "Flow Temperature Graph" -msgstr "Flow Temperature Graph" - -#: fdmprinter.json -msgctxt "material_flow_temp_graph description" -msgid "" -"Data linking material flow (in mm3 per second) to temperature (degrees " -"Celsius)." -msgstr "Data linking material flow (in mm3 per second) to temperature (degrees Celsius)." - -#: fdmprinter.json -msgctxt "material_standby_temperature label" -msgid "Standby Temperature" -msgstr "Standby Temperature" - -#: fdmprinter.json -msgctxt "material_standby_temperature description" -msgid "" -"The temperature of the nozzle when another nozzle is currently used for " -"printing." -msgstr "The temperature of the nozzle when another nozzle is currently in use for printing." - -#: fdmprinter.json -msgctxt "material_extrusion_cool_down_speed label" -msgid "Extrusion Cool Down Speed Modifier" -msgstr "Extrusion Cool Down Speed Modifier" - -#: fdmprinter.json -msgctxt "material_extrusion_cool_down_speed description" -msgid "" -"The extra speed by which the nozzle cools while extruding. The same value is " -"used to signify the heat up speed lost when heating up while extruding." -msgstr "The extra speed by which the nozzle cools while extruding. The same value is used to signify the heat-up speed lost when heating up while extruding." - -#: fdmprinter.json -msgctxt "material_bed_temperature label" -msgid "Bed Temperature" -msgstr "Bed Temperature" - -#: fdmprinter.json -msgctxt "material_bed_temperature description" -msgid "" -"The temperature used for the heated printer bed. Set at 0 to pre-heat it " -"yourself." -msgstr "The temperature used for the heated printer bed. Set to 0 for manual pre-heating." - -#: fdmprinter.json -msgctxt "material_diameter label" -msgid "Diameter" -msgstr "Diameter" - -#: fdmprinter.json -msgctxt "material_diameter description" -msgid "" -"The diameter of your filament needs to be measured as accurately as " -"possible.\n" -"If you cannot measure this value you will have to calibrate it; a higher " -"number means less extrusion, a smaller number generates more extrusion." -msgstr "The diameter of your filament needs to be measured as accurately as possible.\nIf you cannot measure this value you will have to calibrate it; a higher number means less extrusion; a lower number generates more extrusion." - -#: fdmprinter.json -msgctxt "material_flow label" -msgid "Flow" -msgstr "Flow" - -#: fdmprinter.json -msgctxt "material_flow description" -msgid "" -"Flow compensation: the amount of material extruded is multiplied by this " -"value." -msgstr "Flow compensation: the amount of material extruded is multiplied by this value." - -#: fdmprinter.json -msgctxt "retraction_enable label" -msgid "Enable Retraction" -msgstr "Enable Retraction" - -#: fdmprinter.json -msgctxt "retraction_enable description" -msgid "" -"Retract the filament when the nozzle is moving over a non-printed area. " -"Details about the retraction can be configured in the advanced tab." -msgstr "Retract the filament when the nozzle is moving over a non-printed area. Details about the retraction can be configured in the advanced tab." - -#: fdmprinter.json -msgctxt "retraction_amount label" -msgid "Retraction Distance" -msgstr "Retraction Distance" - -#: fdmprinter.json -msgctxt "retraction_amount description" -msgid "" -"The amount of retraction: Set at 0 for no retraction at all. A value of " -"4.5mm seems to generate good results for 3mm filament in bowden tube fed " -"printers." -msgstr "The amount of retraction: Set at 0 for no retraction at all. A value of 4.5 mm seems to produce good results for 3 mm filament in bowden tube fed printers." - -#: fdmprinter.json -msgctxt "retraction_speed label" -msgid "Retraction Speed" -msgstr "Retraction Speed" - -#: fdmprinter.json -msgctxt "retraction_speed description" -msgid "" -"The speed at which the filament is retracted. A higher retraction speed " -"works better, but a very high retraction speed can lead to filament grinding." -msgstr "The speed at which the filament is retracted. A higher retraction speed works better, but a very high retraction speed can lead to filament grinding." - -#: fdmprinter.json -msgctxt "retraction_retract_speed label" -msgid "Retraction Retract Speed" -msgstr "Retraction Retract Speed" - -#: fdmprinter.json -msgctxt "retraction_retract_speed description" -msgid "" -"The speed at which the filament is retracted. A higher retraction speed " -"works better, but a very high retraction speed can lead to filament grinding." -msgstr "The speed at which the filament is retracted. A higher retraction speed works better, but a very high retraction speed can lead to filament grinding." - -#: fdmprinter.json -msgctxt "retraction_prime_speed label" -msgid "Retraction Prime Speed" -msgstr "Retraction Prime Speed" - -#: fdmprinter.json -msgctxt "retraction_prime_speed description" -msgid "The speed at which the filament is pushed back after retraction." -msgstr "The speed at which the filament is pushed back after retraction." - -#: fdmprinter.json -msgctxt "retraction_extra_prime_amount label" -msgid "Retraction Extra Prime Amount" -msgstr "Retraction Extra Prime Amount" - -#: fdmprinter.json -msgctxt "retraction_extra_prime_amount description" -msgid "" -"The amount of material extruded after a retraction. During a travel move, " -"some material might get lost and so we need to compensate for this." -msgstr "The amount of material extruded after a retraction. Some material can be lost during a travel move, which needs to be compensated." - -#: fdmprinter.json -msgctxt "retraction_min_travel label" -msgid "Retraction Minimum Travel" -msgstr "Retraction Minimum Travel" - -#: fdmprinter.json -msgctxt "retraction_min_travel description" -msgid "" -"The minimum distance of travel needed for a retraction to happen at all. " -"This helps to get fewer retractions in a small area." -msgstr "The minimum distance of travel needed for a retraction to happen at all. This helps to get fewer retractions in a small area." - -#: fdmprinter.json -msgctxt "retraction_count_max label" -msgid "Maximum Retraction Count" -msgstr "Maximum Retraction Count" - -#: fdmprinter.json -msgctxt "retraction_count_max description" -msgid "" -"This setting limits the number of retractions occurring within the Minimum " -"Extrusion Distance Window. Further retractions within this window will be " -"ignored. This avoids retracting repeatedly on the same piece of filament, as " -"that can flatten the filament and cause grinding issues." -msgstr "This setting limits the number of retractions occurring within the Minimum Extrusion Distance Window. Further retractions within this window will be ignored. This avoids retracting on the same piece of filament repeatedly, as this can flatten the filament and cause grinding issues." - -#: fdmprinter.json -msgctxt "retraction_extrusion_window label" -msgid "Minimum Extrusion Distance Window" -msgstr "Minimum Extrusion Distance Window" - -#: fdmprinter.json -msgctxt "retraction_extrusion_window description" -msgid "" -"The window in which the Maximum Retraction Count is enforced. This value " -"should be approximately the same as the Retraction distance, so that " -"effectively the number of times a retraction passes the same patch of " -"material is limited." -msgstr "The window in which the Maximum Retraction Count is enforced. This value should be approximately the same as the Retraction distance, which effectively limits the number of times a retraction passes the same patch of material." - -#: fdmprinter.json -msgctxt "retraction_hop label" -msgid "Z Hop when Retracting" -msgstr "Z Hop when Retracting" - -#: fdmprinter.json -msgctxt "retraction_hop description" -msgid "" -"Whenever a retraction is done, the head is lifted by this amount to travel " -"over the print. A value of 0.075 works well. This feature has a large " -"positive effect on delta towers." -msgstr "Whenever a retraction is done, the head is lifted by this amount to travel over the print. A value of 0.075 works well. This feature has a large positive effect on delta towers." - -#: fdmprinter.json -msgctxt "speed label" -msgid "Speed" -msgstr "Speed" - -#: fdmprinter.json -msgctxt "speed_print label" -msgid "Print Speed" -msgstr "Print Speed" - -#: fdmprinter.json -msgctxt "speed_print description" -msgid "" -"The speed at which printing happens. A well-adjusted Ultimaker can reach " -"150mm/s, but for good quality prints you will want to print slower. Printing " -"speed depends on a lot of factors, so you will need to experiment with " -"optimal settings for this." -msgstr "The speed at which printing happens. A well-adjusted Ultimaker can reach 150 mm/s, but you will want to print slower for good quality prints. Printing speed depends on many factors, so you will need to experiment with optimal settings for this." - -#: fdmprinter.json -msgctxt "speed_infill label" -msgid "Infill Speed" -msgstr "Infill Speed" - -#: fdmprinter.json -msgctxt "speed_infill description" -msgid "" -"The speed at which infill parts are printed. Printing the infill faster can " -"greatly reduce printing time, but this can negatively affect print quality." -msgstr "The speed at which infill parts are printed. Printing the infill faster can greatly reduce printing time, but this can negatively affect print quality." - -#: fdmprinter.json -msgctxt "speed_wall label" -msgid "Shell Speed" -msgstr "Shell Speed" - -#: fdmprinter.json -msgctxt "speed_wall description" -msgid "" -"The speed at which the shell is printed. Printing the outer shell at a lower " -"speed improves the final skin quality." -msgstr "The speed at which the shell is printed. Printing the outer shell at a lower speed improves the final skin quality." - -#: fdmprinter.json -msgctxt "speed_wall_0 label" -msgid "Outer Shell Speed" -msgstr "Outer Shell Speed" - -#: fdmprinter.json -msgctxt "speed_wall_0 description" -msgid "" -"The speed at which the outer shell is printed. Printing the outer shell at a " -"lower speed improves the final skin quality. However, having a large " -"difference between the inner shell speed and the outer shell speed will " -"effect quality in a negative way." -msgstr "The speed at which the outer shell is printed. Printing the outer shell at a lower speed improves the final skin quality. However, having a large difference between the inner shell speed and the outer shell speed will negatively affect quality." - -#: fdmprinter.json -msgctxt "speed_wall_x label" -msgid "Inner Shell Speed" -msgstr "Inner Shell Speed" - -#: fdmprinter.json -msgctxt "speed_wall_x description" -msgid "" -"The speed at which all inner shells are printed. Printing the inner shell " -"faster than the outer shell will reduce printing time. It works well to set " -"this in between the outer shell speed and the infill speed." -msgstr "The speed at which all inner shells are printed. Printing the inner shell faster than the outer shell will reduce printing time. It works well to set this to a value between the outer shell speed and the infill speed." - -#: fdmprinter.json -msgctxt "speed_topbottom label" -msgid "Top/Bottom Speed" -msgstr "Top/Bottom Speed" - -#: fdmprinter.json -msgctxt "speed_topbottom description" -msgid "" -"Speed at which top/bottom parts are printed. Printing the top/bottom faster " -"can greatly reduce printing time, but this can negatively affect print " -"quality." -msgstr "Speed at which top/bottom parts are printed. Printing the top/bottom faster can greatly reduce printing time, but this can negatively affect print quality." - -#: fdmprinter.json -msgctxt "speed_support label" -msgid "Support Speed" -msgstr "Support Speed" - -#: fdmprinter.json -msgctxt "speed_support description" -msgid "" -"The speed at which exterior support is printed. Printing exterior supports " -"at higher speeds can greatly improve printing time. The surface quality of " -"exterior support is usually not important anyway, so higher speeds can be " -"used." -msgstr "The speed at which exterior support is printed. Printing exterior supports at higher speeds can greatly improve printing time. The surface quality of exterior support is usually not important anyway, so higher speeds can be used." - -#: fdmprinter.json -msgctxt "speed_support_lines label" -msgid "Support Wall Speed" -msgstr "Support Wall Speed" - -#: fdmprinter.json -msgctxt "speed_support_lines description" -msgid "" -"The speed at which the walls of exterior support are printed. Printing the " -"walls at higher speeds can improve the overall duration." -msgstr "The speed at which the walls of exterior support are printed. Printing the walls at higher speeds can improve the overall duration." - -#: fdmprinter.json -msgctxt "speed_support_roof label" -msgid "Support Roof Speed" -msgstr "Support Roof Speed" - -#: fdmprinter.json -msgctxt "speed_support_roof description" -msgid "" -"The speed at which the roofs of exterior support are printed. Printing the " -"support roof at lower speeds can improve overhang quality." -msgstr "The speed at which the roofs of exterior support are printed. Printing the support roof at lower speeds can improve overhang quality." - -#: fdmprinter.json -msgctxt "speed_travel label" -msgid "Travel Speed" -msgstr "Travel Speed" - -#: fdmprinter.json -msgctxt "speed_travel description" -msgid "" -"The speed at which travel moves are done. A well-built Ultimaker can reach " -"speeds of 250mm/s, but some machines might have misaligned layers then." -msgstr "The speed at which travel moves are done. A well-built Ultimaker can reach speeds of 250 mm/s, but some machines may then have misaligned layers." - -#: fdmprinter.json -msgctxt "speed_layer_0 label" -msgid "Bottom Layer Speed" -msgstr "Bottom Layer Speed" - -#: fdmprinter.json -msgctxt "speed_layer_0 description" -msgid "" -"The print speed for the bottom layer: You want to print the first layer " -"slower so it sticks better to the printer bed." -msgstr "The print speed for the bottom layer: You want to print the first layer slower so it sticks to the printer bed better." - -#: fdmprinter.json -msgctxt "skirt_speed label" -msgid "Skirt Speed" -msgstr "Skirt Speed" - -#: fdmprinter.json -msgctxt "skirt_speed description" -msgid "" -"The speed at which the skirt and brim are printed. Normally this is done at " -"the initial layer speed, but sometimes you might want to print the skirt at " -"a different speed." -msgstr "The speed at which the skirt and brim are printed. Normally this is done at the initial layer speed, but sometimes you might want to print the skirt at a different speed." - -#: fdmprinter.json -msgctxt "speed_slowdown_layers label" -msgid "Number of Slower Layers" -msgstr "Number of Slower Layers" - -#: fdmprinter.json -msgctxt "speed_slowdown_layers description" -msgid "" -"The first few layers are printed slower than the rest of the object, this to " -"get better adhesion to the printer bed and improve the overall success rate " -"of prints. The speed is gradually increased over these layers. 4 layers of " -"speed-up is generally right for most materials and printers." -msgstr "The first few layers are printed slower than the rest of the object to get better adhesion to the printer bed and improve the overall success rate of prints. The speed is gradually increased over these layers. 4 layers of speed-up is generally right for most materials and printers." - -#: fdmprinter.json -msgctxt "travel label" -msgid "Travel" -msgstr "Travel" - -#: fdmprinter.json -msgctxt "retraction_combing label" -msgid "Enable Combing" -msgstr "Enable Combing" - -#: fdmprinter.json -msgctxt "retraction_combing description" -msgid "" -"Combing keeps the head within the interior of the print whenever possible " -"when traveling from one part of the print to another and does not use " -"retraction. If combing is disabled, the print head moves straight from the " -"start point to the end point and it will always retract." -msgstr "Combing keeps the head within the interior of the print whenever possible when traveling from one part of the print to another and does not use retraction. If combing is disabled, the print head moves straight from the start point to the end point and it will always retract." - -#: fdmprinter.json -msgctxt "travel_avoid_other_parts label" -msgid "Avoid Printed Parts" -msgstr "Avoid Printed Parts" - -#: fdmprinter.json -msgctxt "travel_avoid_other_parts description" -msgid "Avoid other parts when traveling between parts." -msgstr "Avoid other parts when traveling between parts." - -#: fdmprinter.json -msgctxt "travel_avoid_distance label" -msgid "Avoid Distance" -msgstr "Avoid Distance" - -#: fdmprinter.json -msgctxt "travel_avoid_distance description" -msgid "The distance to stay clear of parts which are avoided during travel." -msgstr "The distance to stay clear of parts which are avoided during travel." - -#: fdmprinter.json -msgctxt "coasting_enable label" -msgid "Enable Coasting" -msgstr "Enable Coasting" - -#: fdmprinter.json -msgctxt "coasting_enable description" -msgid "" -"Coasting replaces the last part of an extrusion path with a travel path. The " -"oozed material is used to lay down the last piece of the extrusion path in " -"order to reduce stringing." -msgstr "Coasting replaces the last part of an extrusion path with a travel path. The oozed material is used to lay down the last piece of the extrusion path in order to reduce stringing." - -#: fdmprinter.json -msgctxt "coasting_volume label" -msgid "Coasting Volume" -msgstr "Coasting Volume" - -#: fdmprinter.json -msgctxt "coasting_volume description" -msgid "" -"The volume otherwise oozed. This value should generally be close to the " -"nozzle diameter cubed." -msgstr "The volume otherwise oozed. This value should generally be close to the nozzle diameter cubed." - -#: fdmprinter.json -msgctxt "coasting_min_volume label" -msgid "Minimal Volume Before Coasting" -msgstr "Minimal Volume Before Coasting" - -#: fdmprinter.json -msgctxt "coasting_min_volume description" -msgid "" -"The least volume an extrusion path should have to coast the full amount. For " -"smaller extrusion paths, less pressure has been built up in the bowden tube " -"and so the coasted volume is scaled linearly. This value should always be " -"larger than the Coasting Volume." -msgstr "The lowest volume an extrusion path should have to coast the full amount. For smaller extrusion paths, less pressure has been built up in the bowden tube and so the coasted volume is scaled linearly. This value should always be larger than the Coasting Volume." - -#: fdmprinter.json -msgctxt "coasting_speed label" -msgid "Coasting Speed" -msgstr "Coasting Speed" - -#: fdmprinter.json -msgctxt "coasting_speed description" -msgid "" -"The speed by which to move during coasting, relative to the speed of the " -"extrusion path. A value slightly under 100% is advised, since during the " -"coasting move the pressure in the bowden tube drops." -msgstr "The speed by which to move during coasting relative to the speed of the extrusion path. A value slightly under 100% is advised, as the pressure in the bowden tube drops during the coasting move." - -#: fdmprinter.json -msgctxt "cooling label" -msgid "Cooling" -msgstr "Cooling" - -#: fdmprinter.json -msgctxt "cool_fan_enabled label" -msgid "Enable Cooling Fan" -msgstr "Enable Cooling Fan" - -#: fdmprinter.json -msgctxt "cool_fan_enabled description" -msgid "" -"Enable the cooling fan during the print. The extra cooling from the cooling " -"fan helps parts with small cross sections that print each layer quickly." -msgstr "Enable the cooling fan during the print. The extra cooling from the cooling fan helps parts with small cross sections that print each layer quickly." - -#: fdmprinter.json -msgctxt "cool_fan_speed label" -msgid "Fan Speed" -msgstr "Fan Speed" - -#: fdmprinter.json -msgctxt "cool_fan_speed description" -msgid "Fan speed used for the print cooling fan on the printer head." -msgstr "Fan speed used for the print cooling fan on the printer head." - -#: fdmprinter.json -msgctxt "cool_fan_speed_min label" -msgid "Minimum Fan Speed" -msgstr "Minimum Fan Speed" - -#: fdmprinter.json -msgctxt "cool_fan_speed_min description" -msgid "" -"Normally the fan runs at the minimum fan speed. If the layer is slowed down " -"due to minimum layer time, the fan speed adjusts between minimum and maximum " -"fan speed." -msgstr "The fan normally runs at the minimum fan speed. If the layer is slowed down due to minimum layer time, the fan speed adjusts between minimum and maximum fan speed." - -#: fdmprinter.json -msgctxt "cool_fan_speed_max label" -msgid "Maximum Fan Speed" -msgstr "Maximum Fan Speed" - -#: fdmprinter.json -msgctxt "cool_fan_speed_max description" -msgid "" -"Normally the fan runs at the minimum fan speed. If the layer is slowed down " -"due to minimum layer time, the fan speed adjusts between minimum and maximum " -"fan speed." -msgstr "The fan normally runs at the minimum fan speed. If the layer is slowed down due to minimum layer time, the fan speed adjusts between minimum and maximum fan speed." - -#: fdmprinter.json -msgctxt "cool_fan_full_at_height label" -msgid "Fan Full on at Height" -msgstr "Fan Full on at Height" - -#: fdmprinter.json -msgctxt "cool_fan_full_at_height description" -msgid "" -"The height at which the fan is turned on completely. For the layers below " -"this the fan speed is scaled linearly with the fan off for the first layer." -msgstr "The height at which the fan runs at full speed. For the layers below this the fan speed is scaled linearly with the fan off for the first layer." - -#: fdmprinter.json -msgctxt "cool_fan_full_layer label" -msgid "Fan Full on at Layer" -msgstr "Fan Full on at Layer" - -#: fdmprinter.json -msgctxt "cool_fan_full_layer description" -msgid "" -"The layer number at which the fan is turned on completely. For the layers " -"below this the fan speed is scaled linearly with the fan off for the first " -"layer." -msgstr "The layer number at which the fan runs at full speed. For the layers below this the fan speed is scaled linearly with the fan off for the first layer." - -#: fdmprinter.json -msgctxt "cool_min_layer_time label" -msgid "Minimum Layer Time" -msgstr "Minimum Layer Time" - -#: fdmprinter.json -msgctxt "cool_min_layer_time description" -msgid "" -"The minimum time spent in a layer: Gives the layer time to cool down before " -"the next one is put on top. If a layer would print in less time, then the " -"printer will slow down to make sure it has spent at least this many seconds " -"printing the layer." -msgstr "The minimum time spent in a layer: Gives the layer time to cool down before the next one is put on top. If a layer would print in less time, then the printer will slow down to make sure it has spent at least this many seconds printing the layer." - -#: fdmprinter.json -msgctxt "cool_min_layer_time_fan_speed_max label" -msgid "Minimum Layer Time Full Fan Speed" -msgstr "Minimum Layer Time Full Fan Speed" - -#: fdmprinter.json -msgctxt "cool_min_layer_time_fan_speed_max description" -msgid "" -"The minimum time spent in a layer which will cause the fan to be at maximum " -"speed. The fan speed increases linearly from minimum fan speed for layers " -"taking the minimum layer time to maximum fan speed for layers taking the " -"time specified here." -msgstr "The minimum time spent in a layer that will cause the fan to be at maximum speed. The fan speed increases linearly from minimum fan speed for layers taking the minimum layer time to maximum fan speed for layers taking the time specified here." - -#: fdmprinter.json -msgctxt "cool_min_speed label" -msgid "Minimum Speed" -msgstr "Minimum Speed" - -#: fdmprinter.json -msgctxt "cool_min_speed description" -msgid "" -"The minimum layer time can cause the print to slow down so much it starts to " -"droop. The minimum feedrate protects against this. Even if a print gets " -"slowed down it will never be slower than this minimum speed." -msgstr "The minimum layer time can cause the print to slow down so much it starts to droop. The minimum feed rate protects against this. Even if a print is slowed down, it will never be slower than this minimum speed." - -#: fdmprinter.json -msgctxt "cool_lift_head label" -msgid "Lift Head" -msgstr "Lift Head" - -#: fdmprinter.json -msgctxt "cool_lift_head description" -msgid "" -"Lift the head away from the print if the minimum speed is hit because of " -"cool slowdown, and wait the extra time away from the print surface until the " -"minimum layer time is used up." -msgstr "Lift the head away from the print if the minimum speed is hit because of cool slowdown, and wait the extra time away from the print surface until the minimum layer time has elapsed." - -#: fdmprinter.json -msgctxt "support label" -msgid "Support" -msgstr "Support" - -#: fdmprinter.json -msgctxt "support_enable label" -msgid "Enable Support" -msgstr "Enable Support" - -#: fdmprinter.json -msgctxt "support_enable description" -msgid "" -"Enable exterior support structures. This will build up supporting structures " -"below the model to prevent the model from sagging or printing in mid air." -msgstr "Enable exterior support structures. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air." - -#: fdmprinter.json -msgctxt "support_type label" -msgid "Placement" -msgstr "Placement" - -#: fdmprinter.json -msgctxt "support_type description" -msgid "" -"Where to place support structures. The placement can be restricted so that " -"the support structures won't rest on the model, which could otherwise cause " -"scarring." -msgstr "Where to place support structures. The placement can be restricted so that the support structures do not rest on the model, which could otherwise cause scarring." - -#: fdmprinter.json -msgctxt "support_type option buildplate" -msgid "Touching Buildplate" -msgstr "Touching Build Plate" - -#: fdmprinter.json -msgctxt "support_type option everywhere" -msgid "Everywhere" -msgstr "Everywhere" - -#: fdmprinter.json -msgctxt "support_angle label" -msgid "Overhang Angle" -msgstr "Overhang Angle" - -#: fdmprinter.json -msgctxt "support_angle description" -msgid "" -"The maximum angle of overhangs for which support will be added. With 0 " -"degrees being vertical, and 90 degrees being horizontal. A smaller overhang " -"angle leads to more support." -msgstr "The maximum angle of overhangs for which support will be added, where 0 degrees is vertical and 90 degrees is horizontal. A smaller overhang angle leads to more support." - -#: fdmprinter.json -msgctxt "support_xy_distance label" -msgid "X/Y Distance" -msgstr "X/Y Distance" - -#: fdmprinter.json -msgctxt "support_xy_distance description" -msgid "" -"Distance of the support structure from the print in the X/Y directions. " -"0.7mm typically gives a nice distance from the print so the support does not " -"stick to the surface." -msgstr "Distance of the support structure from the print in the X/Y directions. 0.7 mm typically gives a good distance from the print so the support does not stick to the surface." - -#: fdmprinter.json -msgctxt "support_z_distance label" -msgid "Z Distance" -msgstr "Z Distance" - -#: fdmprinter.json -msgctxt "support_z_distance description" -msgid "" -"Distance from the top/bottom of the support to the print. A small gap here " -"makes it easier to remove the support but makes the print a bit uglier. " -"0.15mm allows for easier separation of the support structure." -msgstr "Distance from the top/bottom of the support to the print. A small gap here makes it easier to remove the support but makes the print a bit uglier. 0.15 mm allows for easier separation of the support structure." - -#: fdmprinter.json -msgctxt "support_top_distance label" -msgid "Top Distance" -msgstr "Top Distance" - -#: fdmprinter.json -msgctxt "support_top_distance description" -msgid "Distance from the top of the support to the print." -msgstr "Distance from the top of the support to the print." - -#: fdmprinter.json -msgctxt "support_bottom_distance label" -msgid "Bottom Distance" -msgstr "Bottom Distance" - -#: fdmprinter.json -msgctxt "support_bottom_distance description" -msgid "Distance from the print to the bottom of the support." -msgstr "Distance from the print to the bottom of the support." - -#: fdmprinter.json -msgctxt "support_conical_enabled label" -msgid "Conical Support" -msgstr "Conical Support" - -#: fdmprinter.json -msgctxt "support_conical_enabled description" -msgid "" -"Experimental feature: Make support areas smaller at the bottom than at the " -"overhang." -msgstr "Experimental feature: Make support areas smaller at the bottom than at the overhang." - -#: fdmprinter.json -msgctxt "support_conical_angle label" -msgid "Cone Angle" -msgstr "Cone Angle" - -#: fdmprinter.json -msgctxt "support_conical_angle description" -msgid "" -"The angle of the tilt of conical support. With 0 degrees being vertical, and " -"90 degrees being horizontal. Smaller angles cause the support to be more " -"sturdy, but consist of more material. Negative angles cause the base of the " -"support to be wider than the top." -msgstr "The angle of the tilt of conical support, where 0 degrees is vertical and 90 degrees is horizontal. Smaller angles cause the support to be more sturdy, but consist of more material. Negative angles cause the base of the support to be wider than the top." - -#: fdmprinter.json -msgctxt "support_conical_min_width label" -msgid "Minimal Width" -msgstr "Minimal Width" - -#: fdmprinter.json -msgctxt "support_conical_min_width description" -msgid "" -"Minimal width to which conical support reduces the support areas. Small " -"widths can cause the base of the support to not act well as foundation for " -"support above." -msgstr "Minimal width to which conical support reduces the support areas. Small widths can cause the base of the support to provide a poor foundation for support above." - -#: fdmprinter.json -msgctxt "support_bottom_stair_step_height label" -msgid "Stair Step Height" -msgstr "Stair Step Height" - -#: fdmprinter.json -msgctxt "support_bottom_stair_step_height description" -msgid "" -"The height of the steps of the stair-like bottom of support resting on the " -"model. Small steps can cause the support to be hard to remove from the top " -"of the model." -msgstr "The height of the steps of the stair-like bottom of the support resting on the model. Small steps can cause the support to be difficult to remove from the top of the model." - -#: fdmprinter.json -msgctxt "support_join_distance label" -msgid "Join Distance" -msgstr "Join Distance" - -#: fdmprinter.json -msgctxt "support_join_distance description" -msgid "" -"The maximum distance between support blocks in the X/Y directions, so that " -"the blocks will merge into a single block." -msgstr "The maximum distance between support blocks in the X/Y directions, so that the blocks will merge into a single block." - -#: fdmprinter.json -msgctxt "support_offset label" -msgid "Horizontal Expansion" -msgstr "Horizontal Expansion" - -#: fdmprinter.json -msgctxt "support_offset description" -msgid "" -"Amount of offset applied to all support polygons in each layer. Positive " -"values can smooth out the support areas and result in more sturdy support." -msgstr "Amount of offset applied to all support polygons in each layer. Positive values can smooth out the support areas and result in more sturdy support." - -#: fdmprinter.json -msgctxt "support_area_smoothing label" -msgid "Area Smoothing" -msgstr "Area Smoothing" - -#: fdmprinter.json -msgctxt "support_area_smoothing description" -msgid "" -"Maximum distance in the X/Y directions of a line segment which is to be " -"smoothed out. Ragged lines are introduced by the join distance and support " -"bridge, which cause the machine to resonate. Smoothing the support areas " -"won't cause them to break with the constraints, except it might change the " -"overhang." -msgstr "Maximum distance in the X/Y directions of a line segment which is to be smoothed out. Ragged lines are introduced by the join distance and support bridge, which cause the machine to resonate. Smoothing the support areas will not cause them to break with the constraints, although it might change the overhang." - -#: fdmprinter.json -msgctxt "support_roof_enable label" -msgid "Enable Support Roof" -msgstr "Enable Support Roof" - -#: fdmprinter.json -msgctxt "support_roof_enable description" -msgid "" -"Generate a dense top skin at the top of the support on which the model sits." -msgstr "Generate a dense top skin at the top of the support on which the model sits." - -#: fdmprinter.json -msgctxt "support_roof_height label" -msgid "Support Roof Thickness" -msgstr "Support Roof Thickness" - -#: fdmprinter.json -msgctxt "support_roof_height description" -msgid "The height of the support roofs." -msgstr "The height of the support roofs." - -#: fdmprinter.json -msgctxt "support_roof_density label" -msgid "Support Roof Density" -msgstr "Support Roof Density" - -#: fdmprinter.json -msgctxt "support_roof_density description" -msgid "" -"This controls how densely filled the roofs of the support will be. A higher " -"percentage results in better overhangs, but makes the support more difficult " -"to remove." -msgstr "This controls how densely filled the roofs of the support will be. A higher percentage results in better overhangs, but makes the support more difficult to remove." - -#: fdmprinter.json -msgctxt "support_roof_line_distance label" -msgid "Support Roof Line Distance" -msgstr "Support Roof Line Distance" - -#: fdmprinter.json -msgctxt "support_roof_line_distance description" -msgid "Distance between the printed support roof lines." -msgstr "Distance between the printed support roof lines." - -#: fdmprinter.json -msgctxt "support_roof_pattern label" -msgid "Support Roof Pattern" -msgstr "Support Roof Pattern" - -#: fdmprinter.json -msgctxt "support_roof_pattern description" -msgid "The pattern with which the top of the support is printed." -msgstr "The pattern with which the top of the support is printed." - -#: fdmprinter.json -msgctxt "support_roof_pattern option lines" -msgid "Lines" -msgstr "Lines" - -#: fdmprinter.json -msgctxt "support_roof_pattern option grid" -msgid "Grid" -msgstr "Grid" - -#: fdmprinter.json -msgctxt "support_roof_pattern option triangles" -msgid "Triangles" -msgstr "Triangles" - -#: fdmprinter.json -msgctxt "support_roof_pattern option concentric" -msgid "Concentric" -msgstr "Concentric" - -#: fdmprinter.json -msgctxt "support_roof_pattern option zigzag" -msgid "Zig Zag" -msgstr "Zig Zag" - -#: fdmprinter.json -msgctxt "support_use_towers label" -msgid "Use towers" -msgstr "Use towers" - -#: fdmprinter.json -msgctxt "support_use_towers description" -msgid "" -"Use specialized towers to support tiny overhang areas. These towers have a " -"larger diameter than the region they support. Near the overhang the towers' " -"diameter decreases, forming a roof." -msgstr "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. The towers' diameter decreases near the overhang, forming a roof." - -#: fdmprinter.json -msgctxt "support_minimal_diameter label" -msgid "Minimum Diameter" -msgstr "Minimum Diameter" - -#: fdmprinter.json -msgctxt "support_minimal_diameter description" -msgid "" -"Minimum diameter in the X/Y directions of a small area which is to be " -"supported by a specialized support tower." -msgstr "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower." - -#: fdmprinter.json -msgctxt "support_tower_diameter label" -msgid "Tower Diameter" -msgstr "Tower Diameter" - -#: fdmprinter.json -msgctxt "support_tower_diameter description" -msgid "The diameter of a special tower." -msgstr "The diameter of a special tower." - -#: fdmprinter.json -msgctxt "support_tower_roof_angle label" -msgid "Tower Roof Angle" -msgstr "Tower Roof Angle" - -#: fdmprinter.json -msgctxt "support_tower_roof_angle description" -msgid "" -"The angle of the rooftop of a tower. Larger angles mean more pointy towers." -msgstr "The angle of the rooftop of a tower. Larger angles mean more pointy towers." - -#: fdmprinter.json -msgctxt "support_pattern label" -msgid "Pattern" -msgstr "Pattern" - -#: fdmprinter.json -msgctxt "support_pattern description" -msgid "" -"Cura can generate 3 distinct types of support structure. First is a grid " -"based support structure which is quite solid and can be removed in one " -"piece. The second is a line based support structure which has to be peeled " -"off line by line. The third is a structure in between the other two; it " -"consists of lines which are connected in an accordion fashion." -msgstr "Cura can generate 3 distinct types of support structure. The first is a grid-based support structure which is quite solid and can be removed in one piece. The second is a line-based support structure which has to be peeled off line by line. The third is a structure in between the other two consisting of lines that are connected in an accordion fashion." - -#: fdmprinter.json -msgctxt "support_pattern option lines" -msgid "Lines" -msgstr "Lines" - -#: fdmprinter.json -msgctxt "support_pattern option grid" -msgid "Grid" -msgstr "Grid" - -#: fdmprinter.json -msgctxt "support_pattern option triangles" -msgid "Triangles" -msgstr "Triangles" - -#: fdmprinter.json -msgctxt "support_pattern option concentric" -msgid "Concentric" -msgstr "Concentric" - -#: fdmprinter.json -msgctxt "support_pattern option zigzag" -msgid "Zig Zag" -msgstr "Zig Zag" - -#: fdmprinter.json -msgctxt "support_connect_zigzags label" -msgid "Connect ZigZags" -msgstr "Connect ZigZags" - -#: fdmprinter.json -msgctxt "support_connect_zigzags description" -msgid "" -"Connect the ZigZags. Makes them harder to remove, but prevents stringing of " -"disconnected zigzags." -msgstr "Connect the ZigZags. Makes them harder to remove, but prevents stringing of disconnected zigzags." - -#: fdmprinter.json -msgctxt "support_infill_rate label" -msgid "Fill Amount" -msgstr "Fill Amount" - -#: fdmprinter.json -msgctxt "support_infill_rate description" -msgid "" -"The amount of infill structure in the support; less infill gives weaker " -"support which is easier to remove." -msgstr "The amount of infill structure in the support; less infill gives weaker support which is easier to remove." - -#: fdmprinter.json -msgctxt "support_line_distance label" -msgid "Line distance" -msgstr "Line distance" - -#: fdmprinter.json -msgctxt "support_line_distance description" -msgid "Distance between the printed support lines." -msgstr "Distance between the printed support lines." - -#: fdmprinter.json -msgctxt "platform_adhesion label" -msgid "Platform Adhesion" -msgstr "Platform Adhesion" - -#: fdmprinter.json -msgctxt "adhesion_type label" -msgid "Type" -msgstr "Type" - -#: fdmprinter.json -msgctxt "adhesion_type description" -msgid "" -"Different options that help to improve priming your extrusion.\n" -"Brim and Raft help in preventing corners from lifting due to warping. Brim " -"adds a single-layer-thick flat area around your object which is easy to cut " -"off afterwards, and it is the recommended option.\n" -"Raft adds a thick grid below the object and a thin interface between this " -"and your object.\n" -"The skirt is a line drawn around the first layer of the print, this helps to " -"prime your extrusion and to see if the object fits on your platform." -msgstr "Different options that help to improve priming your extrusion.\nBrim and Raft help in preventing corners from lifting due to warping. Brim adds a single-layer-thick flat area around your object which is easy to cut off afterwards, and is the recommended option.\nRaft adds a thick grid below the object and a thin interface between this and your object.\nThe skirt is a line drawn around the first layer of the print, which helps to prime your extrusion and to see if the object will fit on your platform." - -#: fdmprinter.json -msgctxt "adhesion_type option skirt" -msgid "Skirt" -msgstr "Skirt" - -#: fdmprinter.json -msgctxt "adhesion_type option brim" -msgid "Brim" -msgstr "Brim" - -#: fdmprinter.json -msgctxt "adhesion_type option raft" -msgid "Raft" -msgstr "Raft" - -#: fdmprinter.json -msgctxt "skirt_line_count label" -msgid "Skirt Line Count" -msgstr "Skirt Line Count" - -#: fdmprinter.json -msgctxt "skirt_line_count description" -msgid "" -"Multiple skirt lines help to prime your extrusion better for small objects. " -"Setting this to 0 will disable the skirt." -msgstr "Multiple skirt lines help to prime your extrusion better for small objects. Setting this to 0 will disable the skirt." - -#: fdmprinter.json -msgctxt "skirt_gap label" -msgid "Skirt Distance" -msgstr "Skirt Distance" - -#: fdmprinter.json -msgctxt "skirt_gap description" -msgid "" -"The horizontal distance between the skirt and the first layer of the print.\n" -"This is the minimum distance, multiple skirt lines will extend outwards from " -"this distance." -msgstr "The horizontal distance between the skirt and the first layer of the print.\nThis is the minimum distance; multiple skirt lines will extend outwards from this distance." - -#: fdmprinter.json -msgctxt "skirt_minimal_length label" -msgid "Skirt Minimum Length" -msgstr "Skirt Minimum Length" - -#: fdmprinter.json -msgctxt "skirt_minimal_length description" -msgid "" -"The minimum length of the skirt. If this minimum length is not reached, more " -"skirt lines will be added to reach this minimum length. Note: If the line " -"count is set to 0 this is ignored." -msgstr "The minimum length of the skirt. If this minimum length is not reached, more skirt lines will be added to reach this minimum length. Note: If the line count is set to 0 this is ignored." - -#: fdmprinter.json -msgctxt "brim_width label" -msgid "Brim Width" -msgstr "Brim Width" - -#: fdmprinter.json -msgctxt "brim_width description" -msgid "" -"The distance from the model to the end of the brim. A larger brim sticks " -"better to the build platform, but also makes your effective print area " -"smaller." -msgstr "The distance from the model to the end of the brim. A larger brim sticks better to the build platform, but also makes your effective print area smaller." - -#: fdmprinter.json -msgctxt "brim_line_count label" -msgid "Brim Line Count" -msgstr "Brim Line Count" - -#: fdmprinter.json -msgctxt "brim_line_count description" -msgid "" -"The number of lines used for a brim. More lines means a larger brim which " -"sticks better to the build plate, but this also makes your effective print " -"area smaller." -msgstr "The number of lines used for a brim. More lines means a larger brim which sticks better to the build plate, but this also makes your effective print area smaller." - -#: fdmprinter.json -msgctxt "raft_margin label" -msgid "Raft Extra Margin" -msgstr "Raft Extra Margin" - -#: fdmprinter.json -msgctxt "raft_margin description" -msgid "" -"If the raft is enabled, this is the extra raft area around the object which " -"is also given a raft. Increasing this margin will create a stronger raft " -"while using more material and leaving less area for your print." -msgstr "If the raft is enabled, this is the extra raft area around the object which is also given a raft. Increasing this margin will create a stronger raft while using more material and leaving less area for your print." - -#: fdmprinter.json -msgctxt "raft_airgap label" -msgid "Raft Air-gap" -msgstr "Raft Air-gap" - -#: fdmprinter.json -msgctxt "raft_airgap description" -msgid "" -"The gap between the final raft layer and the first layer of the object. Only " -"the first layer is raised by this amount to lower the bonding between the " -"raft layer and the object. Makes it easier to peel off the raft." -msgstr "The gap between the final raft layer and the first layer of the object. Only the first layer is raised by this amount to lower the bonding between the raft layer and the object. Makes it easier to peel off the raft." - -#: fdmprinter.json -msgctxt "raft_surface_layers label" -msgid "Raft Top Layers" -msgstr "Raft Top Layers" - -#: fdmprinter.json -msgctxt "raft_surface_layers description" -msgid "" -"The number of top layers on top of the 2nd raft layer. These are fully " -"filled layers that the object sits on. 2 layers result in a smoother top " -"surface than 1." -msgstr "The number of top layers on top of the 2nd raft layer. These are fully filled layers that the object sits on. 2 layers result in a smoother top surface than 1." - -#: fdmprinter.json -msgctxt "raft_surface_thickness label" -msgid "Raft Top Layer Thickness" -msgstr "Raft Top Layer Thickness" - -#: fdmprinter.json -msgctxt "raft_surface_thickness description" -msgid "Layer thickness of the top raft layers." -msgstr "Layer thickness of the top raft layers." - -#: fdmprinter.json -msgctxt "raft_surface_line_width label" -msgid "Raft Top Line Width" -msgstr "Raft Top Line Width" - -#: fdmprinter.json -msgctxt "raft_surface_line_width description" -msgid "" -"Width of the lines in the top surface of the raft. These can be thin lines " -"so that the top of the raft becomes smooth." -msgstr "Width of the lines in the top surface of the raft. These can be thin lines so that the top of the raft becomes smooth." - -#: fdmprinter.json -msgctxt "raft_surface_line_spacing label" -msgid "Raft Top Spacing" -msgstr "Raft Top Spacing" - -#: fdmprinter.json -msgctxt "raft_surface_line_spacing description" -msgid "" -"The distance between the raft lines for the top raft layers. The spacing " -"should be equal to the line width, so that the surface is solid." -msgstr "The distance between the raft lines for the top raft layers. The spacing should be equal to the line width to produce a solid surface." - -#: fdmprinter.json -msgctxt "raft_interface_thickness label" -msgid "Raft Middle Thickness" -msgstr "Raft Middle Thickness" - -#: fdmprinter.json -msgctxt "raft_interface_thickness description" -msgid "Layer thickness of the middle raft layer." -msgstr "Layer thickness of the middle raft layer." - -#: fdmprinter.json -msgctxt "raft_interface_line_width label" -msgid "Raft Middle Line Width" -msgstr "Raft Middle Line Width" - -#: fdmprinter.json -msgctxt "raft_interface_line_width description" -msgid "" -"Width of the lines in the middle raft layer. Making the second layer extrude " -"more causes the lines to stick to the bed." -msgstr "Width of the lines in the middle raft layer. Making the second layer extrude more causes the lines to stick to the bed." - -#: fdmprinter.json -msgctxt "raft_interface_line_spacing label" -msgid "Raft Middle Spacing" -msgstr "Raft Middle Spacing" - -#: fdmprinter.json -msgctxt "raft_interface_line_spacing description" -msgid "" -"The distance between the raft lines for the middle raft layer. The spacing " -"of the middle should be quite wide, while being dense enough to support the " -"top raft layers." -msgstr "The distance between the raft lines for the middle raft layer. The spacing of the middle should be quite wide, while being dense enough to support the top raft layers." - -#: fdmprinter.json -msgctxt "raft_base_thickness label" -msgid "Raft Base Thickness" -msgstr "Raft Base Thickness" - -#: fdmprinter.json -msgctxt "raft_base_thickness description" -msgid "" -"Layer thickness of the base raft layer. This should be a thick layer which " -"sticks firmly to the printer bed." -msgstr "Layer thickness of the base raft layer. This should be a thick layer that sticks firmly to the printer bed." - -#: fdmprinter.json -msgctxt "raft_base_line_width label" -msgid "Raft Base Line Width" -msgstr "Raft Base Line Width" - -#: fdmprinter.json -msgctxt "raft_base_line_width description" -msgid "" -"Width of the lines in the base raft layer. These should be thick lines to " -"assist in bed adhesion." -msgstr "Width of the lines in the base raft layer. These should be thick lines to assist in bed adhesion." - -#: fdmprinter.json -msgctxt "raft_base_line_spacing label" -msgid "Raft Line Spacing" -msgstr "Raft Line Spacing" - -#: fdmprinter.json -msgctxt "raft_base_line_spacing description" -msgid "" -"The distance between the raft lines for the base raft layer. Wide spacing " -"makes for easy removal of the raft from the build plate." -msgstr "The distance between the raft lines for the base raft layer. Wide spacing makes for easy removal of the raft from the build plate." - -#: fdmprinter.json -msgctxt "raft_speed label" -msgid "Raft Print Speed" -msgstr "Raft Print Speed" - -#: fdmprinter.json -msgctxt "raft_speed description" -msgid "The speed at which the raft is printed." -msgstr "The speed at which the raft is printed." - -#: fdmprinter.json -msgctxt "raft_surface_speed label" -msgid "Raft Surface Print Speed" -msgstr "Raft Surface Print Speed" - -#: fdmprinter.json -msgctxt "raft_surface_speed description" -msgid "" -"The speed at which the surface raft layers are printed. These should be " -"printed a bit slower, so that the nozzle can slowly smooth out adjacent " -"surface lines." -msgstr "The speed at which the surface raft layers are printed. These should be printed a bit slower to allow the nozzle to slowly smooth out adjacent surface lines." - -#: fdmprinter.json -msgctxt "raft_interface_speed label" -msgid "Raft Interface Print Speed" -msgstr "Raft Interface Print Speed" - -#: fdmprinter.json -msgctxt "raft_interface_speed description" -msgid "" -"The speed at which the interface raft layer is printed. This should be " -"printed quite slowly, as the volume of material coming out of the nozzle is " -"quite high." -msgstr "The speed at which the interface raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high." - -#: fdmprinter.json -msgctxt "raft_base_speed label" -msgid "Raft Base Print Speed" -msgstr "Raft Base Print Speed" - -#: fdmprinter.json -msgctxt "raft_base_speed description" -msgid "" -"The speed at which the base raft layer is printed. This should be printed " -"quite slowly, as the volume of material coming out of the nozzle is quite " -"high." -msgstr "The speed at which the base raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high." - -#: fdmprinter.json -msgctxt "raft_fan_speed label" -msgid "Raft Fan Speed" -msgstr "Raft Fan Speed" - -#: fdmprinter.json -msgctxt "raft_fan_speed description" -msgid "The fan speed for the raft." -msgstr "The fan speed for the raft." - -#: fdmprinter.json -msgctxt "raft_surface_fan_speed label" -msgid "Raft Surface Fan Speed" -msgstr "Raft Surface Fan Speed" - -#: fdmprinter.json -msgctxt "raft_surface_fan_speed description" -msgid "The fan speed for the surface raft layers." -msgstr "The fan speed for the surface raft layers." - -#: fdmprinter.json -msgctxt "raft_interface_fan_speed label" -msgid "Raft Interface Fan Speed" -msgstr "Raft Interface Fan Speed" - -#: fdmprinter.json -msgctxt "raft_interface_fan_speed description" -msgid "The fan speed for the interface raft layer." -msgstr "The fan speed for the interface raft layer." - -#: fdmprinter.json -msgctxt "raft_base_fan_speed label" -msgid "Raft Base Fan Speed" -msgstr "Raft Base Fan Speed" - -#: fdmprinter.json -msgctxt "raft_base_fan_speed description" -msgid "The fan speed for the base raft layer." -msgstr "The fan speed for the base raft layer." - -#: fdmprinter.json -msgctxt "draft_shield_enabled label" -msgid "Enable Draft Shield" -msgstr "Enable Draft Shield" - -#: fdmprinter.json -msgctxt "draft_shield_enabled description" -msgid "" -"Enable exterior draft shield. This will create a wall around the object " -"which traps (hot) air and shields against gusts of wind. Especially useful " -"for materials which warp easily." -msgstr "Enable exterior draft shield. This will create a wall around the object which traps (hot) air and shields against gusts of wind. Especially useful for materials that warp easily." - -#: fdmprinter.json -msgctxt "draft_shield_dist label" -msgid "Draft Shield X/Y Distance" -msgstr "Draft Shield X/Y Distance" - -#: fdmprinter.json -msgctxt "draft_shield_dist description" -msgid "Distance of the draft shield from the print, in the X/Y directions." -msgstr "Distance of the draft shield from the print, in the X/Y directions." - -#: fdmprinter.json -msgctxt "draft_shield_height_limitation label" -msgid "Draft Shield Limitation" -msgstr "Draft Shield Limitation" - -#: fdmprinter.json -msgctxt "draft_shield_height_limitation description" -msgid "Whether or not to limit the height of the draft shield." -msgstr "Whether or not to limit the height of the draft shield." - -#: fdmprinter.json -msgctxt "draft_shield_height_limitation option full" -msgid "Full" -msgstr "Full" - -#: fdmprinter.json -msgctxt "draft_shield_height_limitation option limited" -msgid "Limited" -msgstr "Limited" - -#: fdmprinter.json -msgctxt "draft_shield_height label" -msgid "Draft Shield Height" -msgstr "Draft Shield Height" - -#: fdmprinter.json -msgctxt "draft_shield_height description" -msgid "" -"Height limitation on the draft shield. Above this height no draft shield " -"will be printed." -msgstr "Height limitation on the draft shield. Above this height, no draft shield will be printed." - -#: fdmprinter.json -msgctxt "meshfix label" -msgid "Mesh Fixes" -msgstr "Mesh Fixes" - -#: fdmprinter.json -msgctxt "meshfix_union_all label" -msgid "Union Overlapping Volumes" -msgstr "Union Overlapping Volumes" - -#: fdmprinter.json -msgctxt "meshfix_union_all description" -msgid "" -"Ignore the internal geometry arising from overlapping volumes and print the " -"volumes as one. This may cause internal cavities to disappear." -msgstr "Ignore the internal geometry arising from overlapping volumes and print the volumes as one. This may cause internal cavities to disappear." - -#: fdmprinter.json -msgctxt "meshfix_union_all_remove_holes label" -msgid "Remove All Holes" -msgstr "Remove All Holes" - -#: fdmprinter.json -msgctxt "meshfix_union_all_remove_holes description" -msgid "" -"Remove the holes in each layer and keep only the outside shape. This will " -"ignore any invisible internal geometry. However, it also ignores layer holes " -"which can be viewed from above or below." -msgstr "Remove the holes in each layer and keep only the outside shape. This will ignore any invisible internal geometry. However, it also ignores layer holes which can be viewed from above or below." - -#: fdmprinter.json -msgctxt "meshfix_extensive_stitching label" -msgid "Extensive Stitching" -msgstr "Extensive Stitching" - -#: fdmprinter.json -msgctxt "meshfix_extensive_stitching description" -msgid "" -"Extensive stitching tries to stitch up open holes in the mesh by closing the " -"hole with touching polygons. This option can introduce a lot of processing " -"time." -msgstr "Extensive stitching tries to stitch up open holes in the mesh by closing the hole with touching polygons. This option can introduce a lot of processing time." - -#: fdmprinter.json -msgctxt "meshfix_keep_open_polygons label" -msgid "Keep Disconnected Faces" -msgstr "Keep Disconnected Faces" - -#: fdmprinter.json -msgctxt "meshfix_keep_open_polygons description" -msgid "" -"Normally Cura tries to stitch up small holes in the mesh and remove parts of " -"a layer with big holes. Enabling this option keeps those parts which cannot " -"be stitched. This option should be used as a last resort option when " -"everything else fails to produce proper GCode." -msgstr "Normally, Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper GCode." - -#: fdmprinter.json -msgctxt "blackmagic label" -msgid "Special Modes" -msgstr "Special Modes" - -#: fdmprinter.json -msgctxt "print_sequence label" -msgid "Print sequence" -msgstr "Print sequence" - -#: fdmprinter.json -msgctxt "print_sequence description" -msgid "" -"Whether to print all objects one layer at a time or to wait for one object " -"to finish, before moving on to the next. One at a time mode is only possible " -"if all models are separated in such a way that the whole print head can move " -"in between and all models are lower than the distance between the nozzle and " -"the X/Y axes." -msgstr "Whether to print all objects one layer at a time or to wait for one object to finish before moving on to the next. One at a time mode is only possible if all models are separated in such a way that the whole print head can move in between and all models are lower than the distance between the nozzle and the X/Y axes." - -#: fdmprinter.json -msgctxt "print_sequence option all_at_once" -msgid "All at Once" -msgstr "All at Once" - -#: fdmprinter.json -msgctxt "print_sequence option one_at_a_time" -msgid "One at a Time" -msgstr "One at a Time" - -#: fdmprinter.json -msgctxt "magic_mesh_surface_mode label" -msgid "Surface Mode" -msgstr "Surface Mode" - -#: fdmprinter.json -msgctxt "magic_mesh_surface_mode description" -msgid "" -"Print the surface instead of the volume. No infill, no top/bottom skin, just " -"a single wall of which the middle coincides with the surface of the mesh. " -"It's also possible to do both: print the insides of a closed volume as " -"normal, but print all polygons not part of a closed volume as surface." -msgstr "Print the surface instead of the volume. No infill, no top/bottom skin, just a single wall of which the middle coincides with the surface of the mesh. It is also possible to do both: print the insides of a closed volume as normal, but print all polygons not part of a closed volume as surface." - -#: fdmprinter.json -msgctxt "magic_mesh_surface_mode option normal" -msgid "Normal" -msgstr "Normal" - -#: fdmprinter.json -msgctxt "magic_mesh_surface_mode option surface" -msgid "Surface" -msgstr "Surface" - -#: fdmprinter.json -msgctxt "magic_mesh_surface_mode option both" -msgid "Both" -msgstr "Both" - -#: fdmprinter.json -msgctxt "magic_spiralize label" -msgid "Spiralize Outer Contour" -msgstr "Spiralize Outer Contour" - -#: fdmprinter.json -msgctxt "magic_spiralize description" -msgid "" -"Spiralize smooths out the Z move of the outer edge. This will create a " -"steady Z increase over the whole print. This feature turns a solid object " -"into a single walled print with a solid bottom. This feature used to be " -"called Joris in older versions." -msgstr "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid object into a single-walled print with a solid bottom. This feature used to be called Joris in older versions." - -#: fdmprinter.json -msgctxt "magic_fuzzy_skin_enabled label" -msgid "Fuzzy Skin" -msgstr "Fuzzy Skin" - -#: fdmprinter.json -msgctxt "magic_fuzzy_skin_enabled description" -msgid "" -"Randomly jitter while printing the outer wall, so that the surface has a " -"rough and fuzzy look." -msgstr "Randomly jitter while printing the outer wall, so that the surface has a rough and fuzzy look." - -#: fdmprinter.json -msgctxt "magic_fuzzy_skin_thickness label" -msgid "Fuzzy Skin Thickness" -msgstr "Fuzzy Skin Thickness" - -#: fdmprinter.json -msgctxt "magic_fuzzy_skin_thickness description" -msgid "" -"The width within which to jitter. It's advised to keep this below the outer " -"wall width, since the inner walls are unaltered." -msgstr "The width within which to jitter. It is advised to keep this below the outer wall width, since the inner walls are unaltered." - -#: fdmprinter.json -msgctxt "magic_fuzzy_skin_point_density label" -msgid "Fuzzy Skin Density" -msgstr "Fuzzy Skin Density" - -#: fdmprinter.json -msgctxt "magic_fuzzy_skin_point_density description" -msgid "" -"The average density of points introduced on each polygon in a layer. Note " -"that the original points of the polygon are discarded, so a low density " -"results in a reduction of the resolution." -msgstr "The average density of points introduced on each polygon in a layer. Note that the original points of the polygon are discarded, so a low density results in a reduction of the resolution." - -#: fdmprinter.json -msgctxt "magic_fuzzy_skin_point_dist label" -msgid "Fuzzy Skin Point Distance" -msgstr "Fuzzy Skin Point Distance" - -#: fdmprinter.json -msgctxt "magic_fuzzy_skin_point_dist description" -msgid "" -"The average distance between the random points introduced on each line " -"segment. Note that the original points of the polygon are discarded, so a " -"high smoothness results in a reduction of the resolution. This value must be " -"higher than half the Fuzzy Skin Thickness." -msgstr "The average distance between the random points introduced on each line segment. Note that the original points of the polygon are discarded, so a high smoothness results in a reduction of the resolution. This value must be higher than half the Fuzzy Skin Thickness." - -#: fdmprinter.json -msgctxt "wireframe_enabled label" -msgid "Wire Printing" -msgstr "Wire Printing" - -#: fdmprinter.json -msgctxt "wireframe_enabled description" -msgid "" -"Print only the outside surface with a sparse webbed structure, printing 'in " -"thin air'. This is realized by horizontally printing the contours of the " -"model at given Z intervals which are connected via upward and diagonally " -"downward lines." -msgstr "Print only the outside surface with a sparse webbed structure, printing 'in thin air'. This is realized by horizontally printing the contours of the model at given Z intervals that are connected via upward and diagonally downward lines." - -#: fdmprinter.json -msgctxt "wireframe_height label" -msgid "WP Connection Height" -msgstr "WP Connection Height" - -#: fdmprinter.json -msgctxt "wireframe_height description" -msgid "" -"The height of the upward and diagonally downward lines between two " -"horizontal parts. This determines the overall density of the net structure. " -"Only applies to Wire Printing." -msgstr "The height of the upward and diagonally downward lines between two horizontal parts. This determines the overall density of the net structure. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_roof_inset label" -msgid "WP Roof Inset Distance" -msgstr "WP Roof Inset Distance" - -#: fdmprinter.json -msgctxt "wireframe_roof_inset description" -msgid "" -"The distance covered when making a connection from a roof outline inward. " -"Only applies to Wire Printing." -msgstr "The distance covered when making a connection from a roof outline inward. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_printspeed label" -msgid "WP speed" -msgstr "WP speed" - -#: fdmprinter.json -msgctxt "wireframe_printspeed description" -msgid "" -"Speed at which the nozzle moves when extruding material. Only applies to " -"Wire Printing." -msgstr "Speed at which the nozzle moves when extruding material. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_printspeed_bottom label" -msgid "WP Bottom Printing Speed" -msgstr "WP Bottom Printing Speed" - -#: fdmprinter.json -msgctxt "wireframe_printspeed_bottom description" -msgid "" -"Speed of printing the first layer, which is the only layer touching the " -"build platform. Only applies to Wire Printing." -msgstr "Speed of printing the first layer, which is the only layer touching the build platform. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_printspeed_up label" -msgid "WP Upward Printing Speed" -msgstr "WP Upward Printing Speed" - -#: fdmprinter.json -msgctxt "wireframe_printspeed_up description" -msgid "" -"Speed of printing a line upward 'in thin air'. Only applies to Wire Printing." -msgstr "Speed of printing a line upward 'in thin air'. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_printspeed_down label" -msgid "WP Downward Printing Speed" -msgstr "WP Downward Printing Speed" - -#: fdmprinter.json -msgctxt "wireframe_printspeed_down description" -msgid "" -"Speed of printing a line diagonally downward. Only applies to Wire Printing." -msgstr "Speed of printing a line diagonally downward. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_printspeed_flat label" -msgid "WP Horizontal Printing Speed" -msgstr "WP Horizontal Printing Speed" - -#: fdmprinter.json -msgctxt "wireframe_printspeed_flat description" -msgid "" -"Speed of printing the horizontal contours of the object. Only applies to " -"Wire Printing." -msgstr "Speed of printing the horizontal contours of the object. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_flow label" -msgid "WP Flow" -msgstr "WP Flow" - -#: fdmprinter.json -msgctxt "wireframe_flow description" -msgid "" -"Flow compensation: the amount of material extruded is multiplied by this " -"value. Only applies to Wire Printing." -msgstr "Flow compensation: the amount of material extruded is multiplied by this value. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_flow_connection label" -msgid "WP Connection Flow" -msgstr "WP Connection Flow" - -#: fdmprinter.json -msgctxt "wireframe_flow_connection description" -msgid "Flow compensation when going up or down. Only applies to Wire Printing." -msgstr "Flow compensation when going up or down. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_flow_flat label" -msgid "WP Flat Flow" -msgstr "WP Flat Flow" - -#: fdmprinter.json -msgctxt "wireframe_flow_flat description" -msgid "" -"Flow compensation when printing flat lines. Only applies to Wire Printing." -msgstr "Flow compensation when printing flat lines. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_top_delay label" -msgid "WP Top Delay" -msgstr "WP Top Delay" - -#: fdmprinter.json -msgctxt "wireframe_top_delay description" -msgid "" -"Delay time after an upward move, so that the upward line can harden. Only " -"applies to Wire Printing." -msgstr "Delay time after an upward move, so that the upward line can harden. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_bottom_delay label" -msgid "WP Bottom Delay" -msgstr "WP Bottom Delay" - -#: fdmprinter.json -msgctxt "wireframe_bottom_delay description" -msgid "Delay time after a downward move. Only applies to Wire Printing." -msgstr "Delay time after a downward move. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_flat_delay label" -msgid "WP Flat Delay" -msgstr "WP Flat Delay" - -#: fdmprinter.json -msgctxt "wireframe_flat_delay description" -msgid "" -"Delay time between two horizontal segments. Introducing such a delay can " -"cause better adhesion to previous layers at the connection points, while too " -"long delays cause sagging. Only applies to Wire Printing." -msgstr "Delay time between two horizontal segments. Introducing such a delay can cause better adhesion to previous layers at the connection points, while too long delays cause sagging. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_up_half_speed label" -msgid "WP Ease Upward" -msgstr "WP Ease Upward" - -#: fdmprinter.json -msgctxt "wireframe_up_half_speed description" -msgid "" -"Distance of an upward move which is extruded with half speed.\n" -"This can cause better adhesion to previous layers, while not heating the " -"material in those layers too much. Only applies to Wire Printing." -msgstr "Distance of an upward move which is extruded at half speed.\nThis can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_top_jump label" -msgid "WP Knot Size" -msgstr "WP Knot Size" - -#: fdmprinter.json -msgctxt "wireframe_top_jump description" -msgid "" -"Creates a small knot at the top of an upward line, so that the consecutive " -"horizontal layer has a better chance to connect to it. Only applies to Wire " -"Printing." -msgstr "Creates a small knot at the top of an upward line, so that the next horizontal layer has a better chance of connecting to it. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_fall_down label" -msgid "WP Fall Down" -msgstr "WP Fall Down" - -#: fdmprinter.json -msgctxt "wireframe_fall_down description" -msgid "" -"Distance with which the material falls down after an upward extrusion. This " -"distance is compensated for. Only applies to Wire Printing." -msgstr "Distance the material falls down after an upward extrusion. This distance is compensated for. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_drag_along label" -msgid "WP Drag along" -msgstr "WP Drag along" - -#: fdmprinter.json -msgctxt "wireframe_drag_along description" -msgid "" -"Distance with which the material of an upward extrusion is dragged along " -"with the diagonally downward extrusion. This distance is compensated for. " -"Only applies to Wire Printing." -msgstr "Distance the material of an upward extrusion is dragged along during the diagonally downward extrusion. This distance is compensated for. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_strategy label" -msgid "WP Strategy" -msgstr "WP Strategy" - -#: fdmprinter.json -msgctxt "wireframe_strategy description" -msgid "" -"Strategy for making sure two consecutive layers connect at each connection " -"point. Retraction lets the upward lines harden in the right position, but " -"may cause filament grinding. A knot can be made at the end of an upward line " -"to heighten the chance of connecting to it and to let the line cool; " -"however, it may require slow printing speeds. Another strategy is to " -"compensate for the sagging of the top of an upward line; however, the lines " -"won't always fall down as predicted." -msgstr "Strategy for making sure two consecutive layers connect at each connection point. Retraction lets the upward lines harden in the right position, but may cause filament grinding. A knot can be made at the end of an upward line to increase the chance of connecting to it and to let the line cool; however, it may require slow printing speeds. Another strategy is to compensate for the sagging of the top of an upward line; however, the lines won't always fall down as predicted." - -#: fdmprinter.json -msgctxt "wireframe_strategy option compensate" -msgid "Compensate" -msgstr "Compensate" - -#: fdmprinter.json -msgctxt "wireframe_strategy option knot" -msgid "Knot" -msgstr "Knot" - -#: fdmprinter.json -msgctxt "wireframe_strategy option retract" -msgid "Retract" -msgstr "Retract" - -#: fdmprinter.json -msgctxt "wireframe_straight_before_down label" -msgid "WP Straighten Downward Lines" -msgstr "WP Straighten Downward Lines" - -#: fdmprinter.json -msgctxt "wireframe_straight_before_down description" -msgid "" -"Percentage of a diagonally downward line which is covered by a horizontal " -"line piece. This can prevent sagging of the top most point of upward lines. " -"Only applies to Wire Printing." -msgstr "Percentage of a diagonally downward line which is covered by a horizontal line piece. This can prevent sagging of the top-most point of upward lines. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_roof_fall_down label" -msgid "WP Roof Fall Down" -msgstr "WP Roof Fall Down" - -#: fdmprinter.json -msgctxt "wireframe_roof_fall_down description" -msgid "" -"The distance which horizontal roof lines printed 'in thin air' fall down " -"when being printed. This distance is compensated for. Only applies to Wire " -"Printing." -msgstr "The distance which horizontal roof lines printed 'in thin air' fall down when being printed. This distance is compensated for. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_roof_drag_along label" -msgid "WP Roof Drag Along" -msgstr "WP Roof Drag Along" - -#: fdmprinter.json -msgctxt "wireframe_roof_drag_along description" -msgid "" -"The distance of the end piece of an inward line which gets dragged along " -"when going back to the outer outline of the roof. This distance is " -"compensated for. Only applies to Wire Printing." -msgstr "The distance the end piece of an inward line gets dragged along when going back to the outer outline of the roof. This distance is compensated for. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_roof_outer_delay label" -msgid "WP Roof Outer Delay" -msgstr "WP Roof Outer Delay" - -#: fdmprinter.json -msgctxt "wireframe_roof_outer_delay description" -msgid "" -"Time spent at the outer perimeters of hole which is to become a roof. Longer " -"times can ensure a better connection. Only applies to Wire Printing." -msgstr "Time spent at the outer perimeter of a hole that is to become a roof. Longer times can ensure a better connection. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "wireframe_nozzle_clearance label" -msgid "WP Nozzle Clearance" -msgstr "WP Nozzle Clearance" - -#: fdmprinter.json -msgctxt "wireframe_nozzle_clearance description" -msgid "" -"Distance between the nozzle and horizontally downward lines. Larger " -"clearance results in diagonally downward lines with a less steep angle, " -"which in turn results in less upward connections with the next layer. Only " -"applies to Wire Printing." -msgstr "Distance between the nozzle and horizontally downward lines. Larger clearance results in diagonally downward lines with a less steep angle, which in turn results in fewer upward connections with the next layer. Only applies to Wire Printing." - -#: fdmprinter.json -msgctxt "layer_0_z_overlap label" -msgid "Initial Layer Z Overlap" -msgstr "Initial Layer Z Overlap" - -#: fdmprinter.json -msgctxt "layer_0_z_overlap description" -msgid "" -"Make the first and second layer of the object overlap in the Z direction to " -"compensate for the filament lost in the airgap. All models above the first " -"model layer will be shifted down by this amount." -msgstr "Make the first and second layer of the object overlap in the Z direction to compensate for the filament lost in the airgap. All models above the first model layer will be shifted down by this amount." +msgid "" +msgstr "" +"Project-Id-Version: Uranium json setting files\n" +"Report-Msgid-Bugs-To: http://github.com/ultimaker/uranium\n" +"POT-Creation-Date: 2016-04-01 13:45+0000\n" +"PO-Revision-Date: 2016-04-01 13:45+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: fdmprinter.json +msgctxt "machine label" +msgid "Machine" +msgstr "Machine" + +#: fdmprinter.json +msgctxt "machine_nozzle_size label" +msgid "Nozzle Diameter" +msgstr "Nozzle Diameter" + +#: fdmprinter.json +msgctxt "machine_nozzle_size description" +msgid "" +"The inner diameter of the nozzle. Change this setting when using a non-" +"standard nozzle size." +msgstr "" +"The inner diameter of the nozzle. Change this setting when using a non-" +"standard nozzle size." + +#: fdmprinter.json +msgctxt "resolution label" +msgid "Quality" +msgstr "Quality" + +#: fdmprinter.json +msgctxt "layer_height label" +msgid "Layer Height" +msgstr "Layer Height" + +#: fdmprinter.json +msgctxt "layer_height description" +msgid "" +"The height of each layer in mm. Higher values produce faster prints in lower " +"resolution, lower values produce slower prints in higher resolution." +msgstr "" +"The height of each layer in mm. Higher values produce faster prints in lower " +"resolution, lower values produce slower prints in higher resolution." + +#: fdmprinter.json +msgctxt "layer_height_0 label" +msgid "Initial Layer Height" +msgstr "Initial Layer Height" + +#: fdmprinter.json +msgctxt "layer_height_0 description" +msgid "" +"The height of the initial layer in mm. A thicker initial layer makes " +"adhesion to the build plate easier." +msgstr "" +"The height of the initial layer in mm. A thicker initial layer makes " +"adhesion to the build plate easier." + +#: fdmprinter.json +msgctxt "line_width label" +msgid "Line Width" +msgstr "Line Width" + +#: fdmprinter.json +msgctxt "line_width description" +msgid "" +"Width of a single line. Generally, the width of each line should correspond " +"to the width of the nozzle. However, slightly reducing this value could " +"produce better prints." +msgstr "" +"Width of a single line. Generally, the width of each line should correspond " +"to the width of the nozzle. However, slightly reducing this value could " +"produce better prints." + +#: fdmprinter.json +msgctxt "wall_line_width label" +msgid "Wall Line Width" +msgstr "Wall Line Width" + +#: fdmprinter.json +msgctxt "wall_line_width description" +msgid "Width of a single wall line." +msgstr "Width of a single wall line." + +#: fdmprinter.json +msgctxt "wall_line_width_0 label" +msgid "Outer Wall Line Width" +msgstr "Outer Wall Line Width" + +#: fdmprinter.json +msgctxt "wall_line_width_0 description" +msgid "" +"Width of the outermost wall line. By lowering this value, higher levels of " +"detail can be printed." +msgstr "" +"Width of the outermost wall line. By lowering this value, higher levels of " +"detail can be printed." + +#: fdmprinter.json +msgctxt "wall_line_width_x label" +msgid "Inner Wall(s) Line Width" +msgstr "Inner Wall(s) Line Width" + +#: fdmprinter.json +msgctxt "wall_line_width_x description" +msgid "" +"Width of a single wall line for all wall lines except the outermost one." +msgstr "" +"Width of a single wall line for all wall lines except the outermost one." + +#: fdmprinter.json +msgctxt "skin_line_width label" +msgid "Top/bottom Line Width" +msgstr "Top/bottom Line Width" + +#: fdmprinter.json +msgctxt "skin_line_width description" +msgid "Width of a single top/bottom line." +msgstr "Width of a single top/bottom line." + +#: fdmprinter.json +msgctxt "infill_line_width label" +msgid "Infill Line Width" +msgstr "Infill Line Width" + +#: fdmprinter.json +msgctxt "infill_line_width description" +msgid "Width of a single infill line." +msgstr "Width of a single infill line." + +#: fdmprinter.json +msgctxt "skirt_line_width label" +msgid "Skirt Line Width" +msgstr "Skirt Line Width" + +#: fdmprinter.json +msgctxt "skirt_line_width description" +msgid "Width of a single skirt line." +msgstr "Width of a single skirt line." + +#: fdmprinter.json +msgctxt "support_line_width label" +msgid "Support Line Width" +msgstr "Support Line Width" + +#: fdmprinter.json +msgctxt "support_line_width description" +msgid "Width of a single support structure line." +msgstr "Width of a single support structure line." + +#: fdmprinter.json +msgctxt "support_roof_line_width label" +msgid "Support Roof Line Width" +msgstr "Support Roof Line Width" + +#: fdmprinter.json +msgctxt "support_roof_line_width description" +msgid "Width of a single support roof line." +msgstr "Width of a single support roof line." + +#: fdmprinter.json +msgctxt "shell label" +msgid "Shell" +msgstr "Shell" + +#: fdmprinter.json +msgctxt "wall_thickness label" +msgid "Wall Thickness" +msgstr "Wall Thickness" + +#: fdmprinter.json +msgctxt "wall_thickness description" +msgid "" +"The thickness of the outside walls in the horizontal direction. This value " +"divided by the wall line width defines the number of walls." +msgstr "" +"The thickness of the outside walls in the horizontal direction. This value " +"divided by the wall line width defines the number of walls." + +#: fdmprinter.json +msgctxt "wall_line_count label" +msgid "Wall Line Count" +msgstr "Wall Line Count" + +#: fdmprinter.json +msgctxt "wall_line_count description" +msgid "" +"The number of walls. When calculated by the wall thickness, this value is " +"rounded to a whole number." +msgstr "" +"The number of walls. When calculated by the wall thickness, this value is " +"rounded to a whole number." + +#: fdmprinter.json +msgctxt "top_bottom_thickness label" +msgid "Top/Bottom Thickness" +msgstr "Top/Bottom Thickness" + +#: fdmprinter.json +msgctxt "top_bottom_thickness description" +msgid "" +"The thickness of the top/bottom layers in the print. This value divided by " +"the layer height defines the number of top/bottom layers." +msgstr "" +"The thickness of the top/bottom layers in the print. This value divided by " +"the layer height defines the number of top/bottom layers." + +#: fdmprinter.json +msgctxt "top_thickness label" +msgid "Top Thickness" +msgstr "Top Thickness" + +#: fdmprinter.json +msgctxt "top_thickness description" +msgid "" +"The thickness of the top layers in the print. This value divided by the " +"layer height defines the number of top layers." +msgstr "" +"The thickness of the top layers in the print. This value divided by the " +"layer height defines the number of top layers." + +#: fdmprinter.json +msgctxt "top_layers label" +msgid "Top Layers" +msgstr "Top Layers" + +#: fdmprinter.json +msgctxt "top_layers description" +msgid "" +"The number of top layers. When calculated by the top thickness, this value " +"is rounded to a whole number." +msgstr "" +"The number of top layers. When calculated by the top thickness, this value " +"is rounded to a whole number." + +#: fdmprinter.json +msgctxt "bottom_thickness label" +msgid "Bottom Thickness" +msgstr "Bottom Thickness" + +#: fdmprinter.json +msgctxt "bottom_thickness description" +msgid "" +"The thickness of the bottom layers in the print. This value divided by the " +"layer height defines the number of bottom layers." +msgstr "" +"The thickness of the bottom layers in the print. This value divided by the " +"layer height defines the number of bottom layers." + +#: fdmprinter.json +msgctxt "bottom_layers label" +msgid "Bottom Layers" +msgstr "Bottom Layers" + +#: fdmprinter.json +msgctxt "bottom_layers description" +msgid "" +"The number of bottom layers. When calculated by the bottom thickness, this " +"value is rounded to a whole number." +msgstr "" +"The number of bottom layers. When calculated by the bottom thickness, this " +"value is rounded to a whole number." + +#: fdmprinter.json +msgctxt "top_bottom_pattern label" +msgid "Top/Bottom Pattern" +msgstr "Top/Bottom Pattern" + +#: fdmprinter.json +msgctxt "top_bottom_pattern description" +msgid "The pattern of the top/bottom layers." +msgstr "The pattern of the top/bottom layers." + +#: fdmprinter.json +msgctxt "top_bottom_pattern option lines" +msgid "Lines" +msgstr "Lines" + +#: fdmprinter.json +msgctxt "top_bottom_pattern option concentric" +msgid "Concentric" +msgstr "Concentric" + +#: fdmprinter.json +msgctxt "top_bottom_pattern option zigzag" +msgid "Zig Zag" +msgstr "Zig Zag" + +#: fdmprinter.json +msgctxt "skin_alternate_rotation label" +msgid "Alternate Skin Rotation" +msgstr "Alternate Skin Rotation" + +#: fdmprinter.json +msgctxt "skin_alternate_rotation description" +msgid "" +"Alternate the direction in which the top/bottom layers are printed. Normally " +"they are printed diagonally only. This setting adds the X-only and Y-only " +"directions." +msgstr "" +"Alternate the direction in which the top/bottom layers are printed. Normally " +"they are printed diagonally only. This setting adds the X-only and Y-only " +"directions." + +#: fdmprinter.json +msgctxt "skin_outline_count label" +msgid "Extra Skin Wall Count" +msgstr "Extra Skin Wall Count" + +#: fdmprinter.json +msgctxt "skin_outline_count description" +msgid "" +"Replaces the outermost part of the top/bottom pattern with a number of " +"concentric lines. Using one or two lines improves roofs that start on infill " +"material." +msgstr "" +"Replaces the outermost part of the top/bottom pattern with a number of " +"concentric lines. Using one or two lines improves roofs that start on infill " +"material." + +#: fdmprinter.json +msgctxt "alternate_extra_perimeter label" +msgid "Alternate Extra Wall" +msgstr "Alternate Extra Wall" + +#: fdmprinter.json +msgctxt "alternate_extra_perimeter description" +msgid "" +"Prints an extra wall at every other layer. This way infill gets caught " +"between these extra walls, resulting in stronger prints." +msgstr "" +"Prints an extra wall at every other layer. This way infill gets caught " +"between these extra walls, resulting in stronger prints." + +#: fdmprinter.json +msgctxt "remove_overlapping_walls_enabled label" +msgid "Remove Overlapping Wall Parts" +msgstr "Remove Overlapping Wall Parts" + +#: fdmprinter.json +msgctxt "remove_overlapping_walls_enabled description" +msgid "" +"Remove parts of a wall which share an overlap which would result in " +"overextrusion in some places. These overlaps occur in thin parts and sharp " +"corners in models." +msgstr "" +"Remove parts of a wall which share an overlap which would result in " +"overextrusion in some places. These overlaps occur in thin parts and sharp " +"corners in models." + +#: fdmprinter.json +msgctxt "remove_overlapping_walls_0_enabled label" +msgid "Remove Overlapping Outer Wall Parts" +msgstr "Remove Overlapping Outer Wall Parts" + +#: fdmprinter.json +msgctxt "remove_overlapping_walls_0_enabled description" +msgid "" +"Remove parts of an outer wall which share an overlap which would result in " +"overextrusion in some places. These overlaps occur in thin pieces in a model " +"and sharp corners." +msgstr "" +"Remove parts of an outer wall which share an overlap which would result in " +"overextrusion in some places. These overlaps occur in thin pieces in a model " +"and sharp corners." + +#: fdmprinter.json +msgctxt "remove_overlapping_walls_x_enabled label" +msgid "Remove Overlapping Inner Wall Parts" +msgstr "Remove Overlapping Inner Wall Parts" + +#: fdmprinter.json +msgctxt "remove_overlapping_walls_x_enabled description" +msgid "" +"Remove parts of an inner wall that would otherwise overlap and cause over-" +"extrusion. These overlaps occur in thin pieces in a model and sharp corners." +msgstr "" +"Remove parts of an inner wall that would otherwise overlap and cause over-" +"extrusion. These overlaps occur in thin pieces in a model and sharp corners." + +#: fdmprinter.json +msgctxt "fill_perimeter_gaps label" +msgid "Fill Gaps Between Walls" +msgstr "Fill Gaps Between Walls" + +#: fdmprinter.json +msgctxt "fill_perimeter_gaps description" +msgid "" +"Fills the gaps between walls when overlapping inner wall parts are removed." +msgstr "" +"Fills the gaps between walls when overlapping inner wall parts are removed." + +#: fdmprinter.json +msgctxt "fill_perimeter_gaps option nowhere" +msgid "Nowhere" +msgstr "Nowhere" + +#: fdmprinter.json +msgctxt "fill_perimeter_gaps option everywhere" +msgid "Everywhere" +msgstr "Everywhere" + +#: fdmprinter.json +msgctxt "fill_perimeter_gaps option skin" +msgid "Skin" +msgstr "Skin" + +#: fdmprinter.json +msgctxt "travel_compensate_overlapping_walls_enabled label" +msgid "Compensate Wall Overlaps" +msgstr "Compensate Wall Overlaps" + +#: fdmprinter.json +msgctxt "travel_compensate_overlapping_walls_enabled description" +msgid "" +"Compensate the flow for parts of a wall being printed where there is already " +"a wall in place." +msgstr "" +"Compensate the flow for parts of a wall being printed where there is already " +"a wall in place." + +#: fdmprinter.json +msgctxt "xy_offset label" +msgid "Horizontal Expansion" +msgstr "Horizontal Expansion" + +#: fdmprinter.json +msgctxt "xy_offset description" +msgid "" +"Amount of offset applied to all polygons in each layer. Positive values can " +"compensate for too big holes; negative values can compensate for too small " +"holes." +msgstr "" +"Amount of offset applied to all polygons in each layer. Positive values can " +"compensate for too big holes; negative values can compensate for too small " +"holes." + +#: fdmprinter.json +msgctxt "z_seam_type label" +msgid "Z Seam Alignment" +msgstr "Z Seam Alignment" + +#: fdmprinter.json +msgctxt "z_seam_type description" +msgid "" +"Starting point of each path in a layer. When paths in consecutive layers " +"start at the same point a vertical seam may show on the print. When aligning " +"these at the back, the seam is easiest to remove. When placed randomly the " +"inaccuracies at the paths' start will be less noticeable. When taking the " +"shortest path the print will be quicker." +msgstr "" +"Starting point of each path in a layer. When paths in consecutive layers " +"start at the same point a vertical seam may show on the print. When aligning " +"these at the back, the seam is easiest to remove. When placed randomly the " +"inaccuracies at the paths' start will be less noticeable. When taking the " +"shortest path the print will be quicker." + +#: fdmprinter.json +msgctxt "z_seam_type option back" +msgid "Back" +msgstr "Back" + +#: fdmprinter.json +msgctxt "z_seam_type option shortest" +msgid "Shortest" +msgstr "Shortest" + +#: fdmprinter.json +msgctxt "z_seam_type option random" +msgid "Random" +msgstr "Random" + +#: fdmprinter.json +msgctxt "skin_no_small_gaps_heuristic label" +msgid "Ignore Small Z Gaps" +msgstr "Ignore Small Z Gaps" + +#: fdmprinter.json +msgctxt "skin_no_small_gaps_heuristic description" +msgid "" +"When the model has small vertical gaps, about 5% extra computation time can " +"be spent on generating top and bottom skin in these narrow spaces. In such " +"case, disable the setting." +msgstr "" +"When the model has small vertical gaps, about 5% extra computation time can " +"be spent on generating top and bottom skin in these narrow spaces. In such " +"case, disable the setting." + +#: fdmprinter.json +msgctxt "infill label" +msgid "Infill" +msgstr "Infill" + +#: fdmprinter.json +msgctxt "infill_sparse_density label" +msgid "Infill Density" +msgstr "Infill Density" + +#: fdmprinter.json +msgctxt "infill_sparse_density description" +msgid "Adjusts the density of infill of the print." +msgstr "Adjusts the density of infill of the print." + +#: fdmprinter.json +msgctxt "infill_line_distance label" +msgid "Line Distance" +msgstr "Line Distance" + +#: fdmprinter.json +msgctxt "infill_line_distance description" +msgid "" +"Distance between the printed infill lines. This setting is calculated by the " +"infill density and the infill line width." +msgstr "" +"Distance between the printed infill lines. This setting is calculated by the " +"infill density and the infill line width." + +#: fdmprinter.json +msgctxt "infill_pattern label" +msgid "Infill Pattern" +msgstr "Infill Pattern" + +#: fdmprinter.json +msgctxt "infill_pattern description" +msgid "" +"The pattern of the infill material of the print. The line and zig zag infill " +"swap direction on alternate layers, reducing material cost. The grid, " +"triangle and concentric patterns are fully printed every layer." +msgstr "" +"The pattern of the infill material of the print. The line and zig zag infill " +"swap direction on alternate layers, reducing material cost. The grid, " +"triangle and concentric patterns are fully printed every layer." + +#: fdmprinter.json +msgctxt "infill_pattern option grid" +msgid "Grid" +msgstr "Grid" + +#: fdmprinter.json +msgctxt "infill_pattern option lines" +msgid "Lines" +msgstr "Lines" + +#: fdmprinter.json +msgctxt "infill_pattern option triangles" +msgid "Triangles" +msgstr "Triangles" + +#: fdmprinter.json +msgctxt "infill_pattern option concentric" +msgid "Concentric" +msgstr "Concentric" + +#: fdmprinter.json +msgctxt "infill_pattern option zigzag" +msgid "Zig Zag" +msgstr "Zig Zag" + +#: fdmprinter.json +msgctxt "infill_overlap label" +msgid "Infill Overlap" +msgstr "Infill Overlap" + +#: fdmprinter.json +msgctxt "infill_overlap description" +msgid "" +"The amount of overlap between the infill and the walls. A slight overlap " +"allows the walls to connect firmly to the infill." +msgstr "" +"The amount of overlap between the infill and the walls. A slight overlap " +"allows the walls to connect firmly to the infill." + +#: fdmprinter.json +msgctxt "infill_wipe_dist label" +msgid "Infill Wipe Distance" +msgstr "Infill Wipe Distance" + +#: fdmprinter.json +msgctxt "infill_wipe_dist description" +msgid "" +"Distance of a travel move inserted after every infill line, to make the " +"infill stick to the walls better. This option is similar to infill overlap, " +"but without extrusion and only on one end of the infill line." +msgstr "" +"Distance of a travel move inserted after every infill line, to make the " +"infill stick to the walls better. This option is similar to infill overlap, " +"but without extrusion and only on one end of the infill line." + +#: fdmprinter.json +msgctxt "infill_sparse_thickness label" +msgid "Infill Layer Thickness" +msgstr "Infill Layer Thickness" + +#: fdmprinter.json +msgctxt "infill_sparse_thickness description" +msgid "" +"The thickness per layer of infill material. This value should always be a " +"multiple of the layer height and is otherwise rounded." +msgstr "" +"The thickness per layer of infill material. This value should always be a " +"multiple of the layer height and is otherwise rounded." + +#: fdmprinter.json +msgctxt "infill_before_walls label" +msgid "Infill Before Walls" +msgstr "Infill Before Walls" + +#: fdmprinter.json +msgctxt "infill_before_walls description" +msgid "" +"Print the infill before printing the walls. Printing the walls first may " +"lead to more accurate walls, but overhangs print worse. Printing the infill " +"first leads to sturdier walls, but the infill pattern might sometimes show " +"through the surface." +msgstr "" +"Print the infill before printing the walls. Printing the walls first may " +"lead to more accurate walls, but overhangs print worse. Printing the infill " +"first leads to sturdier walls, but the infill pattern might sometimes show " +"through the surface." + +#: fdmprinter.json +msgctxt "material label" +msgid "Material" +msgstr "Material" + +#: fdmprinter.json +msgctxt "material_flow_dependent_temperature label" +msgid "Auto Temperature" +msgstr "Auto Temperature" + +#: fdmprinter.json +msgctxt "material_flow_dependent_temperature description" +msgid "" +"Change the temperature for each layer automatically with the average flow " +"speed of that layer." +msgstr "" +"Change the temperature for each layer automatically with the average flow " +"speed of that layer." + +#: fdmprinter.json +msgctxt "material_print_temperature label" +msgid "Printing Temperature" +msgstr "Printing Temperature" + +#: fdmprinter.json +msgctxt "material_print_temperature description" +msgid "" +"The temperature used for printing. Set at 0 to pre-heat the printer manually." +msgstr "" +"The temperature used for printing. Set at 0 to pre-heat the printer manually." + +#: fdmprinter.json +msgctxt "material_flow_temp_graph label" +msgid "Flow Temperature Graph" +msgstr "Flow Temperature Graph" + +#: fdmprinter.json +msgctxt "material_flow_temp_graph description" +msgid "" +"Data linking material flow (in mm3 per second) to temperature (degrees " +"Celsius)." +msgstr "" +"Data linking material flow (in mm3 per second) to temperature (degrees " +"Celsius)." + +#: fdmprinter.json +msgctxt "material_extrusion_cool_down_speed label" +msgid "Extrusion Cool Down Speed Modifier" +msgstr "Extrusion Cool Down Speed Modifier" + +#: fdmprinter.json +msgctxt "material_extrusion_cool_down_speed description" +msgid "" +"The extra speed by which the nozzle cools while extruding. The same value is " +"used to signify the heat up speed lost when heating up while extruding." +msgstr "" +"The extra speed by which the nozzle cools while extruding. The same value is " +"used to signify the heat up speed lost when heating up while extruding." + +#: fdmprinter.json +msgctxt "material_bed_temperature label" +msgid "Bed Temperature" +msgstr "Bed Temperature" + +#: fdmprinter.json +msgctxt "material_bed_temperature description" +msgid "" +"The temperature used for the heated bed. Set at 0 to pre-heat the printer " +"manually." +msgstr "" +"The temperature used for the heated bed. Set at 0 to pre-heat the printer " +"manually." + +#: fdmprinter.json +msgctxt "material_diameter label" +msgid "Diameter" +msgstr "Diameter" + +#: fdmprinter.json +msgctxt "material_diameter description" +msgid "" +"Adjusts the diameter of the filament used. Match this value with the " +"diameter of the used filament." +msgstr "" +"Adjusts the diameter of the filament used. Match this value with the " +"diameter of the used filament." + +#: fdmprinter.json +msgctxt "material_flow label" +msgid "Flow" +msgstr "Flow" + +#: fdmprinter.json +msgctxt "material_flow description" +msgid "" +"Flow compensation: the amount of material extruded is multiplied by this " +"value." +msgstr "" +"Flow compensation: the amount of material extruded is multiplied by this " +"value." + +#: fdmprinter.json +msgctxt "retraction_enable label" +msgid "Enable Retraction" +msgstr "Enable Retraction" + +#: fdmprinter.json +msgctxt "retraction_enable description" +msgid "" +"Retract the filament when the nozzle is moving over a non-printed area. " +msgstr "" +"Retract the filament when the nozzle is moving over a non-printed area. " + +#: fdmprinter.json +msgctxt "retraction_amount label" +msgid "Retraction Distance" +msgstr "Retraction Distance" + +#: fdmprinter.json +msgctxt "retraction_amount description" +msgid "The length of material retracted during a retraction move." +msgstr "The length of material retracted during a retraction move." + +#: fdmprinter.json +msgctxt "retraction_speed label" +msgid "Retraction Speed" +msgstr "Retraction Speed" + +#: fdmprinter.json +msgctxt "retraction_speed description" +msgid "" +"The speed at which the filament is retracted and primed during a retraction " +"move." +msgstr "" +"The speed at which the filament is retracted and primed during a retraction " +"move." + +#: fdmprinter.json +msgctxt "retraction_retract_speed label" +msgid "Retraction Retract Speed" +msgstr "Retraction Retract Speed" + +#: fdmprinter.json +msgctxt "retraction_retract_speed description" +msgid "The speed at which the filament is retracted during a retraction move." +msgstr "The speed at which the filament is retracted during a retraction move." + +#: fdmprinter.json +msgctxt "retraction_prime_speed label" +msgid "Retraction Prime Speed" +msgstr "Retraction Prime Speed" + +#: fdmprinter.json +msgctxt "retraction_prime_speed description" +msgid "The speed at which the filament is primed during a retraction move." +msgstr "The speed at which the filament is primed during a retraction move." + +#: fdmprinter.json +msgctxt "retraction_extra_prime_amount label" +msgid "Retraction Extra Prime Amount" +msgstr "Retraction Extra Prime Amount" + +#: fdmprinter.json +msgctxt "retraction_extra_prime_amount description" +msgid "" +"Some material can ooze away during a travel move, which can be compensated " +"for here." +msgstr "" +"Some material can ooze away during a travel move, which can be compensated " +"for here." + +#: fdmprinter.json +msgctxt "retraction_min_travel label" +msgid "Retraction Minimum Travel" +msgstr "Retraction Minimum Travel" + +#: fdmprinter.json +msgctxt "retraction_min_travel description" +msgid "" +"The minimum distance of travel needed for a retraction to happen at all. " +"This helps to get fewer retractions in a small area." +msgstr "" +"The minimum distance of travel needed for a retraction to happen at all. " +"This helps to get fewer retractions in a small area." + +#: fdmprinter.json +msgctxt "retraction_count_max label" +msgid "Maximum Retraction Count" +msgstr "Maximum Retraction Count" + +#: fdmprinter.json +msgctxt "retraction_count_max description" +msgid "" +"This setting limits the number of retractions occurring within the minimum " +"extrusion distance window. Further retractions within this window will be " +"ignored. This avoids retracting repeatedly on the same piece of filament, as " +"that can flatten the filament and cause grinding issues." +msgstr "" +"This setting limits the number of retractions occurring within the minimum " +"extrusion distance window. Further retractions within this window will be " +"ignored. This avoids retracting repeatedly on the same piece of filament, as " +"that can flatten the filament and cause grinding issues." + +#: fdmprinter.json +msgctxt "retraction_extrusion_window label" +msgid "Minimum Extrusion Distance Window" +msgstr "Minimum Extrusion Distance Window" + +#: fdmprinter.json +msgctxt "retraction_extrusion_window description" +msgid "" +"The window in which the maximum retraction count is enforced. This value " +"should be approximately the same as the retraction distance, so that " +"effectively the number of times a retraction passes the same patch of " +"material is limited." +msgstr "" +"The window in which the maximum retraction count is enforced. This value " +"should be approximately the same as the retraction distance, so that " +"effectively the number of times a retraction passes the same patch of " +"material is limited." + +#: fdmprinter.json +msgctxt "retraction_hop label" +msgid "Z Hop when Retracting" +msgstr "Z Hop when Retracting" + +#: fdmprinter.json +msgctxt "retraction_hop description" +msgid "" +"Whenever a retraction is done, the build plate is lowered to create " +"clearance between the nozzle and the print. It prevents the nozzle from " +"hitting the print during travel moves, reducing the chance to knock the " +"print from the build plate." +msgstr "" +"Whenever a retraction is done, the build plate is lowered to create " +"clearance between the nozzle and the print. It prevents the nozzle from " +"hitting the print during travel moves, reducing the chance to knock the " +"print from the build plate." + +#: fdmprinter.json +msgctxt "speed label" +msgid "Speed" +msgstr "Speed" + +#: fdmprinter.json +msgctxt "speed_print label" +msgid "Print Speed" +msgstr "Print Speed" + +#: fdmprinter.json +msgctxt "speed_print description" +msgid "The speed at which printing happens." +msgstr "The speed at which printing happens." + +#: fdmprinter.json +msgctxt "speed_infill label" +msgid "Infill Speed" +msgstr "Infill Speed" + +#: fdmprinter.json +msgctxt "speed_infill description" +msgid "The speed at which infill is printed." +msgstr "The speed at which infill is printed." + +#: fdmprinter.json +msgctxt "speed_wall label" +msgid "Wall Speed" +msgstr "Wall Speed" + +#: fdmprinter.json +msgctxt "speed_wall description" +msgid "The speed at which the walls are printed." +msgstr "The speed at which the walls are printed." + +#: fdmprinter.json +msgctxt "speed_wall_0 label" +msgid "Outer Wall Speed" +msgstr "Outer Wall Speed" + +#: fdmprinter.json +msgctxt "speed_wall_0 description" +msgid "" +"The speed at which the outermost walls are printed. Printing the outer wall " +"at a lower speed improves the final skin quality. However, having a large " +"difference between the inner wall speed and the outer wall speed will effect " +"quality in a negative way." +msgstr "" +"The speed at which the outermost walls are printed. Printing the outer wall " +"at a lower speed improves the final skin quality. However, having a large " +"difference between the inner wall speed and the outer wall speed will effect " +"quality in a negative way." + +#: fdmprinter.json +msgctxt "speed_wall_x label" +msgid "Inner Wall Speed" +msgstr "Inner Wall Speed" + +#: fdmprinter.json +msgctxt "speed_wall_x description" +msgid "" +"The speed at which all inner walls are printed Printing the inner wall " +"faster than the outer wall will reduce printing time. It works well to set " +"this in between the outer wall speed and the infill speed." +msgstr "" +"The speed at which all inner walls are printed Printing the inner wall " +"faster than the outer wall will reduce printing time. It works well to set " +"this in between the outer wall speed and the infill speed." + +#: fdmprinter.json +msgctxt "speed_topbottom label" +msgid "Top/Bottom Speed" +msgstr "Top/Bottom Speed" + +#: fdmprinter.json +msgctxt "speed_topbottom description" +msgid "The speed at which top/bottom layers are printed." +msgstr "The speed at which top/bottom layers are printed." + +#: fdmprinter.json +msgctxt "speed_support label" +msgid "Support Speed" +msgstr "Support Speed" + +#: fdmprinter.json +msgctxt "speed_support description" +msgid "" +"The speed at which the support structure is printed. Printing support at " +"higher speeds can greatly reduce printing time. The surface quality of the " +"support structure is not important since it is removed after printing." +msgstr "" +"The speed at which the support structure is printed. Printing support at " +"higher speeds can greatly reduce printing time. The surface quality of the " +"support structure is not important since it is removed after printing." + +#: fdmprinter.json +msgctxt "speed_support_lines label" +msgid "Support Wall Speed" +msgstr "Support Wall Speed" + +#: fdmprinter.json +msgctxt "speed_support_lines description" +msgid "" +"The speed at which the walls of support are printed. Printing the walls at " +"lower speeds improves stability." +msgstr "" +"The speed at which the walls of support are printed. Printing the walls at " +"lower speeds improves stability." + +#: fdmprinter.json +msgctxt "speed_support_roof label" +msgid "Support Roof Speed" +msgstr "Support Roof Speed" + +#: fdmprinter.json +msgctxt "speed_support_roof description" +msgid "" +"The speed at which the roofs of support are printed. Printing the support " +"roof at lower speeds can improve overhang quality." +msgstr "" +"The speed at which the roofs of support are printed. Printing the support " +"roof at lower speeds can improve overhang quality." + +#: fdmprinter.json +msgctxt "speed_travel label" +msgid "Travel Speed" +msgstr "Travel Speed" + +#: fdmprinter.json +msgctxt "speed_travel description" +msgid "The speed at which travel moves are made." +msgstr "The speed at which travel moves are made." + +#: fdmprinter.json +msgctxt "speed_layer_0 label" +msgid "Initial Layer Speed" +msgstr "Initial Layer Speed" + +#: fdmprinter.json +msgctxt "speed_layer_0 description" +msgid "" +"The print speed for the initial layer. A lower value is advised to improve " +"adhesion to the build plate." +msgstr "" +"The print speed for the initial layer. A lower value is advised to improve " +"adhesion to the build plate." + +#: fdmprinter.json +msgctxt "skirt_speed label" +msgid "Skirt Speed" +msgstr "Skirt Speed" + +#: fdmprinter.json +msgctxt "skirt_speed description" +msgid "" +"The speed at which the skirt and brim are printed. Normally this is done at " +"the initial layer speed, but sometimes you might want to print the skirt at " +"a different speed." +msgstr "" +"The speed at which the skirt and brim are printed. Normally this is done at " +"the initial layer speed, but sometimes you might want to print the skirt at " +"a different speed." + +#: fdmprinter.json +msgctxt "speed_slowdown_layers label" +msgid "Number of Slower Layers" +msgstr "Number of Slower Layers" + +#: fdmprinter.json +msgctxt "speed_slowdown_layers description" +msgid "" +"The first few layers are printed slower than the rest of the object, to get " +"better adhesion to the build plate and improve the overall success rate of " +"prints. The speed is gradually increased over these layers." +msgstr "" +"The first few layers are printed slower than the rest of the object, to get " +"better adhesion to the build plate and improve the overall success rate of " +"prints. The speed is gradually increased over these layers." + +#: fdmprinter.json +msgctxt "travel label" +msgid "Travel" +msgstr "Travel" + +#: fdmprinter.json +msgctxt "retraction_combing label" +msgid "Enable Combing" +msgstr "Enable Combing" + +#: fdmprinter.json +msgctxt "retraction_combing description" +msgid "" +"Combing keeps the nozzle within already printed areas when traveling. This " +"results in slightly longer travel moves but reduces the need for " +"retractions. If combing is disabled, the material will retract and the " +"nozzle moves in a straight line to the next point." +msgstr "" +"Combing keeps the nozzle within already printed areas when traveling. This " +"results in slightly longer travel moves but reduces the need for " +"retractions. If combing is disabled, the material will retract and the " +"nozzle moves in a straight line to the next point." + +#: fdmprinter.json +msgctxt "travel_avoid_other_parts label" +msgid "Avoid Printed Parts" +msgstr "Avoid Printed Parts" + +#: fdmprinter.json +msgctxt "travel_avoid_other_parts description" +msgid "" +"The nozzle avoids already printed parts when traveling. This option is only " +"available when combing is enabled." +msgstr "" +"The nozzle avoids already printed parts when traveling. This option is only " +"available when combing is enabled." + +#: fdmprinter.json +msgctxt "travel_avoid_distance label" +msgid "Avoid Distance" +msgstr "Avoid Distance" + +#: fdmprinter.json +msgctxt "travel_avoid_distance description" +msgid "" +"The distance between the nozzle and already printed parts when avoiding " +"during travel moves." +msgstr "" +"The distance between the nozzle and already printed parts when avoiding " +"during travel moves." + +#: fdmprinter.json +msgctxt "coasting_enable label" +msgid "Enable Coasting" +msgstr "Enable Coasting" + +#: fdmprinter.json +msgctxt "coasting_enable description" +msgid "" +"Coasting replaces the last part of an extrusion path with a travel path. The " +"oozed material is used to print the last piece of the extrusion path in " +"order to reduce stringing." +msgstr "" +"Coasting replaces the last part of an extrusion path with a travel path. The " +"oozed material is used to print the last piece of the extrusion path in " +"order to reduce stringing." + +#: fdmprinter.json +msgctxt "coasting_volume label" +msgid "Coasting Volume" +msgstr "Coasting Volume" + +#: fdmprinter.json +msgctxt "coasting_volume description" +msgid "" +"The volume otherwise oozed. This value should generally be close to the " +"nozzle diameter cubed." +msgstr "" +"The volume otherwise oozed. This value should generally be close to the " +"nozzle diameter cubed." + +#: fdmprinter.json +msgctxt "coasting_min_volume label" +msgid "Minimum Volume Before Coasting" +msgstr "Minimum Volume Before Coasting" + +#: fdmprinter.json +msgctxt "coasting_min_volume description" +msgid "" +"The lowest volume an extrusion path should have before allowing coasting. " +"For smaller extrusion paths, less pressure has been built up in the bowden " +"tube and so the coasted volume is scaled linearly. This value should always " +"be larger than the Coasting Volume." +msgstr "" +"The lowest volume an extrusion path should have before allowing coasting. " +"For smaller extrusion paths, less pressure has been built up in the bowden " +"tube and so the coasted volume is scaled linearly. This value should always " +"be larger than the Coasting Volume." + +#: fdmprinter.json +msgctxt "coasting_speed label" +msgid "Coasting Speed" +msgstr "Coasting Speed" + +#: fdmprinter.json +msgctxt "coasting_speed description" +msgid "" +"The speed by which to move during coasting, relative to the speed of the " +"extrusion path. A value slightly under 100% is advised, since during the " +"coasting move the pressure in the bowden tube drops." +msgstr "" +"The speed by which to move during coasting, relative to the speed of the " +"extrusion path. A value slightly under 100% is advised, since during the " +"coasting move the pressure in the bowden tube drops." + +#: fdmprinter.json +msgctxt "cooling label" +msgid "Cooling" +msgstr "Cooling" + +#: fdmprinter.json +msgctxt "cool_fan_enabled label" +msgid "Enable Cooling Fans" +msgstr "Enable Cooling Fans" + +#: fdmprinter.json +msgctxt "cool_fan_enabled description" +msgid "" +"Enables the cooling fans while printing. The fans improve print quality on " +"layers with short layer times and bridging / overhangs." +msgstr "" +"Enables the cooling fans while printing. The fans improve print quality on " +"layers with short layer times and bridging / overhangs." + +#: fdmprinter.json +msgctxt "cool_fan_speed label" +msgid "Fan Speed" +msgstr "Fan Speed" + +#: fdmprinter.json +msgctxt "cool_fan_speed description" +msgid "The speed at which the cooling fans spin." +msgstr "The speed at which the cooling fans spin." + +#: fdmprinter.json +msgctxt "cool_fan_speed_min label" +msgid "Regular Fan Speed" +msgstr "Regular Fan Speed" + +#: fdmprinter.json +msgctxt "cool_fan_speed_min description" +msgid "" +"The speed at which the fans spin before hitting the threshold. When a layer " +"prints faster than the threshold, the fan speed gradually inclines towards " +"the maximum fan speed." +msgstr "" +"The speed at which the fans spin before hitting the threshold. When a layer " +"prints faster than the threshold, the fan speed gradually inclines towards " +"the maximum fan speed." + +#: fdmprinter.json +msgctxt "cool_fan_speed_max label" +msgid "Maximum Fan Speed" +msgstr "Maximum Fan Speed" + +#: fdmprinter.json +msgctxt "cool_fan_speed_max description" +msgid "" +"The speed at which the fans spin on the minimum layer time. The fan speed " +"gradually increases between the regular fan speed and maximum fan speed when " +"the threshold is hit." +msgstr "" +"The speed at which the fans spin on the minimum layer time. The fan speed " +"gradually increases between the regular fan speed and maximum fan speed when " +"the threshold is hit." + +#: fdmprinter.json +msgctxt "cool_min_layer_time_fan_speed_max label" +msgid "Regular/Maximum Fan Speed Threshold" +msgstr "Regular/Maximum Fan Speed Threshold" + +#: fdmprinter.json +msgctxt "cool_min_layer_time_fan_speed_max description" +msgid "" +"The layer time which sets the threshold between regular fan speed and " +"maximum fan speed. Layers that print slower than this time use regular fan " +"speed. For faster layers the fan speed gradually increases towards the " +"maximum fan speed." +msgstr "" +"The layer time which sets the threshold between regular fan speed and " +"maximum fan speed. Layers that print slower than this time use regular fan " +"speed. For faster layers the fan speed gradually increases towards the " +"maximum fan speed." + +#: fdmprinter.json +msgctxt "cool_fan_full_at_height label" +msgid "Regular Fan Speed at Height" +msgstr "Regular Fan Speed at Height" + +#: fdmprinter.json +msgctxt "cool_fan_full_at_height description" +msgid "" +"The height at which the fans spin on regular fan speed. At the layers below " +"the fan speed gradually increases from zero to regular fan speed." +msgstr "" +"The height at which the fans spin on regular fan speed. At the layers below " +"the fan speed gradually increases from zero to regular fan speed." + +#: fdmprinter.json +msgctxt "cool_fan_full_layer label" +msgid "Regular Fan Speed at Layer" +msgstr "Regular Fan Speed at Layer" + +#: fdmprinter.json +msgctxt "cool_fan_full_layer description" +msgid "" +"The layer at which the fans spin on regular fan speed. If regular fan speed " +"at height is set, this value is calculated and rounded to a whole number." +msgstr "" +"The layer at which the fans spin on regular fan speed. If regular fan speed " +"at height is set, this value is calculated and rounded to a whole number." + +#: fdmprinter.json +msgctxt "cool_min_layer_time label" +msgid "Minimum Layer Time" +msgstr "Minimum Layer Time" + +#: fdmprinter.json +msgctxt "cool_min_layer_time description" +msgid "" +"The minimum time spent in a layer. This forces the printer to slow down, to " +"at least spend the time set here in one layer. This allows the printed " +"material to cool down properly before printing the next layer." +msgstr "" +"The minimum time spent in a layer. This forces the printer to slow down, to " +"at least spend the time set here in one layer. This allows the printed " +"material to cool down properly before printing the next layer." + +#: fdmprinter.json +msgctxt "cool_min_speed label" +msgid "Minimum Speed" +msgstr "Minimum Speed" + +#: fdmprinter.json +msgctxt "cool_min_speed description" +msgid "" +"The minimum print speed, despite slowing down due to the minimum layer time. " +"When the printer would slow down too much, the pressure in the nozzle would " +"be too low and result in bad print quality." +msgstr "" +"The minimum print speed, despite slowing down due to the minimum layer time. " +"When the printer would slow down too much, the pressure in the nozzle would " +"be too low and result in bad print quality." + +#: fdmprinter.json +msgctxt "cool_lift_head label" +msgid "Lift Head" +msgstr "Lift Head" + +#: fdmprinter.json +msgctxt "cool_lift_head description" +msgid "" +"When the minimum speed is hit because of minimum layer time, lift the head " +"away from the print and wait the extra time until the minimum layer time is " +"reached." +msgstr "" +"When the minimum speed is hit because of minimum layer time, lift the head " +"away from the print and wait the extra time until the minimum layer time is " +"reached." + +#: fdmprinter.json +msgctxt "draft_shield_enabled label" +msgid "Enable Draft Shield" +msgstr "Enable Draft Shield" + +#: fdmprinter.json +msgctxt "draft_shield_enabled description" +msgid "" +"This will create a wall around the object, which traps (hot) air and shields " +"against exterior airflow. Especially useful for materials which warp easily." +msgstr "" +"This will create a wall around the object, which traps (hot) air and shields " +"against exterior airflow. Especially useful for materials which warp easily." + +#: fdmprinter.json +msgctxt "draft_shield_dist label" +msgid "Draft Shield X/Y Distance" +msgstr "Draft Shield X/Y Distance" + +#: fdmprinter.json +msgctxt "draft_shield_dist description" +msgid "Distance of the draft shield from the print, in the X/Y directions." +msgstr "Distance of the draft shield from the print, in the X/Y directions." + +#: fdmprinter.json +msgctxt "draft_shield_height_limitation label" +msgid "Draft Shield Limitation" +msgstr "Draft Shield Limitation" + +#: fdmprinter.json +msgctxt "draft_shield_height_limitation description" +msgid "" +"Set the height of the draft shield. Choose to print the draft shield at the " +"full height of the object or at a limited height." +msgstr "" +"Set the height of the draft shield. Choose to print the draft shield at the " +"full height of the object or at a limited height." + +#: fdmprinter.json +msgctxt "draft_shield_height_limitation option full" +msgid "Full" +msgstr "Full" + +#: fdmprinter.json +msgctxt "draft_shield_height_limitation option limited" +msgid "Limited" +msgstr "Limited" + +#: fdmprinter.json +msgctxt "draft_shield_height label" +msgid "Draft Shield Height" +msgstr "Draft Shield Height" + +#: fdmprinter.json +msgctxt "draft_shield_height description" +msgid "" +"Height limitation of the draft shield. Above this height no draft shield " +"will be printed." +msgstr "" +"Height limitation of the draft shield. Above this height no draft shield " +"will be printed." + +#: fdmprinter.json +msgctxt "support label" +msgid "Support" +msgstr "Support" + +#: fdmprinter.json +msgctxt "support_enable label" +msgid "Enable Support" +msgstr "Enable Support" + +#: fdmprinter.json +msgctxt "support_enable description" +msgid "" +"Enable support structures. These structures support parts of the model with " +"severe overhangs." +msgstr "" +"Enable support structures. These structures support parts of the model with " +"severe overhangs." + +#: fdmprinter.json +msgctxt "support_type label" +msgid "Placement" +msgstr "Placement" + +#: fdmprinter.json +msgctxt "support_type description" +msgid "" +"Adjusts the placement of the support structures. The placement can be set to " +"touching build plate or everywhere. When set to everywhere the support " +"structures will also be printed on the model." +msgstr "" +"Adjusts the placement of the support structures. The placement can be set to " +"touching build plate or everywhere. When set to everywhere the support " +"structures will also be printed on the model." + +#: fdmprinter.json +msgctxt "support_type option buildplate" +msgid "Touching Buildplate" +msgstr "Touching Buildplate" + +#: fdmprinter.json +msgctxt "support_type option everywhere" +msgid "Everywhere" +msgstr "Everywhere" + +#: fdmprinter.json +msgctxt "support_angle label" +msgid "Overhang Angle" +msgstr "Overhang Angle" + +#: fdmprinter.json +msgctxt "support_angle description" +msgid "" +"The minimum angle of overhangs for which support is added. At a value of 0° " +"all overhangs are supported, 90° will not provide any support." +msgstr "" +"The minimum angle of overhangs for which support is added. At a value of 0° " +"all overhangs are supported, 90° will not provide any support." + +#: fdmprinter.json +msgctxt "support_pattern label" +msgid "Support Pattern" +msgstr "Support Pattern" + +#: fdmprinter.json +msgctxt "support_pattern description" +msgid "" +"The pattern of the support structures of the print. The different options " +"available result in sturdy or easy to remove support." +msgstr "" +"The pattern of the support structures of the print. The different options " +"available result in sturdy or easy to remove support." + +#: fdmprinter.json +msgctxt "support_pattern option lines" +msgid "Lines" +msgstr "Lines" + +#: fdmprinter.json +msgctxt "support_pattern option grid" +msgid "Grid" +msgstr "Grid" + +#: fdmprinter.json +msgctxt "support_pattern option triangles" +msgid "Triangles" +msgstr "Triangles" + +#: fdmprinter.json +msgctxt "support_pattern option concentric" +msgid "Concentric" +msgstr "Concentric" + +#: fdmprinter.json +msgctxt "support_pattern option zigzag" +msgid "Zig Zag" +msgstr "Zig Zag" + +#: fdmprinter.json +msgctxt "support_connect_zigzags label" +msgid "Connect ZigZags" +msgstr "Connect ZigZags" + +#: fdmprinter.json +msgctxt "support_connect_zigzags description" +msgid "" +"Connect the ZigZags. This will increase the strength of the zig zag support " +"structure." +msgstr "" +"Connect the ZigZags. This will increase the strength of the zig zag support " +"structure." + +#: fdmprinter.json +msgctxt "support_infill_rate label" +msgid "Support Density" +msgstr "Support Density" + +#: fdmprinter.json +msgctxt "support_infill_rate description" +msgid "" +"Adjusts the density of the support structure. A higher value results in " +"better overhangs, but the supports are harder to remove." +msgstr "" +"Adjusts the density of the support structure. A higher value results in " +"better overhangs, but the supports are harder to remove." + +#: fdmprinter.json +msgctxt "support_line_distance label" +msgid "Support Line Distance" +msgstr "Support Line Distance" + +#: fdmprinter.json +msgctxt "support_line_distance description" +msgid "" +"Distance between the printed support structure lines. This setting is " +"calculated by the support density." +msgstr "" +"Distance between the printed support structure lines. This setting is " +"calculated by the support density." + +#: fdmprinter.json +msgctxt "support_xy_distance label" +msgid "X/Y Distance" +msgstr "X/Y Distance" + +#: fdmprinter.json +msgctxt "support_xy_distance description" +msgid "Distance of the support structure from the print in the X/Y directions." +msgstr "" +"Distance of the support structure from the print in the X/Y directions." + +#: fdmprinter.json +msgctxt "support_z_distance label" +msgid "Z Distance" +msgstr "Z Distance" + +#: fdmprinter.json +msgctxt "support_z_distance description" +msgid "" +"Distance from the top/bottom of the support structure to the print. This gap " +"provides clearance to remove the supports after the model is printed. This " +"value is rounded down to a multiple of the layer height." +msgstr "" +"Distance from the top/bottom of the support structure to the print. This gap " +"provides clearance to remove the supports after the model is printed. This " +"value is rounded down to a multiple of the layer height." + +#: fdmprinter.json +msgctxt "support_top_distance label" +msgid "Top Distance" +msgstr "Top Distance" + +#: fdmprinter.json +msgctxt "support_top_distance description" +msgid "Distance from the top of the support to the print." +msgstr "Distance from the top of the support to the print." + +#: fdmprinter.json +msgctxt "support_bottom_distance label" +msgid "Bottom Distance" +msgstr "Bottom Distance" + +#: fdmprinter.json +msgctxt "support_bottom_distance description" +msgid "Distance from the print to the bottom of the support." +msgstr "Distance from the print to the bottom of the support." + +#: fdmprinter.json +msgctxt "support_bottom_stair_step_height label" +msgid "Stair Step Height" +msgstr "Stair Step Height" + +#: fdmprinter.json +msgctxt "support_bottom_stair_step_height description" +msgid "" +"The height of the steps of the stair-like bottom of support resting on the " +"model. A low value makes the support harder to remove, but too high values " +"can lead to unstable support structures." +msgstr "" +"The height of the steps of the stair-like bottom of support resting on the " +"model. A low value makes the support harder to remove, but too high values " +"can lead to unstable support structures." + +#: fdmprinter.json +msgctxt "support_join_distance label" +msgid "Join Distance" +msgstr "Join Distance" + +#: fdmprinter.json +msgctxt "support_join_distance description" +msgid "" +"The maximum distance between support structures in the X/Y directions. When " +"seperate structures are closer together than this value, the structures " +"merge into one." +msgstr "" +"The maximum distance between support structures in the X/Y directions. When " +"seperate structures are closer together than this value, the structures " +"merge into one." + +#: fdmprinter.json +msgctxt "support_offset label" +msgid "Horizontal Expansion" +msgstr "Horizontal Expansion" + +#: fdmprinter.json +msgctxt "support_offset description" +msgid "" +"Amount of offset applied to all support polygons in each layer. Positive " +"values can smooth out the support areas and result in more sturdy support." +msgstr "" +"Amount of offset applied to all support polygons in each layer. Positive " +"values can smooth out the support areas and result in more sturdy support." + +#: fdmprinter.json +msgctxt "support_area_smoothing label" +msgid "Area Smoothing" +msgstr "Area Smoothing" + +#: fdmprinter.json +msgctxt "support_area_smoothing description" +msgid "" +"Maximum distance in the X/Y directions of a line segment which is to be " +"smoothed out. Ragged lines are introduced by the join distance and support " +"bridge, which cause the machine to resonate. Smoothing the support areas " +"won't cause them to break with the constraints, except it might change the " +"overhang." +msgstr "" +"Maximum distance in the X/Y directions of a line segment which is to be " +"smoothed out. Ragged lines are introduced by the join distance and support " +"bridge, which cause the machine to resonate. Smoothing the support areas " +"won't cause them to break with the constraints, except it might change the " +"overhang." + +#: fdmprinter.json +msgctxt "support_roof_enable label" +msgid "Enable Support Roof" +msgstr "Enable Support Roof" + +#: fdmprinter.json +msgctxt "support_roof_enable description" +msgid "" +"Generate a dense top skin at the top of the support on which the model is " +"printed." +msgstr "" +"Generate a dense top skin at the top of the support on which the model is " +"printed." + +#: fdmprinter.json +msgctxt "support_roof_height label" +msgid "Support Roof Thickness" +msgstr "Support Roof Thickness" + +#: fdmprinter.json +msgctxt "support_roof_height description" +msgid "The thickness of the support roofs." +msgstr "The thickness of the support roofs." + +#: fdmprinter.json +msgctxt "support_roof_density label" +msgid "Support Roof Density" +msgstr "Support Roof Density" + +#: fdmprinter.json +msgctxt "support_roof_density description" +msgid "" +"Adjusts the density of the roof of the support structure. A higher value " +"results in better overhangs, but the supports are harder to remove." +msgstr "" +"Adjusts the density of the roof of the support structure. A higher value " +"results in better overhangs, but the supports are harder to remove." + +#: fdmprinter.json +msgctxt "support_roof_line_distance label" +msgid "Support Roof Line Distance" +msgstr "Support Roof Line Distance" + +#: fdmprinter.json +msgctxt "support_roof_line_distance description" +msgid "" +"Distance between the printed support roof lines. This setting is calculated " +"by the support roof Density, but can be adjusted separately." +msgstr "" +"Distance between the printed support roof lines. This setting is calculated " +"by the support roof Density, but can be adjusted separately." + +#: fdmprinter.json +msgctxt "support_roof_pattern label" +msgid "Support Roof Pattern" +msgstr "Support Roof Pattern" + +#: fdmprinter.json +msgctxt "support_roof_pattern description" +msgid "The pattern with which the top of the support is printed." +msgstr "The pattern with which the top of the support is printed." + +#: fdmprinter.json +msgctxt "support_roof_pattern option lines" +msgid "Lines" +msgstr "Lines" + +#: fdmprinter.json +msgctxt "support_roof_pattern option grid" +msgid "Grid" +msgstr "Grid" + +#: fdmprinter.json +msgctxt "support_roof_pattern option triangles" +msgid "Triangles" +msgstr "Triangles" + +#: fdmprinter.json +msgctxt "support_roof_pattern option concentric" +msgid "Concentric" +msgstr "Concentric" + +#: fdmprinter.json +msgctxt "support_roof_pattern option zigzag" +msgid "Zig Zag" +msgstr "Zig Zag" + +#: fdmprinter.json +msgctxt "support_conical_enabled label" +msgid "Conical Support" +msgstr "Conical Support" + +#: fdmprinter.json +msgctxt "support_conical_enabled description" +msgid "" +"Experimental feature: Make support areas smaller at the bottom than at the " +"overhang." +msgstr "" +"Experimental feature: Make support areas smaller at the bottom than at the " +"overhang." + +#: fdmprinter.json +msgctxt "support_conical_angle label" +msgid "Cone Angle" +msgstr "Cone Angle" + +#: fdmprinter.json +msgctxt "support_conical_angle description" +msgid "" +"The angle of the tilt of conical support. With 0 degrees being vertical, and " +"90 degrees being horizontal. Smaller angles cause the support to be more " +"sturdy, but consist of more material. Negative angles cause the base of the " +"support to be wider than the top." +msgstr "" +"The angle of the tilt of conical support. With 0 degrees being vertical, and " +"90 degrees being horizontal. Smaller angles cause the support to be more " +"sturdy, but consist of more material. Negative angles cause the base of the " +"support to be wider than the top." + +#: fdmprinter.json +msgctxt "support_conical_min_width label" +msgid "Cone Minimal Width" +msgstr "Cone Minimal Width" + +#: fdmprinter.json +msgctxt "support_conical_min_width description" +msgid "" +"Minimal width to which the base of the conical support area is reduced. " +"Small widths can lead to unstable support structures." +msgstr "" +"Minimal width to which the base of the conical support area is reduced. " +"Small widths can lead to unstable support structures." + +#: fdmprinter.json +msgctxt "support_use_towers label" +msgid "Use Towers" +msgstr "Use Towers" + +#: fdmprinter.json +msgctxt "support_use_towers description" +msgid "" +"Use specialized towers to support tiny overhang areas. These towers have a " +"larger diameter than the region they support. Near the overhang the towers' " +"diameter decreases, forming a roof." +msgstr "" +"Use specialized towers to support tiny overhang areas. These towers have a " +"larger diameter than the region they support. Near the overhang the towers' " +"diameter decreases, forming a roof." + +#: fdmprinter.json +msgctxt "support_tower_diameter label" +msgid "Tower Diameter" +msgstr "Tower Diameter" + +#: fdmprinter.json +msgctxt "support_tower_diameter description" +msgid "The diameter of a special tower." +msgstr "The diameter of a special tower." + +#: fdmprinter.json +msgctxt "support_minimal_diameter label" +msgid "Minimum Diameter" +msgstr "Minimum Diameter" + +#: fdmprinter.json +msgctxt "support_minimal_diameter description" +msgid "" +"Minimum diameter in the X/Y directions of a small area which is to be " +"supported by a specialized support tower." +msgstr "" +"Minimum diameter in the X/Y directions of a small area which is to be " +"supported by a specialized support tower." + +#: fdmprinter.json +msgctxt "support_tower_roof_angle label" +msgid "Tower Roof Angle" +msgstr "Tower Roof Angle" + +#: fdmprinter.json +msgctxt "support_tower_roof_angle description" +msgid "" +"The angle of a rooftop of a tower. A higher value results in pointed tower " +"roofs, a lower value results in flattened tower roofs." +msgstr "" +"The angle of a rooftop of a tower. A higher value results in pointed tower " +"roofs, a lower value results in flattened tower roofs." + +#: fdmprinter.json +msgctxt "platform_adhesion label" +msgid "Platform Adhesion" +msgstr "Platform Adhesion" + +#: fdmprinter.json +msgctxt "adhesion_type label" +msgid "Type" +msgstr "Type" + +#: fdmprinter.json +msgctxt "adhesion_type description" +msgid "" +"Different options that help to improve both priming your extrusion and " +"adhesion to the build plate. Brim adds a single layer flat area around the " +"base of your object to prevent warping. Raft adds a thick grid with a roof " +"below the object. Skirt is a line printed around the object, but not " +"connected to the model." +msgstr "" +"Different options that help to improve both priming your extrusion and " +"adhesion to the build plate. Brim adds a single layer flat area around the " +"base of your object to prevent warping. Raft adds a thick grid with a roof " +"below the object. Skirt is a line printed around the object, but not " +"connected to the model." + +#: fdmprinter.json +msgctxt "adhesion_type option skirt" +msgid "Skirt" +msgstr "Skirt" + +#: fdmprinter.json +msgctxt "adhesion_type option brim" +msgid "Brim" +msgstr "Brim" + +#: fdmprinter.json +msgctxt "adhesion_type option raft" +msgid "Raft" +msgstr "Raft" + +#: fdmprinter.json +msgctxt "skirt_line_count label" +msgid "Skirt Line Count" +msgstr "Skirt Line Count" + +#: fdmprinter.json +msgctxt "skirt_line_count description" +msgid "" +"Multiple skirt lines help to prime your extrusion better for small objects. " +"Setting this to 0 will disable the skirt." +msgstr "" +"Multiple skirt lines help to prime your extrusion better for small objects. " +"Setting this to 0 will disable the skirt." + +#: fdmprinter.json +msgctxt "skirt_gap label" +msgid "Skirt Distance" +msgstr "Skirt Distance" + +#: fdmprinter.json +msgctxt "skirt_gap description" +msgid "" +"The horizontal distance between the skirt and the first layer of the print.\n" +"This is the minimum distance, multiple skirt lines will extend outwards from " +"this distance." +msgstr "" +"The horizontal distance between the skirt and the first layer of the print.\n" +"This is the minimum distance, multiple skirt lines will extend outwards from " +"this distance." + +#: fdmprinter.json +msgctxt "skirt_minimal_length label" +msgid "Skirt Minimum Length" +msgstr "Skirt Minimum Length" + +#: fdmprinter.json +msgctxt "skirt_minimal_length description" +msgid "" +"The minimum length of the skirt. If this length is not reached by the skirt " +"line count, more skirt lines will be added until the minimum length is " +"reached. Note: If the line count is set to 0 this is ignored." +msgstr "" +"The minimum length of the skirt. If this length is not reached by the skirt " +"line count, more skirt lines will be added until the minimum length is " +"reached. Note: If the line count is set to 0 this is ignored." + +#: fdmprinter.json +msgctxt "brim_width label" +msgid "Brim Width" +msgstr "Brim Width" + +#: fdmprinter.json +msgctxt "brim_width description" +msgid "" +"The distance from the model to the outermost brim line. A larger brim " +"enhances adhesion to the build plate, but also reduces the effective print " +"area." +msgstr "" +"The distance from the model to the outermost brim line. A larger brim " +"enhances adhesion to the build plate, but also reduces the effective print " +"area." + +#: fdmprinter.json +msgctxt "brim_line_count label" +msgid "Brim Line Count" +msgstr "Brim Line Count" + +#: fdmprinter.json +msgctxt "brim_line_count description" +msgid "" +"The number of lines used for a brim. More brim lines enhance adhesion to the " +"build plate, but also reduces the effective print area." +msgstr "" +"The number of lines used for a brim. More brim lines enhance adhesion to the " +"build plate, but also reduces the effective print area." + +#: fdmprinter.json +msgctxt "raft_margin label" +msgid "Raft Extra Margin" +msgstr "Raft Extra Margin" + +#: fdmprinter.json +msgctxt "raft_margin description" +msgid "" +"If the raft is enabled, this is the extra raft area around the object which " +"is also given a raft. Increasing this margin will create a stronger raft " +"while using more material and leaving less area for your print." +msgstr "" +"If the raft is enabled, this is the extra raft area around the object which " +"is also given a raft. Increasing this margin will create a stronger raft " +"while using more material and leaving less area for your print." + +#: fdmprinter.json +msgctxt "raft_airgap label" +msgid "Raft Air-gap" +msgstr "Raft Air-gap" + +#: fdmprinter.json +msgctxt "raft_airgap description" +msgid "" +"The gap between the final raft layer and the first layer of the object. Only " +"the first layer is raised by this amount to lower the bonding between the " +"raft layer and the object. Makes it easier to peel off the raft." +msgstr "" +"The gap between the final raft layer and the first layer of the object. Only " +"the first layer is raised by this amount to lower the bonding between the " +"raft layer and the object. Makes it easier to peel off the raft." + +#: fdmprinter.json +msgctxt "raft_surface_layers label" +msgid "Raft Top Layers" +msgstr "Raft Top Layers" + +#: fdmprinter.json +msgctxt "raft_surface_layers description" +msgid "" +"The number of top layers on top of the 2nd raft layer. These are fully " +"filled layers that the object sits on. 2 layers result in a smoother top " +"surface than 1." +msgstr "" +"The number of top layers on top of the 2nd raft layer. These are fully " +"filled layers that the object sits on. 2 layers result in a smoother top " +"surface than 1." + +#: fdmprinter.json +msgctxt "raft_surface_thickness label" +msgid "Raft Top Layer Thickness" +msgstr "Raft Top Layer Thickness" + +#: fdmprinter.json +msgctxt "raft_surface_thickness description" +msgid "Layer thickness of the top raft layers." +msgstr "Layer thickness of the top raft layers." + +#: fdmprinter.json +msgctxt "raft_surface_line_width label" +msgid "Raft Top Line Width" +msgstr "Raft Top Line Width" + +#: fdmprinter.json +msgctxt "raft_surface_line_width description" +msgid "" +"Width of the lines in the top surface of the raft. These can be thin lines " +"so that the top of the raft becomes smooth." +msgstr "" +"Width of the lines in the top surface of the raft. These can be thin lines " +"so that the top of the raft becomes smooth." + +#: fdmprinter.json +msgctxt "raft_surface_line_spacing label" +msgid "Raft Top Spacing" +msgstr "Raft Top Spacing" + +#: fdmprinter.json +msgctxt "raft_surface_line_spacing description" +msgid "" +"The distance between the raft lines for the top raft layers. The spacing " +"should be equal to the line width, so that the surface is solid." +msgstr "" +"The distance between the raft lines for the top raft layers. The spacing " +"should be equal to the line width, so that the surface is solid." + +#: fdmprinter.json +msgctxt "raft_interface_thickness label" +msgid "Raft Middle Thickness" +msgstr "Raft Middle Thickness" + +#: fdmprinter.json +msgctxt "raft_interface_thickness description" +msgid "Layer thickness of the middle raft layer." +msgstr "Layer thickness of the middle raft layer." + +#: fdmprinter.json +msgctxt "raft_interface_line_width label" +msgid "Raft Middle Line Width" +msgstr "Raft Middle Line Width" + +#: fdmprinter.json +msgctxt "raft_interface_line_width description" +msgid "" +"Width of the lines in the middle raft layer. Making the second layer extrude " +"more causes the lines to stick to the bed." +msgstr "" +"Width of the lines in the middle raft layer. Making the second layer extrude " +"more causes the lines to stick to the bed." + +#: fdmprinter.json +msgctxt "raft_interface_line_spacing label" +msgid "Raft Middle Spacing" +msgstr "Raft Middle Spacing" + +#: fdmprinter.json +msgctxt "raft_interface_line_spacing description" +msgid "" +"The distance between the raft lines for the middle raft layer. The spacing " +"of the middle should be quite wide, while being dense enough to support the " +"top raft layers." +msgstr "" +"The distance between the raft lines for the middle raft layer. The spacing " +"of the middle should be quite wide, while being dense enough to support the " +"top raft layers." + +#: fdmprinter.json +msgctxt "raft_base_thickness label" +msgid "Raft Base Thickness" +msgstr "Raft Base Thickness" + +#: fdmprinter.json +msgctxt "raft_base_thickness description" +msgid "" +"Layer thickness of the base raft layer. This should be a thick layer which " +"sticks firmly to the printer bed." +msgstr "" +"Layer thickness of the base raft layer. This should be a thick layer which " +"sticks firmly to the printer bed." + +#: fdmprinter.json +msgctxt "raft_base_line_width label" +msgid "Raft Base Line Width" +msgstr "Raft Base Line Width" + +#: fdmprinter.json +msgctxt "raft_base_line_width description" +msgid "" +"Width of the lines in the base raft layer. These should be thick lines to " +"assist in bed adhesion." +msgstr "" +"Width of the lines in the base raft layer. These should be thick lines to " +"assist in bed adhesion." + +#: fdmprinter.json +msgctxt "raft_base_line_spacing label" +msgid "Raft Line Spacing" +msgstr "Raft Line Spacing" + +#: fdmprinter.json +msgctxt "raft_base_line_spacing description" +msgid "" +"The distance between the raft lines for the base raft layer. Wide spacing " +"makes for easy removal of the raft from the build plate." +msgstr "" +"The distance between the raft lines for the base raft layer. Wide spacing " +"makes for easy removal of the raft from the build plate." + +#: fdmprinter.json +msgctxt "raft_speed label" +msgid "Raft Print Speed" +msgstr "Raft Print Speed" + +#: fdmprinter.json +msgctxt "raft_speed description" +msgid "The speed at which the raft is printed." +msgstr "The speed at which the raft is printed." + +#: fdmprinter.json +msgctxt "raft_surface_speed label" +msgid "Raft Surface Print Speed" +msgstr "Raft Surface Print Speed" + +#: fdmprinter.json +msgctxt "raft_surface_speed description" +msgid "" +"The speed at which the surface raft layers are printed. These should be " +"printed a bit slower, so that the nozzle can slowly smooth out adjacent " +"surface lines." +msgstr "" +"The speed at which the surface raft layers are printed. These should be " +"printed a bit slower, so that the nozzle can slowly smooth out adjacent " +"surface lines." + +#: fdmprinter.json +msgctxt "raft_interface_speed label" +msgid "Raft Interface Print Speed" +msgstr "Raft Interface Print Speed" + +#: fdmprinter.json +msgctxt "raft_interface_speed description" +msgid "" +"The speed at which the interface raft layer is printed. This should be " +"printed quite slowly, as the volume of material coming out of the nozzle is " +"quite high." +msgstr "" +"The speed at which the interface raft layer is printed. This should be " +"printed quite slowly, as the volume of material coming out of the nozzle is " +"quite high." + +#: fdmprinter.json +msgctxt "raft_base_speed label" +msgid "Raft Base Print Speed" +msgstr "Raft Base Print Speed" + +#: fdmprinter.json +msgctxt "raft_base_speed description" +msgid "" +"The speed at which the base raft layer is printed. This should be printed " +"quite slowly, as the volume of material coming out of the nozzle is quite " +"high." +msgstr "" +"The speed at which the base raft layer is printed. This should be printed " +"quite slowly, as the volume of material coming out of the nozzle is quite " +"high." + +#: fdmprinter.json +msgctxt "raft_fan_speed label" +msgid "Raft Fan Speed" +msgstr "Raft Fan Speed" + +#: fdmprinter.json +msgctxt "raft_fan_speed description" +msgid "The fan speed for the raft." +msgstr "The fan speed for the raft." + +#: fdmprinter.json +msgctxt "raft_surface_fan_speed label" +msgid "Raft Surface Fan Speed" +msgstr "Raft Surface Fan Speed" + +#: fdmprinter.json +msgctxt "raft_surface_fan_speed description" +msgid "The fan speed for the surface raft layers." +msgstr "The fan speed for the surface raft layers." + +#: fdmprinter.json +msgctxt "raft_interface_fan_speed label" +msgid "Raft Interface Fan Speed" +msgstr "Raft Interface Fan Speed" + +#: fdmprinter.json +msgctxt "raft_interface_fan_speed description" +msgid "The fan speed for the interface raft layer." +msgstr "The fan speed for the interface raft layer." + +#: fdmprinter.json +msgctxt "raft_base_fan_speed label" +msgid "Raft Base Fan Speed" +msgstr "Raft Base Fan Speed" + +#: fdmprinter.json +msgctxt "raft_base_fan_speed description" +msgid "The fan speed for the base raft layer." +msgstr "The fan speed for the base raft layer." + +#: fdmprinter.json +msgctxt "meshfix label" +msgid "Mesh Fixes" +msgstr "Mesh Fixes" + +#: fdmprinter.json +msgctxt "meshfix_union_all label" +msgid "Union Overlapping Volumes" +msgstr "Union Overlapping Volumes" + +#: fdmprinter.json +msgctxt "meshfix_union_all description" +msgid "" +"Ignore the internal geometry arising from overlapping volumes and print the " +"volumes as one. This may cause internal cavities to disappear." +msgstr "" +"Ignore the internal geometry arising from overlapping volumes and print the " +"volumes as one. This may cause internal cavities to disappear." + +#: fdmprinter.json +msgctxt "meshfix_union_all_remove_holes label" +msgid "Remove All Holes" +msgstr "Remove All Holes" + +#: fdmprinter.json +msgctxt "meshfix_union_all_remove_holes description" +msgid "" +"Remove the holes in each layer and keep only the outside shape. This will " +"ignore any invisible internal geometry. However, it also ignores layer holes " +"which can be viewed from above or below." +msgstr "" +"Remove the holes in each layer and keep only the outside shape. This will " +"ignore any invisible internal geometry. However, it also ignores layer holes " +"which can be viewed from above or below." + +#: fdmprinter.json +msgctxt "meshfix_extensive_stitching label" +msgid "Extensive Stitching" +msgstr "Extensive Stitching" + +#: fdmprinter.json +msgctxt "meshfix_extensive_stitching description" +msgid "" +"Extensive stitching tries to stitch up open holes in the mesh by closing the " +"hole with touching polygons. This option can introduce a lot of processing " +"time." +msgstr "" +"Extensive stitching tries to stitch up open holes in the mesh by closing the " +"hole with touching polygons. This option can introduce a lot of processing " +"time." + +#: fdmprinter.json +msgctxt "meshfix_keep_open_polygons label" +msgid "Keep Disconnected Faces" +msgstr "Keep Disconnected Faces" + +#: fdmprinter.json +msgctxt "meshfix_keep_open_polygons description" +msgid "" +"Normally Cura tries to stitch up small holes in the mesh and remove parts of " +"a layer with big holes. Enabling this option keeps those parts which cannot " +"be stitched. This option should be used as a last resort option when " +"everything else fails to produce proper GCode." +msgstr "" +"Normally Cura tries to stitch up small holes in the mesh and remove parts of " +"a layer with big holes. Enabling this option keeps those parts which cannot " +"be stitched. This option should be used as a last resort option when " +"everything else fails to produce proper GCode." + +#: fdmprinter.json +msgctxt "blackmagic label" +msgid "Special Modes" +msgstr "Special Modes" + +#: fdmprinter.json +msgctxt "print_sequence label" +msgid "Print Sequence" +msgstr "Print Sequence" + +#: fdmprinter.json +msgctxt "print_sequence description" +msgid "" +"Whether to print all objects one layer at a time or to wait for one object " +"to finish, before moving on to the next. One at a time mode is only possible " +"if all models are separated in such a way that the whole print head can move " +"in between and all models are lower than the distance between the nozzle and " +"the X/Y axes." +msgstr "" +"Whether to print all objects one layer at a time or to wait for one object " +"to finish, before moving on to the next. One at a time mode is only possible " +"if all models are separated in such a way that the whole print head can move " +"in between and all models are lower than the distance between the nozzle and " +"the X/Y axes." + +#: fdmprinter.json +msgctxt "print_sequence option all_at_once" +msgid "All at Once" +msgstr "All at Once" + +#: fdmprinter.json +msgctxt "print_sequence option one_at_a_time" +msgid "One at a Time" +msgstr "One at a Time" + +#: fdmprinter.json +msgctxt "magic_mesh_surface_mode label" +msgid "Surface Mode" +msgstr "Surface Mode" + +#: fdmprinter.json +msgctxt "magic_mesh_surface_mode description" +msgid "" +"Print the surface instead of the volume. No infill, no top/bottom skin, just " +"a single wall of which the middle coincides with the surface of the mesh. " +"It's also possible to do both: print the insides of a closed volume as " +"normal, but print all polygons not part of a closed volume as surface." +msgstr "" +"Print the surface instead of the volume. No infill, no top/bottom skin, just " +"a single wall of which the middle coincides with the surface of the mesh. " +"It's also possible to do both: print the insides of a closed volume as " +"normal, but print all polygons not part of a closed volume as surface." + +#: fdmprinter.json +msgctxt "magic_mesh_surface_mode option normal" +msgid "Normal" +msgstr "Normal" + +#: fdmprinter.json +msgctxt "magic_mesh_surface_mode option surface" +msgid "Surface" +msgstr "Surface" + +#: fdmprinter.json +msgctxt "magic_mesh_surface_mode option both" +msgid "Both" +msgstr "Both" + +#: fdmprinter.json +msgctxt "magic_spiralize label" +msgid "Spiralize Outer Contour" +msgstr "Spiralize Outer Contour" + +#: fdmprinter.json +msgctxt "magic_spiralize description" +msgid "" +"Spiralize smooths out the Z move of the outer edge. This will create a " +"steady Z increase over the whole print. This feature turns a solid object " +"into a single walled print with a solid bottom. This feature used to be " +"called Joris in older versions." +msgstr "" +"Spiralize smooths out the Z move of the outer edge. This will create a " +"steady Z increase over the whole print. This feature turns a solid object " +"into a single walled print with a solid bottom. This feature used to be " +"called Joris in older versions." + +#: fdmprinter.json +msgctxt "experimental label" +msgid "Experimental" +msgstr "Experimental" + +#: fdmprinter.json +msgctxt "magic_fuzzy_skin_enabled label" +msgid "Fuzzy Skin" +msgstr "Fuzzy Skin" + +#: fdmprinter.json +msgctxt "magic_fuzzy_skin_enabled description" +msgid "" +"Randomly jitter while printing the outer wall, so that the surface has a " +"rough and fuzzy look." +msgstr "" +"Randomly jitter while printing the outer wall, so that the surface has a " +"rough and fuzzy look." + +#: fdmprinter.json +msgctxt "magic_fuzzy_skin_thickness label" +msgid "Fuzzy Skin Thickness" +msgstr "Fuzzy Skin Thickness" + +#: fdmprinter.json +msgctxt "magic_fuzzy_skin_thickness description" +msgid "" +"The width within which to jitter. It's advised to keep this below the outer " +"wall width, since the inner walls are unaltered." +msgstr "" +"The width within which to jitter. It's advised to keep this below the outer " +"wall width, since the inner walls are unaltered." + +#: fdmprinter.json +msgctxt "magic_fuzzy_skin_point_density label" +msgid "Fuzzy Skin Density" +msgstr "Fuzzy Skin Density" + +#: fdmprinter.json +msgctxt "magic_fuzzy_skin_point_density description" +msgid "" +"The average density of points introduced on each polygon in a layer. Note " +"that the original points of the polygon are discarded, so a low density " +"results in a reduction of the resolution." +msgstr "" +"The average density of points introduced on each polygon in a layer. Note " +"that the original points of the polygon are discarded, so a low density " +"results in a reduction of the resolution." + +#: fdmprinter.json +msgctxt "magic_fuzzy_skin_point_dist label" +msgid "Fuzzy Skin Point Distance" +msgstr "Fuzzy Skin Point Distance" + +#: fdmprinter.json +msgctxt "magic_fuzzy_skin_point_dist description" +msgid "" +"The average distance between the random points introduced on each line " +"segment. Note that the original points of the polygon are discarded, so a " +"high smoothness results in a reduction of the resolution. This value must be " +"higher than half the Fuzzy Skin Thickness." +msgstr "" +"The average distance between the random points introduced on each line " +"segment. Note that the original points of the polygon are discarded, so a " +"high smoothness results in a reduction of the resolution. This value must be " +"higher than half the Fuzzy Skin Thickness." + +#: fdmprinter.json +msgctxt "wireframe_enabled label" +msgid "Wire Printing" +msgstr "Wire Printing" + +#: fdmprinter.json +msgctxt "wireframe_enabled description" +msgid "" +"Print only the outside surface with a sparse webbed structure, printing 'in " +"thin air'. This is realized by horizontally printing the contours of the " +"model at given Z intervals which are connected via upward and diagonally " +"downward lines." +msgstr "" +"Print only the outside surface with a sparse webbed structure, printing 'in " +"thin air'. This is realized by horizontally printing the contours of the " +"model at given Z intervals which are connected via upward and diagonally " +"downward lines." + +#: fdmprinter.json +msgctxt "wireframe_height label" +msgid "WP Connection Height" +msgstr "WP Connection Height" + +#: fdmprinter.json +msgctxt "wireframe_height description" +msgid "" +"The height of the upward and diagonally downward lines between two " +"horizontal parts. This determines the overall density of the net structure. " +"Only applies to Wire Printing." +msgstr "" +"The height of the upward and diagonally downward lines between two " +"horizontal parts. This determines the overall density of the net structure. " +"Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_roof_inset label" +msgid "WP Roof Inset Distance" +msgstr "WP Roof Inset Distance" + +#: fdmprinter.json +msgctxt "wireframe_roof_inset description" +msgid "" +"The distance covered when making a connection from a roof outline inward. " +"Only applies to Wire Printing." +msgstr "" +"The distance covered when making a connection from a roof outline inward. " +"Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_printspeed label" +msgid "WP speed" +msgstr "WP speed" + +#: fdmprinter.json +msgctxt "wireframe_printspeed description" +msgid "" +"Speed at which the nozzle moves when extruding material. Only applies to " +"Wire Printing." +msgstr "" +"Speed at which the nozzle moves when extruding material. Only applies to " +"Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_printspeed_bottom label" +msgid "WP Bottom Printing Speed" +msgstr "WP Bottom Printing Speed" + +#: fdmprinter.json +msgctxt "wireframe_printspeed_bottom description" +msgid "" +"Speed of printing the first layer, which is the only layer touching the " +"build platform. Only applies to Wire Printing." +msgstr "" +"Speed of printing the first layer, which is the only layer touching the " +"build platform. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_printspeed_up label" +msgid "WP Upward Printing Speed" +msgstr "WP Upward Printing Speed" + +#: fdmprinter.json +msgctxt "wireframe_printspeed_up description" +msgid "" +"Speed of printing a line upward 'in thin air'. Only applies to Wire Printing." +msgstr "" +"Speed of printing a line upward 'in thin air'. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_printspeed_down label" +msgid "WP Downward Printing Speed" +msgstr "WP Downward Printing Speed" + +#: fdmprinter.json +msgctxt "wireframe_printspeed_down description" +msgid "" +"Speed of printing a line diagonally downward. Only applies to Wire Printing." +msgstr "" +"Speed of printing a line diagonally downward. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_printspeed_flat label" +msgid "WP Horizontal Printing Speed" +msgstr "WP Horizontal Printing Speed" + +#: fdmprinter.json +msgctxt "wireframe_printspeed_flat description" +msgid "" +"Speed of printing the horizontal contours of the object. Only applies to " +"Wire Printing." +msgstr "" +"Speed of printing the horizontal contours of the object. Only applies to " +"Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_flow label" +msgid "WP Flow" +msgstr "WP Flow" + +#: fdmprinter.json +msgctxt "wireframe_flow description" +msgid "" +"Flow compensation: the amount of material extruded is multiplied by this " +"value. Only applies to Wire Printing." +msgstr "" +"Flow compensation: the amount of material extruded is multiplied by this " +"value. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_flow_connection label" +msgid "WP Connection Flow" +msgstr "WP Connection Flow" + +#: fdmprinter.json +msgctxt "wireframe_flow_connection description" +msgid "Flow compensation when going up or down. Only applies to Wire Printing." +msgstr "" +"Flow compensation when going up or down. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_flow_flat label" +msgid "WP Flat Flow" +msgstr "WP Flat Flow" + +#: fdmprinter.json +msgctxt "wireframe_flow_flat description" +msgid "" +"Flow compensation when printing flat lines. Only applies to Wire Printing." +msgstr "" +"Flow compensation when printing flat lines. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_top_delay label" +msgid "WP Top Delay" +msgstr "WP Top Delay" + +#: fdmprinter.json +msgctxt "wireframe_top_delay description" +msgid "" +"Delay time after an upward move, so that the upward line can harden. Only " +"applies to Wire Printing." +msgstr "" +"Delay time after an upward move, so that the upward line can harden. Only " +"applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_bottom_delay label" +msgid "WP Bottom Delay" +msgstr "WP Bottom Delay" + +#: fdmprinter.json +msgctxt "wireframe_bottom_delay description" +msgid "Delay time after a downward move. Only applies to Wire Printing." +msgstr "Delay time after a downward move. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_flat_delay label" +msgid "WP Flat Delay" +msgstr "WP Flat Delay" + +#: fdmprinter.json +msgctxt "wireframe_flat_delay description" +msgid "" +"Delay time between two horizontal segments. Introducing such a delay can " +"cause better adhesion to previous layers at the connection points, while too " +"long delays cause sagging. Only applies to Wire Printing." +msgstr "" +"Delay time between two horizontal segments. Introducing such a delay can " +"cause better adhesion to previous layers at the connection points, while too " +"long delays cause sagging. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_up_half_speed label" +msgid "WP Ease Upward" +msgstr "WP Ease Upward" + +#: fdmprinter.json +msgctxt "wireframe_up_half_speed description" +msgid "" +"Distance of an upward move which is extruded with half speed.\n" +"This can cause better adhesion to previous layers, while not heating the " +"material in those layers too much. Only applies to Wire Printing." +msgstr "" +"Distance of an upward move which is extruded with half speed.\n" +"This can cause better adhesion to previous layers, while not heating the " +"material in those layers too much. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_top_jump label" +msgid "WP Knot Size" +msgstr "WP Knot Size" + +#: fdmprinter.json +msgctxt "wireframe_top_jump description" +msgid "" +"Creates a small knot at the top of an upward line, so that the consecutive " +"horizontal layer has a better chance to connect to it. Only applies to Wire " +"Printing." +msgstr "" +"Creates a small knot at the top of an upward line, so that the consecutive " +"horizontal layer has a better chance to connect to it. Only applies to Wire " +"Printing." + +#: fdmprinter.json +msgctxt "wireframe_fall_down label" +msgid "WP Fall Down" +msgstr "WP Fall Down" + +#: fdmprinter.json +msgctxt "wireframe_fall_down description" +msgid "" +"Distance with which the material falls down after an upward extrusion. This " +"distance is compensated for. Only applies to Wire Printing." +msgstr "" +"Distance with which the material falls down after an upward extrusion. This " +"distance is compensated for. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_drag_along label" +msgid "WP Drag along" +msgstr "WP Drag along" + +#: fdmprinter.json +msgctxt "wireframe_drag_along description" +msgid "" +"Distance with which the material of an upward extrusion is dragged along " +"with the diagonally downward extrusion. This distance is compensated for. " +"Only applies to Wire Printing." +msgstr "" +"Distance with which the material of an upward extrusion is dragged along " +"with the diagonally downward extrusion. This distance is compensated for. " +"Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_strategy label" +msgid "WP Strategy" +msgstr "WP Strategy" + +#: fdmprinter.json +msgctxt "wireframe_strategy description" +msgid "" +"Strategy for making sure two consecutive layers connect at each connection " +"point. Retraction lets the upward lines harden in the right position, but " +"may cause filament grinding. A knot can be made at the end of an upward line " +"to heighten the chance of connecting to it and to let the line cool; " +"however, it may require slow printing speeds. Another strategy is to " +"compensate for the sagging of the top of an upward line; however, the lines " +"won't always fall down as predicted." +msgstr "" +"Strategy for making sure two consecutive layers connect at each connection " +"point. Retraction lets the upward lines harden in the right position, but " +"may cause filament grinding. A knot can be made at the end of an upward line " +"to heighten the chance of connecting to it and to let the line cool; " +"however, it may require slow printing speeds. Another strategy is to " +"compensate for the sagging of the top of an upward line; however, the lines " +"won't always fall down as predicted." + +#: fdmprinter.json +msgctxt "wireframe_strategy option compensate" +msgid "Compensate" +msgstr "Compensate" + +#: fdmprinter.json +msgctxt "wireframe_strategy option knot" +msgid "Knot" +msgstr "Knot" + +#: fdmprinter.json +msgctxt "wireframe_strategy option retract" +msgid "Retract" +msgstr "Retract" + +#: fdmprinter.json +msgctxt "wireframe_straight_before_down label" +msgid "WP Straighten Downward Lines" +msgstr "WP Straighten Downward Lines" + +#: fdmprinter.json +msgctxt "wireframe_straight_before_down description" +msgid "" +"Percentage of a diagonally downward line which is covered by a horizontal " +"line piece. This can prevent sagging of the top most point of upward lines. " +"Only applies to Wire Printing." +msgstr "" +"Percentage of a diagonally downward line which is covered by a horizontal " +"line piece. This can prevent sagging of the top most point of upward lines. " +"Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_roof_fall_down label" +msgid "WP Roof Fall Down" +msgstr "WP Roof Fall Down" + +#: fdmprinter.json +msgctxt "wireframe_roof_fall_down description" +msgid "" +"The distance which horizontal roof lines printed 'in thin air' fall down " +"when being printed. This distance is compensated for. Only applies to Wire " +"Printing." +msgstr "" +"The distance which horizontal roof lines printed 'in thin air' fall down " +"when being printed. This distance is compensated for. Only applies to Wire " +"Printing." + +#: fdmprinter.json +msgctxt "wireframe_roof_drag_along label" +msgid "WP Roof Drag Along" +msgstr "WP Roof Drag Along" + +#: fdmprinter.json +msgctxt "wireframe_roof_drag_along description" +msgid "" +"The distance of the end piece of an inward line which gets dragged along " +"when going back to the outer outline of the roof. This distance is " +"compensated for. Only applies to Wire Printing." +msgstr "" +"The distance of the end piece of an inward line which gets dragged along " +"when going back to the outer outline of the roof. This distance is " +"compensated for. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_roof_outer_delay label" +msgid "WP Roof Outer Delay" +msgstr "WP Roof Outer Delay" + +#: fdmprinter.json +msgctxt "wireframe_roof_outer_delay description" +msgid "" +"Time spent at the outer perimeters of hole which is to become a roof. Longer " +"times can ensure a better connection. Only applies to Wire Printing." +msgstr "" +"Time spent at the outer perimeters of hole which is to become a roof. Longer " +"times can ensure a better connection. Only applies to Wire Printing." + +#: fdmprinter.json +msgctxt "wireframe_nozzle_clearance label" +msgid "WP Nozzle Clearance" +msgstr "WP Nozzle Clearance" + +#: fdmprinter.json +msgctxt "wireframe_nozzle_clearance description" +msgid "" +"Distance between the nozzle and horizontally downward lines. Larger " +"clearance results in diagonally downward lines with a less steep angle, " +"which in turn results in less upward connections with the next layer. Only " +"applies to Wire Printing." +msgstr "" +"Distance between the nozzle and horizontally downward lines. Larger " +"clearance results in diagonally downward lines with a less steep angle, " +"which in turn results in less upward connections with the next layer. Only " +"applies to Wire Printing." + +#: fdmprinter.json +msgctxt "layer_0_z_overlap label" +msgid "Initial Layer Z Overlap" +msgstr "Initial Layer Z Overlap" + +#: fdmprinter.json +msgctxt "layer_0_z_overlap description" +msgid "" +"Make the first and second layer of the object overlap in the Z direction to " +"compensate for the filament lost in the airgap. All models above the first " +"model layer will be shifted down by this amount." +msgstr "" +"Make the first and second layer of the object overlap in the Z direction to " +"compensate for the filament lost in the airgap. All models above the first " +"model layer will be shifted down by this amount." diff --git a/resources/materials/generic_abs.xml.fdm_material b/resources/materials/generic_abs.xml.fdm_material index ceb6e8698e..ef2db0b7fd 100644 --- a/resources/materials/generic_abs.xml.fdm_material +++ b/resources/materials/generic_abs.xml.fdm_material @@ -1,6 +1,6 @@ @@ -10,20 +10,21 @@ Generic PLA profile. Serves as an example file, data in this file is not correct Generic 60636bb4-518f-42e7-8237-fe77b194ebe0 - 0 + 1 #8cb219 - 1.07 + 1.10 2.85 - 250 + 240 80 + 200 - - + + diff --git a/resources/materials/generic_cpe.xml.fdm_material b/resources/materials/generic_cpe.xml.fdm_material index 19a0072de9..1fa878e466 100644 --- a/resources/materials/generic_cpe.xml.fdm_material +++ b/resources/materials/generic_cpe.xml.fdm_material @@ -1,6 +1,6 @@ @@ -10,20 +10,21 @@ Generic PLA profile. Serves as an example file, data in this file is not correct Generic 12f41353-1a33-415e-8b4f-a775a6c70cc6 - 0 + 1 #159499 - 0.94 + 1.27 2.85 250 70 + 175 - - + + diff --git a/resources/materials/generic_cpe_plus.xml.fdm_material b/resources/materials/generic_cpe_plus.xml.fdm_material new file mode 100644 index 0000000000..f234d7cb45 --- /dev/null +++ b/resources/materials/generic_cpe_plus.xml.fdm_material @@ -0,0 +1,39 @@ + + + + + + Generic + CPE+ + Generic + + e2409626-b5a0-4025-b73e-b58070219259 + 1 + #3633F2 + + + 1.18 + 2.85 + + + no + 260 + 110 + 175 + + + + + yes + + + no + + + + + + + diff --git a/resources/materials/generic_nylon.xml.fdm_material b/resources/materials/generic_nylon.xml.fdm_material new file mode 100644 index 0000000000..02b2d5414b --- /dev/null +++ b/resources/materials/generic_nylon.xml.fdm_material @@ -0,0 +1,36 @@ + + + + + + Generic + Nylon + Generic + + 35ebb8df-66d2-41cd-9662-b7d96b9c2cbd + 1 + #3DF266 + + + 1.14 + 2.85 + + + 250 + 60 + 175 + + + + + yes + + + + + + + + diff --git a/resources/materials/generic_pc.xml.fdm_material b/resources/materials/generic_pc.xml.fdm_material new file mode 100644 index 0000000000..77d7e60bf5 --- /dev/null +++ b/resources/materials/generic_pc.xml.fdm_material @@ -0,0 +1,37 @@ + + + + + + Generic + PC + Generic + + 98c05714-bf4e-4455-ba27-57d74fe331e4 + 1 + #F29030 + + + 1.19 + 2.85 + + + no + 260 + 110 + 175 + + + + + yes + + + + + + + + diff --git a/resources/materials/generic_pla.xml.fdm_material b/resources/materials/generic_pla.xml.fdm_material index 9d60be93fe..a98e0e469c 100644 --- a/resources/materials/generic_pla.xml.fdm_material +++ b/resources/materials/generic_pla.xml.fdm_material @@ -10,25 +10,42 @@ Generic PLA profile. Serves as an example file, data in this file is not correct Generic 506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9 - 0 + 1 #ffc924 - 1.3 + 1.24 2.85 - 210 + 200 60 + 175 - - + + + + + + + + 150 + + + + + + + + + 150 + diff --git a/resources/materials/generic_tpu.xml.fdm_material b/resources/materials/generic_tpu.xml.fdm_material new file mode 100644 index 0000000000..5a0c793cda --- /dev/null +++ b/resources/materials/generic_tpu.xml.fdm_material @@ -0,0 +1,39 @@ + + + + + + Generic + TPU 95A + Generic + + 1d52b2be-a3a2-41de-a8b1-3bcdb5618695 + 1 + #B22744 + + + 1.22 + 2.85 + + + no + 260 + 110 + 175 + + + + + yes + + + + + + no + + + + diff --git a/resources/materials/ultimaker_abs_black.xml.fdm_material b/resources/materials/ultimaker_abs_black.xml.fdm_material new file mode 100644 index 0000000000..2993ae3133 --- /dev/null +++ b/resources/materials/ultimaker_abs_black.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + Black + + 2f9d2279-9b0e-4765-bf9b-d1e1e13f3c49 + 0 + #2a292a + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_abs_blue.xml.fdm_material b/resources/materials/ultimaker_abs_blue.xml.fdm_material new file mode 100644 index 0000000000..4273ec8f9f --- /dev/null +++ b/resources/materials/ultimaker_abs_blue.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + Blue + + 7c9575a6-c8d6-40ec-b3dd-18d7956bfaae + 0 + #00387b + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_abs_green.xml.fdm_material b/resources/materials/ultimaker_abs_green.xml.fdm_material new file mode 100644 index 0000000000..87c178fb01 --- /dev/null +++ b/resources/materials/ultimaker_abs_green.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + Green + + 3400c0d1-a4e3-47de-a444-7b704f287171 + 0 + #61993b + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_abs_grey.xml.fdm_material b/resources/materials/ultimaker_abs_grey.xml.fdm_material new file mode 100644 index 0000000000..f8b67c7a41 --- /dev/null +++ b/resources/materials/ultimaker_abs_grey.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + Grey + + 8b75b775-d3f2-4d0f-8fb2-2a3dd53cf673 + 0 + #52595d + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_abs_orange.xml.fdm_material b/resources/materials/ultimaker_abs_orange.xml.fdm_material new file mode 100644 index 0000000000..af3369ca97 --- /dev/null +++ b/resources/materials/ultimaker_abs_orange.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + Orange + + 0b4ca6ef-eac8-4b23-b3ca-5f21af00e54f + 0 + #ed6b21 + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_abs_pearl-gold.xml.fdm_material b/resources/materials/ultimaker_abs_pearl-gold.xml.fdm_material new file mode 100644 index 0000000000..29bec52466 --- /dev/null +++ b/resources/materials/ultimaker_abs_pearl-gold.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + Pearl Gold + + 7cbdb9ca-081a-456f-a6ba-f73e4e9cb856 + 0 + #80643f + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_abs_red.xml.fdm_material b/resources/materials/ultimaker_abs_red.xml.fdm_material new file mode 100644 index 0000000000..0d0dc3f098 --- /dev/null +++ b/resources/materials/ultimaker_abs_red.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + Red + + 5df7afa6-48bd-4c19-b314-839fe9f08f1f + 0 + #bb1e10 + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_abs_silver-metallic.xml.fdm_material b/resources/materials/ultimaker_abs_silver-metallic.xml.fdm_material new file mode 100644 index 0000000000..fc7fb1c2b5 --- /dev/null +++ b/resources/materials/ultimaker_abs_silver-metallic.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + Silver Metallic + + 763c926e-a5f7-4ba0-927d-b4e038ea2735 + 0 + #a1a1a0 + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_abs_white.xml.fdm_material b/resources/materials/ultimaker_abs_white.xml.fdm_material new file mode 100644 index 0000000000..fbf4518c90 --- /dev/null +++ b/resources/materials/ultimaker_abs_white.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + White + + 5253a75a-27dc-4043-910f-753ae11bc417 + 0 + #ecece7 + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_abs_yellow.xml.fdm_material b/resources/materials/ultimaker_abs_yellow.xml.fdm_material new file mode 100644 index 0000000000..2b1a0a2784 --- /dev/null +++ b/resources/materials/ultimaker_abs_yellow.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + ABS + Yellow + + e873341d-d9b8-45f9-9a6f-5609e1bcff68 + 0 + #f7b500 + + + 1.10 + 2.85 + + + 240 + 80 + 200 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_cpe_black.xml.fdm_material b/resources/materials/ultimaker_cpe_black.xml.fdm_material new file mode 100644 index 0000000000..8e06ad7176 --- /dev/null +++ b/resources/materials/ultimaker_cpe_black.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + CPE + Black + + a8955dc3-9d7e-404d-8c03-0fd6fee7f22d + 0 + #2a292a + + + 1.27 + 2.85 + + + 250 + 70 + 175 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_cpe_blue.xml.fdm_material b/resources/materials/ultimaker_cpe_blue.xml.fdm_material new file mode 100644 index 0000000000..f4675c7876 --- /dev/null +++ b/resources/materials/ultimaker_cpe_blue.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + CPE + Blue + + 4d816290-ce2e-40e0-8dc8-3f702243131e + 0 + #00a3e0 + + + 1.27 + 2.85 + + + 250 + 70 + 175 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_cpe_dark-grey.xml.fdm_material b/resources/materials/ultimaker_cpe_dark-grey.xml.fdm_material new file mode 100644 index 0000000000..aa22712d08 --- /dev/null +++ b/resources/materials/ultimaker_cpe_dark-grey.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + CPE + Dark Grey + + 10961c00-3caf-48e9-a598-fa805ada1e8d + 0 + #4f5250 + + + 1.27 + 2.85 + + + 250 + 70 + 175 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_cpe_green.xml.fdm_material b/resources/materials/ultimaker_cpe_green.xml.fdm_material new file mode 100644 index 0000000000..f22425f658 --- /dev/null +++ b/resources/materials/ultimaker_cpe_green.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + CPE + Green + + 7ff6d2c8-d626-48cd-8012-7725fa537cc9 + 0 + #78be20 + + + 1.27 + 2.85 + + + 250 + 70 + 175 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_cpe_light-grey.xml.fdm_material b/resources/materials/ultimaker_cpe_light-grey.xml.fdm_material new file mode 100644 index 0000000000..1a996e9bf2 --- /dev/null +++ b/resources/materials/ultimaker_cpe_light-grey.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + CPE + Light Grey + + 173a7bae-5e14-470e-817e-08609c61e12b + 0 + #c5c7c4 + + + 1.27 + 2.85 + + + 250 + 70 + 175 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_cpe_red.xml.fdm_material b/resources/materials/ultimaker_cpe_red.xml.fdm_material new file mode 100644 index 0000000000..77a9caa196 --- /dev/null +++ b/resources/materials/ultimaker_cpe_red.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + CPE + Red + + 00181d6c-7024-479a-8eb7-8a2e38a2619a + 0 + #c8102e + + + 1.27 + 2.85 + + + 250 + 70 + 175 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_cpe_transparent.xml.fdm_material b/resources/materials/ultimaker_cpe_transparent.xml.fdm_material new file mode 100644 index 0000000000..ff3cbce64b --- /dev/null +++ b/resources/materials/ultimaker_cpe_transparent.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + CPE + Transparent + + bd0d9eb3-a920-4632-84e8-dcd6086746c5 + 0 + #d0d0d0 + + + 1.27 + 2.85 + + + 250 + 70 + 175 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_cpe_white.xml.fdm_material b/resources/materials/ultimaker_cpe_white.xml.fdm_material new file mode 100644 index 0000000000..bb72152d09 --- /dev/null +++ b/resources/materials/ultimaker_cpe_white.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + CPE + White + + 881c888e-24fb-4a64-a4ac-d5c95b096cd7 + 0 + #f1ece1 + + + 1.27 + 2.85 + + + 250 + 70 + 175 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_cpe_yellow.xml.fdm_material b/resources/materials/ultimaker_cpe_yellow.xml.fdm_material new file mode 100644 index 0000000000..8fe699277d --- /dev/null +++ b/resources/materials/ultimaker_cpe_yellow.xml.fdm_material @@ -0,0 +1,35 @@ + + + + + + Ultimaker + CPE + Yellow + + b9176a2a-7a0f-4821-9f29-76d882a88682 + 0 + #f6b600 + + + 1.27 + 2.85 + + + 250 + 70 + 175 + + + + + + + + + + + + diff --git a/resources/materials/ultimaker_pla_black.xml.fdm_material b/resources/materials/ultimaker_pla_black.xml.fdm_material new file mode 100644 index 0000000000..257f9b3235 --- /dev/null +++ b/resources/materials/ultimaker_pla_black.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + Black + + 3ee70a86-77d8-4b87-8005-e4a1bc57d2ce + 0 + #0e0e10 + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_blue.xml.fdm_material b/resources/materials/ultimaker_pla_blue.xml.fdm_material new file mode 100644 index 0000000000..e75b9fada1 --- /dev/null +++ b/resources/materials/ultimaker_pla_blue.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + Blue + + 44a029e6-e31b-4c9e-a12f-9282e29a92ff + 0 + #00387b + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_green.xml.fdm_material b/resources/materials/ultimaker_pla_green.xml.fdm_material new file mode 100644 index 0000000000..41b015b216 --- /dev/null +++ b/resources/materials/ultimaker_pla_green.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + Green + + 2433b8fb-dcd6-4e36-9cd5-9f4ee551c04c + 0 + #61993b + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_magenta.xml.fdm_material b/resources/materials/ultimaker_pla_magenta.xml.fdm_material new file mode 100644 index 0000000000..4f821337dc --- /dev/null +++ b/resources/materials/ultimaker_pla_magenta.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + Magenta + + fe3982c8-58f4-4d86-9ac0-9ff7a3ab9cbc + 0 + #bc4077 + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_orange.xml.fdm_material b/resources/materials/ultimaker_pla_orange.xml.fdm_material new file mode 100644 index 0000000000..1cd028efad --- /dev/null +++ b/resources/materials/ultimaker_pla_orange.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + Orange + + d9549dba-b9df-45b9-80a5-f7140a9a2f34 + 0 + #ed6b21 + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_pearl-white.xml.fdm_material b/resources/materials/ultimaker_pla_pearl-white.xml.fdm_material new file mode 100644 index 0000000000..7e23606f65 --- /dev/null +++ b/resources/materials/ultimaker_pla_pearl-white.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + Pearl-White + + d9fc79db-82c3-41b5-8c99-33b3747b8fb3 + 0 + #e3d9c6 + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_red.xml.fdm_material b/resources/materials/ultimaker_pla_red.xml.fdm_material new file mode 100644 index 0000000000..f4e381c815 --- /dev/null +++ b/resources/materials/ultimaker_pla_red.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + Red + + 9cfe5bf1-bdc5-4beb-871a-52c70777842d + 0 + #bb1e10 + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_silver-metallic.xml.fdm_material b/resources/materials/ultimaker_pla_silver-metallic.xml.fdm_material new file mode 100644 index 0000000000..2b7fbaac46 --- /dev/null +++ b/resources/materials/ultimaker_pla_silver-metallic.xml.fdm_material @@ -0,0 +1,50 @@ + + + + + + Ultimaker + PLA + Silver Metallic + + 0e01be8c-e425-4fb1-b4a3-b79f255f1db9 + 0 + #a1a1a0 + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_transparent.xml.fdm_material b/resources/materials/ultimaker_pla_transparent.xml.fdm_material new file mode 100644 index 0000000000..773828b620 --- /dev/null +++ b/resources/materials/ultimaker_pla_transparent.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + Transparent + + 532e8b3d-5fd4-4149-b936-53ada9bd6b85 + 0 + #d0d0d0 + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_white.xml.fdm_material b/resources/materials/ultimaker_pla_white.xml.fdm_material new file mode 100644 index 0000000000..acd5059cef --- /dev/null +++ b/resources/materials/ultimaker_pla_white.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + White + + e509f649-9fe6-4b14-ac45-d441438cb4ef + 0 + #f1ece1 + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/materials/ultimaker_pla_yellow.xml.fdm_material b/resources/materials/ultimaker_pla_yellow.xml.fdm_material new file mode 100644 index 0000000000..92d947e555 --- /dev/null +++ b/resources/materials/ultimaker_pla_yellow.xml.fdm_material @@ -0,0 +1,51 @@ + + + + + + Ultimaker + PLA + Yellow + + 9c1959d0-f597-46ec-9131-34020c7a54fc + 0 + #f9a800 + + + 1.24 + 2.85 + + + 200 + 60 + 175 + + + + + + + + + + + + + + + + 150 + + + + + + + + + 150 + + + diff --git a/resources/meshes/inventor_platform.stl b/resources/meshes/inventor_platform.stl index c83f58b66f..a55ab0705b 100644 Binary files a/resources/meshes/inventor_platform.stl and b/resources/meshes/inventor_platform.stl differ diff --git a/resources/meshes/printrbot_simple_metal_platform.stl b/resources/meshes/printrbot_simple_metal_platform.stl new file mode 100644 index 0000000000..717d224f1f Binary files /dev/null and b/resources/meshes/printrbot_simple_metal_platform.stl differ diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 536ec289fe..3ee8630183 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -45,6 +45,7 @@ Item property alias preferences: preferencesAction; property alias showEngineLog: showEngineLogAction; + property alias showProfileFolder: showProfileFolderAction; property alias documentation: documentationAction; property alias reportBug: reportBugAction; property alias about: aboutAction; @@ -122,7 +123,7 @@ Item id: updateProfileAction; enabled: Cura.MachineManager.isActiveStackValid && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings"); - onTriggered: Cura.MachineManager.updateQualityContainerFromUserContainer() + onTriggered: Cura.ContainerManager.updateQualityChanges(); } Action @@ -130,7 +131,7 @@ Item id: resetProfileAction; enabled: Cura.MachineManager.hasUserSettings text: catalog.i18nc("@action:inmenu menubar:profile","&Discard current settings"); - onTriggered: Cura.MachineManager.clearUserSettings(); + onTriggered: Cura.ContainerManager.clearUserContainers(); } Action @@ -289,10 +290,17 @@ Item shortcut: StandardKey.WhatsThis; } + Action + { + id: showProfileFolderAction; + text: catalog.i18nc("@action:inmenu menubar:help","Show Configuration Folder"); + } + + Action { id: configureSettingVisibilityAction - text: catalog.i18nc("@action:menu", "Configure setting visiblity..."); + text: catalog.i18nc("@action:menu", "Configure setting visibility..."); iconName: "configure" } } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 5f45a062b8..eba803ef28 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -143,20 +143,21 @@ UM.MainWindow model: Cura.ExtrudersModel { } Menu { title: model.name + visible: machineExtruderCount.properties.value > 1 - NozzleMenu { title: catalog.i18nc("@title:menu", "&Nozzle"); visible: Cura.MachineManager.hasVariants } - MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials } + NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index } + MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index } ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); } MenuSeparator { } - MenuItem { text: "Set as Active Extruder" } + MenuItem { text: catalog.i18nc("@action:inmenu", "Set as Active Extruder"); onTriggered: ExtruderManager.setActiveExtruderIndex(model.index) } } onObjectAdded: settingsMenu.insertItem(index, object) onObjectRemoved: settingsMenu.removeItem(object) } - NozzleMenu { title: catalog.i18nc("@title:menu", "&Nozzle"); visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasVariants } + NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasVariants } MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasMaterials } ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); visible: machineExtruderCount.properties.value <= 1 } @@ -211,7 +212,7 @@ UM.MainWindow //: Help menu title: catalog.i18nc("@title:menu menubar:toplevel","&Help"); - MenuItem { action: Cura.Actions.showEngineLog; } + MenuItem { action: Cura.Actions.showProfileFolder; } MenuItem { action: Cura.Actions.documentation; } MenuItem { action: Cura.Actions.reportBug; } MenuSeparator { } @@ -345,6 +346,7 @@ UM.MainWindow bottom: parent.bottom; right: parent.right; } + z: 1 onMonitoringPrintChanged: base.monitoringPrint = monitoringPrint width: UM.Theme.getSize("sidebar").width; } @@ -401,7 +403,7 @@ UM.MainWindow anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenterOffset: - UM.Theme.getSize("sidebar").width / 2 visible: base.monitoringPrint - source: Cura.MachineManager.printerOutputDevices.length > 0 ? Cura.MachineManager.printerOutputDevices[0].cameraImage : "" + source: Cura.MachineManager.printerOutputDevices.length > 0 && Cura.MachineManager.printerOutputDevices[0].cameraImage ? Cura.MachineManager.printerOutputDevices[0].cameraImage : "" } UM.MessageStack @@ -427,6 +429,9 @@ UM.MainWindow removePage(0); insertPage(0, catalog.i18nc("@title:tab","General"), Qt.resolvedUrl("Preferences/GeneralPage.qml")); + removePage(1); + insertPage(1, catalog.i18nc("@title:tab","Settings"), Qt.resolvedUrl("Preferences/SettingVisibilityPage.qml")); + insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("Preferences/MachinesPage.qml")); insertPage(3, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml")); @@ -459,12 +464,11 @@ UM.MainWindow target: Cura.Actions.addProfile onTriggered: { - Cura.MachineManager.newQualityContainerFromQualityAndUser(); preferences.setPage(4); preferences.show(); - // Show the renameDialog after a very short delay so the preference page has time to initiate - showProfileNameDialogTimer.start(); + // Create a new profile after a very short delay so the preference page has time to initiate + createProfileTimer.start(); } } @@ -511,11 +515,11 @@ UM.MainWindow Timer { - id: showProfileNameDialogTimer + id: createProfileTimer repeat: false interval: 1 - onTriggered: preferences.getCurrentItem().showProfileNameDialog() + onTriggered: preferences.getCurrentItem().createProfile() } // BlurSettings is a way to force the focus away from any of the setting items. @@ -668,8 +672,15 @@ UM.MainWindow Connections { - target: Cura.Actions.showEngineLog - onTriggered: engineLog.visible = true; + target: Cura.Actions.showProfileFolder + onTriggered: + { + var path = UM.Resources.getPath(UM.Resources.Preferences, ""); + if(Qt.platform.os == "windows") { + path = path.replace(/\\/g,"/"); + } + Qt.openUrlExternally(path); + } } AddMachineDialog diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index be2ef4a551..d2e6bc03ce 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -12,46 +12,45 @@ Menu id: menu title: "Material" - Instantiator + property int extruderIndex: 0 + property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 + + MenuItem { - model: UM.InstanceContainersModel + id: automaticMaterial + text: { - filter: + var materialName = Cura.MachineManager.printerOutputDevices[0].materialNames[extruderIndex]; + return catalog.i18nc("@title:menuitem %1 is the value from the printer", "Automatic: %1").arg(materialName); + } + visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].materialNames.length > extruderIndex + onTriggered: + { + var material_id = Cura.MachineManager.printerOutputDevices[0].materialIds[extruderIndex]; + var items = materialsModel.items; + // materialsModel.find cannot be used because we need to look inside the metadata property of items + for(var i in items) { - var result = { "type": "material" } - if(Cura.MachineManager.filterMaterialsByMachine) + if (items[i]["metadata"]["GUID"] == material_id) { - result.definition = Cura.MachineManager.activeDefinitionId - if(Cura.MachineManager.hasVariants) - { - result.variant = Cura.MachineManager.activeVariantId - } + Cura.MachineManager.setActiveMaterial(items[i].id); + break; } - else - { - result.definition = "fdmprinter" - } - return result } } + } + + MenuSeparator + { + visible: automaticMaterial.visible + } + + Instantiator + { + model: genericMaterialsModel MenuItem { - text: - { - var result = model.name - - if(model.metadata.brand != undefined && model.metadata.brand != "Generic") - { - result = model.metadata.brand + " " + result - } - - if(model.metadata.color_name != undefined && model.metadata.color_name != "Generic") - { - result = result + " (%1)".arg(model.metadata.color_name) - } - - return result - } + text: model.name checkable: true; checked: model.id == Cura.MachineManager.activeMaterialId; exclusiveGroup: group; @@ -63,10 +62,151 @@ Menu onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) } + MenuSeparator { } + Instantiator + { + model: brandModel + Menu + { + id: brandMenu + title: brandName + property string brandName: model.name + property var brandMaterials: model.materials + + Instantiator + { + model: brandMaterials + Menu + { + id: brandMaterialsMenu + title: materialName + property string materialName: model.name + property var brandMaterialColors: model.colors + + Instantiator + { + model: brandMaterialColors + MenuItem + { + text: model.name + checkable: true; + checked: model.id == Cura.MachineManager.activeMaterialId; + exclusiveGroup: group; + onTriggered: + { + Cura.MachineManager.setActiveMaterial(model.id); + } + } + onObjectAdded: brandMaterialsMenu.insertItem(index, object) + onObjectRemoved: brandMaterialsMenu.removeItem(object) + } + } + onObjectAdded: brandMenu.insertItem(index, object) + onObjectRemoved: brandMenu.removeItem(object) + } + } + onObjectAdded: menu.insertItem(index, object) + onObjectRemoved: menu.removeItem(object) + } + + ListModel + { + id: genericMaterialsModel + Component.onCompleted: populateMenuModels() + } + + ListModel + { + id: brandModel + } + + //: Model used to populate the brandModel + UM.InstanceContainersModel + { + id: materialsModel + filter: materialFilter() + onModelReset: populateMenuModels() + onDataChanged: populateMenuModels() + } ExclusiveGroup { id: group } MenuSeparator { } MenuItem { action: Cura.Actions.manageMaterials } + + function materialFilter() + { + var result = { "type": "material" }; + if(Cura.MachineManager.filterMaterialsByMachine) + { + result.definition = Cura.MachineManager.activeQualityDefinitionId; + if(Cura.MachineManager.hasVariants) + { + result.variant = Cura.MachineManager.activeQualityVariantId; + } + } + else + { + result.definition = "fdmprinter"; + } + return result; + } + + function populateMenuModels() + { + // Create a structure of unique brands and their material-types + genericMaterialsModel.clear() + brandModel.clear(); + + var items = materialsModel.items; + var materialsByBrand = {}; + for (var i in items) { + var brandName = items[i]["metadata"]["brand"]; + var materialName = items[i]["metadata"]["material"]; + + if (brandName == "Generic") + { + // Add to top section + var materialId = items[i].id; + genericMaterialsModel.append({ + id:materialId, + name:items[i].name + }); + } + else + { + // Add to per-brand, per-material menu + if (!materialsByBrand.hasOwnProperty(brandName)) + { + materialsByBrand[brandName] = {}; + } + if (!materialsByBrand[brandName].hasOwnProperty(materialName)) + { + materialsByBrand[brandName][materialName] = []; + } + materialsByBrand[brandName][materialName].push({ + id: items[i].id, + name: items[i].name + }); + } + } + + for (var brand in materialsByBrand) + { + var materialsByBrandModel = []; + var materials = materialsByBrand[brand]; + for (var material in materials) + { + materialsByBrandModel.push({ + name: material, + colors: materials[material] + }) + } + brandModel.append({ + name: brand, + materials: materialsByBrandModel + }); + } + } } diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index 506a9a2a01..7f1c652c4a 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -12,8 +12,37 @@ Menu id: menu title: "Nozzle" + property int extruderIndex: 0 + property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 + + MenuItem + { + id: automaticNozzle + text: + { + var nozzleName = Cura.MachineManager.printerOutputDevices[0].hotendIds[extruderIndex]; + return catalog.i18nc("@title:menuitem %1 is the value from the printer", "Automatic: %1").arg(nozzleName); + } + visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].hotendIds.length > extruderIndex + onTriggered: + { + var hotendId = Cura.MachineManager.printerOutputDevices[0].hotendIds[extruderIndex]; + var itemIndex = nozzleInstantiator.model.find("name", hotendId); + if(itemIndex > -1) + { + Cura.MachineManager.setActiveVariant(nozzleInstantiator.model.getItem(itemIndex).id) + } + } + } + + MenuSeparator + { + visible: automaticNozzle.visible + } + Instantiator { + id: nozzleInstantiator model: UM.InstanceContainersModel { filter: diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 68f83305d7..45af0c7965 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -7,7 +7,7 @@ import QtQuick.Controls 1.1 import UM 1.2 as UM import Cura 1.0 as Cura - Menu +Menu { id: menu @@ -15,14 +15,14 @@ import Cura 1.0 as Cura { model: UM.InstanceContainersModel { - filter: menu.getFilter({ "read_only": true }); + filter: menu.getFilter({ "type": "quality" }); } MenuItem { text: model.name checkable: true - checked: Cura.MachineManager.activeQualityId == model.id + checked: Cura.MachineManager.activeQualityChangesId == "empty_quality_changes" && Cura.MachineManager.activeQualityType == model.metadata.quality_type exclusiveGroup: group onTriggered: Cura.MachineManager.setActiveQuality(model.id) } @@ -38,7 +38,7 @@ import Cura 1.0 as Cura id: customProfileInstantiator model: UM.InstanceContainersModel { - filter: menu.getFilter({ "read_only": false }); + filter: { "type": "quality_changes", "extruder": null, "definition": Cura.MachineManager.filterQualityByMachine ? Cura.MachineManager.activeQualityDefinitionId : "fdmprinter" }; onModelReset: customSeparator.visible = rowCount() > 0 } @@ -76,14 +76,13 @@ import Cura 1.0 as Cura function getFilter(initial_conditions) { var result = initial_conditions; - result.type = "quality" if(Cura.MachineManager.filterQualityByMachine) { - result.definition = Cura.MachineManager.activeDefinitionId; + result.definition = Cura.MachineManager.activeQualityDefinitionId; if(Cura.MachineManager.hasMaterials) { - result.material = Cura.MachineManager.activeMaterialId; + result.material = Cura.MachineManager.activeQualityMaterialId; } } else diff --git a/resources/qml/MonitorButton.qml b/resources/qml/MonitorButton.qml index 5fa68b77cc..0aac7d5197 100644 --- a/resources/qml/MonitorButton.qml +++ b/resources/qml/MonitorButton.qml @@ -4,6 +4,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 +import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import UM 1.1 as UM @@ -29,14 +30,14 @@ Rectangle switch(Cura.MachineManager.printerOutputDevices[0].jobState) { case "printing": - case "pre_print": // heating, etc. case "paused": return true; + case "pre_print": // heating, etc. case "wait_cleanup": - case "ready": // nut sure if this occurs, "" seems to be the ready state. case "offline": case "abort": // note sure if this jobState actually occurs in the wild case "error": // after clicking abort you apparently get "error" + case "ready": // ready to print or getting ready case "": // ready to print or getting ready default: return false; @@ -48,6 +49,14 @@ Rectangle if(!printerConnected || !printerAcceptsCommands) return UM.Theme.getColor("text"); + switch(Cura.MachineManager.printerOutputDevices[0].printerState) + { + case "maintenance": + return UM.Theme.getColor("status_busy"); + case "error": + return UM.Theme.getColor("status_stopped"); + } + switch(Cura.MachineManager.printerOutputDevices[0].jobState) { case "printing": @@ -79,6 +88,11 @@ Rectangle return catalog.i18nc("@label:MonitorStatus", "Printer does not accept commands"); var printerOutputDevice = Cura.MachineManager.printerOutputDevices[0] + + if(printerOutputDevice.printerState == "maintenance") + { + return catalog.i18nc("@label:MonitorStatus", "In maintenance. Please check the printer"); + } switch(printerOutputDevice.jobState) { case "offline": @@ -145,182 +159,104 @@ Rectangle } } - Button - { - id: abortButton - - visible: printerConnected - enabled: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands && - (["paused", "printing", "pre_print"].indexOf(Cura.MachineManager.printerOutputDevices[0].jobState) >= 0) - - height: UM.Theme.getSize("save_button_save_to_button").height + Row { + id: buttonsRow + height: abortButton.height anchors.top: progressBar.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width + spacing: UM.Theme.getSize("default_margin").width - text: catalog.i18nc("@label:", "Abort Print") - onClicked: Cura.MachineManager.printerOutputDevices[0].setJobState("abort") + Row { + id: additionalComponentsRow + spacing: UM.Theme.getSize("default_margin").width + } - style: ButtonStyle - { - background: Rectangle + Connections { + target: Printer + onAdditionalComponentsChanged: { - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_border"); - else if(control.pressed) - return UM.Theme.getColor("action_button_active_border"); - else if(control.hovered) - return UM.Theme.getColor("action_button_hovered_border"); - else - return UM.Theme.getColor("action_button_border"); - } - color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled"); - else if(control.pressed) - return UM.Theme.getColor("action_button_active"); - else if(control.hovered) - return UM.Theme.getColor("action_button_hovered"); - else - return UM.Theme.getColor("action_button"); - } - Behavior on color { ColorAnimation { duration: 50; } } - - implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("default_margin").width * 2) - - Label - { - id: actualLabel - anchors.centerIn: parent - color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_text"); - else if(control.pressed) - return UM.Theme.getColor("action_button_active_text"); - else if(control.hovered) - return UM.Theme.getColor("action_button_hovered_text"); - else - return UM.Theme.getColor("action_button_text"); + if(areaId == "monitorButtons") { + for (var component in Printer.additionalComponents["monitorButtons"]) { + Printer.additionalComponents["monitorButtons"][component].parent = additionalComponentsRow } - font: UM.Theme.getFont("action_button") - text: control.text; } } - label: Item { } - } - } - - Button - { - id: pauseResumeButton - - height: UM.Theme.getSize("save_button_save_to_button").height - anchors.top: progressBar.bottom - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.right: abortButton.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - - property bool userClicked: false - property string lastJobState: "" - - visible: printerConnected - enabled: (!userClicked) && printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands && - (["paused", "printing"].indexOf(Cura.MachineManager.printerOutputDevices[0].jobState) >= 0) - - text: { - var result = ""; - var jobState = Cura.MachineManager.printerOutputDevices[0].jobState; - if (!printerConnected) { - return ""; - } - - if (lastJobState !== jobState) { - // the userClicked message must disappear when an "automated" jobState comes by - userClicked = false; - lastJobState = jobState; - } - - if (jobState == "paused") - { - if (userClicked) { - // User feedback for pretending we're already in "printing" mode. - result = catalog.i18nc("@label:", "Pause"); - } else { - result = catalog.i18nc("@label:", "Resume"); - } - } else { - if (userClicked) { - // User feedback for pretending we're already in "pause" mode. - result = catalog.i18nc("@label:", "Resume"); - } else { - result = catalog.i18nc("@label:", "Pause"); - } - } - return result; - } - onClicked: { - var newJobState = Cura.MachineManager.printerOutputDevices[0].jobState == "paused" ? "print" : "pause"; - Cura.MachineManager.printerOutputDevices[0].setJobState(newJobState); - userClicked = true; } - style: ButtonStyle + Button { - background: Rectangle - { - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_border"); - else if(control.pressed) - return UM.Theme.getColor("action_button_active_border"); - else if(control.hovered) - return UM.Theme.getColor("action_button_hovered_border"); - else - return UM.Theme.getColor("action_button_border"); - } - color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled"); - else if(control.pressed) - return UM.Theme.getColor("action_button_active"); - else if(control.hovered) - return UM.Theme.getColor("action_button_hovered"); - else - return UM.Theme.getColor("action_button"); - } - Behavior on color { ColorAnimation { duration: 50; } } + id: pauseResumeButton - implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("default_margin").width * 2) + height: UM.Theme.getSize("save_button_save_to_button").height - Label + property bool userClicked: false + property string lastJobState: "" + + visible: printerConnected + enabled: (!userClicked) && printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands && + (["paused", "printing"].indexOf(Cura.MachineManager.printerOutputDevices[0].jobState) >= 0) + + text: { + var result = ""; + if (!printerConnected) { - id: actualLabel - anchors.centerIn: parent - color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_text"); - else if(control.pressed) - return UM.Theme.getColor("action_button_active_text"); - else if(control.hovered) - return UM.Theme.getColor("action_button_hovered_text"); - else - return UM.Theme.getColor("action_button_text"); - } - font: UM.Theme.getFont("action_button") - text: control.text + return ""; + } + var jobState = Cura.MachineManager.printerOutputDevices[0].jobState; + + if (jobState == "paused") + { + return catalog.i18nc("@label:", "Resume"); + } + else + { + return catalog.i18nc("@label:", "Pause"); } } - label: Item { } + onClicked: + { + var current_job_state = Cura.MachineManager.printerOutputDevices[0].jobState + if(current_job_state == "paused") + { + Cura.MachineManager.printerOutputDevices[0].setJobState("print"); + } + else if(current_job_state == "printing") + { + Cura.MachineManager.printerOutputDevices[0].setJobState("pause"); + } + } + + style: UM.Theme.styles.sidebar_action_button + } + + Button + { + id: abortButton + + visible: printerConnected + enabled: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands && + (["paused", "printing", "pre_print"].indexOf(Cura.MachineManager.printerOutputDevices[0].jobState) >= 0) + + height: UM.Theme.getSize("save_button_save_to_button").height + + text: catalog.i18nc("@label:", "Abort Print") + onClicked: confirmationDialog.visible = true + + style: UM.Theme.styles.sidebar_action_button + } + + MessageDialog + { + id: confirmationDialog + + title: catalog.i18nc("@window:title", "Abort print") + icon: StandardIcon.Warning + text: catalog.i18nc("@label", "Are you sure you want to abort the print?") + standardButtons: StandardButton.Yes | StandardButton.No + Component.onCompleted: visible = false + onYes: Cura.MachineManager.printerOutputDevices[0].setJobState("abort") } } } diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 001d2af8d4..2839e1bc72 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -33,6 +33,8 @@ UM.PreferencesPage UM.Preferences.resetPreference("physics/automatic_push_free") pushFreeCheckbox.checked = boolCheck(UM.Preferences.getValue("physics/automatic_push_free")) + UM.Preferences.resetPreference("physics/automatic_drop_down") + dropDownCheckbox.checked = boolCheck(UM.Preferences.getValue("physics/automatic_drop_down")) UM.Preferences.resetPreference("mesh/scale_to_fit") scaleToFitCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_to_fit")) UM.Preferences.resetPreference("mesh/scale_tiny_meshes") @@ -46,11 +48,11 @@ UM.PreferencesPage UM.Preferences.resetPreference("view/top_layer_count"); topLayerCountCheckbox.checked = boolCheck(UM.Preferences.getValue("view/top_layer_count")) - if (plugins.model.find("id", "SliceInfoPlugin") > -1) { + if (plugins.find("id", "SliceInfoPlugin") > -1) { UM.Preferences.resetPreference("info/send_slice_info") sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info")) } - if (plugins.model.find("id", "UpdateChecker") > -1) { + if (plugins.find("id", "UpdateChecker") > -1) { UM.Preferences.resetPreference("info/automatic_update_check") checkUpdatesCheckbox.checked = boolCheck(UM.Preferences.getValue("info/automatic_update_check")) } @@ -58,6 +60,9 @@ UM.PreferencesPage Column { + //: Model used to check if a plugin exists + UM.PluginsModel { id: plugins } + //: Language selection label UM.I18nCatalog{id: catalog; name:"cura"} @@ -192,7 +197,19 @@ UM.PreferencesPage onCheckedChanged: UM.Preferences.setValue("physics/automatic_push_free", checked) } } + UM.TooltipArea { + width: childrenRect.width + height: childrenRect.height + text: catalog.i18nc("@info:tooltip", "Should models on the platform be moved down to touch the build plate?") + CheckBox + { + id: dropDownCheckbox + text: catalog.i18nc("@option:check", "Automatically drop models to the build plate") + checked: boolCheck(UM.Preferences.getValue("physics/automatic_drop_down")) + onCheckedChanged: UM.Preferences.setValue("physics/automatic_drop_down", checked) + } + } UM.TooltipArea { width: childrenRect.width; @@ -301,7 +318,7 @@ UM.PreferencesPage } UM.TooltipArea { - visible: plugins.model.find("id", "UpdateChecker") > -1 + visible: plugins.find("id", "UpdateChecker") > -1 width: childrenRect.width height: visible ? childrenRect.height : 0 text: catalog.i18nc("@info:tooltip","Should Cura check for updates when the program is started?") @@ -316,7 +333,7 @@ UM.PreferencesPage } UM.TooltipArea { - visible: plugins.model.find("id", "SliceInfoPlugin") > -1 + visible: plugins.find("id", "SliceInfoPlugin") > -1 width: childrenRect.width height: visible ? childrenRect.height : 0 text: catalog.i18nc("@info:tooltip","Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored.") @@ -329,13 +346,5 @@ UM.PreferencesPage onCheckedChanged: UM.Preferences.setValue("info/send_slice_info", checked) } } - - //: Invisible list used to check if a plugin exists - ListView - { - id: plugins - model: UM.PluginsModel { } - visible: false - } } } diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index 3135ab1df6..a5e985efe0 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -3,6 +3,7 @@ import QtQuick 2.1 import QtQuick.Controls 1.1 +import QtQuick.Window 2.1 import UM 1.2 as UM import Cura 1.0 as Cura @@ -106,6 +107,8 @@ UM.ManagementPage { id: actionDialog property var content + minimumWidth: 350 * Screen.devicePixelRatio; + minimumHeight: 350 * Screen.devicePixelRatio; onContentChanged: { contents = content; @@ -120,23 +123,109 @@ UM.ManagementPage } } - Row + Grid { + id: machineInfo + anchors.top: machineActions.visible ? machineActions.bottom : machineActions.anchors.top anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: parent.left anchors.right: parent.right - spacing: UM.Theme.getSize("default_margin").height + rowSpacing: UM.Theme.getSize("default_lining").height + columns: 2 + + visible: base.currentItem + + property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 + property var connectedPrinter: printerConnected ? Cura.MachineManager.printerOutputDevices[0] : null + property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands Label { - text: catalog.i18nc("@label", "Type") + text: catalog.i18nc("@label", "Printer type:") visible: base.currentItem && "definition_name" in base.currentItem.metadata } Label { text: (base.currentItem && "definition_name" in base.currentItem.metadata) ? base.currentItem.metadata.definition_name : "" } + Label + { + text: catalog.i18nc("@label", "Connection:") + visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId + } + Label { + width: parent.width * 0.7 + text: machineInfo.printerConnected ? machineInfo.connectedPrinter.connectionText : catalog.i18nc("@info:status", "The printer is not connected.") + visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId + wrapMode: Text.WordWrap + } + Label + { + text: catalog.i18nc("@label", "State:") + visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId && machineInfo.printerAcceptsCommands + } + Label { + width: parent.width * 0.7 + text: + { + if(!machineInfo.printerConnected || !machineInfo.printerAcceptsCommands) { + return ""; + } + + switch(Cura.MachineManager.printerOutputDevices[0].jobState) + { + case "printing": + return catalog.i18nc("@label:MonitorStatus", "Printing..."); + case "paused": + return catalog.i18nc("@label:MonitorStatus", "Paused"); + case "pre_print": + return catalog.i18nc("@label:MonitorStatus", "Preparing..."); + case "wait_cleanup": + return catalog.i18nc("@label:MonitorStatus", "Waiting for someone to clear the build plate"); + case "error": + return printerOutputDevice.errorText; + case "maintenance": + return catalog.i18nc("@label:MonitorStatus", "In maintenance. Please check the printer"); + case "abort": // note sure if this jobState actually occurs in the wild + return catalog.i18nc("@label:MonitorStatus", "Aborting print..."); + case "ready": // ready to print or getting ready + case "": // ready to print or getting ready + return catalog.i18nc("@label:MonitorStatus", "Waiting for a printjob"); + } + } + visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId && machineInfo.printerAcceptsCommands + wrapMode: Text.WordWrap + } + } + + Column { + id: additionalComponentsColumn + anchors.left: parent.left + anchors.right: parent.right + anchors.top: machineInfo.visible ? machineInfo.bottom : machineInfo.anchors.top + anchors.topMargin: UM.Theme.getSize("default_margin").width + + spacing: UM.Theme.getSize("default_margin").width + + Component.onCompleted: + { + for (var component in Printer.additionalComponents["machinesDetailPane"]) { + Printer.additionalComponents["machinesDetailPane"][component].parent = additionalComponentsColumn + } + } + } + + Connections { + target: Printer + onAdditionalComponentsChanged: + { + if(areaId == "machinesDetailPane") { + for (var component in Printer.additionalComponents["machinesDetailPane"]) { + Printer.additionalComponents["machinesDetailPane"][component].parent = additionalComponentsColumn + } + } + } } UM.I18nCatalog { id: catalog; name: "uranium"; } diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 9dbb5c6d15..6115671563 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -44,6 +44,16 @@ TabView property real rowHeight: textField.height; + Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") } + ReadOnlyTextField + { + id: displayNameTextField; + width: base.secondColumnWidth; + text: properties.name; + readOnly: !base.editingEnabled; + onEditingFinished: base.setName(properties.name, text) + } + Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") } ReadOnlyTextField { @@ -105,7 +115,7 @@ TabView width: base.secondColumnWidth; value: properties.density; decimals: 2 - suffix: "g/cm" + suffix: "g/cm³" stepSize: 0.01 readOnly: !base.editingEnabled; @@ -118,7 +128,7 @@ TabView width: base.secondColumnWidth; value: properties.diameter; decimals: 2 - suffix: "mm³" + suffix: "mm" stepSize: 0.01 readOnly: !base.editingEnabled; @@ -254,7 +264,17 @@ TabView { if(old_value != new_value) { - Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value) + Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value); + } + } + + function setName(old_value, new_value) + { + if(old_value != new_value) + { + Cura.ContainerManager.setContainerName(base.containerId, new_value); + // update material name label. not so pretty, but it works + materialProperties.name = new_value; } } } diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml index f4a8df1dcf..25156c03be 100644 --- a/resources/qml/Preferences/MaterialsPage.qml +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -37,6 +37,58 @@ UM.ManagementPage sectionProperty: "brand" } + delegate: Rectangle + { + width: objectList.width; + height: childrenRect.height; + color: isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase + property bool isCurrentItem: ListView.isCurrentItem + + Row + { + spacing: UM.Theme.getSize("default_margin").width / 2; + anchors.left: parent.left; + anchors.leftMargin: UM.Theme.getSize("default_margin").width; + anchors.right: parent.right; + Rectangle + { + width: parent.height * 0.8 + height: parent.height * 0.8 + color: model.metadata.color_code + border.color: isCurrentItem ? palette.highlightedText : palette.text; + anchors.verticalCenter: parent.verticalCenter + } + Label + { + width: parent.width * 0.3 + text: model.metadata.material + elide: Text.ElideRight + font.italic: model.id == activeId + color: isCurrentItem ? palette.highlightedText : palette.text; + } + Label + { + text: (model.name != model.metadata.material) ? model.name : "" + elide: Text.ElideRight + font.italic: model.id == activeId + color: isCurrentItem ? palette.highlightedText : palette.text; + } + } + + MouseArea + { + anchors.fill: parent; + onClicked: + { + if(!parent.ListView.isCurrentItem) + { + parent.ListView.view.currentIndex = index; + base.itemActivated(); + } + } + } + } + activeId: Cura.MachineManager.activeMaterialId activeIndex: { for(var i = 0; i < model.rowCount(); i++) { @@ -47,7 +99,17 @@ UM.ManagementPage return -1; } - scrollviewCaption: "Printer: %1, Nozzle: %2".arg(Cura.MachineManager.activeMachineName).arg(Cura.MachineManager.activeVariantName) + scrollviewCaption: + { + if (Cura.MachineManager.hasVariants) + { + catalog.i18nc("@action:label %1 is printer name, %2 is how this printer names variants, %3 is variant name", "Printer: %1, %2: %3").arg(Cura.MachineManager.activeMachineName).arg(Cura.MachineManager.activeDefinitionVariantsName).arg(Cura.MachineManager.activeVariantName) + } + else + { + catalog.i18nc("@action:label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName) + } + } detailsVisible: true section.property: "section" @@ -67,8 +129,6 @@ UM.ManagementPage enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId onClicked: Cura.MachineManager.setActiveMaterial(base.currentItem.id) }, - /* - // disabled because it has a lot of issues Button { text: catalog.i18nc("@action:button", "Duplicate"); @@ -76,27 +136,22 @@ UM.ManagementPage enabled: base.currentItem != null onClicked: { - var material_id = Cura.ContainerManager.duplicateContainer(base.currentItem.id) + var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file") + // We need to copy the base container instead of the specific variant. + var material_id = base_file == "" ? Cura.ContainerManager.duplicateMaterial(base.currentItem.id): Cura.ContainerManager.duplicateMaterial(base_file) if(material_id == "") { return } - if(Cura.MachineManager.filterQualityByMachine) - { - var quality_id = Cura.ContainerManager.duplicateContainer(Cura.MachineManager.activeQualityId) - Cura.ContainerManager.setContainerMetaDataEntry(quality_id, "material", material_id) - Cura.MachineManager.setActiveQuality(quality_id) - } - Cura.MachineManager.setActiveMaterial(material_id) } - }, */ + }, Button { text: catalog.i18nc("@action:button", "Remove"); iconName: "list-remove"; - enabled: base.currentItem != null && !base.currentItem.readOnly + enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) onClicked: confirmDialog.open() }, Button @@ -104,6 +159,7 @@ UM.ManagementPage text: catalog.i18nc("@action:button", "Import"); iconName: "document-import"; onClicked: importDialog.open(); + visible: true; }, Button { @@ -115,8 +171,6 @@ UM.ManagementPage ] Item { - UM.I18nCatalog { id: catalog; name: "cura"; } - visible: base.currentItem != null anchors.fill: parent @@ -188,7 +242,14 @@ UM.ManagementPage object: base.currentItem != null ? base.currentItem.name : "" onYes: { - var containers = Cura.ContainerManager.findInstanceContainers({"GUID": base.currentItem.metadata.GUID}) + // A material container can actually be multiple items, so we need to find (and remove) all of them. + var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file") + if(base_file == "") + { + base_file = base.currentItem.id + } + var guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID") + var containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "base_file": base_file, "type": "material"}) for(var i in containers) { Cura.ContainerManager.removeContainer(containers[i]) @@ -266,6 +327,9 @@ UM.ManagementPage { id: messageDialog } + + UM.I18nCatalog { id: catalog; name: "cura"; } + SystemPalette { id: palette } } onCurrentItemChanged: @@ -274,7 +338,6 @@ UM.ManagementPage { return } - materialProperties.name = currentItem.name; if(currentItem.metadata != undefined && currentItem.metadata != null) @@ -297,6 +360,7 @@ UM.ManagementPage materialProperties.density = 0.0; materialProperties.diameter = 0.0; } + } } } diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml new file mode 100644 index 0000000000..d50689ccf9 --- /dev/null +++ b/resources/qml/Preferences/ProfileTab.qml @@ -0,0 +1,63 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Cura is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Tab +{ + id: base + + property string extruderId: ""; + property string quality: ""; + property string material: ""; + + TableView + { + anchors.fill: parent + anchors.margins: UM.Theme.getSize("default_margin").width + + TableViewColumn + { + role: "label" + title: catalog.i18nc("@title:column", "Setting") + width: parent.width * 0.4 + } + TableViewColumn + { + role: "profile_value" + title: catalog.i18nc("@title:column", "Profile") + width: parent.width * 0.18 + } + TableViewColumn + { + role: "user_value" + title: catalog.i18nc("@title:column", "Current"); + visible: quality == Cura.MachineManager.activeQualityId + width: parent.width * 0.18 + } + TableViewColumn + { + role: "unit" + title: catalog.i18nc("@title:column", "Unit") + width: parent.width * 0.14 + } + + section.property: "category" + section.delegate: Label + { + text: section + font.bold: true + } + + model: Cura.QualitySettingsModel + { + extruderId: base.extruderId != "" ? base.extruderId : "" + quality: base.quality != null ? base.quality : "" + material: base.material != null ? base.material : "" + } + } +} diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 0ef55a1e37..94e452444e 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -13,18 +13,19 @@ UM.ManagementPage id: base; title: catalog.i18nc("@title:tab", "Profiles"); + property var extrudersModel: Cura.ExtrudersModel{} model: UM.InstanceContainersModel { filter: { - var result = { "type": "quality" }; + var result = { "type": "quality*", "extruder": null }; if(Cura.MachineManager.filterQualityByMachine) { - result.definition = Cura.MachineManager.activeDefinitionId; + result.definition = Cura.MachineManager.activeQualityDefinitionId; if(Cura.MachineManager.hasMaterials) { - result.material = Cura.MachineManager.activeMaterialId; + result.material = Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeMachineId]; } } else @@ -59,6 +60,10 @@ UM.ManagementPage return -1; } + function canCreateProfile() { + return base.currentItem && (base.currentItem.id == Cura.MachineManager.activeQualityId) && Cura.MachineManager.hasUserSettings; + } + buttons: [ Button { @@ -67,31 +72,44 @@ UM.ManagementPage enabled: base.currentItem != null ? base.currentItem.id != Cura.MachineManager.activeQualityId : false; onClicked: Cura.MachineManager.setActiveQuality(base.currentItem.id) }, + + // Create button Button { - text: base.currentItem && (base.currentItem.id == Cura.MachineManager.activeQualityId) ? catalog.i18nc("@label", "Create") : catalog.i18nc("@label", "Duplicate") + text: catalog.i18nc("@label", "Create") + enabled: base.canCreateProfile() + visible: base.canCreateProfile() iconName: "list-add"; onClicked: { - var selectedContainer; - if (base.currentItem.id == Cura.MachineManager.activeQualityId) { - selectedContainer = Cura.MachineManager.newQualityContainerFromQualityAndUser(); - } else { - selectedContainer = Cura.MachineManager.duplicateContainer(base.currentItem.id); - } - base.selectContainer(selectedContainer); - - renameDialog.removeWhenRejected = true; - renameDialog.open(); - renameDialog.selectText(); + newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(base.currentItem.name) : ""; + newNameDialog.open(); + newNameDialog.selectText(); } }, + + // Duplicate button + Button + { + text: catalog.i18nc("@label", "Duplicate") + enabled: ! base.canCreateProfile() + visible: ! base.canCreateProfile() + iconName: "list-add"; + + onClicked: + { + newDuplicateNameDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name); + newDuplicateNameDialog.open(); + newDuplicateNameDialog.selectText(); + } + }, + Button { text: catalog.i18nc("@action:button", "Remove"); iconName: "list-remove"; - enabled: base.currentItem != null ? !base.currentItem.readOnly : false; + enabled: base.currentItem != null ? !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) : false; onClicked: confirmDialog.open(); }, Button @@ -99,7 +117,11 @@ UM.ManagementPage text: catalog.i18nc("@action:button", "Rename"); iconName: "edit-rename"; enabled: base.currentItem != null ? !base.currentItem.readOnly : false; - onClicked: { renameDialog.removeWhenRejected = false; renameDialog.open(); renameDialog.selectText(); } + onClicked: + { + renameDialog.open(); + renameDialog.selectText(); + } }, Button { @@ -118,12 +140,18 @@ UM.ManagementPage scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName) - signal showProfileNameDialog() - onShowProfileNameDialog: { renameDialog.removeWhenRejected = true; renameDialog.open(); renameDialog.selectText(); } + signal createProfile() + onCreateProfile: + { + newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(base.currentItem.name) : ""; + newNameDialog.open(); + newNameDialog.selectText(); + } - signal selectContainer(string id) - onSelectContainer: { - objectList.currentIndex = objectList.model.find("id", id); + signal selectContainer(string name) + onSelectContainer: + { + objectList.currentIndex = objectList.model.find("name", name); } Item { @@ -132,17 +160,17 @@ UM.ManagementPage Label { id: profileName - text: base.currentItem ? base.currentItem.name : "" + text: base.currentItem ? base.currentItem.name: "" font: UM.Theme.getFont("large") width: parent.width elide: Text.ElideRight } - Row { + Flow { id: currentSettingsActions visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId - anchors.left: parent.left + anchors.right: parent.right anchors.top: profileName.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height @@ -152,14 +180,14 @@ UM.ManagementPage return catalog.i18nc("@action:button", "Update profile with current settings"); } enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) - onClicked: Cura.MachineManager.updateQualityContainerFromUserContainer() + onClicked: Cura.ContainerManager.updateQualityChanges() } Button { text: catalog.i18nc("@action:button", "Discard current settings"); enabled: Cura.MachineManager.hasUserSettings - onClicked: Cura.MachineManager.clearUserSettings(); + onClicked: Cura.ContainerManager.clearUserContainers(); } } @@ -173,8 +201,8 @@ UM.ManagementPage Label { id: defaultsMessage - visible: currentItem && !currentItem.metadata.has_settings - text: catalog.i18nc("@action:label", "This profile has no settings and uses the defaults specified by the printer.") + visible: false + text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings in the list below.") wrapMode: Text.WordWrap width: parent.width } @@ -187,71 +215,31 @@ UM.ManagementPage } } - ScrollView { - id: scrollView - + TabView + { anchors.left: parent.left anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.right: parent.right anchors.bottom: parent.bottom - ListView { - model: Cura.ContainerSettingsModel + ProfileTab + { + title: catalog.i18nc("@title:tab", "Global Settings"); + quality: base.currentItem != null ? base.currentItem.id : ""; + material: Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeMachineId] + } + + Repeater + { + model: base.extrudersModel + + ProfileTab { - containers: - { - if (!currentItem) { - return [] - } else if (currentItem.id == Cura.MachineManager.activeQualityId) { - return [base.currentItem.id, Cura.MachineManager.activeUserProfileId] - } else { - return [base.currentItem.id] - } - } - } - delegate: Row { - property variant setting: model - spacing: UM.Theme.getSize("default_margin").width/2 - Label { - text: model.label - elide: Text.ElideMiddle - width: scrollView.width / 100 * 40 - } - Repeater { - model: setting.values.length - Label { - text: setting.values[index].toString() - width: scrollView.width / 100 * 15 - elide: Text.ElideRight - font.strikeout: index < setting.values.length - 1 && setting.values[index + 1] != "" - opacity: font.strikeout ? 0.5 : 1 - } - } - Label { - text: model.unit - } - } - header: Row { - visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId - spacing: UM.Theme.getSize("default_margin").width - Label { - text: catalog.i18nc("@action:label", "Profile:") - width: scrollView.width / 100 * 55 - horizontalAlignment: Text.AlignRight - font.bold: true - } - Label { - text: catalog.i18nc("@action:label", "Current:") - visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId - font.bold: true - } - } - section.property: "category" - section.criteria: ViewSection.FullString - section.delegate: Label { - text: section - font.bold: true + title: model.name; + extruderId: model.id; + quality: base.currentItem != null ? base.currentItem.id : ""; + material: Cura.MachineManager.allActiveMaterialIds[model.id] } } } @@ -265,20 +253,58 @@ UM.ManagementPage { id: confirmDialog object: base.currentItem != null ? base.currentItem.name : "" - onYes: Cura.MachineManager.removeQualityContainer(base.currentItem.id) - } - UM.RenameDialog - { - id: renameDialog; - object: base.currentItem != null ? base.currentItem.name : "" - property bool removeWhenRejected: false - onAccepted: Cura.MachineManager.renameQualityContainer(base.currentItem.id, newName) - onRejected: { - if(removeWhenRejected) { - Cura.MachineManager.removeQualityContainer(base.currentItem.id) + onYes: + { + var name = base.currentItem.name; + Cura.ContainerManager.removeQualityChanges(name) + if(Cura.MachineManager.activeQualityName == name) + { + Cura.MachineManager.setActiveQuality(base.model.getItem(0).name) } + objectList.currentIndex = -1 //Reset selection. } } + + UM.RenameDialog + { + title: catalog.i18nc("@title:window", "Rename Profile") + id: renameDialog; + object: base.currentItem != null ? base.currentItem.name : "" + onAccepted: + { + Cura.ContainerManager.renameQualityChanges(base.currentItem.name, newName) + objectList.currentIndex = -1 //Reset selection. + } + } + + // Dialog to request a name when creating a new profile + UM.RenameDialog + { + title: catalog.i18nc("@title:window", "Create Profile") + id: newNameDialog; + object: ""; + onAccepted: + { + var selectedContainer = Cura.ContainerManager.createQualityChanges(newName); + base.selectContainer(selectedContainer); + objectList.currentIndex = -1 //Reset selection. + } + } + + // Dialog to request a name when duplicating a new profile + UM.RenameDialog + { + title: catalog.i18nc("@title:window", "Duplicate Profile") + id: newDuplicateNameDialog; + object: ""; + onAccepted: + { + var selectedContainer = Cura.ContainerManager.duplicateQualityOrQualityChanges(base.currentItem.name, newName); + base.selectContainer(selectedContainer); + objectList.currentIndex = -1 //Reset selection. + } + } + MessageDialog { id: messageDialog @@ -324,7 +350,12 @@ UM.ManagementPage folder: CuraApplication.getDefaultPath("dialog_profile_path") onAccepted: { - var result = base.model.exportProfile(base.currentItem.id, fileUrl, selectedNameFilter) + var profiles_to_export = [base.currentItem.id] + for(var extruder_nr in base.extrudersModel.items) + { + profiles_to_export.push(ExtruderManager.getQualityChangesIdByExtruderStackId(base.extrudersModel.items[extruder_nr].id)) + } + var result = base.model.exportProfile(profiles_to_export, fileUrl, selectedNameFilter) if(result && result.status == "error") { messageDialog.icon = StandardIcon.Critical diff --git a/resources/qml/Preferences/ReadOnlyTextField.qml b/resources/qml/Preferences/ReadOnlyTextField.qml index 28c714259b..2ff0357020 100644 --- a/resources/qml/Preferences/ReadOnlyTextField.qml +++ b/resources/qml/Preferences/ReadOnlyTextField.qml @@ -1,5 +1,6 @@ // Copyright (c) 2016 Ultimaker B.V. // Uranium is released under the terms of the AGPLv3 or higher. +// Different than the name suggests, it is not always read-only. import QtQuick 2.1 import QtQuick.Controls 1.1 diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml new file mode 100644 index 0000000000..e68df94122 --- /dev/null +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -0,0 +1,167 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.2 as UM + +import Cura 1.0 as Cura + +UM.PreferencesPage +{ + title: catalog.i18nc("@title:tab", "Setting Visibility"); + + property int scrollToIndex: 0 + + signal scrollToSection( string key ) + onScrollToSection: + { + settingsListView.positionViewAtIndex(definitionsModel.getIndex(key), ListView.Beginning) + } + + function reset() + { + UM.Preferences.resetPreference("general/visible_settings") + } + resetEnabled: true; + + Item + { + id: base; + anchors.fill: parent; + + CheckBox + { + id: toggleVisibleSettings + anchors + { + verticalCenter: filter.verticalCenter; + left: parent.left; + leftMargin: UM.Theme.getSize("default_margin").width + } + text: catalog.i18nc("@label:textbox", "Check all") + checkedState: + { + if(definitionsModel.visibleCount == definitionsModel.categoryCount) + { + return Qt.Unchecked + } + else if(definitionsModel.visibleCount == definitionsModel.rowCount(null)) + { + return Qt.Checked + } + else + { + return Qt.PartiallyChecked + } + } + partiallyCheckedEnabled: true + + MouseArea + { + anchors.fill: parent; + onClicked: + { + if(parent.checkedState == Qt.Unchecked || parent.checkedState == Qt.PartiallyChecked) + { + definitionsModel.setAllVisible(true) + } + else + { + definitionsModel.setAllVisible(false) + } + } + } + } + + TextField + { + id: filter; + + anchors + { + top: parent.top + left: toggleVisibleSettings.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + } + + placeholderText: catalog.i18nc("@label:textbox", "Filter...") + + onTextChanged: definitionsModel.filter = {"label": "*" + text} + } + + ScrollView + { + id: scrollView + + frameVisible: true + + anchors + { + top: filter.bottom; + topMargin: UM.Theme.getSize("default_margin").height + left: parent.left; + right: parent.right; + bottom: parent.bottom; + } + ListView + { + id: settingsListView + + model: UM.SettingDefinitionsModel + { + id: definitionsModel + containerId: Cura.MachineManager.activeDefinitionId + showAll: true + exclude: ["machine_settings"] + expanded: ["*"] + visibilityHandler: UM.SettingPreferenceVisibilityHandler { } + } + + delegate: Loader + { + id: loader + + width: parent.width + height: model.type != undefined ? UM.Theme.getSize("section").height : 0 + + property var definition: model + property var settingDefinitionsModel: definitionsModel + + asynchronous: true + active: model.type != undefined + sourceComponent: + { + switch(model.type) + { + case "category": + return settingVisibilityCategory + default: + return settingVisibilityItem + } + } + } + } + } + + UM.I18nCatalog { name: "cura"; } + SystemPalette { id: palette; } + + Component + { + id: settingVisibilityCategory; + + UM.SettingVisibilityCategory { } + } + + Component + { + id: settingVisibilityItem; + + UM.SettingVisibilityItem { } + } + } +} diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml index c766b2d947..8d04122aa8 100644 --- a/resources/qml/PrintMonitor.qml +++ b/resources/qml/PrintMonitor.qml @@ -14,11 +14,15 @@ Column id: printMonitor property var connectedPrinter: printerConnected ? Cura.MachineManager.printerOutputDevices[0] : null - Cura.ExtrudersModel { id: extrudersModel } + Cura.ExtrudersModel + { + id: extrudersModel + simpleNames: true + } Label { - text: printerConnected ? connectedPrinter.connectionText : catalog.i18nc("@label", "The printer is not connected.") + text: printerConnected ? connectedPrinter.connectionText : catalog.i18nc("@info:status", "The printer is not connected.") color: printerConnected && printerAcceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") font: UM.Theme.getFont("default") wrapMode: Text.WordWrap diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 9ea6e181bb..9b63fccf94 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -14,9 +14,7 @@ Rectangle { property real progress: UM.Backend.progress; property int backendState: UM.Backend.state; - property bool activity: Printer.getPlatformActivity; - //Behavior on progress { NumberAnimation { duration: 250; } } property int totalHeight: childrenRect.height + UM.Theme.getSize("default_margin").height property string fileBaseName property string statusText: @@ -26,21 +24,18 @@ Rectangle { return catalog.i18nc("@label:PrintjobStatus", "Please load a 3d model"); } - if(base.backendState == 1) + switch(base.backendState) { - return catalog.i18nc("@label:PrintjobStatus", "Preparing to slice..."); - } - else if(base.backendState == 2) - { - return catalog.i18nc("@label:PrintjobStatus", "Slicing..."); - } - else if(base.backendState == 3) - { - return catalog.i18nc("@label:PrintjobStatus %1 is target operation","Ready to %1").arg(UM.OutputDeviceManager.activeDeviceShortDescription); - } - else if(base.backendState == 4) - { - return catalog.i18nc("@label:PrintjobStatus", "Unable to Slice") + case 1: + return catalog.i18nc("@label:PrintjobStatus", "Preparing to slice..."); + case 2: + return catalog.i18nc("@label:PrintjobStatus", "Slicing..."); + case 3: + return catalog.i18nc("@label:PrintjobStatus %1 is target operation","Ready to %1").arg(UM.OutputDeviceManager.activeDeviceShortDescription); + case 4: + return catalog.i18nc("@label:PrintjobStatus", "Unable to Slice"); + default: + return ""; } } @@ -126,12 +121,29 @@ Rectangle { background: Rectangle { border.width: UM.Theme.getSize("default_lining").width - border.color: !control.enabled ? UM.Theme.getColor("action_button_disabled_border") : - control.pressed ? UM.Theme.getColor("action_button_active_border") : - control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border") - color: !control.enabled ? UM.Theme.getColor("action_button_disabled") : - control.pressed ? UM.Theme.getColor("action_button_active") : - control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") + border.color: + { + if(!control.enabled) + return UM.Theme.getColor("action_button_disabled_border"); + else if(control.pressed) + return UM.Theme.getColor("action_button_active_border"); + else if(control.hovered) + return UM.Theme.getColor("action_button_hovered_border"); + else + return UM.Theme.getColor("action_button_border"); + } + color: + { + if(!control.enabled) + return UM.Theme.getColor("action_button_disabled"); + else if(control.pressed) + return UM.Theme.getColor("action_button_active"); + else if(control.hovered) + return UM.Theme.getColor("action_button_hovered"); + else + return UM.Theme.getColor("action_button"); + } + Behavior on color { ColorAnimation { duration: 50; } } implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("default_margin").width * 2) @@ -139,9 +151,17 @@ Rectangle { Label { id: actualLabel anchors.centerIn: parent - color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") : - control.pressed ? UM.Theme.getColor("action_button_active_text") : - control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text") + color: + { + if(!control.enabled) + return UM.Theme.getColor("action_button_disabled_text"); + else if(control.pressed) + return UM.Theme.getColor("action_button_active_text"); + else if(control.hovered) + return UM.Theme.getColor("action_button_hovered_text"); + else + return UM.Theme.getColor("action_button_text"); + } font: UM.Theme.getFont("action_button") text: control.text; } @@ -167,12 +187,28 @@ Rectangle { background: Rectangle { id: deviceSelectionIcon border.width: UM.Theme.getSize("default_lining").width - border.color: !control.enabled ? UM.Theme.getColor("action_button_disabled_border") : - control.pressed ? UM.Theme.getColor("action_button_active_border") : - control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border") - color: !control.enabled ? UM.Theme.getColor("action_button_disabled") : - control.pressed ? UM.Theme.getColor("action_button_active") : - control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") + border.color: + { + if(!control.enabled) + return UM.Theme.getColor("action_button_disabled_border"); + else if(control.pressed) + return UM.Theme.getColor("action_button_active_border"); + else if(control.hovered) + return UM.Theme.getColor("action_button_hovered_border"); + else + return UM.Theme.getColor("action_button_border"); + } + color: + { + if(!control.enabled) + return UM.Theme.getColor("action_button_disabled"); + else if(control.pressed) + return UM.Theme.getColor("action_button_active"); + else if(control.hovered) + return UM.Theme.getColor("action_button_hovered"); + else + return UM.Theme.getColor("action_button"); + } Behavior on color { ColorAnimation { duration: 50; } } anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("save_button_text_margin").width / 2; @@ -186,9 +222,17 @@ Rectangle { height: UM.Theme.getSize("standard_arrow").height sourceSize.width: width sourceSize.height: height - color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") : - control.pressed ? UM.Theme.getColor("action_button_active_text") : - control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text"); + color: + { + if(!control.enabled) + return UM.Theme.getColor("action_button_disabled_text"); + else if(control.pressed) + return UM.Theme.getColor("action_button_active_text"); + else if(control.hovered) + return UM.Theme.getColor("action_button_hovered_text"); + else + return UM.Theme.getColor("action_button_text"); + } source: UM.Theme.getIcon("arrow_bottom"); } } diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index 9b50c82395..1fcd24ccf6 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -20,18 +20,40 @@ SettingItem property bool checked: { - switch(propertyProvider.properties.value) + // FIXME this needs to go away once 'resolve' is combined with 'value' in our data model. + // Stacklevels + // 0: user -> unsaved change + // 1: quality changes -> saved change + // 2: quality + // 3: material -> user changed material in materials page + // 4: variant + // 5: machine + var value; + if ((propertyProvider.properties.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) { + // We have a resolve function. Indicates that the setting is not settable per extruder and that + // we have to choose between the resolved value (default) and the global value + // (if user has explicitly set this). + value = propertyProvider.properties.resolve; + } else { + value = propertyProvider.properties.value; + } + + switch(value) { case "True": - return true + return true; case "False": - return false + return false; default: - return propertyProvider.properties.value + return value; } } - onClicked: { forceActiveFocus(); propertyProvider.setPropertyValue("value", !checked) } + onClicked: + { + forceActiveFocus(); + propertyProvider.setPropertyValue("value", !checked); + } Rectangle { diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index 283e309e6a..0f6bab438d 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -96,8 +96,19 @@ SettingItem } function updateCurrentIndex() { + // FIXME this needs to go away once 'resolve' is combined with 'value' in our data model. + var value; + if ((propertyProvider.properties.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) { + // We have a resolve function. Indicates that the setting is not settable per extruder and that + // we have to choose between the resolved value (default) and the global value + // (if user has explicitly set this). + value = propertyProvider.properties.resolve; + } else { + value = propertyProvider.properties.value; + } + for(var i = 0; i < definition.options.length; ++i) { - if(definition.options[i].key == propertyProvider.properties.value) { + if(definition.options[i].key == value) { currentIndex = i; return; } diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index dae9953690..943f8e84bb 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -27,7 +27,7 @@ Item { // Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise) property var state: propertyProvider.properties.state - property var settablePerExtruder: propertyProvider.properties.settable_per_extruder + property var resolve: propertyProvider.properties.resolve property var stackLevels: propertyProvider.stackLevels property var stackLevel: stackLevels[0] @@ -138,7 +138,7 @@ Item { { id: linkedSettingIcon; - visible: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId && base.settablePerExtruder != "True" && base.showLinkedSettingIcon + visible: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId && (!definition.settable_per_extruder || definition.limit_to_extruder != "-1") && base.showLinkedSettingIcon height: parent.height; width: height; @@ -150,7 +150,15 @@ Item { iconSource: UM.Theme.getIcon("link") - onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders")) } + onEntered: { + hoverTimer.stop(); + var tooltipText = catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders") + "."; + if ((resolve != "None") && (stackLevel != 0)) { + // We come here if a setting has a resolve and the setting is not manually edited. + tooltipText += " " + catalog.i18nc("@label", "The value is resolved from per-extruder values ") + "[" + ExtruderManager.getInstanceExtruderValues(definition.key) + "]."; + } + base.showTooltip(tooltipText); + } onExited: base.showTooltip(base.tooltipText); } @@ -171,8 +179,8 @@ Item { iconSource: UM.Theme.getIcon("reset") onClicked: { - revertButton.focus = true - propertyProvider.removeFromContainer(0) + revertButton.focus = true; + Cura.MachineManager.clearUserSettingAllCurrentStacks(propertyProvider.key); } onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) } @@ -238,8 +246,8 @@ Item { // This ensures that the value in any of the deeper containers need not be removed, which is // needed for the reset button (which deletes the top value) to correctly go back to profile // defaults. - propertyProvider.setPropertyValue("state", "InstanceState.Calculated") propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry)) + propertyProvider.setPropertyValue("state", "InstanceState.Calculated") } } diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index 686a47ca47..e4c93d9b8c 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -106,7 +106,23 @@ SettingItem { target: input property: "text" - value: propertyProvider.properties.value + value: { + // Stacklevels + // 0: user -> unsaved change + // 1: quality changes -> saved change + // 2: quality + // 3: material -> user changed material in materialspage + // 4: variant + // 5: machine + if ((propertyProvider.properties.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) { + // We have a resolve function. Indicates that the setting is not settable per extruder and that + // we have to choose between the resolved value (default) and the global value + // (if user has explicitly set this). + return propertyProvider.properties.resolve; + } else { + return propertyProvider.properties.value; + } + } when: !input.activeFocus } } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 978e2dcaed..50e0ab804f 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -40,7 +40,7 @@ ScrollView id: delegate width: UM.Theme.getSize("sidebar").width; - height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : 0 + height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : - contents.spacing Behavior on height { NumberAnimation { duration: 100 } } opacity: provider.properties.enabled == "True" ? 1 : 0 Behavior on opacity { NumberAnimation { duration: 100 } } @@ -57,6 +57,7 @@ ScrollView property var definition: model property var settingDefinitionsModel: definitionsModel property var propertyProvider: provider + property var globalPropertyProvider: inheritStackProvider //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, @@ -88,37 +89,43 @@ ScrollView } // Binding to ensure that the right containerstack ID is set for the provider. - // This ensures that if a setting has a global_inherits_stack id (for instance; Support speed points to the + // This ensures that if a setting has a limit_to_extruder id (for instance; Support speed points to the // extruder that actually prints the support, as that is the setting we need to use to calculate the value) Binding { target: provider property: "containerStackId" + when: model.settable_per_extruder || (inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0); value: { - if(inheritStackProvider.properties.global_inherits_stack == -1 || inheritStackProvider.properties.global_inherits_stack == null) + if(!model.settable_per_extruder) { - if( ExtruderManager.activeExtruderStackId) - { - return ExtruderManager.activeExtruderStackId - } - else - { - return Cura.MachineManager.activeMachineId - } + //Not settable per extruder, so we must pick global. + return Cura.MachineManager.activeMachineId; } - return ExtruderManager.extruderIds[String(inheritStackProvider.properties.global_inherits_stack)] + if(inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0) + { + //We have limit_to_extruder, so pick that stack. + return ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)]; + } + if(ExtruderManager.activeExtruderStackId) + { + //We're on an extruder tab. Pick the current extruder. + return ExtruderManager.activeExtruderStackId; + } + //No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab. + return Cura.MachineManager.activeMachineId; } } // Specialty provider that only watches global_inherits (we cant filter on what property changed we get events - // so we bypass that to make a dedicated provider. + // so we bypass that to make a dedicated provider). UM.SettingPropertyProvider { id: inheritStackProvider containerStackId: Cura.MachineManager.activeMachineId key: model.key - watchedProperties: [ "global_inherits_stack"] + watchedProperties: [ "limit_to_extruder" ] } UM.SettingPropertyProvider @@ -127,7 +134,7 @@ ScrollView containerStackId: Cura.MachineManager.activeMachineId key: model.key ? model.key : "" - watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder" ] + watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder", "resolve" ] storeIndex: 0 } diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index aa51fcfefe..036f1283cc 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -112,6 +112,11 @@ Rectangle else if(!printerAcceptsCommands) return UM.Theme.getIcon("tab_monitor_unknown"); + if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance") + { + return UM.Theme.getIcon("tab_monitor_busy"); + } + switch(Cura.MachineManager.printerOutputDevices[0].jobState) { case "printing": @@ -144,7 +149,6 @@ Rectangle SidebarHeader { id: header width: parent.width - height: totalHeightHeader anchors.top: sidebarHeaderBar.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index b1cf45f6d3..9ed30477d8 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -14,8 +14,7 @@ Column { id: base; - property int totalHeightHeader: childrenRect.height - property int currentExtruderIndex:ExtruderManager.activeExtruderIndex; + property int currentExtruderIndex: ExtruderManager.activeExtruderIndex; spacing: UM.Theme.getSize("default_margin").height @@ -67,7 +66,7 @@ Column id: extrudersList property var index: 0 - visible: machineExtruderCount.properties.value > 1 + visible: machineExtruderCount.properties.value > 1 && !sidebar.monitoringPrint height: UM.Theme.getSize("sidebar_header_mode_toggle").height boundsBehavior: Flickable.StopAtBounds @@ -92,8 +91,8 @@ Column onGlobalContainerChanged: { forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - base.currentExtruderIndex = (machineExtruderCount.properties.value == 1) ? -1 : 0; - ExtruderManager.setActiveExtruderIndex(base.currentExtruderIndex); + var extruder_index = (machineExtruderCount.properties.value == 1) ? -1 : 0 + ExtruderManager.setActiveExtruderIndex(extruder_index); } } @@ -105,13 +104,11 @@ Column text: model.name tooltip: model.name exclusiveGroup: extruderMenuGroup - checkable: true checked: base.currentExtruderIndex == index onClicked: { forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values. - base.currentExtruderIndex = index; ExtruderManager.setActiveExtruderIndex(index); } @@ -170,7 +167,7 @@ Column id: variantRow height: UM.Theme.getSize("sidebar_setup").height - visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials + visible: (Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials) && !sidebar.monitoringPrint anchors { @@ -183,8 +180,23 @@ Column Label { id: variantLabel - text: (Cura.MachineManager.hasVariants && Cura.MachineManager.hasMaterials) ? catalog.i18nc("@label","Nozzle & Material:"): - Cura.MachineManager.hasVariants ? catalog.i18nc("@label","Nozzle:") : catalog.i18nc("@label","Material:"); + text: + { + var label; + if(Cura.MachineManager.hasVariants && Cura.MachineManager.hasMaterials) + { + label = "%1 & %2".arg(Cura.MachineManager.activeDefinitionVariantsName).arg(catalog.i18nc("@label","Material")); + } + else if(Cura.MachineManager.hasVariants) + { + label = Cura.MachineManager.activeDefinitionVariantsName; + } + else + { + label = catalog.i18nc("@label","Material"); + } + return "%1:".arg(label); + } anchors.verticalCenter: parent.verticalCenter width: parent.width * 0.45 - UM.Theme.getSize("default_margin").width @@ -211,7 +223,7 @@ Column anchors.left: parent.left style: UM.Theme.styles.sidebar_header_button - menu: NozzleMenu { } + menu: NozzleMenu { extruderIndex: base.currentExtruderIndex } } ToolButton { @@ -219,6 +231,19 @@ Column text: Cura.MachineManager.activeMaterialName tooltip: Cura.MachineManager.activeMaterialName visible: Cura.MachineManager.hasMaterials + property var valueError: + { + var data = Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeMaterialId, "compatible") + if(data == "False") + { + return true + } + else + { + return false + } + + } enabled: !extrudersList.visible || base.currentExtruderIndex > -1 height: UM.Theme.getSize("setting_control").height @@ -226,7 +251,7 @@ Column anchors.right: parent.right style: UM.Theme.styles.sidebar_header_button - menu: MaterialMenu { } + menu: MaterialMenu { extruderIndex: base.currentExtruderIndex } } } } @@ -235,6 +260,7 @@ Column { id: globalProfileRow height: UM.Theme.getSize("sidebar_setup").height + visible: !sidebar.monitoringPrint anchors { @@ -264,7 +290,7 @@ Column height: UM.Theme.getSize("setting_control").height tooltip: Cura.MachineManager.activeQualityName style: UM.Theme.styles.sidebar_header_button - + property var valueWarning: Cura.MachineManager.activeQualityId == "empty_quality" menu: ProfileMenu { } UM.SimpleButton diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 0272e063cb..37d72d189d 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -213,7 +213,7 @@ Item id: adhesionHelperLabel anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width - anchors.verticalCenter: brimCheckBox.verticalCenter + anchors.verticalCenter: adhesionCheckBox.verticalCenter width: parent.width / 100 * 35 - 3 * UM.Theme.getSize("default_margin").width //: Bed adhesion label text: catalog.i18nc("@label", "Helper Parts:"); @@ -222,33 +222,45 @@ Item } CheckBox{ - id: brimCheckBox - property alias _hovered: brimMouseArea.containsMouse + id: adhesionCheckBox + property alias _hovered: adhesionMouseArea.containsMouse anchors.top: parent.top anchors.left: adhesionHelperLabel.right anchors.leftMargin: UM.Theme.getSize("default_margin").width - //: Setting enable skirt adhesion checkbox - text: catalog.i18nc("@option:check", "Print Brim"); + //: Setting enable printing build-plate adhesion helper checkbox + text: catalog.i18nc("@option:check", "Print Build Plate Adhesion"); style: UM.Theme.styles.checkbox; enabled: base.settingsEnabled - checked: platformAdhesionType.properties.value == "brim" + checked: platformAdhesionType.properties.value != "skirt" MouseArea { - id: brimMouseArea + id: adhesionMouseArea anchors.fill: parent hoverEnabled: true enabled: base.settingsEnabled onClicked: { - platformAdhesionType.setPropertyValue("value", !parent.checked ? "brim" : "skirt") + var adhesionType = "skirt"; + if(!parent.checked) + { + // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft + platformAdhesionType.removeFromContainer(0); + adhesionType = platformAdhesionType.properties.value; + if(adhesionType == "skirt") + { + // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim + adhesionType = "brim"; + } + } + platformAdhesionType.setPropertyValue("value", adhesionType); } onEntered: { - base.showTooltip(brimCheckBox, Qt.point(-brimCheckBox.x, 0), - catalog.i18nc("@label", "Enable printing a brim. This will add a single-layer-thick flat area around your object which is easy to cut off afterwards.")); + base.showTooltip(adhesionCheckBox, Qt.point(-adhesionCheckBox.x, 0), + catalog.i18nc("@label", "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards.")); } onExited: { @@ -274,7 +286,7 @@ Item visible: machineExtruderCount.properties.value <= 1 property alias _hovered: supportMouseArea.containsMouse - anchors.top: brimCheckBox.bottom + anchors.top: adhesionCheckBox.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: supportHelperLabel.right anchors.leftMargin: UM.Theme.getSize("default_margin").width @@ -311,7 +323,7 @@ Item visible: machineExtruderCount.properties.value > 1 model: extruderModel - anchors.top: brimCheckBox.bottom + anchors.top: adhesionCheckBox.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: supportHelperLabel.right anchors.leftMargin: UM.Theme.getSize("default_margin").width @@ -354,12 +366,11 @@ Item Component.onCompleted: populateExtruderModel() } - //: Invisible list used to populate the extrudelModel - ListView + //: Model used to populate the extrudelModel + Cura.ExtrudersModel { id: extruders - model: Cura.ExtrudersModel { onModelChanged: populateExtruderModel() } - visible: false + onModelChanged: populateExtruderModel() } } @@ -370,10 +381,10 @@ Item text: catalog.i18nc("@label", "Don't print support"), color: "" }) - for(var extruderNumber = 0; extruderNumber < extruders.model.rowCount() ; extruderNumber++) { + for(var extruderNumber = 0; extruderNumber < extruders.rowCount() ; extruderNumber++) { extruderModel.append({ - text: catalog.i18nc("@label", "Print using %1").arg(extruders.model.getItem(extruderNumber).name), - color: extruders.model.getItem(extruderNumber).color + text: catalog.i18nc("@label", "Print support using %1").arg(extruders.getItem(extruderNumber).name), + color: extruders.getItem(extruderNumber).color }) } } @@ -415,7 +426,7 @@ Item { id: platformAdhesionType - containerStackId: Cura.MachineManager.activeStackId + containerStackId: Cura.MachineManager.activeMachineId key: "adhesion_type" watchedProperties: [ "value" ] storeIndex: 0 @@ -425,7 +436,7 @@ Item { id: supportEnabled - containerStackId: Cura.MachineManager.activeStackId + containerStackId: Cura.MachineManager.activeMachineId key: "support_enable" watchedProperties: [ "value" ] storeIndex: 0 @@ -445,7 +456,7 @@ Item { id: supportExtruderNr - containerStackId: Cura.MachineManager.activeStackId + containerStackId: Cura.MachineManager.activeMachineId key: "support_extruder_nr" watchedProperties: [ "value" ] storeIndex: 0 diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index bde063de10..60fc6fd723 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -48,7 +48,15 @@ Item { MouseArea { anchors.fill: parent; onClicked: { - parent.checked ? UM.Controller.setActiveTool(null) : UM.Controller.setActiveTool(model.id); + forceActiveFocus() //First grab focus, so all the text fields are updated + if(parent.checked) + { + UM.Controller.setActiveTool(null) + } + else + { + UM.Controller.setActiveTool(model.id); + } } } } @@ -81,8 +89,6 @@ Item { Behavior on opacity { NumberAnimation { duration: 100 } } color: UM.Theme.getColor("lining"); - //border.width: UM.Theme.getSize("default_lining").width - //border.color: UM.Theme.getColor("lining") UM.PointingRectangle { id: panelBackground; diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index b4498c6c8b..ec3ab18fd6 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +quality_type = high weight = -3 [values] diff --git a/resources/quality/low.inst.cfg b/resources/quality/low.inst.cfg index d34a7c6461..787325c27c 100644 --- a/resources/quality/low.inst.cfg +++ b/resources/quality/low.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +quality_type = low weight = -1 [values] diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index 417c7c700f..cfd70de49c 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -5,6 +5,7 @@ definition = fdmprinter [metadata] type = quality +quality_type = normal weight = -2 [values] diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg deleted file mode 100644 index 11b926378d..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.25_normal.inst.cfg +++ /dev/null @@ -1,22 +0,0 @@ -[general] -version = 2 -name = High Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_abs_ultimaker2_extended_plus_0.25_mm -weight = -2 - -[values] -layer_height = 0.06 -wall_thickness = 0.88 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 30 -cool_min_layer_time = 3 -cool_fan_speed_min = 20 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - - diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg deleted file mode 100644 index bdeeb935f4..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_fast.inst.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[general] -version = 2 -name = Fast Print -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_abs_ultimaker2_extended_plus_0.4_mm -weight = -1 - -[values] -layer_height = 0.15 -wall_thickness = 0.7 -top_bottom_thickness = 0.75 -infill_sparse_density = 18 -speed_print = 55 -speed_wall = 40 -speed_topbottom = 30 -speed_travel = 150 -speed_layer_0 = 30 -cool_min_layer_time = 3 -cool_fan_speed_min = 20 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg deleted file mode 100644 index d658ee5bb5..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_high.inst.cfg +++ /dev/null @@ -1,22 +0,0 @@ -[general] -version = 2 -name = High Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_abs_ultimaker2_extended_plus_0.4_mm -weight = -3 - -[values] -layer_height = 0.06 -wall_thickness = 1.05 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 45 -speed_wall = 30 -cool_min_layer_time = 3 -cool_fan_speed_min = 20 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg deleted file mode 100644 index ff024ccc69..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.4_normal.inst.cfg +++ /dev/null @@ -1,21 +0,0 @@ -[general] -version = 2 -name = Normal Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_abs_ultimaker2_extended_plus_0.4_mm -weight = -2 - -[values] -layer_height = 0.1 -wall_thickness = 1.05 -top_bottom_thickness = 0.8 -infill_sparse_density = 20 -speed_print = 45 -speed_wall = 30 -cool_min_layer_time = 3 -cool_fan_speed_min = 20 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg deleted file mode 100644 index c2f4daa86f..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.6_normal.inst.cfg +++ /dev/null @@ -1,23 +0,0 @@ -[general] -version = 2 -name = Normal Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_abs_ultimaker2_extended_plus_0.6_mm -weight = -2 - -[values] -layer_height = 0.15 -wall_thickness = 1.59 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -speed_infill = 55 -cool_min_layer_time = 3 -cool_fan_speed_min = 50 -cool_min_speed = 20 -cool_min_layer_time_fan_speed_max = 20 - - diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg deleted file mode 100644 index 362e844214..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_abs_0.8_normal.inst.cfg +++ /dev/null @@ -1,21 +0,0 @@ -[general] -version = 2 -name = Fast Print -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_abs_ultimaker2_extended_plus_0.8_mm -weight = -2 - -[values] -layer_height = 0.2 -wall_thickness = 2.1 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -cool_min_layer_time = 3 -cool_fan_speed_min = 50 -cool_min_speed = 15 -cool_min_layer_time_fan_speed_max = 25 - diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg deleted file mode 100644 index f4d9264d3e..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.25_normal.inst.cfg +++ /dev/null @@ -1,21 +0,0 @@ -[general] -version = 2 -name = High Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_cpe_ultimaker2_extended_plus_0.25_mm -weight = -2 - -[values] -layer_height = 0.06 -wall_thickness = 0.88 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 30 -cool_min_layer_time = 2 -cool_fan_speed_min = 20 -cool_min_speed = 15 -cool_min_layer_time_fan_speed_max = 15 - diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg deleted file mode 100644 index f514f22294..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_fast.inst.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[general] -version = 2 -name = Fast Print -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_cpe_ultimaker2_extended_plus_0.4_mm -weight = -1 - -[values] -layer_height = 0.15 -wall_thickness = 0.7 -top_bottom_thickness = 0.75 -infill_sparse_density = 18 -speed_print = 45 -speed_wall = 40 -speed_travel = 150 -speed_layer_0 = 30 -cool_min_layer_time = 3 -cool_fan_speed_min = 80 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - - diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg deleted file mode 100644 index 0c68be2f5f..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_high.inst.cfg +++ /dev/null @@ -1,21 +0,0 @@ -[general] -version = 2 -name = High Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_cpe_ultimaker2_extended_plus_0.4_mm -weight = -3 - -[values] -layer_height = 0.06 -wall_thickness = 1.05 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 45 -speed_wall = 30 -cool_min_layer_time = 2 -cool_fan_speed_min = 80 -cool_min_speed = 15 -cool_min_layer_time_fan_speed_max = 15 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg deleted file mode 100644 index 26ea8ce9bc..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.4_normal.inst.cfg +++ /dev/null @@ -1,22 +0,0 @@ -[general] -version = 2 -name = Normal Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_cpe_ultimaker2_extended_plus_0.4_mm -weight = -2 - -[values] -layer_height = 0.1 -wall_thickness = 1.05 -top_bottom_thickness = 0.8 -infill_sparse_density = 20 -speed_print = 45 -speed_wall = 30 -cool_min_layer_time = 3 -cool_fan_speed_min = 80 -cool_min_speed = 10 -cool_min_layer_time_fan_speed_max = 15 - diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg deleted file mode 100644 index d6d10dbe1a..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.6_normal.inst.cfg +++ /dev/null @@ -1,20 +0,0 @@ -[general] -version = 2 -name = Normal Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_cpe_ultimaker2_extended_plus_0.6_mm -weight = -2 - -[values] -layer_height = 0.15 -wall_thickness = 1.59 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -cool_min_layer_time = 5 -cool_fan_speed_min = 80 -cool_min_speed = 8 -cool_min_layer_time_fan_speed_max = 20 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg deleted file mode 100644 index 53d5e0bc8c..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_cpe_0.8_normal.inst.cfg +++ /dev/null @@ -1,20 +0,0 @@ -[general] -version = 2 -name = Fast Print -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_cpe_ultimaker2_extended_plus_0.8_mm -weight = -2 - -[values] -layer_height = 0.2 -wall_thickness = 2.1 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -cool_min_layer_time = 3 -cool_fan_speed_min = 80 -cool_min_speed = 8 -cool_min_layer_time_fan_speed_max = 25 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg deleted file mode 100644 index 5e54b3194a..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.25_normal.inst.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 2 -name = High Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_pla_ultimaker2_extended_plus_0.25_mm -weight = -2 - -[values] -layer_height = 0.06 -wall_thickness = 0.88 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 30 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg deleted file mode 100644 index 893256bb33..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_fast.inst.cfg +++ /dev/null @@ -1,20 +0,0 @@ -[general] -version = 2 -name = Fast Print -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_pla_ultimaker2_extended_plus_0.4_mm -weight = -1 - -[values] -layer_height = 0.15 -wall_thickness = 0.7 -top_bottom_thickness = 0.75 -infill_sparse_density = 18 -speed_print = 60 -speed_travel = 150 -speed_layer_0 = 30 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg deleted file mode 100644 index 844e2b3eac..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_high.inst.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 2 -name = High Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_pla_ultimaker2_extended_plus_0.4_mm -weight = -3 - -[values] -layer_height = 0.06 -wall_thickness = 1.05 -top_bottom_thickness = 0.72 -infill_sparse_density = 22 -speed_print = 50 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg deleted file mode 100644 index 47d511446a..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.4_normal.inst.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 2 -name = Normal Quality -definition = ultimaker2_extended_plus - -[metadata] -type = quality -material = generic_pla_ultimaker2_extended_plus_0.4_mm -weight = -2 - -[values] -layer_height = 0.1 -wall_thickness = 1.05 -top_bottom_thickness = 0.8 -infill_sparse_density = 20 -speed_print = 50 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg deleted file mode 100644 index a2b15b6f16..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.6_normal.inst.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 2 -name = Normal Quality -definition = ultimaker2_extended_plus - -[metadata] -material = generic_pla_ultimaker2_extended_plus_0.6_mm -type = quality -weight = -2 - -[values] -layer_height = 0.15 -wall_thickness = 1.59 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 55 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg deleted file mode 100644 index 08b5bec667..0000000000 --- a/resources/quality/ultimaker2_extended_plus/um2ep_pla_0.8_normal.inst.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[general] -version = 2 -name = Fast Print -definition = ultimaker2_extended_plus - -[metadata] -material = generic_pla_ultimaker2_extended_plus_0.8_mm -type = quality -weight = -2 - -[values] -layer_height = 0.2 -wall_thickness = 2.1 -top_bottom_thickness = 1.2 -infill_sparse_density = 20 -speed_print = 40 -cool_min_layer_time = 5 -cool_min_speed = 10 diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg index 9a44582610..18d74386cf 100644 --- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.25_mm weight = -2 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg index 0df882e418..b17a1f2a6a 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -1 +quality_type = fast [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg index a8abdb081f..ff542c7c19 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -3 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg index c29b017bbe..79d868f25f 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_pla_ultimaker2_plus_0.4_mm weight = -2 +quality_type = normal [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg index 5a0a840ae7..63beca8fbb 100644 --- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus material = generic_pla_ultimaker2_plus_0.6_mm type = quality weight = -2 +quality_type = normal [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg index bd90b8c059..f2b78846a8 100644 --- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus material = generic_pla_ultimaker2_plus_0.8_mm type = quality weight = -2 +quality_type = fast [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg index 05a9bce71c..8457d5cd2b 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.25_mm weight = -2 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg index cd0a25981a..8bcb3efee4 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.4_mm weight = -1 +quality_type = fast [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg index 4b1ece31ef..f2235abd41 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.4_mm weight = -3 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg index f1b01fd408..1b8c1035db 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.4_mm weight = -2 +quality_type = normal [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg index 89e73dda38..4ef0f34484 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.6_mm weight = -2 +quality_type = normal [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg index 2171fd3837..ca2f736c01 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_abs_ultimaker2_plus_0.8_mm weight = -2 +quality_type = fast [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg index 6a300ba27d..0f2a612619 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.25_mm weight = -2 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg index e76c5205f5..8f8fb9e01b 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.4_mm weight = -1 +quality_type = fast [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg index 60f171dc17..abc5e562f7 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.4_mm weight = -3 +quality_type = high [values] layer_height = 0.06 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg index 04116dbe21..5531f245f0 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.4_mm weight = -2 +quality_type = normal [values] layer_height = 0.1 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg index 35e666e6d9..3765f98709 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.6_mm weight = -2 +quality_type = normal [values] layer_height = 0.15 diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg index c36d1714a0..179b554973 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg @@ -7,6 +7,7 @@ definition = ultimaker2_plus type = quality material = generic_cpe_ultimaker2_plus_0.8_mm weight = -2 +quality_type = fast [values] layer_height = 0.2 diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg new file mode 100644 index 0000000000..7e4ae3911d --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg @@ -0,0 +1,42 @@ +[general] +version = 2 +name = Draft Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_plus_ultimaker2_plus_0.4_mm +weight = 0 +quality_type = draft + +[values] +speed_wall_x = 25 +support_z_distance = 0.26 +raft_interface_line_spacing = 1 +cool_min_speed = 8 +cool_fan_speed = 50 +wall_thickness = 1.14 +raft_margin = 15 +speed_layer_0 = 15 +raft_airgap = 0.37 +infill_overlap = 5 +layer_height = 0.2 +raft_interface_line_width = 0.8 +top_bottom_thickness = 1.5 +cool_fan_speed_min = 25 +raft_surface_line_width = 0.38 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 20 +support_enable = True +speed_wall_0 = 20 +adhesion_type = raft +infill_sparse_density = 30 +layer_0_z_overlap = 0.22 +cool_min_layer_time = 3 +speed_print = 25 +line_width = 0.38 +support_angle = 45 +raft_base_line_spacing = 1.6 +raft_base_line_width = 0.8 + diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg new file mode 100644 index 0000000000..0929c04908 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg @@ -0,0 +1,42 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_plus_ultimaker2_plus_0.4_mm +weight = 0 +quality_type = normal + +[values] +speed_wall_x = 30 +support_z_distance = 0.26 +raft_interface_line_spacing = 1 +cool_min_speed = 8 +cool_fan_speed = 50 +wall_thickness = 1.14 +raft_margin = 15 +speed_layer_0 = 15 +raft_airgap = 0.37 +infill_overlap = 5 +layer_height = 0.15 +raft_interface_line_width = 0.8 +top_bottom_thickness = 1.5 +cool_fan_speed_min = 25 +raft_surface_line_width = 0.38 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 20 +support_enable = True +speed_wall_0 = 20 +adhesion_type = raft +infill_sparse_density = 30 +layer_0_z_overlap = 0.22 +cool_min_layer_time = 3 +speed_print = 35 +line_width = 0.38 +support_angle = 45 +raft_base_line_spacing = 1.6 +raft_base_line_width = 0.8 + diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg new file mode 100644 index 0000000000..069f7cb9f3 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg @@ -0,0 +1,46 @@ +[general] +version = 2 +name = Draft Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_plus_ultimaker2_plus_0.6_mm +weight = 0 +quality_type = draft + +[values] +support_xy_distance = 0.6 +speed_travel = 150 +support_z_distance = 0.22 +speed_wall_x = 25 +cool_min_speed = 8 +cool_fan_speed = 45 +raft_surface_thickness = 0.2 +raft_surface_line_width = 0.57 +raft_interface_line_spacing = 1.4 +raft_margin = 15 +speed_layer_0 = 30 +raft_airgap = 0.37 +infill_overlap = 5 +layer_height = 0.3 +raft_base_line_spacing = 2.4 +raft_interface_line_width = 1.2 +speed_wall_0 = 20 +cool_fan_speed_min = 25 +wall_thickness = 1.14 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 20 +support_enable = True +infill_sparse_density = 35 +top_bottom_thickness = 0.75 +adhesion_type = raft +line_width = 0.57 +layer_0_z_overlap = 0.22 +raft_base_line_width = 1.2 +speed_print = 25 +support_line_distance = 2.85 +support_angle = 45 +cool_min_layer_time = 3 + diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg new file mode 100644 index 0000000000..902970cd04 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg @@ -0,0 +1,46 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_plus_ultimaker2_plus_0.6_mm +weight = 0 +quality_type = normal + +[values] +support_xy_distance = 0.6 +speed_travel = 150 +support_z_distance = 0.22 +speed_wall_x = 35 +cool_min_speed = 8 +cool_fan_speed = 45 +raft_surface_thickness = 0.2 +raft_surface_line_width = 0.57 +raft_interface_line_spacing = 1.4 +raft_margin = 15 +speed_layer_0 = 30 +raft_airgap = 0.37 +infill_overlap = 5 +layer_height = 0.22 +raft_base_line_spacing = 2.4 +raft_interface_line_width = 1.2 +speed_wall_0 = 30 +cool_fan_speed_min = 25 +wall_thickness = 1.14 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 20 +support_enable = True +infill_sparse_density = 35 +top_bottom_thickness = 0.75 +adhesion_type = raft +line_width = 0.57 +layer_0_z_overlap = 0.22 +raft_base_line_width = 1.2 +speed_print = 35 +support_line_distance = 2.85 +support_angle = 45 +cool_min_layer_time = 3 + diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg new file mode 100644 index 0000000000..ccfe46dc2a --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg @@ -0,0 +1,40 @@ +[general] +version = 2 +name = Draft Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_plus_ultimaker2_plus_0.8_mm +weight = 0 +quality_type = draft + +[values] +support_z_distance = 0.26 +speed_wall_x = 25 +cool_fan_speed = 50 +raft_surface_thickness = 0.2 +raft_surface_line_width = 0.7 +raft_interface_line_spacing = 1.8 +raft_airgap = 0.37 +infill_overlap = 5 +layer_height = 0.3 +raft_interface_line_width = 1.6 +top_bottom_thickness = 1.2 +cool_fan_speed_min = 25 +brim_line_count = 10 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 20 +support_enable = True +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 40 +layer_0_z_overlap = 0.22 +raft_base_line_width = 1.6 +speed_print = 25 +speed_wall_0 = 20 +support_angle = 45 +cool_min_layer_time = 3 +wall_thickness = 2.1 + diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg new file mode 100644 index 0000000000..f243637cd7 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg @@ -0,0 +1,40 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_cpe_plus_ultimaker2_plus_0.8_mm +weight = 0 +quality_type = normal + +[values] +support_z_distance = 0.26 +speed_wall_x = 30 +cool_fan_speed = 50 +raft_surface_thickness = 0.2 +raft_surface_line_width = 0.7 +raft_interface_line_spacing = 1.8 +raft_airgap = 0.37 +infill_overlap = 5 +layer_height = 0.2 +raft_interface_line_width = 1.6 +top_bottom_thickness = 1.2 +cool_fan_speed_min = 25 +brim_line_count = 10 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 20 +support_enable = True +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 40 +layer_0_z_overlap = 0.22 +raft_base_line_width = 1.6 +speed_print = 30 +speed_wall_0 = 20 +support_angle = 45 +cool_min_layer_time = 3 +wall_thickness = 2.1 + diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg new file mode 100644 index 0000000000..2cf00fdbf4 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg @@ -0,0 +1,43 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_nylon_ultimaker2_plus_0.25_mm +weight = 0 +quality_type = high + +[values] +support_xy_distance = 0.6 +speed_travel = 150 +cool_fan_speed = 60 +support_z_distance = 0.45 +speed_wall_x = 40 +cool_min_speed = 15 +raft_surface_line_width = 0.2 +raft_interface_line_width = 0.5 +brim_line_count = 8 +raft_margin = 15 +speed_layer_0 = 30 +raft_airgap = 0.15 +infill_overlap = 5 +layer_height = 0.06 +raft_interface_line_spacing = 0.7 +speed_support = 40 +top_bottom_thickness = 1.2 +cool_fan_speed_min = 35 +wall_thickness = 1 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 35 +support_enable = True +retraction_hop_enabled = 0.2 +speed_wall_0 = 20 +adhesion_type = raft +infill_sparse_density = 25 +layer_0_z_overlap = 0.1 +raft_base_line_width = 0.5 +speed_print = 40 + diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg new file mode 100644 index 0000000000..301a800480 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg @@ -0,0 +1,43 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_nylon_ultimaker2_plus_0.25_mm +weight = 0 +quality_type = normal + +[values] +support_xy_distance = 0.6 +speed_travel = 150 +cool_fan_speed = 60 +support_z_distance = 0.45 +speed_wall_x = 40 +cool_min_speed = 15 +raft_surface_line_width = 0.2 +raft_interface_line_width = 0.5 +brim_line_count = 8 +raft_margin = 15 +speed_layer_0 = 30 +raft_airgap = 0.15 +infill_overlap = 5 +layer_height = 0.1 +raft_interface_line_spacing = 0.7 +speed_support = 40 +top_bottom_thickness = 1.2 +cool_fan_speed_min = 35 +wall_thickness = 1 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 35 +support_enable = True +retraction_hop_enabled = 0.2 +speed_wall_0 = 20 +adhesion_type = raft +infill_sparse_density = 25 +layer_0_z_overlap = 0.1 +raft_base_line_width = 0.5 +speed_print = 40 + diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg new file mode 100644 index 0000000000..b09113943b --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg @@ -0,0 +1,42 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_nylon_ultimaker2_plus_0.4_mm +weight = 0 +quality_type = fast + +[values] +support_xy_distance = 0.6 +speed_travel = 150 +support_z_distance = 0.45 +raft_interface_line_spacing = 1 +cool_min_speed = 15 +raft_surface_thickness = 0.15 +raft_surface_line_width = 0.5 +speed_layer_0 = 30 +raft_airgap = 0.57 +infill_overlap = 5 +layer_height = 0.2 +raft_interface_line_width = 0.8 +top_bottom_thickness = 0.75 +cool_fan_speed_min = 35 +wall_thickness = 1.06 +support_pattern = lines +support_infill_rate = 25 +speed_topbottom = 20 +support_enable = True +speed_wall = 40 +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 30 +layer_0_z_overlap = 0.22 +raft_base_line_spacing = 1.6 +speed_print = 45 +support_angle = 45 +cool_min_layer_time = 3 +raft_base_line_width = 0.8 + diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg new file mode 100644 index 0000000000..6294bbe241 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg @@ -0,0 +1,41 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_nylon_ultimaker2_plus_0.4_mm +weight = 0 +quality_type = normal + +[values] +support_xy_distance = 0.6 +speed_travel = 150 +support_z_distance = 0.45 +raft_interface_line_spacing = 1 +cool_min_speed = 15 +raft_surface_thickness = 0.15 +raft_surface_line_width = 0.5 +speed_layer_0 = 30 +raft_airgap = 0.57 +infill_overlap = 5 +layer_height = 0.15 +raft_interface_line_width = 0.8 +top_bottom_thickness = 0.75 +cool_fan_speed_min = 35 +wall_thickness = 1.06 +support_pattern = lines +support_infill_rate = 25 +support_enable = True +speed_wall = 40 +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 30 +layer_0_z_overlap = 0.22 +raft_base_line_spacing = 1.6 +speed_print = 45 +support_angle = 45 +cool_min_layer_time = 3 +raft_base_line_width = 0.8 + diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg new file mode 100644 index 0000000000..cdecab8f91 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg @@ -0,0 +1,46 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_nylon_ultimaker2_plus_0.6_mm +weight = 0 +quality_type = fast + +[values] +support_xy_distance = 0.7 +speed_travel = 150 +speed_wall_x = 40 +cool_min_speed = 15 +support_top_distance = 0.55 +raft_surface_line_width = 0.6 +raft_surface_thickness = 0.15 +brim_line_count = 8 +speed_layer_0 = 30 +raft_interface_line_spacing = 1.4 +infill_overlap = 5 +layer_height = 0.3 +raft_interface_line_width = 1.2 +speed_support = 40 +speed_wall_0 = 15 +cool_fan_speed_min = 35 +wall_thickness = 1.2 +support_pattern = lines +support_infill_rate = 25 +speed_topbottom = 35 +support_enable = True +retraction_hop_enabled = 0.2 +support_bottom_distance = 0.55 +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 35 +layer_0_z_overlap = 0.22 +top_bottom_thickness = 1.2 +speed_print = 55 +raft_airgap = 0.44 +support_angle = 45 +raft_base_line_spacing = 2.4 +raft_base_line_width = 1.2 + diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg new file mode 100644 index 0000000000..6d9ac062a0 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg @@ -0,0 +1,45 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_nylon_ultimaker2_plus_0.6_mm +weight = 0 +quality_type = normal + +[values] +support_xy_distance = 0.7 +speed_travel = 150 +support_z_distance = 0.55 +speed_wall_x = 40 +cool_min_speed = 15 +raft_surface_line_width = 0.6 +raft_surface_thickness = 0.15 +brim_line_count = 8 +speed_layer_0 = 30 +raft_interface_line_spacing = 1.4 +infill_overlap = 5 +layer_height = 0.15 +raft_interface_line_width = 1.2 +speed_support = 40 +speed_wall_0 = 15 +cool_fan_speed_min = 35 +wall_thickness = 1.2 +support_pattern = lines +support_infill_rate = 25 +speed_topbottom = 35 +support_enable = True +retraction_hop_enabled = 0.2 +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 35 +layer_0_z_overlap = 0.22 +top_bottom_thickness = 1.2 +speed_print = 55 +raft_airgap = 0.44 +support_angle = 45 +raft_base_line_spacing = 2.4 +raft_base_line_width = 1.2 + diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg new file mode 100644 index 0000000000..89852991bf --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg @@ -0,0 +1,46 @@ +[general] +version = 2 +name = Draft Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_nylon_ultimaker2_plus_0.8_mm +weight = 0 +quality_type = draft + +[values] +support_xy_distance = 0.75 +speed_travel = 150 +support_z_distance = 0.5 +speed_wall_x = 40 +cool_min_speed = 15 +brim_line_count = 8 +support_top_distance = 0.5 +raft_surface_thickness = 0.2 +wall_thickness = 2.4 +raft_margin = 15 +speed_layer_0 = 30 +raft_airgap = 0.44 +infill_overlap = 5 +layer_height = 0.3 +raft_interface_line_width = 1.6 +speed_support = 40 +speed_wall_0 = 15 +cool_fan_speed_min = 35 +raft_surface_line_width = 0.7 +support_pattern = lines +support_infill_rate = 25 +speed_topbottom = 35 +support_enable = True +retraction_hop_enabled = 0.2 +support_bottom_distance = 0.65 +top_bottom_thickness = 1.2 +adhesion_type = raft +infill_sparse_density = 40 +layer_0_z_overlap = 0.25 +raft_base_line_width = 1.6 +speed_print = 55 +support_angle = 45 +raft_interface_line_spacing = 1.8 + diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg new file mode 100644 index 0000000000..023ffd7498 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg @@ -0,0 +1,46 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_nylon_ultimaker2_plus_0.8_mm +weight = 0 +quality_type = normal + +[values] +support_xy_distance = 0.75 +speed_travel = 150 +support_z_distance = 0.5 +speed_wall_x = 40 +cool_min_speed = 15 +brim_line_count = 8 +support_top_distance = 0.5 +raft_surface_thickness = 0.2 +wall_thickness = 2.4 +raft_margin = 15 +speed_layer_0 = 30 +raft_airgap = 0.44 +infill_overlap = 5 +layer_height = 0.2 +raft_interface_line_width = 1.6 +speed_support = 40 +speed_wall_0 = 15 +cool_fan_speed_min = 35 +raft_surface_line_width = 0.7 +support_pattern = lines +support_infill_rate = 25 +speed_topbottom = 35 +support_enable = True +retraction_hop_enabled = 0.2 +support_bottom_distance = 0.65 +top_bottom_thickness = 1.2 +adhesion_type = raft +infill_sparse_density = 40 +layer_0_z_overlap = 0.25 +raft_base_line_width = 1.6 +speed_print = 55 +support_angle = 45 +raft_interface_line_spacing = 1.8 + diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg new file mode 100644 index 0000000000..5358afd2be --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg @@ -0,0 +1,36 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pc_ultimaker2_plus_0.25_mm +weight = 0 +quality_type = high + +[values] +support_z_distance = 0.19 +raft_interface_line_spacing = 0.7 +cool_min_speed = 15 +cool_fan_speed = 50 +raft_surface_line_width = 0.2 +wall_thickness = 0.88 +raft_airgap = 0.5 +infill_overlap = 5 +layer_height = 0.06 +raft_interface_line_width = 0.5 +cool_fan_speed_min = 0 +brim_line_count = 32 +support_pattern = lines +support_infill_rate = 20 +support_enable = True +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 25 +layer_0_z_overlap = 0.22 +cool_min_layer_time = 2 +speed_print = 30 +raft_base_line_spacing = 1 +raft_base_line_width = 0.5 + diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg new file mode 100644 index 0000000000..a5df9972b9 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg @@ -0,0 +1,36 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pc_ultimaker2_plus_0.25_mm +weight = 0 +quality_type = normal + +[values] +support_z_distance = 0.19 +raft_interface_line_spacing = 0.7 +cool_min_speed = 15 +cool_fan_speed = 50 +raft_surface_line_width = 0.2 +wall_thickness = 0.88 +raft_airgap = 0.5 +infill_overlap = 5 +layer_height = 0.1 +raft_interface_line_width = 0.5 +cool_fan_speed_min = 0 +brim_line_count = 32 +support_pattern = lines +support_infill_rate = 20 +support_enable = True +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 25 +layer_0_z_overlap = 0.22 +cool_min_layer_time = 2 +speed_print = 30 +raft_base_line_spacing = 1 +raft_base_line_width = 0.5 + diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg new file mode 100644 index 0000000000..c4af6dd366 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg @@ -0,0 +1,37 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pc_ultimaker2_plus_0.4_mm +weight = 0 +quality_type = fast + +[values] +speed_wall_x = 30 +support_z_distance = 0.19 +raft_airgap = 0.57 +cool_min_speed = 8 +cool_fan_speed = 50 +raft_interface_line_spacing = 1 +infill_overlap = 5 +layer_height = 0.2 +raft_interface_line_width = 0.8 +speed_wall_0 = 20 +cool_fan_speed_min = 0 +wall_thickness = 1.2 +support_pattern = lines +support_infill_rate = 20 +support_enable = True +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 30 +layer_0_z_overlap = 0.22 +cool_min_layer_time = 3 +speed_print = 45 +support_angle = 45 +raft_base_line_spacing = 1.6 +raft_base_line_width = 0.8 + diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg new file mode 100644 index 0000000000..0b79ed29bd --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg @@ -0,0 +1,37 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pc_ultimaker2_plus_0.4_mm +weight = 0 +quality_type = normal + +[values] +speed_wall_x = 30 +support_z_distance = 0.19 +raft_airgap = 0.57 +cool_min_speed = 8 +cool_fan_speed = 50 +raft_interface_line_spacing = 1 +infill_overlap = 5 +layer_height = 0.1 +raft_interface_line_width = 0.8 +speed_wall_0 = 20 +cool_fan_speed_min = 0 +wall_thickness = 1.2 +support_pattern = lines +support_infill_rate = 20 +support_enable = True +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 30 +layer_0_z_overlap = 0.22 +cool_min_layer_time = 3 +speed_print = 45 +support_angle = 45 +raft_base_line_spacing = 1.6 +raft_base_line_width = 0.8 + diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg new file mode 100644 index 0000000000..ef6d1a20b3 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg @@ -0,0 +1,44 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pc_ultimaker2_plus_0.6_mm +weight = 0 +quality_type = fast + +[values] +speed_travel = 150 +support_z_distance = 0.21 +speed_wall_x = 40 +cool_min_speed = 8 +cool_fan_speed = 50 +raft_surface_thickness = 0.15 +raft_surface_line_width = 0.6 +raft_interface_line_spacing = 1.4 +speed_layer_0 = 30 +raft_airgap = 0.52 +infill_overlap = 5 +layer_height = 0.3 +raft_interface_line_width = 1.2 +raft_margin = 15 +cool_fan_speed_min = 0 +wall_thickness = 1.06 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 20 +support_enable = True +top_bottom_thickness = 0.75 +adhesion_type = raft +infill_sparse_density = 35 +layer_0_z_overlap = 0.22 +raft_base_line_spacing = 2.4 +speed_print = 45 +support_line_distance = 3.5333 +speed_wall_0 = 30 +support_angle = 45 +cool_min_layer_time = 3 +raft_base_line_width = 1.2 + diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg new file mode 100644 index 0000000000..bf65d1b8aa --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg @@ -0,0 +1,44 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pc_ultimaker2_plus_0.6_mm +weight = 0 +quality_type = normal + +[values] +speed_travel = 150 +support_z_distance = 0.21 +speed_wall_x = 40 +cool_min_speed = 8 +cool_fan_speed = 50 +raft_surface_thickness = 0.15 +raft_surface_line_width = 0.6 +raft_interface_line_spacing = 1.4 +speed_layer_0 = 30 +raft_airgap = 0.52 +infill_overlap = 5 +layer_height = 0.15 +raft_interface_line_width = 1.2 +raft_margin = 15 +cool_fan_speed_min = 0 +wall_thickness = 1.06 +support_pattern = lines +support_infill_rate = 20 +speed_topbottom = 20 +support_enable = True +top_bottom_thickness = 0.75 +adhesion_type = raft +infill_sparse_density = 35 +layer_0_z_overlap = 0.22 +raft_base_line_spacing = 2.4 +speed_print = 45 +support_line_distance = 3.5333 +speed_wall_0 = 30 +support_angle = 45 +cool_min_layer_time = 3 +raft_base_line_width = 1.2 + diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg new file mode 100644 index 0000000000..1207b562ee --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg @@ -0,0 +1,37 @@ +[general] +version = 2 +name = Draft Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pc_ultimaker2_plus_0.8_mm +weight = 0 +quality_type = draft + +[values] +support_z_distance = 0.26 +raft_airgap = 0.47 +cool_fan_speed = 50 +raft_surface_line_width = 0.7 +raft_surface_thickness = 0.2 +brim_line_count = 10 +raft_interface_line_spacing = 1.8 +infill_overlap = 5 +layer_height = 0.5 +raft_interface_line_width = 1.6 +top_bottom_thickness = 2.0 +cool_fan_speed_min = 25 +wall_thickness = 2.1 +support_pattern = lines +support_infill_rate = 20 +support_enable = True +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 40 +layer_0_z_overlap = 0.22 +raft_base_line_width = 1.6 +speed_print = 40 +support_angle = 45 +cool_min_layer_time = 3 + diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg new file mode 100644 index 0000000000..383fe8722f --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg @@ -0,0 +1,37 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_pc_ultimaker2_plus_0.8_mm +weight = 0 +quality_type = normal + +[values] +support_z_distance = 0.26 +raft_airgap = 0.47 +cool_fan_speed = 50 +raft_surface_line_width = 0.7 +raft_surface_thickness = 0.2 +brim_line_count = 10 +raft_interface_line_spacing = 1.8 +infill_overlap = 5 +layer_height = 0.2 +raft_interface_line_width = 1.6 +top_bottom_thickness = 1.2 +cool_fan_speed_min = 25 +wall_thickness = 2.1 +support_pattern = lines +support_infill_rate = 20 +support_enable = True +raft_margin = 15 +adhesion_type = raft +infill_sparse_density = 40 +layer_0_z_overlap = 0.22 +raft_base_line_width = 1.6 +speed_print = 40 +support_angle = 45 +cool_min_layer_time = 3 + diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg new file mode 100644 index 0000000000..5ca9c7f055 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg @@ -0,0 +1,42 @@ +[general] +version = 2 +name = High Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_tpu_ultimaker2_plus_0.25_mm +weight = 0 +quality_type = high + +[values] +support_xy_distance = 0.6 +cool_min_speed = 15 +support_infill_rate = 25 +speed_wall_0 = 15 +layer_0_z_overlap = 0.1 +cool_min_layer_time = 7 +speed_layer_0 = 30 +speed_print = 40 +wall_thickness = 0.88 +support_enable = True +speed_topbottom = 35 +raft_surface_line_width = 0.2 +raft_base_line_spacing = 1 +top_bottom_thickness = 1.2 +layer_height = 0.06 +support_angle = 45 +infill_sparse_density = 10 +cool_fan_speed = 60 +speed_travel = 150 +speed_support = 40 +support_z_distance = 0.45 +cool_fan_speed_min = 35 +brim_line_count = 8 +retraction_hop_enabled = 0.2 +speed_wall_x = 38 +raft_airgap = 0.2 +raft_interface_line_spacing = 1 +adhesion_type = brim +raft_interface_line_width = 0.2 + diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg new file mode 100644 index 0000000000..c5a9df841d --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg @@ -0,0 +1,39 @@ +[general] +version = 2 +name = Normal Quality +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_tpu_ultimaker2_plus_0.4_mm +weight = 0 +quality_type = normal + +[values] +support_xy_distance = 0.65 +speed_travel = 150 +support_z_distance = 0.45 +speed_wall_x = 35 +cool_min_speed = 15 +cool_fan_speed = 60 +retraction_hop_enabled = 0.2 +brim_line_count = 8 +speed_layer_0 = 30 +raft_interface_line_spacing = 1 +raft_base_line_spacing = 2 +speed_support = 40 +raft_margin = 12 +cool_fan_speed_min = 35 +wall_thickness = 1.05 +support_infill_rate = 25 +speed_topbottom = 35 +support_enable = True +speed_wall_0 = 20 +adhesion_type = brim +infill_sparse_density = 10 +top_bottom_thickness = 1.2 +speed_print = 40 +support_angle = 45 +cool_min_layer_time = 10 +raft_base_line_width = 0.8 + diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg new file mode 100644 index 0000000000..9ef7263e63 --- /dev/null +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg @@ -0,0 +1,44 @@ +[general] +version = 2 +name = Fast Print +definition = ultimaker2_plus + +[metadata] +type = quality +material = generic_tpu_ultimaker2_plus_0.6_mm +weight = 0 +quality_type = fast + +[values] +support_xy_distance = 0.7 +raft_base_line_width = 0.6 +cool_min_speed = 15 +line_width = 0.57 +support_infill_rate = 25 +speed_wall_0 = 15 +wall_thickness = 1.14 +raft_base_line_spacing = 1.2 +speed_layer_0 = 30 +raft_margin = 15 +speed_travel = 150 +raft_surface_line_width = 0.5 +layer_height = 0.12 +raft_interface_line_width = 0.57 +speed_print = 45 +top_bottom_thickness = 1.2 +speed_topbottom = 35 +layer_0_z_overlap = 0.12 +support_angle = 45 +infill_sparse_density = 10 +cool_fan_speed = 60 +speed_support = 40 +support_z_distance = 0.45 +cool_fan_speed_min = 35 +brim_line_count = 8 +retraction_hop_enabled = 0.2 +speed_wall_x = 40 +support_enable = True +raft_interface_line_spacing = 1.2 +adhesion_type = brim +raft_airgap = 0.24 + diff --git a/resources/themes/cura/styles.qml b/resources/themes/cura/styles.qml index 8d813bc2b5..354aa15165 100644 --- a/resources/themes/cura/styles.qml +++ b/resources/themes/cura/styles.qml @@ -11,7 +11,26 @@ QtObject { property Component sidebar_header_button: Component { ButtonStyle { background: Rectangle { - color: control.enabled ? Theme.getColor("setting_control") : Theme.getColor("setting_control_disabled") + color: + { + if(control.enabled) + { + if(control.valueError) + { + return Theme.getColor("setting_validation_error"); + } + else if(control.valueWarning) + { + return Theme.getColor("setting_validation_warning"); + } else + { + return Theme.getColor("setting_control"); + } + } else { + return Theme.getColor("setting_control_disabled"); + } + } + border.width: Theme.getSize("default_lining").width border.color: !control.enabled ? Theme.getColor("setting_control_disabled_border") : control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border") @@ -184,18 +203,32 @@ QtObject { property Component progressbar: Component{ ProgressBarStyle { - background:Rectangle { + background: Rectangle { implicitWidth: Theme.getSize("message").width - (Theme.getSize("default_margin").width * 2) implicitHeight: Theme.getSize("progressbar").height radius: Theme.getSize("progressbar_radius").width - color: Theme.getColor("progressbar_background") + color: control.hasOwnProperty("backgroundColor") ? control.backgroundColor : Theme.getColor("progressbar_background") } progress: Rectangle { - color: control.indeterminate ? "transparent" : Theme.getColor("progressbar_control") + color: + { + if(control.indeterminate) + { + return "transparent"; + } + else if(control.hasOwnProperty("controlColor")) + { + return control.controlColor; + } + else + { + return Theme.getColor("progressbar_control"); + } + } radius: Theme.getSize("progressbar_radius").width Rectangle{ radius: Theme.getSize("progressbar_radius").width - color: Theme.getColor("progressbar_control") + color: control.hasOwnProperty("controlColor") ? control.controlColor : Theme.getColor("progressbar_control") width: Theme.getSize("progressbar_control").width height: Theme.getSize("progressbar_control").height visible: control.indeterminate @@ -473,4 +506,59 @@ QtObject { } } } + + property Component sidebar_action_button: Component { + ButtonStyle + { + background: Rectangle + { + border.width: UM.Theme.getSize("default_lining").width + border.color: + { + if(!control.enabled) + return UM.Theme.getColor("action_button_disabled_border"); + else if(control.pressed) + return UM.Theme.getColor("action_button_active_border"); + else if(control.hovered) + return UM.Theme.getColor("action_button_hovered_border"); + else + return UM.Theme.getColor("action_button_border"); + } + color: + { + if(!control.enabled) + return UM.Theme.getColor("action_button_disabled"); + else if(control.pressed) + return UM.Theme.getColor("action_button_active"); + else if(control.hovered) + return UM.Theme.getColor("action_button_hovered"); + else + return UM.Theme.getColor("action_button"); + } + Behavior on color { ColorAnimation { duration: 50; } } + + implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("default_margin").width * 2) + + Label + { + id: actualLabel + anchors.centerIn: parent + color: + { + if(!control.enabled) + return UM.Theme.getColor("action_button_disabled_text"); + else if(control.pressed) + return UM.Theme.getColor("action_button_active_text"); + else if(control.hovered) + return UM.Theme.getColor("action_button_hovered_text"); + else + return UM.Theme.getColor("action_button_text"); + } + font: UM.Theme.getFont("action_button") + text: control.text + } + } + label: Item { } + } + } } diff --git a/resources/themes/cura/theme.json b/resources/themes/cura/theme.json index 69fc2c2c71..f90467c9e8 100644 --- a/resources/themes/cura/theme.json +++ b/resources/themes/cura/theme.json @@ -159,9 +159,17 @@ "tooltip": [12, 169, 227, 255], "tooltip_text": [255, 255, 255, 255], - "message_background": [255, 255, 255, 255], - "message_text": [32, 166, 219, 255], - "message_dismiss": [127, 127, 127, 255], + "message_background": [24, 41, 77, 255], + "message_text": [255, 255, 255, 255], + "message_border": [24, 41, 77, 255], + "message_button": [255, 255, 255, 255], + "message_button_hover": [12, 169, 227, 255], + "message_button_active": [32, 166, 219, 255], + "message_button_text": [24, 41, 77, 255], + "message_button_text_hover": [255, 255, 255, 255], + "message_button_text_active": [255, 255, 255, 255], + "message_progressbar_background": [255, 255, 255, 255], + "message_progressbar_control": [12, 169, 227, 255], "tool_panel_background": [255, 255, 255, 255],