Browse Source

Merge branch 'master' into feature_dark_colours_icons

CURA-4148

Resolve merge conflicts.
Lipu Fei 7 years ago
parent
commit
3fbdb27e8e

+ 1 - 0
.gitignore

@@ -6,6 +6,7 @@ __pycache__
 docs/html
 *.log
 resources/i18n/en
+resources/i18n/7s
 resources/i18n/x-test
 resources/firmware
 resources/materials

+ 4 - 5
README.md

@@ -50,12 +50,11 @@ Third party plugins
 * [X3G Writer](https://github.com/Ghostkeeper/X3GWriter): Adds support for exporting X3G files.
 * [Auto orientation](https://github.com/nallath/CuraOrientationPlugin): Calculate the optimal orientation for a model.
 * [OctoPrint Plugin](https://github.com/fieldofview/OctoPrintPlugin): Send printjobs directly to OctoPrint and monitor their progress in Cura.
-* [WirelessPrinting Plugin](https://github.com/probonopd/WirelessPrinting): Print wirelessly from Cura to your 3D printer connected to an ESP8266 module.
 * [Electric Print Cost Calculator Plugin](https://github.com/zoff99/ElectricPrintCostCalculator): Calculate the electric costs of a print.
 
 Making profiles for other printers
 ----------------------------------
-There are two ways of doing it. You can either use the generator [here](http://quillford.github.io/CuraProfileMaker/) or you can use [this](https://github.com/Ultimaker/Cura/blob/master/resources/definitions/ultimaker_original.def.json) as a template.
+If your make of printer is not in the list of supported printers, and using the "Custom FDM Printer" does not offer enough flexibility, you can use [this](https://github.com/Ultimaker/Cura/blob/master/resources/definitions/ultimaker_original.def.json) as a template.
 
 * Change the machine ID to something unique
 * Change the machine_name to your printer's name
@@ -63,12 +62,12 @@ There are two ways of doing it. You can either use the generator [here](http://q
 * Set your machine's dimensions with machine_width, machine_depth, and machine_height
 * If your printer's origin is in the center of the bed, set machine_center_is_zero to true.
 * Set your print head dimensions with the machine_head_shape parameters
-* Set the nozzle offset with machine_nozzle_offset_x and machine_nozzle_offset_y
 * Set the start and end gcode in machine_start_gcode and machine_end_gcode
-* If your printer has a heated bed, set visible to true under material_bed_temperature
 
 Once you are done, put the profile you have made into resources/definitions, or in definitions in your cura profile folder.
 
+If you want to make a definition for a multi-extrusion printer, have a look at [this](https://github.com/Ultimaker/Cura/blob/master/resources/definitions/ultimaker_original_dual.def.json) as a template, along with the two extruder definitions it references [here](https://github.com/Ultimaker/Cura/blob/master/resources/extruders/ultimaker_original_dual_1st.def.json) and [here](https://github.com/Ultimaker/Cura/blob/master/resources/extruders/ultimaker_original_dual_2nd.def.json)
+
 Translating Cura
 ----------------
 If you'd like to contribute a translation of Cura, please first look for [any existing translation](https://github.com/Ultimaker/Cura/tree/master/resources/i18n). If your language is already there in the source code but not in Cura's interface, it may be partially translated.
@@ -89,4 +88,4 @@ To submit your translation, ideally you would make two pull requests where all `
 
 After the translation is submitted, the Cura maintainers will check for its completeness and check whether it is consistent. We will take special care to look for common mistakes, such as translating mark-up `<message>` code and such. We are often not fluent in every language, so we expect the translator and the international users to make corrections where necessary. Of course, there will always be some mistakes in every translation.
 
-When the next Cura release comes around, some of the texts will have changed and some new texts will have been added. Around the time when the beta is released we will invoke a string freeze, meaning that no developer is allowed to make changes to the texts. Then we will update the translation template `.pot` files and ask all our translators to update their translations. If you are unable to update the translation in time for the actual release, we will remove the language from the drop-down menu in the Preferences window. The translation stays in Cura however, so that someone might pick it up again later and update it with the newest texts. Also, users who had previously selected the language can still continue Cura in their language but English text will appear among the original text.
+When the next Cura release comes around, some of the texts will have changed and some new texts will have been added. Around the time when the beta is released we will invoke a string freeze, meaning that no developer is allowed to make changes to the texts. Then we will update the translation template `.pot` files and ask all our translators to update their translations. If you are unable to update the translation in time for the actual release, we will remove the language from the drop-down menu in the Preferences window. The translation stays in Cura however, so that someone might pick it up again later and update it with the newest texts. Also, users who had previously selected the language can still continue Cura in their language but English text will appear among the original text.

+ 75 - 11
cura/BuildVolume.py

@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Ultimaker B.V.
+# Copyright (c) 2017 Ultimaker B.V.
 # Cura is released under the terms of the AGPLv3 or higher.
 
 from cura.Settings.ExtruderManager import ExtruderManager
@@ -27,8 +27,9 @@ import math
 
 from typing import List
 
-# Setting for clearance around the prime
-PRIME_CLEARANCE = 6.5
+PRIME_CLEARANCE = 6.5 #Setting for clearance around the prime.
+MAJOR_GRID_SIZE = 10 #Size of the grid cells.
+MINOR_GRID_SIZE = 1
 
 
 ##  Build volume is a special kind of node that is responsible for rendering the printable area & disallowed areas.
@@ -44,6 +45,8 @@ class BuildVolume(SceneNode):
         self._z_axis_color = None
         self._disallowed_area_color = None
         self._error_area_color = None
+        self._grid_color = None
+        self._grid_minor_color = None
 
         self._width = 0
         self._height = 0
@@ -56,8 +59,9 @@ class BuildVolume(SceneNode):
         self._origin_line_length = 20
         self._origin_line_width = 0.5
 
+        self._plate_mesh = None
         self._grid_mesh = None
-        self._grid_shader = None
+        self._plate_shader = None
 
         self._disallowed_areas = []
         self._disallowed_area_mesh = None
@@ -167,14 +171,15 @@ class BuildVolume(SceneNode):
 
         if not self._shader:
             self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))
-            self._grid_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "grid.shader"))
+            self._plate_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
             theme = Application.getInstance().getTheme()
-            self._grid_shader.setUniformValue("u_gridColor0", Color(*theme.getColor("buildplate").getRgb()))
-            self._grid_shader.setUniformValue("u_gridColor1", Color(*theme.getColor("buildplate_alt").getRgb()))
+            self._plate_shader.setUniformValue("u_color", Color(*theme.getColor("buildplate").getRgb()))
+            self._plate_shader.setUniformValue("u_z_bias", 0.000001)
 
         renderer.queueNode(self, mode = RenderBatch.RenderMode.Lines)
         renderer.queueNode(self, mesh = self._origin_mesh)
-        renderer.queueNode(self, mesh = self._grid_mesh, shader = self._grid_shader, backface_cull = True)
+        renderer.queueNode(self, mesh = self._plate_mesh, shader = self._plate_shader, backface_cull = True)
+        renderer.queueNode(self, mesh = self._grid_mesh, mode = RenderBatch.RenderMode.Lines, transparent = True)
         if self._disallowed_area_mesh:
             renderer.queueNode(self, mesh = self._disallowed_area_mesh, shader = self._shader, transparent = True, backface_cull = True, sort = -9)
 
@@ -247,6 +252,8 @@ class BuildVolume(SceneNode):
             self._z_axis_color = Color(*theme.getColor("z_axis").getRgb())
             self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb())
             self._error_area_color = Color(*theme.getColor("error_area").getRgb())
+            self._grid_color = Color(*theme.getColor("buildplate_grid").getRgb())
+            self._grid_minor_color = Color(*theme.getColor("buildplate_grid_minor").getRgb())
 
         min_w = -self._width / 2
         max_w = self._width / 2
@@ -277,7 +284,7 @@ class BuildVolume(SceneNode):
 
             self.setMeshData(mb.build())
 
-            # Build plate grid mesh
+            # Build plate surface.
             mb = MeshBuilder()
             mb.addQuad(
                 Vector(min_w, min_h - z_fight_distance, min_d),
@@ -289,6 +296,30 @@ class BuildVolume(SceneNode):
             for n in range(0, 6):
                 v = mb.getVertex(n)
                 mb.setVertexUVCoordinates(n, v[0], v[2])
+            self._plate_mesh = mb.build()
+
+            #Build plate grid mesh.
+            mb = MeshBuilder()
+            for x in range(0, int(math.ceil(max_w)), MAJOR_GRID_SIZE):
+                mb.addLine(Vector(x, min_h, min_d), Vector(x, min_h, max_d), color = self._grid_color)
+                #Start from 0 in both cases, so you need to do this in two for loops.
+                mb.addLine(Vector(-x, min_h, min_d), Vector(-x, min_h, max_d), color = self._grid_color)
+            for y in range(0, int(math.ceil(max_d)), MAJOR_GRID_SIZE):
+                mb.addLine(Vector(min_w, min_h, y), Vector(max_w, min_h, y), color = self._grid_color)
+                mb.addLine(Vector(min_w, min_h, -y), Vector(max_w, min_h, -y), color = self._grid_color)
+
+            #More fine grained grid.
+            for x in range(0, int(math.ceil(max_w)), MINOR_GRID_SIZE):
+                if x % MAJOR_GRID_SIZE == 0: #Don't overlap with the major grid.
+                    pass
+                mb.addLine(Vector(x, min_h, min_d), Vector(x, min_h, max_d), color = self._grid_minor_color)
+                mb.addLine(Vector(-x, min_h, min_d), Vector(-x, min_h, max_d), color = self._grid_minor_color)
+            for y in range(0, int(math.ceil(max_d)), MINOR_GRID_SIZE):
+                if y % MAJOR_GRID_SIZE == 0:
+                    pass
+                mb.addLine(Vector(min_w, min_h, y), Vector(max_w, min_h, y), color = self._grid_minor_color)
+                mb.addLine(Vector(min_w, min_h, -y), Vector(max_w, min_h, -y), color = self._grid_minor_color)
+
             self._grid_mesh = mb.build()
 
         else:
@@ -304,7 +335,7 @@ class BuildVolume(SceneNode):
             mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0),  color = self._volume_outline_color)
             self.setMeshData(mb.build().getTransformed(scale_matrix))
 
-            # Build plate grid mesh
+            # Build plate surface.
             mb = MeshBuilder()
             mb.addVertex(0, min_h - z_fight_distance, 0)
             mb.addArc(max_w, Vector.Unit_Y, center = Vector(0, min_h - z_fight_distance, 0))
@@ -318,7 +349,40 @@ class BuildVolume(SceneNode):
             for n in range(0, mb.getVertexCount()):
                 v = mb.getVertex(n)
                 mb.setVertexUVCoordinates(n, v[0], v[2] * aspect)
-            self._grid_mesh = mb.build().getTransformed(scale_matrix)
+            self._plate_mesh = mb.build().getTransformed(scale_matrix)
+
+            #Build plate grid mesh.
+            #We need to constrain the length of the lines to the build plate ellipsis. Time to get out the calculator!
+            mb = MeshBuilder()
+            for x in range(0, int(math.ceil(max_w)), MAJOR_GRID_SIZE):
+                #x / max_w is the fraction along the build plate we have progressed, counting from the centre.
+                #So x / max_w is sin(a), where a is the angle towards an endpoint of the grid line from the centre.
+                #So math.asin(x / max_w) is a.
+                #So math.cos(math.asin(x / max_w)) is half of the length of the grid line on a unit circle, which scales between 0 and 1.
+                length_factor = math.cos(math.asin(x / max_w))
+                mb.addLine(Vector(x, min_h, min_d * length_factor), Vector(x, min_h, max_d * length_factor), color = self._grid_color)
+                #Start from 0 in both cases, so you need to do this in two for loops.
+                mb.addLine(Vector(-x, min_h, min_d * length_factor), Vector(-x, min_h, max_d * length_factor), color = self._grid_color)
+            for y in range(0, int(math.ceil(max_d)), MAJOR_GRID_SIZE):
+                length_factor = math.sin(math.acos(y / max_d))
+                mb.addLine(Vector(min_w * length_factor, min_h, y), Vector(max_w * length_factor, min_h, y), color = self._grid_color)
+                mb.addLine(Vector(min_w * length_factor, min_h, -y), Vector(max_w * length_factor, min_h, -y), color = self._grid_color)
+
+            #More fine grained grid.
+            for x in range(0, int(math.ceil(max_w)), MINOR_GRID_SIZE):
+                if x % MAJOR_GRID_SIZE == 0: #Don't overlap with the major grid.
+                    pass
+                length_factor = math.cos(math.asin(x / max_w))
+                mb.addLine(Vector(x, min_h, min_d * length_factor), Vector(x, min_h, max_d * length_factor), color = self._grid_minor_color)
+                mb.addLine(Vector(-x, min_h, min_d * length_factor), Vector(-x, min_h, max_d * length_factor), color = self._grid_minor_color)
+            for y in range(0, int(math.ceil(max_d)), MINOR_GRID_SIZE):
+                if y % MAJOR_GRID_SIZE == 0:
+                    pass
+                length_factor = math.sin(math.acos(y / max_d))
+                mb.addLine(Vector(min_w * length_factor, min_h, y), Vector(max_w * length_factor, min_h, y), color = self._grid_minor_color)
+                mb.addLine(Vector(min_w * length_factor, min_h, -y), Vector(max_w * length_factor, min_h, -y), color = self._grid_minor_color)
+
+            self._grid_mesh = mb.build()
 
         # Indication of the machine origin
         if self._global_container_stack.getProperty("machine_center_is_zero", "value"):

+ 4 - 0
cura/Settings/CuraContainerStack.py

@@ -432,6 +432,7 @@ class CuraContainerStack(ContainerStack):
     #   - If the machine definition has a metadata entry "has_machine_materials", the definition of the material should
     #     be the same as the machine definition for this stack. Otherwise, the definition should be "fdmprinter".
     #   - The container should have a metadata entry "type" with value "material".
+    #   - The material should have an approximate diameter that matches the machine
     #   - If the machine definition has a metadata entry "has_variants" and set to True, the "variant" metadata entry of
     #     the material should be the same as the ID of the variant in the stack. Only applies if "has_machine_materials" is also True.
     #   - If the stack currently has a material set, try to find a material that matches the current material by name.
@@ -460,6 +461,9 @@ class CuraContainerStack(ContainerStack):
             if preferred_material:
                 search_criteria["id"] = preferred_material
 
+        approximate_material_diameter = str(round(self.getProperty("material_diameter", "value")))
+        search_criteria["approximate_diameter"] = approximate_material_diameter
+
         materials = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
         if not materials:
             Logger.log("w", "The preferred material \"{material}\" could not be found for stack {stack}", material = preferred_material, stack = self.id)

+ 0 - 10
cura/Settings/MachineManager.py

@@ -504,16 +504,6 @@ class MachineManager(QObject):
 
         return result
 
-    @pyqtProperty("QVariantList", notify = activeVariantChanged)
-    def activeMaterialIds(self):
-        result = []
-        if ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() is not None:
-            for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
-                if stack.variant and stack.variant != self._empty_variant_container:
-                    result.append(stack.variant.getId())
-
-        return result
-
     @pyqtProperty("QVariantList", notify = activeMaterialChanged)
     def activeMaterialNames(self):
         result = []

+ 73 - 20
plugins/3MFReader/ThreeMFWorkspaceReader.py

@@ -818,29 +818,27 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
                                 each_extruder_stack.definitionChanges = each_changes_container
 
         if self._resolve_strategies["material"] == "new":
+            # the actual material instance container can have an ID such as
+            #  <material>_<machine>_<variant>
+            # which cannot be determined immediately, so here we use a HACK to find the right new material
+            # instance ID:
+            #  - get the old material IDs for all material
+            #  - find the old material with the longest common prefix in ID, that's the old material
+            #  - update the name by replacing the old prefix with the new
+            #  - find the new material container and set it to the stack
+            old_to_new_material_dict = {}
             for each_material in material_containers:
-                old_material = global_stack.material
-
-                # check if the old material container has been renamed to this material container ID
-                # if the container hasn't been renamed, we do nothing.
-                new_id = self._id_mapping.get(old_material.getId())
-                if new_id is None or new_id != each_material.getId():
-                    continue
-
-                if old_material.getId() in self._id_mapping:
-                    global_stack.material = each_material
+                # find the material's old name
+                for old_id, new_id in self._id_mapping.items():
+                    if each_material.getId() == new_id:
+                        old_to_new_material_dict[old_id] = each_material
+                        break
 
+            # replace old material in global and extruder stacks with new
+            self._replaceStackMaterialWithNew(global_stack, old_to_new_material_dict)
+            if extruder_stacks:
                 for each_extruder_stack in extruder_stacks:
-                    old_material = each_extruder_stack.material
-
-                    # check if the old material container has been renamed to this material container ID
-                    # if the container hasn't been renamed, we do nothing.
-                    new_id = self._id_mapping.get(old_material.getId())
-                    if new_id is None or new_id != each_material.getId():
-                        continue
-
-                    if old_material.getId() in self._id_mapping:
-                        each_extruder_stack.material = each_material
+                    self._replaceStackMaterialWithNew(each_extruder_stack, old_to_new_material_dict)
 
         if extruder_stacks:
             for stack in extruder_stacks:
@@ -865,6 +863,61 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
             nodes = []
         return nodes
 
+    ##  HACK: Replaces the material container in the given stack with a newly created material container.
+    #         This function is used when the user chooses to resolve material conflicts by creating new ones.
+    def _replaceStackMaterialWithNew(self, stack, old_new_material_dict):
+        # The material containers in the project file are 'parent' material such as "generic_pla",
+        # but a material container used in a global/extruder stack is a 'child' material,
+        # such as "generic_pla_ultimaker3_AA_0.4", which can be formalised as the following:
+        #
+        #    <material_name>_<machine_name>_<variant_name>
+        #
+        # In the project loading, when a user chooses to resolve material conflicts by creating new ones,
+        # the old 'parent' material ID and the new 'parent' material ID are known, but not the child material IDs.
+        # In this case, the global stack and the extruder stacks need to use the newly created material, but the
+        # material containers they use are 'child' material. So, here, we need to find the right 'child' material for
+        # the stacks.
+        #
+        # This hack approach works as follows:
+        #   - No matter there is a child material or not, the actual material we are looking for has the prefix
+        #     "<material_name>", which is the old material name. For the material in a stack, we know that the new
+        #     material's ID will be "<new_material_name>_blabla..", so we just need to replace the old material ID
+        #     with the new one to get the new 'child' material.
+        #   - Because the material containers have IDs such as "m #nn", if we use simple prefix matching, there can
+        #     be a problem in the following scenario:
+        #        - there are two materials in the project file, namely "m #1" and "m #11"
+        #        - the child materials in use are for example: "m #1_um3_aa04", "m #11_um3_aa04"
+        #        - if we only check for a simple prefix match, then "m #11_um3_aa04" will match with "m #1", but they
+        #          are not the same material
+        #     To avoid this, when doing the prefix matching, we use the result with the longest mactching prefix.
+
+        # find the old material ID
+        old_material_id_in_stack = stack.material.getId()
+        best_matching_old_material_id = None
+        best_matching_old_meterial_prefix_length = -1
+        for old_parent_material_id in old_new_material_dict:
+            if len(old_parent_material_id) < best_matching_old_meterial_prefix_length:
+                continue
+            if len(old_parent_material_id) <= len(old_material_id_in_stack):
+                if old_parent_material_id == old_material_id_in_stack[0:len(old_parent_material_id)]:
+                    best_matching_old_meterial_prefix_length = len(old_parent_material_id)
+                    best_matching_old_material_id = old_parent_material_id
+
+        if best_matching_old_material_id is None:
+            Logger.log("w", "Cannot find any matching old material ID for stack [%s] material [%s]. Something can go wrong",
+                       stack.getId(), old_material_id_in_stack)
+            return
+
+        # find the new material container
+        new_material_id = old_new_material_dict[best_matching_old_material_id].getId() + old_material_id_in_stack[len(best_matching_old_material_id):]
+        new_material_containers = self._container_registry.findInstanceContainers(id = new_material_id, type = "material")
+        if not new_material_containers:
+            Logger.log("e", "Cannot find new material container [%s]", new_material_id)
+            return
+
+        # replace the material in the given stack
+        stack.material = new_material_containers[0]
+
     def _stripFileToId(self, file):
         mime_type = MimeTypeDatabase.getMimeTypeForFile(file)
         file = mime_type.stripExtension(file)

+ 2 - 2
plugins/ChangeLogPlugin/ChangeLog.txt

@@ -36,7 +36,7 @@ A dark theme for Cura. Select this theme to reduce eyestrain when working in dar
 The top bar user interface been improved so that “Prepare” and “Print” have moved from the right side of the interface to the left side.
 
 *New keyboard shortcuts
-Models can now be manipulated on the build plate using hotkeys Q, A, Z, W, and tab keys. Q selects “move”, A selects “scale”, Z selects “rotate”, and W selects “mirror”. Use the tab key to navigate between interfaces.
+Models can now be manipulated on the build plate using hotkeys Q, A, Z, W, and tab keys. Q selects “move”, A selects “scale”, Z selects “rotate”, and W selects “mirror”. Use the tab key to navigate between settings.
 
 *Plugin browser
 Easily download and install plugins using an integrated plugin browser. Go to “Extensions > Plugin Browser > Browse plugins” to select it.
@@ -61,7 +61,7 @@ Polish language support added. This can be selected in the preferences menu.
 - Crashes when adding printers
 - Jerk fixes
 - Z-hop over-extrusion
-
+- Material diameter in machine settings
 
 *3rd party printers
 - Peopoly Moai

+ 1 - 0
plugins/CuraEngineBackend/CuraEngineBackend.py

@@ -427,6 +427,7 @@ class CuraEngineBackend(QObject, Backend):
 
     ##  Convenient function: set need_slicing, emit state and clear layer data
     def needsSlicing(self):
+        self.stopSlicing()
         self._need_slicing = True
         self.processingProgress.emit(0.0)
         self.backendStateChange.emit(BackendState.NotStarted)

+ 6 - 1
plugins/LayerView/LayerView.qml

@@ -71,7 +71,7 @@ Item
                 id: layersLabel
                 anchors.left: parent.left
                 text: catalog.i18nc("@label","View Mode: Layers")
-                font.bold: true
+                font: UM.Theme.getFont("default_bold");
                 color: UM.Theme.getColor("text")
                 Layout.fillWidth: true
                 elide: Text.ElideMiddle;
@@ -90,6 +90,7 @@ Item
                 id: layerViewTypesLabel
                 anchors.left: parent.left
                 text: catalog.i18nc("@label","Color scheme")
+                font: UM.Theme.getFont("default");
                 visible: !UM.LayerView.compatibilityMode
                 Layout.fillWidth: true
                 color: UM.Theme.getColor("text")
@@ -148,6 +149,7 @@ Item
                 id: compatibilityModeLabel
                 anchors.left: parent.left
                 text: catalog.i18nc("@label","Compatibility Mode")
+                font: UM.Theme.getFont("default")
                 color: UM.Theme.getColor("text")
                 visible: UM.LayerView.compatibilityMode
                 Layout.fillWidth: true
@@ -210,6 +212,7 @@ Item
                         text: model.name
                         elide: Text.ElideRight
                         color: UM.Theme.getColor("text")
+                        font: UM.Theme.getFont("default")
                         anchors.verticalCenter: parent.verticalCenter
                         anchors.left: extrudersModelCheckBox.left;
                         anchors.right: extrudersModelCheckBox.right;
@@ -275,6 +278,7 @@ Item
                     Label
                     {
                         text: label
+                        font: UM.Theme.getFont("default")
                         elide: Text.ElideRight
                         color: UM.Theme.getColor("text")
                         anchors.verticalCenter: parent.verticalCenter
@@ -340,6 +344,7 @@ Item
                     Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
                     Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
                     color: UM.Theme.getColor("text")
+                    font: UM.Theme.getFont("default")
                 }
             }
         }

+ 1 - 0
plugins/MachineSettingsAction/MachineSettingsAction.qml

@@ -233,6 +233,7 @@ Cura.MachineAction
                                 property string label: catalog.i18nc("@label", "Gantry height")
                                 property string unit: catalog.i18nc("@label", "mm")
                                 property string tooltip: catalog.i18nc("@tooltip", "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\".")
+                                property bool forceUpdateOnChange: true
                             }
 
                             Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }

Some files were not shown because too many files changed in this diff