diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 67a57bd0cb..462f411037 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -106,6 +106,7 @@ import copy import os import argparse import json +import time numpy.seterr(all="ignore") @@ -143,6 +144,7 @@ class CuraApplication(QtApplication): Q_ENUMS(ResourceTypes) def __init__(self, **kwargs): + self._boot_loading_time = time.time() # this list of dir names will be used by UM to detect an old cura directory for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "user", "variants"]: Resources.addExpectedDirNameInData(dir_name) @@ -689,16 +691,29 @@ class CuraApplication(QtApplication): else: self.runWithGUI() - # Pre-load files if requested - for file_name in self.getCommandLineOption("file", []): - self._openFile(file_name) - for file_name in self._open_file_queue: # Open all the files that were queued up while plug-ins were loading. - self._openFile(file_name) - self.started = True self.initializationFinished.emit() + Logger.log("d", "Booting Cura took %s seconds", time.time() - self._boot_loading_time) + + + # For now use a timer to postpone some things that need to be done after the application and GUI are + # initialized, for example opening files because they may show dialogs which can be closed due to incomplete + # GUI initialization. + self._post_start_timer = QTimer(self) + self._post_start_timer.setInterval(700) + self._post_start_timer.setSingleShot(True) + self._post_start_timer.timeout.connect(self._onPostStart) + self._post_start_timer.start() + + self.exec_() + def _onPostStart(self): + for file_name in self.getCommandLineOption("file", []): + self.callLater(self._openFile, file_name) + for file_name in self._open_file_queue: # Open all the files that were queued up while plug-ins were loading. + self.callLater(self._openFile, file_name) + initializationFinished = pyqtSignal() ## Run Cura without GUI elements and interaction (server mode). @@ -1545,6 +1560,8 @@ class CuraApplication(QtApplication): def log(self, msg): Logger.log("d", msg) + openProjectFile = pyqtSignal(QUrl, arguments = ["project_file"]) # Emitted when a project file is about to open. + @pyqtSlot(QUrl) def readLocalFile(self, file): if not file.isValid(): @@ -1557,6 +1574,10 @@ class CuraApplication(QtApplication): self.deleteAll() break + if self.checkIsValidProjectFile(file): + self.callLater(self.openProjectFile.emit, file) + return + f = file.toLocalFile() extension = os.path.splitext(f)[1] filename = os.path.basename(f) diff --git a/cura/PrinterOutput/GenericOutputController.py b/cura/PrinterOutput/GenericOutputController.py index c445a0a71c..470848c208 100644 --- a/cura/PrinterOutput/GenericOutputController.py +++ b/cura/PrinterOutput/GenericOutputController.py @@ -58,7 +58,8 @@ class GenericOutputController(PrinterOutputController): self._output_device.sendCommand("G90") def homeHead(self, printer): - self._output_device.sendCommand("G28 XY") + self._output_device.sendCommand("G28 X") + self._output_device.sendCommand("G28 Y") def homeBed(self, printer): self._output_device.sendCommand("G28 Z") diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 9873d91c05..314983404c 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -609,6 +609,7 @@ class CuraEngineBackend(QObject, Backend): self._slicing = False Logger.log("d", "Slicing took %s seconds", time() - self._slice_start_time ) + Logger.log("d", "Number of models per buildplate: %s", dict(self._numObjectsPerBuildPlate())) # See if we need to process the sliced layers job. active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate diff --git a/plugins/PerObjectSettingsTool/PerObjectCategory.qml b/plugins/PerObjectSettingsTool/PerObjectCategory.qml index 2dc4ba6326..2be716fd39 100644 --- a/plugins/PerObjectSettingsTool/PerObjectCategory.qml +++ b/plugins/PerObjectSettingsTool/PerObjectCategory.qml @@ -58,5 +58,5 @@ Button { checkable: true checked: definition.expanded - onClicked: definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandAll(definition.key) + onClicked: definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandRecursive(definition.key) } diff --git a/plugins/PluginBrowser/PluginBrowser.py b/plugins/PluginBrowser/PluginBrowser.py index 8912a7a202..ad36ebe6da 100644 --- a/plugins/PluginBrowser/PluginBrowser.py +++ b/plugins/PluginBrowser/PluginBrowser.py @@ -301,46 +301,21 @@ class PluginBrowser(QObject, Extension): return self._plugins_model + def _checkCanUpgrade(self, plugin_id, version): + if plugin_id not in self._plugin_registry.getInstalledPlugins(): + return False - - def _checkCanUpgrade(self, id, version): - - # TODO: This could maybe be done more efficiently using a dictionary... - + plugin_object = self._plugin_registry.getPluginObject(plugin_id) # Scan plugin server data for plugin with the given id: for plugin in self._plugins_metadata: - if id == plugin["id"]: - reg_version = Version(version) + if plugin_id == plugin["id"]: + reg_version = Version(plugin_object.getVersion()) new_version = Version(plugin["version"]) if new_version > reg_version: - Logger.log("i", "%s has an update availible: %s", plugin["id"], plugin["version"]) + Logger.log("i", "%s has an update available: %s", plugin["id"], plugin["version"]) return True return False - def _checkAlreadyInstalled(self, id): - metadata = self._plugin_registry.getMetaData(id) - # We already installed this plugin, but the registry just doesn't know it yet. - if id in self._newly_installed_plugin_ids: - return True - # We already uninstalled this plugin, but the registry just doesn't know it yet: - elif id in self._newly_uninstalled_plugin_ids: - return False - elif metadata != {}: - return True - else: - return False - - def _checkInstallStatus(self, plugin_id): - if plugin_id in self._plugin_registry.getInstalledPlugins(): - return "installed" - else: - return "uninstalled" - - def _checkEnabled(self, id): - if id in self._plugin_registry.getActivePlugins(): - return True - return False - def _onRequestFinished(self, reply): reply_url = reply.url().toString() if reply.error() == QNetworkReply.TimeoutError: diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index e1c990c596..d618f63b53 100755 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -57,7 +57,7 @@ class SliceInfo(Extension): def messageActionTriggered(self, message_id, action_id): Preferences.getInstance().setValue("info/asked_send_slice_info", True) if action_id == "Disable": - CuraApplication.getInstance().showPreferences() + Preferences.getInstance().addPreference("info/send_slice_info", False) self.send_slice_info_message.hide() def _onWriteStarted(self, output_device): diff --git a/plugins/UltimakerMachineActions/BedLevelMachineAction.py b/plugins/UltimakerMachineActions/BedLevelMachineAction.py index 6a8a337d8c..d6de21c89b 100644 --- a/plugins/UltimakerMachineActions/BedLevelMachineAction.py +++ b/plugins/UltimakerMachineActions/BedLevelMachineAction.py @@ -42,6 +42,7 @@ class BedLevelMachineAction(MachineAction): printer.homeBed() printer.moveHead(0, 0, 3) printer.homeHead() + printer.homeBed() def _getPrinterOutputDevices(self) -> List[PrinterOutputDevice]: return [printer_output_device for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices() if isinstance(printer_output_device, PrinterOutputDevice)] @@ -60,6 +61,7 @@ class BedLevelMachineAction(MachineAction): printer.moveHead(0, 0, 3) printer.moveHead(Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") - 10, 0, 0) printer.moveHead(0, 0, -3) + printer.homeBed() self._bed_level_position += 1 elif self._bed_level_position == 1: printer.moveHead(0, 0, 3) diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py b/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py index 3014eca4a2..1419325cc1 100644 --- a/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py @@ -17,7 +17,6 @@ def getMetaData(): # if any is updated. ("quality_changes", 2000000): ("quality_changes", 2000001, upgrade.upgradeInstanceContainer), ("user", 2000000): ("user", 2000001, upgrade.upgradeInstanceContainer), - ("quality", 2000000): ("quality", 2000001, upgrade.upgradeInstanceContainer), ("definition_changes", 2000000): ("definition_changes", 2000001, upgrade.upgradeInstanceContainer), ("machine_stack", 3000000): ("machine_stack", 3000001, upgrade.upgradeMachineStack), }, diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py b/plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py index 699faacab6..79ed5e8b68 100644 --- a/plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade26to27/__init__.py @@ -27,7 +27,6 @@ def getMetaData(): # if any is updated. ("quality_changes", 2000001): ("quality_changes", 2000002, upgrade.upgradeOtherContainer), ("user", 2000001): ("user", 2000002, upgrade.upgradeOtherContainer), - ("quality", 2000001): ("quality", 2000002, upgrade.upgradeOtherContainer), ("definition_changes", 2000001): ("definition_changes", 2000002, upgrade.upgradeOtherContainer), ("variant", 2000000): ("variant", 2000002, upgrade.upgradeOtherContainer) }, diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/__init__.py b/plugins/VersionUpgrade/VersionUpgrade27to30/__init__.py index 396ce4abe0..4da7257b1c 100644 --- a/plugins/VersionUpgrade/VersionUpgrade27to30/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade27to30/__init__.py @@ -16,7 +16,6 @@ def getMetaData(): ("quality_changes", 2000002): ("quality_changes", 2000003, upgrade.upgradeQualityChangesContainer), ("user", 2000002): ("user", 2000003, upgrade.upgradeOtherContainer), - ("quality", 2000002): ("quality", 2000003, upgrade.upgradeOtherContainer), ("definition_changes", 2000002): ("definition_changes", 2000003, upgrade.upgradeOtherContainer), ("variant", 2000002): ("variant", 2000003, upgrade.upgradeOtherContainer) }, diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py b/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py index c853e2b93b..7b2c213a31 100644 --- a/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py @@ -16,7 +16,6 @@ def getMetaData(): ("quality_changes", 2000003): ("quality_changes", 2000004, upgrade.upgradeInstanceContainer), ("user", 2000003): ("user", 2000004, upgrade.upgradeInstanceContainer), - ("quality", 2000003): ("quality", 2000004, upgrade.upgradeInstanceContainer), ("definition_changes", 2000003): ("definition_changes", 2000004, upgrade.upgradeInstanceContainer), ("variant", 2000003): ("variant", 2000004, upgrade.upgradeInstanceContainer) }, diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py b/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py index 36e0036bec..ae4bf7b2f9 100644 --- a/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py @@ -13,7 +13,6 @@ def getMetaData(): ("extruder_train", 3000004): ("extruder_train", 4000004, upgrade.upgradeStack), ("definition_changes", 2000004): ("definition_changes", 3000004, upgrade.upgradeInstanceContainer), - ("quality", 2000004): ("quality", 3000004, upgrade.upgradeInstanceContainer), ("quality_changes", 2000004): ("quality_changes", 3000004, upgrade.upgradeQualityChanges), ("user", 2000004): ("user", 3000004, upgrade.upgradeInstanceContainer), ("variant", 2000004): ("variant", 3000004, upgrade.upgradeVariants) @@ -31,10 +30,6 @@ def getMetaData(): "get_version": upgrade.getCfgVersion, "location": {"./definition_changes"} }, - "quality": { - "get_version": upgrade.getCfgVersion, - "location": {"./quality"} - }, "quality_changes": { "get_version": upgrade.getCfgVersion, "location": {"./quality"} diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index d7d9698439..a89baa67c8 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2271,6 +2271,16 @@ "settable_per_mesh": false, "settable_per_extruder": true }, + "limit_support_retractions": + { + "label": "Limit Support Retractions", + "description": "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure.", + "type": "bool", + "default_value": true, + "enabled": "retraction_enable and support_enable", + "settable_per_mesh": false, + "settable_per_extruder": true + }, "material_standby_temperature": { "label": "Standby Temperature", @@ -6585,6 +6595,14 @@ "type": "float", "enabled": "bridge_settings_enabled and bridge_enable_more_layers", "settable_per_mesh": true + }, + "wall_try_line_thickness": + { + "label": "Try Multiple Line Thicknesses", + "description": "When creating inner walls, try various line thicknesses to fit the wall lines better in narrow spaces. This reduces or increases the inner wall line width by up to 0.01mm.", + "default_value": false, + "type": "bool", + "settable_per_mesh": true } } }, diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index c4ebb790e8..005cb17220 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -855,6 +855,16 @@ UM.MainWindow id: askOpenAsProjectOrModelsDialog } + Connections + { + target: CuraApplication + onOpenProjectFile: + { + askOpenAsProjectOrModelsDialog.fileUrl = project_file; + askOpenAsProjectOrModelsDialog.show(); + } + } + EngineLog { id: engineLog; diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 3612c4cf29..419285d893 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2017 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 @@ -63,8 +63,6 @@ Button property var focusItem: base - //text: definition.label - contentItem: Item { anchors.fill: parent anchors.left: parent.left @@ -160,7 +158,7 @@ Button if (definition.expanded) { settingDefinitionsModel.collapse(definition.key); } else { - settingDefinitionsModel.expandAll(definition.key); + settingDefinitionsModel.expandRecursive(definition.key); } //Set focus so that tab navigation continues from this point on. //NB: This must be set AFTER collapsing/expanding the category so that the scroll position is correct. @@ -237,7 +235,7 @@ Button onClicked: { - settingDefinitionsModel.expandAll(definition.key); + settingDefinitionsModel.expandRecursive(definition.key); base.checked = true; base.showAllHiddenInheritedSettings(definition.key); } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 4a919ab9bd..272569daea 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -601,6 +601,17 @@ Item onTriggered: Cura.Actions.configureSettingVisibility.trigger(contextMenu); } + MenuSeparator {} + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Collapse All") + onTriggered: definitionsModel.collapseAll() + } + MenuItem + { + text: catalog.i18nc("@action:inmenu", "Expand All") + onTriggered: definitionsModel.expandRecursive() + } } UM.SettingPropertyProvider