From 6176b939d6e4186877adb66f33e2bce542ecbd8f Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 19 Oct 2017 10:02:13 +0200 Subject: [PATCH 01/25] cross_infill_density_image setting --- resources/definitions/fdmprinter.def.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index e953d18865..1d9285441c 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5263,6 +5263,16 @@ "limit_to_extruder": "infill_extruder_nr", "settable_per_mesh": true }, + "cross_infill_density_image": + { + "label": "Cross Infill Density Image", + "description": "The file location of an image of which the brightness values determine the minimal density at the corresponding location in the infill of the print.", + "type": "str", + "default_value": "", + "enabled": "infill_pattern == 'cross' or infill_pattern == 'cross_3d'", + "limit_to_extruder": "infill_extruder_nr", + "settable_per_mesh": true + }, "spaghetti_infill_enabled": { "label": "Spaghetti Infill", From 87c1f1a3778e46f3f0927cceb007d39cde6747a1 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Thu, 19 Oct 2017 10:57:41 +0200 Subject: [PATCH 02/25] cross_support_density_image setting --- resources/definitions/fdmprinter.def.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 1d9285441c..3a42b7b326 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5273,6 +5273,17 @@ "limit_to_extruder": "infill_extruder_nr", "settable_per_mesh": true }, + "cross_support_density_image": + { + "label": "Cross Fill Density Image for Support", + "description": "The file location of an image of which the brightness values determine the minimal density at the corresponding location in the support.", + "type": "str", + "default_value": "", + "enabled": "infill_pattern == 'cross' or infill_pattern == 'cross_3d'", + "limit_to_extruder": "support_infill_extruder_nr", + "settable_per_mesh": false, + "settable_per_extruder": true + }, "spaghetti_infill_enabled": { "label": "Spaghetti Infill", From 9080e756348e232324b60da64f8d533cd30c7084 Mon Sep 17 00:00:00 2001 From: Nicolas Graziano Date: Mon, 14 May 2018 12:13:23 +0200 Subject: [PATCH 03/25] Correct the test to hide bed temperature when no heated bed is present. --- resources/qml/PrintMonitor.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml index ae74170004..b24bcb6d6c 100644 --- a/resources/qml/PrintMonitor.qml +++ b/resources/qml/PrintMonitor.qml @@ -67,7 +67,7 @@ Column HeatedBedBox { visible: { - if(activePrinter != null && activePrinter.bed_temperature != -1) + if(activePrinter != null && activePrinter.bedTemperature != -1) { return true } From 7a25841816e95be0e69b37cb699dafaf10d03e11 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 14 May 2018 14:29:41 +0200 Subject: [PATCH 04/25] Fix support blocker on older (legacy) opengl --- resources/shaders/camera_distance.shader | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/shaders/camera_distance.shader b/resources/shaders/camera_distance.shader index e6e894a2f6..437aa39cc2 100644 --- a/resources/shaders/camera_distance.shader +++ b/resources/shaders/camera_distance.shader @@ -25,9 +25,9 @@ fragment = highp float distance_to_camera = distance(v_vertex, u_viewPosition) * 1000.; // distance in micron vec3 encoded; // encode float into 3 8-bit channels; this gives a precision of a micron at a range of up to ~16 meter - encoded.b = floor(distance_to_camera / 65536.0); - encoded.g = floor((distance_to_camera - encoded.b * 65536.0) / 256.0); - encoded.r = floor(distance_to_camera - encoded.b * 65536.0 - encoded.g * 256.0); + encoded.r = floor(distance_to_camera / 65536.0); + encoded.g = floor((distance_to_camera - encoded.r * 65536.0) / 256.0); + encoded.b = floor(distance_to_camera - encoded.r * 65536.0 - encoded.g * 256.0); gl_FragColor.rgb = encoded / 255.; gl_FragColor.a = 1.0; From c13b77d8a19b59c66e20b77cbd1263ec9b5f4a74 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 16 May 2018 19:18:09 +0200 Subject: [PATCH 05/25] Do not load material when no GUID is present instead of crashing Cura --- cura/Machines/MaterialManager.py | 8 +++++--- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index ad3c7f165f..e357a3fbe1 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -76,10 +76,12 @@ class MaterialManager(QObject): def initialize(self): # Find all materials and put them in a matrix for quick search. - material_metadatas = {metadata["id"]: metadata for metadata in self._container_registry.findContainersMetadata(type = "material")} + material_metadatas = {metadata["id"]: metadata for metadata in + self._container_registry.findContainersMetadata(type = "material") if + metadata.get("GUID")} self._material_group_map = dict() - + # Map #1 # root_material_id -> MaterialGroup for material_id, material_metadata in material_metadatas.items(): @@ -93,7 +95,7 @@ class MaterialManager(QObject): self._material_group_map[root_material_id].is_read_only = self._container_registry.isReadOnly(root_material_id) group = self._material_group_map[root_material_id] - #Store this material in the group of the appropriate root material. + # Store this material in the group of the appropriate root material. if material_id != root_material_id: new_node = MaterialNode(material_metadata) group.derived_material_node_list.append(new_node) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 6dcd5a5ccc..7f8c34a873 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -540,7 +540,8 @@ class XmlMaterialProfile(InstanceContainer): validation_message = XmlMaterialValidator.validateMaterialMetaData(meta_data) if validation_message is not None: - raise Exception("Not valid material profile: %s" % (validation_message)) + return + # raise Exception("Not valid material profile: %s" % (validation_message)) property_values = {} properties = data.iterfind("./um:properties/*", self.__namespaces) From ddc9da63b85644d62eb1ccb87180b0aaf2c546e2 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Wed, 16 May 2018 19:22:02 +0200 Subject: [PATCH 06/25] Still raise exception when loading incorrect material file --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 7f8c34a873..6dcd5a5ccc 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -540,8 +540,7 @@ class XmlMaterialProfile(InstanceContainer): validation_message = XmlMaterialValidator.validateMaterialMetaData(meta_data) if validation_message is not None: - return - # raise Exception("Not valid material profile: %s" % (validation_message)) + raise Exception("Not valid material profile: %s" % (validation_message)) property_values = {} properties = data.iterfind("./um:properties/*", self.__namespaces) From 8eea60bada0053b7e0c942e685869aa0796ed000 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 17 May 2018 14:28:10 +0200 Subject: [PATCH 07/25] CURA-5358 Fix typos --- cura/Machines/MaterialManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index e357a3fbe1..8b74596667 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -160,11 +160,11 @@ class MaterialManager(QObject): key_data.append(root_material_metadata.get(key)) key_data = tuple(key_data) - # If the key_data doesn't exist, no matter if the material is read only... + # If the key_data doesn't exist, it doesn't matter if the material is read only... if key_data not in material_group_dict: material_group_dict[key_data] = dict() else: - # ...but if key_data exists, we just overrite it if the material is read only, otherwise we skip it + # ...but if key_data exists, we just overwrite it if the material is read only, otherwise we skip it if not machine_node.is_read_only: continue approximate_diameter = root_material_metadata.get("approximate_diameter") From 850f6f9b15a7e2d2504cc1a75e1d2af09bbe0797 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 17 May 2018 16:46:32 +0200 Subject: [PATCH 08/25] Change name to Community materials --- plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index 5b9697eda2..e1ffc6326c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -15,7 +15,7 @@ Column Label { id: heading - text: toolbox.viewCategory == "material" ? catalog.i18nc("@label", "Maker Choices") : catalog.i18nc("@label", "Community Plugins") + text: toolbox.viewCategory == "material" ? catalog.i18nc("@label", "Community contributions") : catalog.i18nc("@label", "Community plugins") width: parent.width color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") From 1f149b2821f4f52283e84397e44a53fe5c6c8f5b Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 18 May 2018 10:50:54 +0200 Subject: [PATCH 09/25] Do not show not printed models on snapshot for UFP files CURA-5373 --- cura/PreviewPass.py | 7 +++++-- cura/Snapshot.py | 5 +++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cura/PreviewPass.py b/cura/PreviewPass.py index f6b963d141..662284c111 100644 --- a/cura/PreviewPass.py +++ b/cura/PreviewPass.py @@ -34,9 +34,10 @@ def prettier_color(color_list): # # This is useful to get a preview image of a scene taken from a different location as the active camera. class PreviewPass(RenderPass): - def __init__(self, width: int, height: int): + def __init__(self, width: int, height: int, skip_non_printed_objects: bool = False): super().__init__("preview", width, height, 0) + self._skip_non_printed_objects = skip_non_printed_objects self._camera = None # type: Optional[Camera] self._renderer = Application.getInstance().getRenderer() @@ -112,7 +113,9 @@ class PreviewPass(RenderPass): batch.render(render_camera) batch_support_mesh.render(render_camera) - batch_non_printing.render(render_camera) + + if not self._skip_non_printed_objects: + batch_non_printing.render(render_camera) self.release() diff --git a/cura/Snapshot.py b/cura/Snapshot.py index 1f2a24aecd..7745712651 100644 --- a/cura/Snapshot.py +++ b/cura/Snapshot.py @@ -43,7 +43,8 @@ class Snapshot: render_width, render_height = active_camera.getWindowSize() render_width = int(render_width) render_height = int(render_height) - preview_pass = PreviewPass(render_width, render_height) + skip_non_printed_objects = True + preview_pass = PreviewPass(render_width, render_height, skip_non_printed_objects) root = scene.getRoot() camera = Camera("snapshot", root) @@ -51,7 +52,7 @@ class Snapshot: # determine zoom and look at bbox = None for node in DepthFirstIterator(root): - if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible(): + if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible() and not node.callDecoration("isNonPrintingMesh"): if bbox is None: bbox = node.getBoundingBox() else: From 36dbc70813d594ea4e93d1528fd6dad35563608a Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 18 May 2018 14:01:31 +0200 Subject: [PATCH 10/25] Remove unnecessary code for taking snapshot for UFP file CURA-5373 --- cura/PreviewPass.py | 10 ++-------- cura/Snapshot.py | 6 +----- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/cura/PreviewPass.py b/cura/PreviewPass.py index 662284c111..4241a2f243 100644 --- a/cura/PreviewPass.py +++ b/cura/PreviewPass.py @@ -1,7 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from UM.Application import Application -from UM.Math.Color import Color from UM.Resources import Resources from UM.View.RenderPass import RenderPass @@ -34,10 +33,9 @@ def prettier_color(color_list): # # This is useful to get a preview image of a scene taken from a different location as the active camera. class PreviewPass(RenderPass): - def __init__(self, width: int, height: int, skip_non_printed_objects: bool = False): + def __init__(self, width: int, height: int): super().__init__("preview", width, height, 0) - self._skip_non_printed_objects = skip_non_printed_objects self._camera = None # type: Optional[Camera] self._renderer = Application.getInstance().getRenderer() @@ -75,7 +73,6 @@ class PreviewPass(RenderPass): # Create batches to be rendered batch = RenderBatch(self._shader) - batch_non_printing = RenderBatch(self._non_printing_shader, type = RenderBatch.RenderType.Transparent) batch_support_mesh = RenderBatch(self._support_mesh_shader) # Fill up the batch with objects that can be sliced. ` @@ -84,7 +81,7 @@ class PreviewPass(RenderPass): per_mesh_stack = node.callDecoration("getStack") if node.callDecoration("isNonPrintingMesh"): # Non printing mesh - batch_non_printing.addItem(node.getWorldTransformation(), node.getMeshData(), uniforms = {}) + continue elif per_mesh_stack is not None and per_mesh_stack.getProperty("support_mesh", "value") == True: # Support mesh uniforms = {} @@ -114,8 +111,5 @@ class PreviewPass(RenderPass): batch.render(render_camera) batch_support_mesh.render(render_camera) - if not self._skip_non_printed_objects: - batch_non_printing.render(render_camera) - self.release() diff --git a/cura/Snapshot.py b/cura/Snapshot.py index 7745712651..d1bfeea40f 100644 --- a/cura/Snapshot.py +++ b/cura/Snapshot.py @@ -6,13 +6,10 @@ from PyQt5 import QtCore from PyQt5.QtGui import QImage from cura.PreviewPass import PreviewPass -from cura.Scene import ConvexHullNode from UM.Application import Application -from UM.Math.AxisAlignedBox import AxisAlignedBox from UM.Math.Matrix import Matrix from UM.Math.Vector import Vector -from UM.Mesh.MeshData import transformVertices from UM.Scene.Camera import Camera from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator @@ -43,8 +40,7 @@ class Snapshot: render_width, render_height = active_camera.getWindowSize() render_width = int(render_width) render_height = int(render_height) - skip_non_printed_objects = True - preview_pass = PreviewPass(render_width, render_height, skip_non_printed_objects) + preview_pass = PreviewPass(render_width, render_height) root = scene.getRoot() camera = Camera("snapshot", root) From e7f70d68c72153985d7fd36ee741e2e552f1070a Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 18 May 2018 17:19:14 +0200 Subject: [PATCH 11/25] Focus on IP address field when adding networked printer --- plugins/UM3NetworkPrinting/DiscoverUM3Action.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml index 72c956b8d7..1cf2074979 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml @@ -354,12 +354,10 @@ Cura.MachineAction onShowDialog: { printerKey = key; - addressText = address; + manualPrinterDialog.show(); addressField.selectAll(); addressField.focus = true; - - manualPrinterDialog.show(); } onAccepted: From 314f9135105613ff532ff6af21635d6ab3919937 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Fri, 18 May 2018 17:21:59 +0200 Subject: [PATCH 12/25] Remove extra "if" statement and unused code --- plugins/UM3NetworkPrinting/DiscoverUM3Action.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py index 0b8d6e9f53..4c32a1c19c 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py @@ -83,15 +83,8 @@ class DiscoverUM3Action(MachineAction): @pyqtProperty("QVariantList", notify = discoveredDevicesChanged) def foundDevices(self): if self._network_plugin: - # TODO: Check if this needs to stay. - if Application.getInstance().getGlobalContainerStack(): - global_printer_type = Application.getInstance().getGlobalContainerStack().getBottom().getId() - else: - global_printer_type = "unknown" printers = list(self._network_plugin.getDiscoveredDevices().values()) - # TODO; There are still some testing printers that don't have a correct printer type, so don't filter out unkown ones just yet. - #printers = [printer for printer in printers if printer.printerType == global_printer_type or printer.printerType == "unknown"] printers.sort(key = lambda k: k.name) return printers else: From 9f21c2bd86a9eca6e878f5cfa1143ddfb6f61f3a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 22 May 2018 10:15:20 +0200 Subject: [PATCH 13/25] Add CuraPackageVersion --- cura/CuraVersion.py.in | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/CuraVersion.py.in b/cura/CuraVersion.py.in index c489485c2c..1d55f4dd95 100644 --- a/cura/CuraVersion.py.in +++ b/cura/CuraVersion.py.in @@ -4,3 +4,4 @@ CuraVersion = "@CURA_VERSION@" CuraBuildType = "@CURA_BUILDTYPE@" CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False +CuraPackagesVersion = "@CURA_PACKAGES_VERSION" From ea421204f3ab5512072e0216d6d6fc7ed10857f6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 22 May 2018 11:02:12 +0200 Subject: [PATCH 14/25] Add CURA_PACKAGES_VERSION to CMakeLists.txt --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9296c4ce4e..470d5c966f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ endif() set(CURA_VERSION "master" CACHE STRING "Version name of Cura") set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'") +set(CURA_PACKAGES_VERSION "${CURA_PACKAGES_VERSION}" CACHE STRING "Packages version of Cura") configure_file(${CMAKE_SOURCE_DIR}/cura.desktop.in ${CMAKE_BINARY_DIR}/cura.desktop @ONLY) configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY) From 95a4edb8de285ea0af65315945659f4e3026dbba Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 22 May 2018 11:34:41 +0200 Subject: [PATCH 15/25] CURA-5296 Improve button styling --- .../resources/qml/ToolboxDetailTile.qml | 30 +-------- .../qml/ToolboxDetailTileActions.qml | 66 +++++++++++++++++++ .../qml/ToolboxInstalledTileActions.qml | 13 +++- .../resources/qml/ToolboxProgressButton.qml | 41 +++++++++++- resources/bundled_packages.json | 2 +- 5 files changed, 118 insertions(+), 34 deletions(-) create mode 100644 plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index da53fc94af..355fa5dece 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -9,7 +9,6 @@ import UM 1.1 as UM Item { id: tile - property bool installed: toolbox.isInstalled(model.id) width: detailList.width - UM.Theme.getSize("wide_margin").width height: normalData.height + compatibilityChart.height + 4 * UM.Theme.getSize("default_margin").height Item @@ -46,7 +45,7 @@ Item } } - Item + ToolboxDetailTileActions { id: controls anchors.right: tile.right @@ -54,28 +53,6 @@ Item width: childrenRect.width height: childrenRect.height - ToolboxProgressButton - { - id: installButton - active: toolbox.isDownloading && toolbox.activePackage == model - complete: tile.installed - readyAction: function() - { - toolbox.activePackage = model - toolbox.startDownload(model.download_url) - } - activeAction: function() - { - toolbox.cancelDownload() - } - completeAction: function() - { - toolbox.viewCategory = "installed" - } - // Don't allow installing while another download is running - enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model) - opacity: enabled ? 1.0 : 0.5 - } } ToolboxCompatibilityChart @@ -94,9 +71,4 @@ Item anchors.top: compatibilityChart.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height + UM.Theme.getSize("wide_margin").height //Normal margin for spacing after chart, wide margin between items. } - Connections - { - target: toolbox - onInstallChanged: installed = toolbox.isInstalled(model.id) - } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml new file mode 100644 index 0000000000..f82fb049d8 --- /dev/null +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml @@ -0,0 +1,66 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Toolbox is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +Column +{ + property bool installed: toolbox.isInstalled(model.id) + property bool canUpdate: toolbox.canUpdate(model.id) + width: UM.Theme.getSize("toolbox_action_button").width + spacing: UM.Theme.getSize("narrow_margin").height + + ToolboxProgressButton + { + id: installButton + active: toolbox.isDownloading && toolbox.activePackage == model + complete: installed + readyAction: function() + { + toolbox.activePackage = model + toolbox.startDownload(model.download_url) + } + activeAction: function() + { + toolbox.cancelDownload() + } + completeAction: function() + { + toolbox.viewCategory = "installed" + } + // Don't allow installing while another download is running + enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model) + opacity: enabled ? 1.0 : 0.5 + } + + ToolboxProgressButton + { + id: updateButton + active: toolbox.isDownloading && toolbox.activePackage == model + readyLabel: catalog.i18nc("@action:button", "Update") + activeLabel: catalog.i18nc("@action:button", "Updating") + completeLabel: catalog.i18nc("@action:button", "Updated") + readyAction: function() + { + toolbox.activePackage = model + toolbox.update(model.id) + } + activeAction: function() + { + toolbox.cancelDownload() + } + // Don't allow installing while another download is running + enabled: !(toolbox.isDownloading && toolbox.activePackage != model) + opacity: enabled ? 1.0 : 0.5 + visible: installed && canUpdate + } + Connections + { + target: toolbox + onInstallChanged: installed = toolbox.isInstalled(model.id) + onMetadataChanged: canUpdate = toolbox.canUpdate(model.id) + } +} diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml index 8bdec4da5f..204b755909 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml @@ -49,7 +49,17 @@ Column border { width: UM.Theme.getSize("default_lining").width - color: UM.Theme.getColor("lining") + color: + { + if (control.hovered) + { + return UM.Theme.getColor("primary_hover") + } + else + { + return UM.Theme.getColor("lining") + } + } } } label: Label @@ -58,6 +68,7 @@ Column color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter + font: UM.Theme.getFont("default") } } onClicked: toolbox.uninstall(model.id) diff --git a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml index a977ef999b..b598bd96d0 100644 --- a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml @@ -68,7 +68,7 @@ Item { if (base.complete) { - return UM.Theme.getColor("action_button_disabled") + return "transparent" } else { @@ -82,6 +82,31 @@ Item } } } + border + { + width: + { + if (base.complete) + { + UM.Theme.getSize("default_lining").width + } + else + { + return 0 + } + } + color: + { + if (control.hovered) + { + return UM.Theme.getColor("primary_hover") + } + else + { + return UM.Theme.getColor("lining") + } + } + } } label: Label { @@ -90,7 +115,7 @@ Item { if (base.complete) { - return UM.Theme.getColor("action_button_disabled_text") + return UM.Theme.getColor("text") } else { @@ -106,7 +131,17 @@ Item } verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter - font: UM.Theme.getFont("default_bold") + font: + { + if (base.complete) + { + return UM.Theme.getFont("default") + } + else + { + return UM.Theme.getFont("default_bold") + } + } } } } diff --git a/resources/bundled_packages.json b/resources/bundled_packages.json index 8d58f226b0..5f5ce12554 100644 --- a/resources/bundled_packages.json +++ b/resources/bundled_packages.json @@ -974,7 +974,7 @@ "package_type": "material", "display_name": "Ultimaker ABS", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "1.0.0", + "package_version": "0.5.0", "cura_version": 4, "website": "https://ultimaker.com/products/materials/abs", "author": { From eea9b7ab4662bba30a5e7f15ea6d50be5cc0e485 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 22 May 2018 12:05:33 +0200 Subject: [PATCH 16/25] CURA-5254 Keep track of the latest manual entry key, so it is then selected in the list. --- plugins/UM3NetworkPrinting/DiscoverUM3Action.py | 10 +++++++++- plugins/UM3NetworkPrinting/DiscoverUM3Action.qml | 5 ++++- plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py | 12 ++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py index 4c32a1c19c..9b25de7f42 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.py +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.py @@ -45,6 +45,8 @@ class DiscoverUM3Action(MachineAction): @pyqtSlot() def reset(self): Logger.log("d", "Reset the list of found devices.") + if self._network_plugin: + self._network_plugin.resetLastManualDevice() self.discoveredDevicesChanged.emit() @pyqtSlot() @@ -131,7 +133,7 @@ class DiscoverUM3Action(MachineAction): self._network_plugin.reCheckConnections() @pyqtSlot(result = str) - def getStoredKey(self): + def getStoredKey(self) -> str: global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: meta_data = global_container_stack.getMetaData() @@ -140,6 +142,12 @@ class DiscoverUM3Action(MachineAction): return "" + @pyqtSlot(result = str) + def getLastManualEntryKey(self) -> str: + if self._network_plugin: + return self._network_plugin.getLastManualDevice() + return "" + @pyqtSlot(str, result = bool) def existsKey(self, key) -> bool: return Application.getInstance().getMachineManager().existNetworkInstances(network_key = key) diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml index 1cf2074979..3662fe291e 100644 --- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml @@ -158,7 +158,10 @@ Cura.MachineAction model: manager.foundDevices onModelChanged: { - var selectedKey = manager.getStoredKey(); + var selectedKey = manager.getLastManualEntryKey() + // If there is no last manual entry key, then we select the stored key (if any) + if (selectedKey == "") + selectedKey = manager.getStoredKey() for(var i = 0; i < model.length; i++) { if(model[i].key == selectedKey) { diff --git a/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py index 74a4b044ff..bf5ac96197 100644 --- a/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/UM3OutputDevicePlugin.py @@ -60,6 +60,9 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._manual_instances = self._preferences.getValue("um3networkprinting/manual_instances").split(",") + # Store the last manual entry key + self._last_manual_entry_key = "" # type: str + # The zero-conf service changed requests are handled in a separate thread, so we can re-schedule the requests # which fail to get detailed service info. # Any new or re-scheduled requests will be appended to the request queue, and the handling thread will pick @@ -72,6 +75,12 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): def getDiscoveredDevices(self): return self._discovered_devices + def getLastManualDevice(self) -> str: + return self._last_manual_entry_key + + def resetLastManualDevice(self) -> None: + self._last_manual_entry_key = "" + ## Start looking for devices on network. def start(self): self.startDiscovery() @@ -93,6 +102,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): for address in self._manual_instances: if address: self.addManualDevice(address) + self.resetLastManualDevice() def reCheckConnections(self): active_machine = Application.getInstance().getGlobalContainerStack() @@ -136,6 +146,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): if not address: address = self._discovered_devices[key].ipAddress self._onRemoveDevice(key) + self.resetLastManualDevice() if address in self._manual_instances: self._manual_instances.remove(address) @@ -157,6 +168,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): if instance_name not in self._discovered_devices: # Add a preliminary printer instance self._onAddDevice(instance_name, address, properties) + self._last_manual_entry_key = instance_name self._checkManualDevice(address) From fea37b52be2f5bc316d0ec8d80f60f13915d925a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 22 May 2018 12:06:43 +0200 Subject: [PATCH 17/25] Fix CURA_PACKAGES_VERSION --- CMakeLists.txt | 2 +- cura/CuraVersion.py.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 470d5c966f..96efd68a2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ endif() set(CURA_VERSION "master" CACHE STRING "Version name of Cura") set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'") -set(CURA_PACKAGES_VERSION "${CURA_PACKAGES_VERSION}" CACHE STRING "Packages version of Cura") +set(CURA_PACKAGES_VERSION "" CACHE STRING "Packages version of Cura") configure_file(${CMAKE_SOURCE_DIR}/cura.desktop.in ${CMAKE_BINARY_DIR}/cura.desktop @ONLY) configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY) diff --git a/cura/CuraVersion.py.in b/cura/CuraVersion.py.in index 1d55f4dd95..f45a24cae9 100644 --- a/cura/CuraVersion.py.in +++ b/cura/CuraVersion.py.in @@ -4,4 +4,4 @@ CuraVersion = "@CURA_VERSION@" CuraBuildType = "@CURA_BUILDTYPE@" CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False -CuraPackagesVersion = "@CURA_PACKAGES_VERSION" +CuraPackagesVersion = "@CURA_PACKAGES_VERSION@" From 0b0fb4cd2f5097b8c5413d9c886c0327259f8e34 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 22 May 2018 14:52:22 +0200 Subject: [PATCH 18/25] CURA-5296 Added "canDowngrade" functionality Shows "Downgrade" instead of "Uninstall" for bundled packages with an upgrade installed. --- .../Toolbox/resources/qml/ToolboxInstalledTile.qml | 2 -- .../resources/qml/ToolboxInstalledTileActions.qml | 10 +++++++++- plugins/Toolbox/src/Toolbox.py | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 435319b5e9..78c970659c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -10,7 +10,6 @@ Item { height: UM.Theme.getSize("toolbox_installed_tile").height width: parent.width - property bool canUpdate: false property bool isEnabled: true Rectangle @@ -109,7 +108,6 @@ Item { target: toolbox onEnabledChanged: isEnabled = toolbox.isEnabled(model.id) - onMetadataChanged: canUpdate = toolbox.canUpdate(model.id) } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml index 204b755909..0ca0bd4fd5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml @@ -8,6 +8,8 @@ import UM 1.1 as UM Column { + property bool canUpdate: false + property bool canDowngrade: false width: UM.Theme.getSize("toolbox_action_button").width spacing: UM.Theme.getSize("narrow_margin").height @@ -36,7 +38,7 @@ Column Button { id: removeButton - text: catalog.i18nc("@action:button", "Uninstall") + text: canDowngrade ? catalog.i18nc("@action:button", "Downgrade") : catalog.i18nc("@action:button", "Uninstall") visible: !model.is_bundled enabled: !toolbox.isDownloading style: ButtonStyle @@ -72,5 +74,11 @@ Column } } onClicked: toolbox.uninstall(model.id) + Connections + { + target: toolbox + onMetadataChanged: canUpdate = toolbox.canUpdate(model.id) + onMetadataChanged: canDowngrade = toolbox.canDowngrade(model.id) + } } } diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 622198666d..776f2a3870 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -300,6 +300,20 @@ class Toolbox(QObject, Extension): remote_version = Version(remote_package["package_version"]) return remote_version > local_version + @pyqtSlot(str, result=bool) + def canDowngrade(self, package_id: str) -> bool: + local_package = self._package_manager.getInstalledPackageInfo(package_id) + if local_package is None: + return False + + remote_package = self.getRemotePackage(package_id) + if remote_package is None: + return False + + local_version = Version(local_package["package_version"]) + remote_version = Version(remote_package["package_version"]) + return remote_version < local_version + @pyqtSlot(str, result = bool) def isInstalled(self, package_id: str) -> bool: return self._package_manager.isPackageInstalled(package_id) From eecbe20830ca35c0930d86de90a2ee846f08834d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 22 May 2018 15:06:27 +0200 Subject: [PATCH 19/25] Enabled drag-n-drop for curapackages --- cura/CuraPackageManager.py | 9 ++++++++- resources/qml/Cura.qml | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 0c2c438fcc..a4b60b3251 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -8,13 +8,14 @@ import shutil import zipfile import tempfile -from PyQt5.QtCore import pyqtSlot, QObject, pyqtSignal +from PyQt5.QtCore import pyqtSlot, QObject, pyqtSignal, QUrl from UM.Application import Application from UM.Logger import Logger from UM.Resources import Resources from UM.Version import Version + class CuraPackageManager(QObject): Version = 1 @@ -184,6 +185,12 @@ class CuraPackageManager(QObject): def isPackageInstalled(self, package_id: str) -> bool: return self.getInstalledPackageInfo(package_id) is not None + # This is called by drag-and-dropping curapackage files. + @pyqtSlot(QUrl) + def installPackageViaDragAndDrop(self, file_url: str) -> None: + filename = QUrl(file_url).toLocalFile() + return self.installPackage(filename) + # Schedules the given package file to be installed upon the next start. @pyqtSlot(str) def installPackage(self, filename: str) -> None: diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index ac37cce10a..9d21de0535 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -323,6 +323,21 @@ UM.MainWindow { if (drop.urls.length > 0) { + // As the drop area also supports plugins, first check if it's a plugin that was dropped. + if (drop.urls.length == 1) + { + var filename = drop.urls[0]; + if (filename.endsWith(".curapackage")) + { + // Try to install plugin & close. + CuraApplication.getCuraPackageManager().installPackageViaDragAndDrop(filename); + packageInstallDialog.text = catalog.i18nc("@label", "This package will be installed after restarting."); + packageInstallDialog.icon = StandardIcon.Information; + packageInstallDialog.open(); + return; + } + } + openDialog.handleOpenFileUrls(drop.urls); } } @@ -789,6 +804,14 @@ UM.MainWindow } } + MessageDialog + { + id: packageInstallDialog + title: catalog.i18nc("@window:title", "Install Package"); + standardButtons: StandardButton.Ok + modality: Qt.ApplicationModal + } + MessageDialog { id: infoMultipleFilesWithGcodeDialog title: catalog.i18nc("@title:window", "Open File(s)") From 7861840886bd827420312c8fedb5cdbff65f3d0b Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 22 May 2018 16:04:38 +0200 Subject: [PATCH 20/25] CURA-5296 Small QML bug fix --- .../Toolbox/resources/qml/ToolboxInstalledTileActions.qml | 7 +++++-- resources/bundled_packages.json | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml index 0ca0bd4fd5..0ae738b71d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml @@ -77,8 +77,11 @@ Column Connections { target: toolbox - onMetadataChanged: canUpdate = toolbox.canUpdate(model.id) - onMetadataChanged: canDowngrade = toolbox.canDowngrade(model.id) + onMetadataChanged: + { + canUpdate = toolbox.canUpdate(model.id) + canDowngrade = toolbox.canDowngrade(model.id) + } } } } diff --git a/resources/bundled_packages.json b/resources/bundled_packages.json index 5f5ce12554..8d58f226b0 100644 --- a/resources/bundled_packages.json +++ b/resources/bundled_packages.json @@ -974,7 +974,7 @@ "package_type": "material", "display_name": "Ultimaker ABS", "description": "Example package for material and quality profiles for Ultimaker materials.", - "package_version": "0.5.0", + "package_version": "1.0.0", "cura_version": 4, "website": "https://ultimaker.com/products/materials/abs", "author": { From 0a395a7305df15215d7ba74fe9437ca39d7bdbfe Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 22 May 2018 16:29:04 +0200 Subject: [PATCH 21/25] CURA-5385 Project summary should use scroll view --- resources/qml/WorkspaceSummaryDialog.qml | 399 +++++++++++------------ 1 file changed, 191 insertions(+), 208 deletions(-) diff --git a/resources/qml/WorkspaceSummaryDialog.qml b/resources/qml/WorkspaceSummaryDialog.qml index 4d15860257..0869d7e698 100644 --- a/resources/qml/WorkspaceSummaryDialog.qml +++ b/resources/qml/WorkspaceSummaryDialog.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.1 @@ -61,237 +61,220 @@ UM.Dialog { id: palette } - - Column + Label { - anchors.fill: parent - spacing: 2 * screenScaleFactor - Label + id: mainHeading + width: parent.width + text: catalog.i18nc("@action:title", "Summary - Cura Project") + font.pointSize: 18 + anchors.top: parent.top + } + ScrollView + { + id: scroll + width: parent.width + anchors { - id: titleLabel - text: catalog.i18nc("@action:title", "Summary - Cura Project") - font.pointSize: 18 + top: mainHeading.bottom + topMargin: UM.Theme.getSize("default_margin").height + bottom: controls.top + bottomMargin: UM.Theme.getSize("default_margin").height } - Rectangle + style: UM.Theme.styles.scrollview + ColumnLayout { - id: separator - color: palette.text - width: parent.width - height: 1 - } - Item // Spacer - { - height: spacerHeight - width: height - } - - Label - { - text: catalog.i18nc("@action:label", "Printer settings") - font.bold: true - } - Row - { - width: parent.width - height: childrenRect.height - Label + spacing: UM.Theme.getSize("default_margin").height + Column { - text: catalog.i18nc("@action:label", "Type") - width: (parent.width / 3) | 0 - } - Label - { - text: (Cura.MachineManager.activeMachine == null) ? "" : Cura.MachineManager.activeMachine.definition.name - width: (parent.width / 3) | 0 - } - } - Row - { - width: parent.width - height: childrenRect.height - Label - { - text: catalog.i18nc("@action:label", Cura.MachineManager.activeMachineNetworkGroupName != "" ? "Printer Group" : "Name") - width: (parent.width / 3) | 0 - } - Label - { - text: Cura.MachineManager.activeMachineNetworkGroupName != "" ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName - width: (parent.width / 3) | 0 - } - } - Column - { - width: parent.width - visible: Cura.MachineManager.hasVariantBuildplates - Item // Spacer - { - height: spacerHeight - width: height - } - Row - { - width: parent.width - height: childrenRect.height Label { - text: catalog.i18nc("@action:label", "Build plate") - width: (parent.width / 3) | 0 + id: settingsHeading + text: catalog.i18nc("@action:label", "Printer settings") + font.bold: true } - Label - { - text: Cura.MachineManager.activeVariantBuildplateName - width: (parent.width / 3) | 0 - } - } - } - - Repeater - { - model: Cura.MachineManager.currentExtruderPositions - delegate: Column - { - Item // Spacer - { - height: spacerHeight - width: height - } - Label - { - text: catalog.i18nc("@action:label", "Extruder %1").arg(modelData) - } - height: childrenRect.height - width: parent.width Row { width: parent.width height: childrenRect.height Label { - text: catalog.i18nc("@action:label", "%1 & material").arg(Cura.MachineManager.activeDefinitionVariantsName) - width: (parent.width / 3) | 0 + text: catalog.i18nc("@action:label", "Type") + width: Math.floor(scroll.width / 3) | 0 } Label { - text: Cura.MachineManager.activeVariantNames[modelData] + ", " + Cura.MachineManager.getExtruder(modelData).material.name - width: (parent.width / 3) | 0 + text: (Cura.MachineManager.activeMachine == null) ? "" : Cura.MachineManager.activeMachine.definition.name + width: Math.floor(scroll.width / 3) | 0 + } + } + Row + { + width: parent.width + height: childrenRect.height + Label + { + text: catalog.i18nc("@action:label", Cura.MachineManager.activeMachineNetworkGroupName != "" ? "Printer Group" : "Name") + width: Math.floor(scroll.width / 3) | 0 + } + Label + { + text: Cura.MachineManager.activeMachineNetworkGroupName != "" ? Cura.MachineManager.activeMachineNetworkGroupName : Cura.MachineManager.activeMachineName + width: Math.floor(scroll.width / 3) | 0 + } + } + } + Row + { + visible: Cura.MachineManager.hasVariantBuildplates + width: parent.width + height: childrenRect.height + Label + { + text: catalog.i18nc("@action:label", "Build plate") + width: Math.floor(scroll.width / 3) | 0 + } + Label + { + text: Cura.MachineManager.activeVariantBuildplateName + width: Math.floor(scroll.width / 3) | 0 + } + } + Repeater + { + width: parent.width + height: childrenRect.height + model: Cura.MachineManager.currentExtruderPositions + delegate: Column + { + height: childrenRect.height + width: parent.width + Label + { + text: catalog.i18nc("@action:label", "Extruder %1").arg(modelData) + font.bold: true + } + Row + { + width: parent.width + height: childrenRect.height + Label + { + text: catalog.i18nc("@action:label", "%1 & material").arg(Cura.MachineManager.activeDefinitionVariantsName) + width: Math.floor(scroll.width / 3) | 0 + } + Label + { + text: Cura.MachineManager.activeVariantNames[modelData] + ", " + Cura.MachineManager.getExtruder(modelData).material.name + width: Math.floor(scroll.width / 3) | 0 + } + } + } + } + Column + { + width: parent.width + height: childrenRect.height + Label + { + text: catalog.i18nc("@action:label", "Profile settings") + font.bold: true + } + Row + { + width: parent.width + Label + { + text: catalog.i18nc("@action:label", "Not in profile") + width: Math.floor(scroll.width / 3) | 0 + } + Label + { + text: catalog.i18ncp("@action:label", "%1 override", "%1 overrides", Cura.MachineManager.numUserSettings).arg(Cura.MachineManager.numUserSettings) + width: Math.floor(scroll.width / 3) | 0 + } + visible: Cura.MachineManager.numUserSettings + } + Row + { + width: parent.width + height: childrenRect.height + Label + { + text: catalog.i18nc("@action:label", "Name") + width: Math.floor(scroll.width / 3) | 0 + } + Label + { + text: Cura.MachineManager.activeQualityOrQualityChangesName + width: Math.floor(scroll.width / 3) | 0 + } + + } + } + Column + { + width: parent.width + height: childrenRect.height + Label + { + text: catalog.i18nc("@action:label", "Setting visibility") + font.bold: true + } + Row + { + width: parent.width + height: childrenRect.height + Label + { + text: catalog.i18nc("@action:label", "Visible settings:") + width: Math.floor(scroll.width / 3) | 0 + } + Label + { + text: catalog.i18nc("@action:label", "%1 out of %2" ).arg(definitionsModel.visibleCount).arg(Cura.MachineManager.totalNumberOfSettings) + width: Math.floor(scroll.width / 3) | 0 } } } } - - Item // Spacer - { - height: spacerHeight - width: height - } - - Label - { - text: catalog.i18nc("@action:label", "Profile settings") - font.bold: true - } - Row - { - width: parent.width - Label - { - text: catalog.i18nc("@action:label", "Not in profile") - width: (parent.width / 3) | 0 - } - Label - { - text: catalog.i18ncp("@action:label", "%1 override", "%1 overrides", Cura.MachineManager.numUserSettings).arg(Cura.MachineManager.numUserSettings) - width: (parent.width / 3) | 0 - } - visible: Cura.MachineManager.numUserSettings - } - Row - { - width: parent.width - height: childrenRect.height - Label - { - text: catalog.i18nc("@action:label", "Name") - width: (parent.width / 3) | 0 - } - Label - { - text: Cura.MachineManager.activeQualityOrQualityChangesName - width: (parent.width / 3) | 0 - } - - } - - Item // Spacer - { - height: spacerHeight - width: height - } - - Label - { - text: catalog.i18nc("@action:label", "Setting visibility") - font.bold: true - } - Row - { - width: parent.width - height: childrenRect.height - Label - { - text: catalog.i18nc("@action:label", "Visible settings:") - width: (parent.width / 3) | 0 - } - Label - { - text: catalog.i18nc("@action:label", "%1 out of %2" ).arg(definitionsModel.visibleCount).arg(Cura.MachineManager.totalNumberOfSettings) - width: (parent.width / 3) | 0 - } - } - - Item // Spacer - { - height: spacerHeight - width: height - } } - - CheckBox + Item { - id: dontShowAgainCheckbox - anchors.bottom: cancel_button.top - anchors.bottomMargin: UM.Theme.getSize("default_margin").height - anchors.left: parent.left - - text: catalog.i18nc("@action:label", "Don't show project summary on save again") - checked: dontShowAgain - } - - Button - { - id: cancel_button + id: controls + width: parent.width + height: childrenRect.height anchors.bottom: parent.bottom - anchors.right: ok_button.left - anchors.rightMargin: 2 - - text: catalog.i18nc("@action:button","Cancel"); - enabled: true - onClicked: close() - } - - Button - { - id: ok_button - anchors.bottom: parent.bottom - anchors.right: parent.right - - text: catalog.i18nc("@action:button","Save"); - enabled: true - onClicked: { - close() - yes() + CheckBox + { + id: dontShowAgainCheckbox + anchors.left: parent.left + text: catalog.i18nc("@action:label", "Don't show project summary on save again") + checked: dontShowAgain + } + Button + { + id: cancel_button + anchors + { + right: ok_button.left + rightMargin: UM.Theme.getSize("default_margin").width + } + text: catalog.i18nc("@action:button","Cancel"); + enabled: true + onClicked: close() + } + Button + { + id: ok_button + anchors.right: parent.right + text: catalog.i18nc("@action:button","Save"); + enabled: true + onClicked: + { + close() + yes() + } } } } -} +} \ No newline at end of file From 36c2e80121713ee3ab0754eb72b274dec0592edd Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 22 May 2018 17:32:38 +0200 Subject: [PATCH 22/25] Adds release notes link in version upgrade messagebox CURA-5348 --- cura/CuraApplication.py | 2 +- resources/qml/Cura.qml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 034d045ce6..ccc2b9f8c4 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -448,7 +448,7 @@ class CuraApplication(QtApplication): ## A reusable dialogbox # - showMessageBox = pyqtSignal(str, str, str, str, int, int, arguments = ["title", "text", "informativeText", "detailedText", "buttons", "icon"]) + showMessageBox = pyqtSignal(str, str, str, str, str, int, int, arguments = ["title", "footer", "text", "informativeText", "detailedText", "buttons", "icon"]) def messageBox(self, title, text, informativeText = "", detailedText = "", buttons = QMessageBox.Ok, icon = QMessageBox.NoIcon, callback = None, callback_arguments = []): self._message_box_callback = callback diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index ac37cce10a..c2f984f1ba 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -489,6 +489,7 @@ UM.MainWindow horizontalCenterOffset: -(Math.round(UM.Theme.getSize("sidebar").width / 2)) top: parent.verticalCenter; bottom: parent.bottom; + bottomMargin: UM.Theme.getSize("default_margin").height } } } From b8417bcccbde323159af5dcdf6d5bb29ca70bbf3 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 23 May 2018 09:34:21 +0200 Subject: [PATCH 23/25] If the label tag exists in the xml material file, but without any string in it, the label.text return None and then it makes Cura crashing when creating the models. This is intended to fix the issue #3750 --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 6dcd5a5ccc..6e9f2af911 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -514,7 +514,7 @@ class XmlMaterialProfile(InstanceContainer): color = entry.find("./um:color", self.__namespaces) label = entry.find("./um:label", self.__namespaces) - if label is not None: + if label is not None and label.text is not None: meta_data["name"] = label.text else: meta_data["name"] = self._profile_name(material.text, color.text) @@ -805,7 +805,9 @@ class XmlMaterialProfile(InstanceContainer): color = entry.find("./um:color", cls.__namespaces) label = entry.find("./um:label", cls.__namespaces) - if label is not None: + if "Rigid" in brand.text: + print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", label, label is not None, label.text if label is not None else ":") + if label is not None and label.text is not None: base_metadata["name"] = label.text else: base_metadata["name"] = cls._profile_name(material.text, color.text) From ba234f5c8a43f382e05e6728134b353949465fa9 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 23 May 2018 09:38:16 +0200 Subject: [PATCH 24/25] Remove debug prints --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 6e9f2af911..70d07c1fc5 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -805,8 +805,6 @@ class XmlMaterialProfile(InstanceContainer): color = entry.find("./um:color", cls.__namespaces) label = entry.find("./um:label", cls.__namespaces) - if "Rigid" in brand.text: - print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", label, label is not None, label.text if label is not None else ":") if label is not None and label.text is not None: base_metadata["name"] = label.text else: From 7136b8649a3c6aac5556ca42f6e4635da62c4340 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Wed, 23 May 2018 10:48:19 +0200 Subject: [PATCH 25/25] CURA-5388 disable automatic_push_free / Ensure models are kept apart by default --- cura/PlatformPhysics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PlatformPhysics.py b/cura/PlatformPhysics.py index 1a5d6ef837..b22552d8c5 100755 --- a/cura/PlatformPhysics.py +++ b/cura/PlatformPhysics.py @@ -36,7 +36,7 @@ class PlatformPhysics: self._max_overlap_checks = 10 # How many times should we try to find a new spot per tick? self._minimum_gap = 2 # It is a minimum distance (in mm) between two models, applicable for small models - Preferences.getInstance().addPreference("physics/automatic_push_free", True) + Preferences.getInstance().addPreference("physics/automatic_push_free", False) Preferences.getInstance().addPreference("physics/automatic_drop_down", True) def _onSceneChanged(self, source):