diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 2515d22127..579be0d953 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1620,8 +1620,12 @@ class CuraApplication(QtApplication): openProjectFile = pyqtSignal(QUrl, arguments = ["project_file"]) # Emitted when a project file is about to open. - @pyqtSlot(QUrl, bool) - def readLocalFile(self, file, skip_project_file_check = False): + @pyqtSlot(QUrl, str) + @pyqtSlot(QUrl) + ## Open a local file + # \param project_mode How to handle project files. Either None(default): Follow user preference, "open_as_model" or + # "open_as_project". This parameter is only considered if the file is a project file. + def readLocalFile(self, file: QUrl, project_mode: Optional[str] = None): if not file.isValid(): return @@ -1632,10 +1636,24 @@ class CuraApplication(QtApplication): self.deleteAll() break - if not skip_project_file_check and self.checkIsValidProjectFile(file): + is_project_file = self.checkIsValidProjectFile(file) + + if project_mode is None: + project_mode = self.getPreferences().getValue("cura/choice_on_open_project") + + if is_project_file and project_mode == "open_as_project": + # open as project immediately without presenting a dialog + workspace_handler = self.getWorkspaceFileHandler() + workspace_handler.readLocalFile(file) + return + + if is_project_file and project_mode == "always_ask": + # present a dialog asking to open as project or import models self.callLater(self.openProjectFile.emit, file) return + # Either the file is a model file or we want to load only models from project. Continue to load models. + if self.getPreferences().getValue("cura/select_models_on_load"): Selection.clear() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 57da690d6d..a4ff8fbbfa 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1592,18 +1592,20 @@ class MachineManager(QObject): if not no_dialog and self.hasUserSettings and self._application.getPreferences().getValue("cura/active_mode") == 1: self._application.discardOrKeepProfileChanges() - # The display name of currently active quality. + # The display name map of currently active quality. + # The display name has 2 parts, a main part and a suffix part. # This display name is: # - For built-in qualities (quality/intent): the quality type name, such as "Fine", "Normal", etc. # - For custom qualities: - - # Examples: # - "my_profile - Fine" (only based on a default quality, no intent involved) # - "my_profile - Engineering - Fine" (based on an intent) - @pyqtProperty(str, notify = activeQualityDisplayNameChanged) - def activeQualityDisplayName(self) -> str: + @pyqtProperty("QVariantMap", notify = activeQualityDisplayNameChanged) + def activeQualityDisplayNameMap(self) -> Dict[str, str]: global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack() if global_stack is None: - return "" + return {"main": "", + "suffix": ""} display_name = global_stack.quality.getName() @@ -1612,13 +1614,18 @@ class MachineManager(QObject): intent_display_name = IntentCategoryModel.name_translation.get(intent_category, catalog.i18nc("@label", "Unknown")) display_name = "{intent_name} - {the_rest}".format(intent_name = intent_display_name, - the_rest = display_name) + the_rest = display_name) + + main_part = display_name + suffix_part = "" # Not a custom quality if global_stack.qualityChanges != empty_quality_changes_container: - display_name = self.activeQualityOrQualityChangesName + " - " + display_name + main_part = self.activeQualityOrQualityChangesName + suffix_part = display_name - return display_name + return {"main": main_part, + "suffix": suffix_part} ## Change the intent category of the current printer. # diff --git a/cura/SingleInstance.py b/cura/SingleInstance.py index cf07b143c6..6fcf0da6cf 100644 --- a/cura/SingleInstance.py +++ b/cura/SingleInstance.py @@ -87,7 +87,7 @@ class SingleInstance: if command == "clear-all": self._application.callLater(lambda: self._application.deleteAll()) - # Command: Load a model file + # Command: Load a model or project file elif command == "open": self._application.callLater(lambda f = payload["filePath"]: self._application._openFile(f)) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 05355f7e23..9959fcd492 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5832,6 +5832,32 @@ "enabled": "not (support_enable or support_tree_enable)", "settable_per_mesh": false, "settable_per_extruder": false + }, + "meshfix_maximum_travel_resolution": + { + "label": "Maximum Travel Resolution", + "description": "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate.", + "type": "float", + "unit": "mm", + "default_value": 1.0, + "value": "min(meshfix_maximum_resolution * speed_travel / speed_print, 2 * line_width)", + "minimum_value": "0.001", + "minimum_value_warning": "0.05", + "maximum_value_warning": "10", + "settable_per_mesh": false, + "settable_per_extruder": true + }, + "meshfix_maximum_deviation": + { + "label": "Maximum Deviation", + "description": "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution, so if the two conflict the Maximum Deviation will always be held true.", + "type": "float", + "unit": "mm", + "default_value": 0.05, + "minimum_value": "0.001", + "minimum_value_warning": "0.01", + "maximum_value_warning": "0.3", + "settable_per_mesh": true } } }, @@ -6222,7 +6248,7 @@ "unit": "mm", "type": "float", "default_value": 1.0, - "minimum_value": "0.001", + "minimum_value": "0", "minimum_value_warning": "0.05", "maximum_value_warning": "1.0", "settable_per_mesh": true, @@ -6240,32 +6266,6 @@ "maximum_value_warning": "3", "settable_per_mesh": true }, - "meshfix_maximum_travel_resolution": - { - "label": "Maximum Travel Resolution", - "description": "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate.", - "type": "float", - "unit": "mm", - "default_value": 1.0, - "value": "min(meshfix_maximum_resolution * speed_travel / speed_print, 2 * line_width)", - "minimum_value": "0.001", - "minimum_value_warning": "0.05", - "maximum_value_warning": "10", - "settable_per_mesh": false, - "settable_per_extruder": true - }, - "meshfix_maximum_deviation": - { - "label": "Maximum Deviation", - "description": "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution, so if the two conflict the Maximum Deviation will always be held true.", - "type": "float", - "unit": "mm", - "default_value": 0.05, - "minimum_value": "0.001", - "minimum_value_warning": "0.01", - "maximum_value_warning": "0.3", - "settable_per_mesh": true - }, "support_skip_some_zags": { "label": "Break Up Support In Chunks", diff --git a/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml b/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml index f6436f62c5..2566a2d44c 100644 --- a/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml +++ b/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml @@ -53,7 +53,7 @@ UM.Dialog UM.Preferences.setValue("cura/choice_on_open_project", "open_as_model") } - CuraApplication.readLocalFile(base.fileUrl, true) + CuraApplication.readLocalFile(base.fileUrl, "open_as_model") var meshName = backgroundItem.getMeshName(base.fileUrl.toString()) backgroundItem.hasMesh(decodeURIComponent(meshName)) diff --git a/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml b/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml index 0df914805a..187578f12c 100644 --- a/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml +++ b/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml @@ -42,7 +42,7 @@ UM.Dialog { for (var i in fileUrls) { - CuraApplication.readLocalFile(fileUrls[i], true); + CuraApplication.readLocalFile(fileUrls[i], "open_as_model"); } var meshName = backgroundItem.getMeshName(fileUrls[0].toString()); diff --git a/resources/qml/MachineSettings/PrintHeadMinMaxTextField.qml b/resources/qml/MachineSettings/PrintHeadMinMaxTextField.qml index a08fa92c78..7bb5f5fc76 100644 --- a/resources/qml/MachineSettings/PrintHeadMinMaxTextField.qml +++ b/resources/qml/MachineSettings/PrintHeadMinMaxTextField.qml @@ -24,7 +24,7 @@ import Cura 1.1 as Cura // NumericTextFieldWithUnit { - id: machineXMaxField + id: printerHeadMinMaxField UM.I18nCatalog { id: catalog; name: "cura" } containerStackId: Cura.MachineManager.activeMachineId @@ -64,7 +64,7 @@ NumericTextFieldWithUnit // show the correct value. if (!textField.activeFocus && !textField.acceptableInput) { - valueText = axisValue + valueText = Qt.binding(function() { return printerHeadMinMaxField.axisValue }) } } } @@ -94,6 +94,6 @@ NumericTextFieldWithUnit } // Recreate the binding to show the correct value. - valueText = axisValue + valueText = Qt.binding(function() { return axisValue }) } } diff --git a/resources/qml/Menus/RecentFilesMenu.qml b/resources/qml/Menus/RecentFilesMenu.qml index 0f1f67b6fa..b788b5e72e 100644 --- a/resources/qml/Menus/RecentFilesMenu.qml +++ b/resources/qml/Menus/RecentFilesMenu.qml @@ -29,42 +29,8 @@ Menu } onTriggered: { - var toShowDialog = false; - var toOpenAsProject = false; - var toOpenAsModel = false; + CuraApplication.readLocalFile(modelData); - if (CuraApplication.checkIsValidProjectFile(modelData)) { - // check preference - var choice = UM.Preferences.getValue("cura/choice_on_open_project"); - - if (choice == "open_as_project") - { - toOpenAsProject = true; - }else if (choice == "open_as_model"){ - toOpenAsModel = true; - }else{ - toShowDialog = true; - } - } - else { - toOpenAsModel = true; - } - - if (toShowDialog) { - askOpenAsProjectOrModelsDialog.fileUrl = modelData; - askOpenAsProjectOrModelsDialog.show(); - return; - } - - // open file in the prefered way - if (toOpenAsProject) - { - UM.WorkspaceFileHandler.readLocalFile(modelData); - } - else if (toOpenAsModel) - { - CuraApplication.readLocalFile(modelData, true); - } var meshName = backgroundItem.getMeshName(modelData.toString()) backgroundItem.hasMesh(decodeURIComponent(meshName)) } diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index a297b0a769..2698089d0c 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -100,18 +100,30 @@ Item function generateActiveQualityText() { - var result = Cura.MachineManager.activeQualityDisplayName + var resultMap = Cura.MachineManager.activeQualityDisplayNameMap + var resultMain = resultMap["main"] + var resultSuffix = resultMap["suffix"] + var result = "" if (Cura.MachineManager.isActiveQualityExperimental) { - result += " (Experimental)" + resultSuffix += " (Experimental)" } if (Cura.MachineManager.isActiveQualitySupported) { if (Cura.MachineManager.activeQualityLayerHeight > 0) { - result += " " + result = resultMain + if (resultSuffix) + { + result += " - " + } + result += "" + if (resultSuffix) + { + result += resultSuffix + } result += " - " result += Cura.MachineManager.activeQualityLayerHeight + "mm" result += "" diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml index bb3a986929..a23b87fdbe 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml @@ -20,7 +20,12 @@ RowLayout { if (Cura.MachineManager.activeStack) { - var text = Cura.MachineManager.activeQualityDisplayName + var resultMap = Cura.MachineManager.activeQualityDisplayNameMap + var text = resultMap["main"] + if (resultMap["suffix"]) + { + text += " - " + resultMap["suffix"] + } if (!Cura.MachineManager.hasNotSupportedQuality) {