From bc84c1f6e6b3991c7c5aeda6dc5c8bec9634db8d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Wed, 4 Apr 2018 13:47:40 +0200 Subject: [PATCH 01/14] Prevent preheat timeout from occurring during a print --- cura/PrinterOutput/GenericOutputController.py | 14 ++++++++++++++ plugins/USBPrinting/USBPrinterOutputDevice.py | 3 +++ 2 files changed, 17 insertions(+) diff --git a/cura/PrinterOutput/GenericOutputController.py b/cura/PrinterOutput/GenericOutputController.py index 470848c208..45669ca08a 100644 --- a/cura/PrinterOutput/GenericOutputController.py +++ b/cura/PrinterOutput/GenericOutputController.py @@ -152,3 +152,17 @@ class GenericOutputController(PrinterOutputController): for extruder in self._preheat_hotends: self.setTargetHotendTemperature(extruder.getPrinter(), extruder.getPosition(), 0) self._preheat_hotends = set() + + # Cancel any ongoing preheating timers, without setting back the temperature to 0 + # This can be used eg at the start of a print + def stopPreheatTimers(self): + if self._preheat_hotends_timer.isActive(): + for extruder in self._preheat_hotends: + extruder.updateIsPreheating(False) + self._preheat_hotends = set() + + self._preheat_hotends_timer.stop() + + if self._preheat_bed_timer.isActive(): + self._active_printer.updateIsPreheating(False) + self._preheat_bed_timer.stop() diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 24feedd628..74952ece6e 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -96,6 +96,9 @@ class USBPrinterOutputDevice(PrinterOutputDevice): if self._is_printing: return # Aleady printing + # cancel any ongoing preheat timer before starting a print + self._printers[0].stopPreheatTimers() + Application.getInstance().getController().setActiveStage("MonitorStage") # find the G-code for the active build plate to print From 1fefc0569852da8298c4779dfa00c28bf4bc9f2b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 18 Apr 2018 10:54:04 +0200 Subject: [PATCH 02/14] Fix UM2 custom profile upgrade from 2.7 CURA-5218 --- .../VersionUpgrade27to30/VersionUpgrade27to30.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py b/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py index 972d238921..5a141f1558 100644 --- a/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py +++ b/plugins/VersionUpgrade/VersionUpgrade27to30/VersionUpgrade27to30.py @@ -4,6 +4,8 @@ import configparser #To parse preference files. import io #To serialise the preference files afterwards. import os +import urllib.parse +import re from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this. @@ -118,6 +120,12 @@ class VersionUpgrade27to30(VersionUpgrade): if not parser.has_section("general"): parser.add_section("general") + # Clean up the filename + file_base_name = os.path.basename(filename) + file_base_name = urllib.parse.unquote_plus(file_base_name) + + um2_pattern = re.compile(r"^ultimaker[^a-zA-Z\\d\\s:]2_.*$") + # The ultimaker 2 family ultimaker2_prefix_list = ["ultimaker2_extended_", "ultimaker2_go_", @@ -127,9 +135,8 @@ class VersionUpgrade27to30(VersionUpgrade): "ultimaker2_plus_"] # set machine definition to "ultimaker2" for the custom quality profiles that can be for the ultimaker 2 family - file_base_name = os.path.basename(filename) - is_ultimaker2_family = False - if not any(file_base_name.startswith(ep) for ep in exclude_prefix_list): + is_ultimaker2_family = um2_pattern.match(file_base_name) is not None + if not is_ultimaker2_family and not any(file_base_name.startswith(ep) for ep in exclude_prefix_list): is_ultimaker2_family = any(file_base_name.startswith(ep) for ep in ultimaker2_prefix_list) # ultimaker2 family quality profiles used to set as "fdmprinter" profiles From bae1d2a59d1a87c1c71532e0cd88ae526a97677b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 18 Apr 2018 11:16:18 +0200 Subject: [PATCH 03/14] Switch to a default quality if the specified is not available CURA-5218 --- cura/Settings/MachineManager.py | 46 ++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 9bb66aa36a..69e2f6cf8e 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -310,19 +310,41 @@ class MachineManager(QObject): global_quality_changes = global_stack.qualityChanges global_quality_changes_name = global_quality_changes.getName() + # Try to set the same quality/quality_changes as the machine specified. + # If the quality/quality_changes is not available, switch to the default or the first quality that's available. + same_quality_found = False + quality_groups = self._application.getQualityManager().getQualityGroups(global_stack) + if global_quality_changes.getId() != "empty_quality_changes": - quality_changes_groups = self._application._quality_manager.getQualityChangesGroups(global_stack) - if global_quality_changes_name in quality_changes_groups: - new_quality_changes_group = quality_changes_groups[global_quality_changes_name] + quality_changes_groups = self._application.getQualityManager().getQualityChangesGroups(global_stack) + new_quality_changes_group = quality_changes_groups.get(global_quality_changes_name) + if new_quality_changes_group is not None and new_quality_changes_group.is_available: self._setQualityChangesGroup(new_quality_changes_group) + same_quality_found = True + Logger.log("i", "Machine '%s' quality changes set to '%s'", + global_stack.getName(), new_quality_changes_group.name) else: - quality_groups = self._application._quality_manager.getQualityGroups(global_stack) - if quality_type not in quality_groups: - Logger.log("w", "Quality type [%s] not found in available qualities [%s]", quality_type, ", ".join(quality_groups.keys())) - self._setEmptyQuality() - return - new_quality_group = quality_groups[quality_type] - self._setQualityGroup(new_quality_group, empty_quality_changes = True) + if quality_type in quality_groups: + new_quality_group = quality_groups[quality_type] + self._setQualityGroup(new_quality_group, empty_quality_changes = True) + same_quality_found = True + Logger.log("i", "Machine '%s' quality set to '%s'", + global_stack.getName(), new_quality_group.quality_type) + + # Could not find the specified quality/quality_changes, switch to the preferred quality if available, + # otherwise the first quality that's available, otherwise empty (not supported). + if not same_quality_found: + Logger.log("i", "Machine '%s' could not find quality_type '%s' and quality_changes '%s'. " + "Available quality types are [%s]. Switching to default quality.", + global_stack.getName(), quality_type, global_quality_changes_name, + ", ".join(quality_groups.keys())) + preferred_quality_type = global_stack.getMetaDataEntry("preferred_quality_type") + quality_group = quality_groups.get(preferred_quality_type) + if quality_group is None: + if quality_groups: + quality_group = next(quality_groups.values()) + if quality_group is None: + self.setQua_setQualityGrouplityGroup(quality_group, empty_quality_changes = True) @pyqtSlot(str) def setActiveMachine(self, stack_id: str) -> None: @@ -1004,6 +1026,10 @@ class MachineManager(QObject): if empty_quality_changes: self._current_quality_changes_group = None + if quality_group is None: + self._setEmptyQuality() + return + # Set quality and quality_changes for the GlobalStack self._global_container_stack.quality = quality_group.node_for_global.getContainer() if empty_quality_changes: From 7326ee8c401b440512737fcea70a4c179503826e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 18 Apr 2018 11:19:03 +0200 Subject: [PATCH 04/14] Fix typo CURA-5218 --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 69e2f6cf8e..3ab9c45f17 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -344,7 +344,7 @@ class MachineManager(QObject): if quality_groups: quality_group = next(quality_groups.values()) if quality_group is None: - self.setQua_setQualityGrouplityGroup(quality_group, empty_quality_changes = True) + self._setQualityGroup(quality_group, empty_quality_changes = True) @pyqtSlot(str) def setActiveMachine(self, stack_id: str) -> None: From 650638fcddfb22e63a122af4b621f5eb5639a625 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 18 Apr 2018 11:20:41 +0200 Subject: [PATCH 05/14] Fix setting default quality CURA-5218 --- cura/Settings/MachineManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 3ab9c45f17..ff60436381 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -343,8 +343,7 @@ class MachineManager(QObject): if quality_group is None: if quality_groups: quality_group = next(quality_groups.values()) - if quality_group is None: - self._setQualityGroup(quality_group, empty_quality_changes = True) + self._setQualityGroup(quality_group, empty_quality_changes = True) @pyqtSlot(str) def setActiveMachine(self, stack_id: str) -> None: From 372419c223a25f213fb1e24c48f3284da1884283 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 18 Apr 2018 11:24:08 +0200 Subject: [PATCH 06/14] Fix fallback quality setting CURA-5218 --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index ff60436381..fd77c9fc85 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -342,7 +342,7 @@ class MachineManager(QObject): quality_group = quality_groups.get(preferred_quality_type) if quality_group is None: if quality_groups: - quality_group = next(quality_groups.values()) + quality_group = list(quality_groups.values())[0] self._setQualityGroup(quality_group, empty_quality_changes = True) @pyqtSlot(str) From 340916179ab28cf4672eedc1dc41d02977f3dcef Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 18 Apr 2018 12:00:44 +0200 Subject: [PATCH 07/14] Small typo fixes for preheat timeout CURA-5227 --- cura/PrinterOutput/GenericOutputController.py | 2 +- plugins/USBPrinting/USBPrinterOutputDevice.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/PrinterOutput/GenericOutputController.py b/cura/PrinterOutput/GenericOutputController.py index 45669ca08a..bfa3cfbc82 100644 --- a/cura/PrinterOutput/GenericOutputController.py +++ b/cura/PrinterOutput/GenericOutputController.py @@ -164,5 +164,5 @@ class GenericOutputController(PrinterOutputController): self._preheat_hotends_timer.stop() if self._preheat_bed_timer.isActive(): - self._active_printer.updateIsPreheating(False) + self._preheat_printer.updateIsPreheating(False) self._preheat_bed_timer.stop() diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 74952ece6e..74c24e2fca 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -97,7 +97,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): return # Aleady printing # cancel any ongoing preheat timer before starting a print - self._printers[0].stopPreheatTimers() + self._printers[0].getController().stopPreheatTimers() Application.getInstance().getController().setActiveStage("MonitorStage") From 2ba7a6e4620a7e3764a7c696678db912a6d354e0 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 18 Apr 2018 16:00:08 +0200 Subject: [PATCH 08/14] Revert "Fix gcode.gz double extension problem on Mac" This reverts commit fa90fcf18e26871df030ddb8371cdc05f4d4b6cc. CURA-5228 --- plugins/GCodeGzReader/GCodeGzReader.py | 6 +++--- plugins/GCodeGzReader/__init__.py | 9 +++------ plugins/GCodeGzWriter/__init__.py | 7 ++----- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/plugins/GCodeGzReader/GCodeGzReader.py b/plugins/GCodeGzReader/GCodeGzReader.py index fd9bf0ed84..0843f8f3c0 100644 --- a/plugins/GCodeGzReader/GCodeGzReader.py +++ b/plugins/GCodeGzReader/GCodeGzReader.py @@ -3,11 +3,11 @@ import gzip -from UM.Platform import Platform +from io import TextIOWrapper + from UM.Mesh.MeshReader import MeshReader #The class we're extending/implementing. from UM.PluginRegistry import PluginRegistry - ## A file reader that reads gzipped g-code. # # If you're zipping g-code, you might as well use gzip! @@ -15,7 +15,7 @@ class GCodeGzReader(MeshReader): def __init__(self): super().__init__() - self._supported_extensions = [".gz"] + self._supported_extensions = [".gcode.gz"] def read(self, file_name): with open(file_name, "rb") as file: diff --git a/plugins/GCodeGzReader/__init__.py b/plugins/GCodeGzReader/__init__.py index 6e720b1ed1..98965c00aa 100644 --- a/plugins/GCodeGzReader/__init__.py +++ b/plugins/GCodeGzReader/__init__.py @@ -1,24 +1,21 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from UM.i18n import i18nCatalog -from UM.Platform import Platform - from . import GCodeGzReader +from UM.i18n import i18nCatalog i18n_catalog = i18nCatalog("cura") def getMetaData(): - file_extension = "gz" if Platform.isOSX() else "gcode.gz" return { "mesh_reader": [ { - "extension": file_extension, + "extension": "gcode.gz", "description": i18n_catalog.i18nc("@item:inlistbox", "Compressed G-code File") } ] } def register(app): - app.addNonSliceableExtension(".gz") + app.addNonSliceableExtension(".gcode.gz") return { "mesh_reader": GCodeGzReader.GCodeGzReader() } diff --git a/plugins/GCodeGzWriter/__init__.py b/plugins/GCodeGzWriter/__init__.py index a4d576aef6..c001467b3d 100644 --- a/plugins/GCodeGzWriter/__init__.py +++ b/plugins/GCodeGzWriter/__init__.py @@ -1,19 +1,16 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from UM.i18n import i18nCatalog -from UM.Platform import Platform - from . import GCodeGzWriter +from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") def getMetaData(): - file_extension = "gz" if Platform.isOSX() else "gcode.gz" return { "mesh_writer": { "output": [{ - "extension": file_extension, + "extension": "gcode.gz", "description": catalog.i18nc("@item:inlistbox", "Compressed G-code File"), "mime_type": "application/gzip", "mode": GCodeGzWriter.GCodeGzWriter.OutputMode.BinaryMode From ee359571c0833643ce18fa61dc736851875252e3 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 18 Apr 2018 16:53:33 +0200 Subject: [PATCH 09/14] CURA-5246 Start the timer for updating the platform activity also when the node that changed is a GCode, that has layer data. --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index c9529f8025..83d6b46228 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -984,7 +984,7 @@ class CuraApplication(QtApplication): return self._i18n_catalog.i18nc("@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm.", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_bounding_box.width.item(), 'depth': self._scene_bounding_box.depth.item(), 'height' : self._scene_bounding_box.height.item()} def updatePlatformActivityDelayed(self, node = None): - if node is not None and node.getMeshData() is not None: + if node is not None and (node.getMeshData() is not None or node.callDecoration("getLayerData")): self._update_platform_activity_timer.start() ## Update scene bounding box for current build plate From 0e85802f9cc32e32e6050763245d6194433b667c Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Sun, 15 Apr 2018 12:08:49 +0200 Subject: [PATCH 10/14] Only respond to left mouse button --- plugins/SupportEraser/SupportEraser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SupportEraser/SupportEraser.py b/plugins/SupportEraser/SupportEraser.py index 7884ca30c7..f1306df04c 100644 --- a/plugins/SupportEraser/SupportEraser.py +++ b/plugins/SupportEraser/SupportEraser.py @@ -56,7 +56,7 @@ class SupportEraser(Tool): modifiers = QApplication.keyboardModifiers() ctrl_is_active = modifiers & Qt.ControlModifier - if event.type == Event.MousePressEvent and self._controller.getToolsEnabled(): + if event.type == Event.MousePressEvent and MouseEvent.LeftButton in event.buttons and self._controller.getToolsEnabled(): if ctrl_is_active: self._controller.setActiveTool("TranslateTool") return From ea6d4d96f9ab60459e4e795c745e25ad30941958 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 9 Apr 2018 11:29:49 +0200 Subject: [PATCH 11/14] Exclude non-printing-meshes from bounding box of parents Non-printing-meshes inside a group should not affect push apart or drop to build plate --- cura/Scene/CuraSceneNode.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cura/Scene/CuraSceneNode.py b/cura/Scene/CuraSceneNode.py index 48d271a2f2..428a59f554 100644 --- a/cura/Scene/CuraSceneNode.py +++ b/cura/Scene/CuraSceneNode.py @@ -103,6 +103,25 @@ class CuraSceneNode(SceneNode): return True return False + ## Override of SceneNode._calculateAABB to exclude non-printing-meshes from bounding box + def _calculateAABB(self): + aabb = None + if self._mesh_data: + aabb = self._mesh_data.getExtents(self.getWorldTransformation()) + else: # If there is no mesh_data, use a boundingbox that encompasses the local (0,0,0) + position = self.getWorldPosition() + aabb = AxisAlignedBox(minimum = position, maximum = position) + + for child in self._children: + if child.callDecoration("isNonPrintingMesh"): + # Non-printing-meshes inside a group should not affect push apart or drop to build plate + continue + if aabb is None: + aabb = child.getBoundingBox() + else: + aabb = aabb + child.getBoundingBox() + self._aabb = aabb + ## Taken from SceneNode, but replaced SceneNode with CuraSceneNode def __deepcopy__(self, memo): copy = CuraSceneNode(no_setting_override = True) # Setting override will be added later From a52eaa98f1509d7e290a31e7b2d8f0365d905264 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 23 Mar 2018 16:35:36 +0100 Subject: [PATCH 12/14] When multiplying a parented node, multiply the parent instead (like groups) --- cura/MultiplyObjectsJob.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cura/MultiplyObjectsJob.py b/cura/MultiplyObjectsJob.py index b9f37ec6f8..3444da249f 100644 --- a/cura/MultiplyObjectsJob.py +++ b/cura/MultiplyObjectsJob.py @@ -32,14 +32,19 @@ class MultiplyObjectsJob(Job): root = scene.getRoot() arranger = Arrange.create(scene_root=root) + processed_nodes = [] nodes = [] for node in self._objects: # If object is part of a group, multiply group current_node = node - while current_node.getParent() and current_node.getParent().callDecoration("isGroup"): + while current_node.getParent() and (current_node.getParent().callDecoration("isGroup") or current_node.getParent().callDecoration("isSliceable")): current_node = current_node.getParent() + if current_node in processed_nodes: + continue + processed_nodes.append(current_node) + node_too_big = False if node.getBoundingBox().width < 300 or node.getBoundingBox().depth < 300: offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(current_node, min_offset=self._min_offset) From 57404deba695c0e35595eb8c1f2797f6a7197cd7 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 23 Mar 2018 09:46:05 +0100 Subject: [PATCH 13/14] Prevent scaling support eraser with scaled parent --- plugins/SupportEraser/SupportEraser.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/SupportEraser/SupportEraser.py b/plugins/SupportEraser/SupportEraser.py index f1306df04c..06d9fc3707 100644 --- a/plugins/SupportEraser/SupportEraser.py +++ b/plugins/SupportEraser/SupportEraser.py @@ -19,8 +19,10 @@ from cura.Scene.CuraSceneNode import CuraSceneNode from cura.PickingPass import PickingPass +from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation +from cura.Operations.SetParentOperation import SetParentOperation from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator from cura.Scene.BuildPlateDecorator import BuildPlateDecorator @@ -117,7 +119,10 @@ class SupportEraser(Tool): new_instance.resetState() # Ensure that the state is not seen as a user state. settings.addInstance(new_instance) - op = AddSceneNodeOperation(node, parent) + op = GroupedOperation() + # First add node to the scene at the correct position/scale, before parenting, so the eraser mesh does not get scaled with the parent + op.addOperation(AddSceneNodeOperation(node, self._controller.getScene().getRoot())) + op.addOperation(SetParentOperation(node, parent)) op.push() node.setPosition(position, CuraSceneNode.TransformSpace.World) From f24e1da934a27e7b7a564e1de1adbcebaaef142d Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 19 Apr 2018 09:17:20 +0200 Subject: [PATCH 14/14] Always update job name for gcode files CURA-5246 --- cura/PrintInformation.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index d0e9e43e3f..1d66916b52 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -323,16 +323,21 @@ class PrintInformation(QObject): # when a file is opened using the terminal; the filename comes from _onFileLoaded and still contains its # extension. This cuts the extension off if necessary. name = os.path.splitext(name)[0] + filename_parts = os.path.basename(base_name).split(".") + + # If it's a gcode, also always update the job name + is_gcode = False + if len(filename_parts) > 1: + # Only check the extension(s) + is_gcode = "gcode" in filename_parts[1:] # if this is a profile file, always update the job name # name is "" when I first had some meshes and afterwards I deleted them so the naming should start again is_empty = name == "" - if is_project_file or (is_empty or (self._base_name == "" and self._base_name != name)): - # remove ".curaproject" suffix from (imported) the file name - if name.endswith(".curaproject"): - name = name[:name.rfind(".curaproject")] - self._base_name = name - self._updateJobName() + if is_gcode or is_project_file or (is_empty or (self._base_name == "" and self._base_name != name)): + # Only take the file name part + self._base_name = filename_parts[0] + self._updateJobName() @pyqtProperty(str, fset = setBaseName, notify = baseNameChanged) def baseName(self):