From 7291026bec6bc516e36c5ebbde3591079871ed24 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 22 Feb 2019 15:13:50 +0100 Subject: [PATCH 01/11] Fix material container removal CURA-6237 --- cura/Machines/MaterialManager.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 160508e7a6..aa5af9f01d 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -537,6 +537,24 @@ class MaterialManager(QObject): return nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list + # FIXME: CURA-6237 + # Sort all nodes with respect to the container ID lengths in the ascending order so the base material container + # will be the last one to remove. Adding this is because in ContainerRegistry.removeContainer(), the container + # will be loaded if it has not been loaded before. If the base material has been removed before this happens, + # it will not be able to find and load the material container, resulting in a crash. + # We may need to consider changing how the signal ContainerRegistry.containerRemoved works: Now it requires + # the container that's being removed, meaning that in order to remove a container, it must be loaded first. + # But it can also be that for ContainerRegistry.containerRemoved, we just need to notify the id, name, and/or + # type of the container that's being removed, thus removing removeContainer()'s dependency on a container being + # loaded first. + nodes_to_remove = sorted(nodes_to_remove, key = lambda x: len(x.getMetaDataEntry("id", "")), reverse = True) + # Try to load all containers first. If there is any faulty ones, they will be put into the faulty container + # list, so removeContainer() can ignore those ones. + for node in nodes_to_remove: + container_id = node.getMetaDataEntry("id", "") + results = self._container_registry.findContainers(id = container_id) + if not results: + self._container_registry.addWrongContainerId(container_id) for node in nodes_to_remove: self._container_registry.removeContainer(node.getMetaDataEntry("id", "")) From 91cceea6e0fe5220854db469b3730c6d72f3c36b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 28 Feb 2019 16:17:34 +0100 Subject: [PATCH 02/11] Fix the situation where an upgraded single extrusion machine and loading project caused issues If the upgraded single extrusion machine was never activated, it would not have it's extruders set. CURA-6252 --- cura/Settings/ExtruderManager.py | 4 ++-- cura/Settings/MachineManager.py | 2 +- plugins/3MFReader/ThreeMFWorkspaceReader.py | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 8fa0172305..4f1a2c5a4e 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -341,7 +341,7 @@ class ExtruderManager(QObject): extruder_train.setNextStack(global_stack) extruders_changed = True - self._fixSingleExtrusionMachineExtruderDefinition(global_stack) + self.fixSingleExtrusionMachineExtruderDefinition(global_stack) if extruders_changed: self.extrudersChanged.emit(global_stack_id) self.setActiveExtruderIndex(0) @@ -349,7 +349,7 @@ class ExtruderManager(QObject): # After 3.4, all single-extrusion machines have their own extruder definition files instead of reusing # "fdmextruder". We need to check a machine here so its extruder definition is correct according to this. - def _fixSingleExtrusionMachineExtruderDefinition(self, global_stack: "GlobalStack") -> None: + def fixSingleExtrusionMachineExtruderDefinition(self, global_stack: "GlobalStack") -> None: container_registry = ContainerRegistry.getInstance() expected_extruder_definition_0_id = global_stack.getMetaDataEntry("machine_extruder_trains")["0"] extruder_stack_0 = global_stack.extruders.get("0") diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index bb0c0c00ed..bb83a5f25a 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -365,7 +365,7 @@ class MachineManager(QObject): # Make sure that the default machine actions for this machine have been added self._application.getMachineActionManager().addDefaultMachineActions(global_stack) - ExtruderManager.getInstance()._fixSingleExtrusionMachineExtruderDefinition(global_stack) + ExtruderManager.getInstance().fixSingleExtrusionMachineExtruderDefinition(global_stack) if not global_stack.isValid(): # Mark global stack as invalid ConfigurationErrorMessage.getInstance().addFaultyContainers(global_stack.getId()) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index bf190f7e39..38652361a5 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -26,6 +26,7 @@ from UM.Preferences import Preferences from cura.Machines.VariantType import VariantType from cura.Settings.CuraStackBuilder import CuraStackBuilder +from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderStack import ExtruderStack from cura.Settings.GlobalStack import GlobalStack from cura.Settings.CuraContainerStack import _ContainerIndexes @@ -781,6 +782,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader): if not quality_changes_info.extruder_info_dict: container_info = ContainerInfo(None, None, None) quality_changes_info.extruder_info_dict["0"] = container_info + # If the global stack we're "targeting" has never been active, but was updated from Cura 3.4, + # it might not have it's extruders set properly. + if not global_stack.extruders: + ExtruderManager.getInstance().fixSingleExtrusionMachineExtruderDefinition(global_stack) extruder_stack = global_stack.extruders["0"] container = quality_manager._createQualityChanges(quality_changes_quality_type, quality_changes_name, From cf9a1c0248f071283fc4958acfcec5113ade9223 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 1 Mar 2019 10:46:27 +0100 Subject: [PATCH 03/11] Sort UM imports alphabetically for easy scanning Contributes to CL-1274 --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 ++ plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 8 ++++---- plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py | 9 +++++---- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 8 +++++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 7b5add276a..86c7e1cab6 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -12,8 +12,10 @@ from UM.Backend.Backend import BackendState from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger from UM.Message import Message +from UM.PluginRegistry import PluginRegistry from UM.Qt.Duration import Duration, DurationFormat from UM.Scene.SceneNode import SceneNode + from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 4bbb7ddb5f..07c968c960 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -10,13 +10,13 @@ import os from UM.FileHandler.FileHandler import FileHandler from UM.FileHandler.WriteFileJob import WriteFileJob # To call the file writer asynchronously. -from UM.Logger import Logger -from UM.Settings.ContainerRegistry import ContainerRegistry from UM.i18n import i18nCatalog -from UM.Qt.Duration import Duration, DurationFormat - +from UM.Logger import Logger from UM.Message import Message +from UM.PluginRegistry import PluginRegistry +from UM.Qt.Duration import Duration, DurationFormat from UM.Scene.SceneNode import SceneNode # For typing. +from UM.Settings.ContainerRegistry import ContainerRegistry from cura.CuraApplication import CuraApplication from cura.PrinterOutput.ConfigurationModel import ConfigurationModel diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py index 3ce0460d6b..d6e71fd56f 100644 --- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py @@ -1,7 +1,5 @@ from typing import List, Optional -from UM.FileHandler.FileHandler import FileHandler -from UM.Scene.SceneNode import SceneNode from cura.CuraApplication import CuraApplication from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel @@ -12,10 +10,13 @@ from cura.PrinterOutputDevice import ConnectionType from cura.Settings.ContainerManager import ContainerManager from cura.Settings.ExtruderManager import ExtruderManager -from UM.Logger import Logger -from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.FileHandler.FileHandler import FileHandler from UM.i18n import i18nCatalog +from UM.Logger import Logger from UM.Message import Message +from UM.PluginRegistry import PluginRegistry +from UM.Scene.SceneNode import SceneNode +from UM.Settings.ContainerRegistry import ContainerRegistry from PyQt5.QtNetwork import QNetworkRequest from PyQt5.QtCore import QTimer, QUrl diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 723bcf2b7c..aedd29d247 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -14,12 +14,14 @@ from PyQt5.QtGui import QDesktopServices from cura.CuraApplication import CuraApplication from cura.PrinterOutputDevice import ConnectionType from cura.Settings.GlobalStack import GlobalStack # typing -from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin + +from UM.i18n import i18nCatalog from UM.Logger import Logger +from UM.Message import Message +from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin +from UM.PluginRegistry import PluginRegistry from UM.Signal import Signal, signalemitter from UM.Version import Version -from UM.Message import Message -from UM.i18n import i18nCatalog from . import ClusterUM3OutputDevice, LegacyUM3OutputDevice from .Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager From cac8c85489a5b941ce939523c6ccf6d6dfb53f11 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 1 Mar 2019 10:46:41 +0100 Subject: [PATCH 04/11] Don't use __file__ Contributes to CL-1274 --- .../src/Cloud/CloudOutputDevice.py | 6 ++++-- .../UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 10 ++++++++-- .../UM3NetworkPrinting/src/LegacyUM3OutputDevice.py | 5 ++++- .../UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 12 ++++++++---- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 86c7e1cab6..4d5673effe 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -84,8 +84,10 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._account = api_client.account # We use the Cura Connect monitor tab to get most functionality right away. - self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), - "../../resources/qml/MonitorStage.qml") + self._monitor_view_qml_path = os.path.join( + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" + ) # Trigger the printersChanged signal when the private signal is triggered. self.printersChanged.connect(self._clusterPrintersChanged) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 07c968c960..919788f10e 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -65,7 +65,10 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._received_print_jobs = False # type: bool - self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorStage.qml") + self._monitor_view_qml_path = os.path.join( + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" + ) # Trigger the printersChanged signal when the private signal is triggered self.printersChanged.connect(self._clusterPrintersChanged) @@ -126,7 +129,10 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _spawnPrinterSelectionDialog(self): if self._printer_selection_dialog is None: - path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/PrintWindow.qml") + path = os.path.join( + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "qml", "PrintWindow.qml" + ) self._printer_selection_dialog = self._application.createQmlComponent(path, {"OutputDevice": self}) if self._printer_selection_dialog is not None: self._printer_selection_dialog.show() diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py index d6e71fd56f..68a4e7d42c 100644 --- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py @@ -77,7 +77,10 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self.setIconName("print") - self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorItem.qml") + self._monitor_view_qml_path = os.path.join( + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "qml", "MonitorItem.qml" + ) self._output_controller = LegacyUM3PrinterOutputController(self) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index aedd29d247..10476d55b4 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -457,8 +457,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._start_cloud_flow_message = Message( text = i18n_catalog.i18nc("@info:status", "Send and monitor print jobs from anywhere using your Ultimaker account."), lifetime = 0, - image_source = QUrl.fromLocalFile(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", - "resources", "svg", "cloud-flow-start.svg")), + image_source = QUrl.fromLocalFile(os.path.join( + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "svg", "cloud-flow-start.svg" + )), image_caption = i18n_catalog.i18nc("@info:status", "Connect to Ultimaker Cloud"), option_text = i18n_catalog.i18nc("@action", "Don't ask me again for this printer."), option_state = False @@ -479,8 +481,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): self._cloud_flow_complete_message = Message( text = i18n_catalog.i18nc("@info:status", "You can now send and monitor print jobs from anywhere using your Ultimaker account."), lifetime = 30, - image_source = QUrl.fromLocalFile(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", - "resources", "svg", "cloud-flow-completed.svg")), + image_source = QUrl.fromLocalFile(os.path.join( + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "svg", "cloud-flow-completed.svg" + )), image_caption = i18n_catalog.i18nc("@info:status", "Connected!") ) # Don't show the review connection link if we're not on the local network From 2af3ae8efba15b6549e21c70f7026ab0eb894c94 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 1 Mar 2019 10:53:55 +0100 Subject: [PATCH 05/11] Ensure that the materials get removed in order If we remove the materials in order, it doesn't cause any issues. This is probably because loading the base profile causes the others to be properly instantiated (and subsequently deleted) CURA-6237 --- cura/Machines/MaterialManager.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index aa5af9f01d..ae6dbbd9bd 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -537,17 +537,9 @@ class MaterialManager(QObject): return nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list - # FIXME: CURA-6237 # Sort all nodes with respect to the container ID lengths in the ascending order so the base material container - # will be the last one to remove. Adding this is because in ContainerRegistry.removeContainer(), the container - # will be loaded if it has not been loaded before. If the base material has been removed before this happens, - # it will not be able to find and load the material container, resulting in a crash. - # We may need to consider changing how the signal ContainerRegistry.containerRemoved works: Now it requires - # the container that's being removed, meaning that in order to remove a container, it must be loaded first. - # But it can also be that for ContainerRegistry.containerRemoved, we just need to notify the id, name, and/or - # type of the container that's being removed, thus removing removeContainer()'s dependency on a container being - # loaded first. - nodes_to_remove = sorted(nodes_to_remove, key = lambda x: len(x.getMetaDataEntry("id", "")), reverse = True) + # will be the first one to be removed. We need to do this to ensure that all containers get loaded & deleted. + nodes_to_remove = sorted(nodes_to_remove, key = lambda x: len(x.getMetaDataEntry("id", ""))) # Try to load all containers first. If there is any faulty ones, they will be put into the faulty container # list, so removeContainer() can ignore those ones. for node in nodes_to_remove: From a1e0ddd9df3062dd03984c0892642cc6268bb66e Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 4 Mar 2019 10:19:33 +0100 Subject: [PATCH 06/11] Don't hardcode plugin directory Contributes to CL-1274 --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 5 +++-- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 5 +++-- plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py | 5 +++-- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 8 ++++---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 4d5673effe..6d19044dd7 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -23,6 +23,7 @@ from cura.PrinterOutputDevice import ConnectionType from .CloudOutputController import CloudOutputController from ..MeshFormatHandler import MeshFormatHandler +from ..UM3OutputDevicePlugin import UM3OutputDevicePlugin from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel from .CloudProgressMessage import CloudProgressMessage from .CloudApiClient import CloudApiClient @@ -85,8 +86,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # We use the Cura Connect monitor tab to get most functionality right away. self._monitor_view_qml_path = os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" + PluginRegistry.getInstance().getPluginPath(UM3OutputDevicePlugin().getPluginId()), + "resources", "qml", "MonitorStage.qml" ) # Trigger the printersChanged signal when the private signal is triggered. diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 919788f10e..7ed81391a9 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -32,6 +32,7 @@ from .ConfigurationChangeModel import ConfigurationChangeModel from .MeshFormatHandler import MeshFormatHandler from .SendMaterialJob import SendMaterialJob from .UM3PrintJobOutputModel import UM3PrintJobOutputModel +from .UM3OutputDevicePlugin import UM3OutputDevicePlugin from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from PyQt5.QtGui import QDesktopServices, QImage @@ -66,8 +67,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._received_print_jobs = False # type: bool self._monitor_view_qml_path = os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" + PluginRegistry.getInstance().getPluginPath(UM3OutputDevicePlugin().getPluginId()), + "resources", "qml", "MonitorStage.qml" ) # Trigger the printersChanged signal when the private signal is triggered diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py index 68a4e7d42c..6bdfbbf8c8 100644 --- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py @@ -23,6 +23,7 @@ from PyQt5.QtCore import QTimer, QUrl from PyQt5.QtWidgets import QMessageBox from .LegacyUM3PrinterOutputController import LegacyUM3PrinterOutputController +from .UM3OutputDevicePlugin import UM3OutputDevicePlugin from time import time @@ -78,8 +79,8 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self.setIconName("print") self._monitor_view_qml_path = os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "qml", "MonitorItem.qml" + PluginRegistry.getInstance().getPluginPath(UM3OutputDevicePlugin().getPluginId()), + "resources", "qml", "MonitorStage.qml" ) self._output_controller = LegacyUM3PrinterOutputController(self) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 10476d55b4..6132c0bc42 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -458,8 +458,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): text = i18n_catalog.i18nc("@info:status", "Send and monitor print jobs from anywhere using your Ultimaker account."), lifetime = 0, image_source = QUrl.fromLocalFile(os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "svg", "cloud-flow-start.svg" + PluginRegistry.getInstance().getPluginPath(self.getPluginId()), + "resources", "svg", "cloud-flow-start.svg" )), image_caption = i18n_catalog.i18nc("@info:status", "Connect to Ultimaker Cloud"), option_text = i18n_catalog.i18nc("@action", "Don't ask me again for this printer."), @@ -482,8 +482,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): text = i18n_catalog.i18nc("@info:status", "You can now send and monitor print jobs from anywhere using your Ultimaker account."), lifetime = 30, image_source = QUrl.fromLocalFile(os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "svg", "cloud-flow-completed.svg" + PluginRegistry.getInstance().getPluginPath(self.getPluginId()), + "resources", "svg", "cloud-flow-completed.svg" )), image_caption = i18n_catalog.i18nc("@info:status", "Connected!") ) From c8580cf4177334d1849a563fa9dcd9bc32b8c096 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 4 Mar 2019 11:27:52 +0100 Subject: [PATCH 07/11] Prevent circular dependencies Contributes to CL-1274 --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 3 +-- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 3 +-- plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 6d19044dd7..395741391a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -23,7 +23,6 @@ from cura.PrinterOutputDevice import ConnectionType from .CloudOutputController import CloudOutputController from ..MeshFormatHandler import MeshFormatHandler -from ..UM3OutputDevicePlugin import UM3OutputDevicePlugin from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel from .CloudProgressMessage import CloudProgressMessage from .CloudApiClient import CloudApiClient @@ -86,7 +85,7 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # We use the Cura Connect monitor tab to get most functionality right away. self._monitor_view_qml_path = os.path.join( - PluginRegistry.getInstance().getPluginPath(UM3OutputDevicePlugin().getPluginId()), + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), "resources", "qml", "MonitorStage.qml" ) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 7ed81391a9..97987cee9d 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -32,7 +32,6 @@ from .ConfigurationChangeModel import ConfigurationChangeModel from .MeshFormatHandler import MeshFormatHandler from .SendMaterialJob import SendMaterialJob from .UM3PrintJobOutputModel import UM3PrintJobOutputModel -from .UM3OutputDevicePlugin import UM3OutputDevicePlugin from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply from PyQt5.QtGui import QDesktopServices, QImage @@ -67,7 +66,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._received_print_jobs = False # type: bool self._monitor_view_qml_path = os.path.join( - PluginRegistry.getInstance().getPluginPath(UM3OutputDevicePlugin().getPluginId()), + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), "resources", "qml", "MonitorStage.qml" ) diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py index 6bdfbbf8c8..dd100d7433 100644 --- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py @@ -23,7 +23,6 @@ from PyQt5.QtCore import QTimer, QUrl from PyQt5.QtWidgets import QMessageBox from .LegacyUM3PrinterOutputController import LegacyUM3PrinterOutputController -from .UM3OutputDevicePlugin import UM3OutputDevicePlugin from time import time @@ -79,7 +78,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self.setIconName("print") self._monitor_view_qml_path = os.path.join( - PluginRegistry.getInstance().getPluginPath(UM3OutputDevicePlugin().getPluginId()), + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), "resources", "qml", "MonitorStage.qml" ) From 38895706976f8de6e02bd577687faef2ab3f6435 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 4 Mar 2019 12:04:34 +0100 Subject: [PATCH 08/11] K.I.S.S. Contributes to CL-1274 --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 4 ++-- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 4 ++-- plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py | 4 ++-- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 395741391a..4d5673effe 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -85,8 +85,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # We use the Cura Connect monitor tab to get most functionality right away. self._monitor_view_qml_path = os.path.join( - PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), - "resources", "qml", "MonitorStage.qml" + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" ) # Trigger the printersChanged signal when the private signal is triggered. diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 97987cee9d..919788f10e 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -66,8 +66,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._received_print_jobs = False # type: bool self._monitor_view_qml_path = os.path.join( - PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), - "resources", "qml", "MonitorStage.qml" + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" ) # Trigger the printersChanged signal when the private signal is triggered diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py index dd100d7433..ab4bcddaf4 100644 --- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py @@ -78,8 +78,8 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self.setIconName("print") self._monitor_view_qml_path = os.path.join( - PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), - "resources", "qml", "MonitorStage.qml" + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" ) self._output_controller = LegacyUM3PrinterOutputController(self) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 6132c0bc42..10476d55b4 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -458,8 +458,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): text = i18n_catalog.i18nc("@info:status", "Send and monitor print jobs from anywhere using your Ultimaker account."), lifetime = 0, image_source = QUrl.fromLocalFile(os.path.join( - PluginRegistry.getInstance().getPluginPath(self.getPluginId()), - "resources", "svg", "cloud-flow-start.svg" + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "svg", "cloud-flow-start.svg" )), image_caption = i18n_catalog.i18nc("@info:status", "Connect to Ultimaker Cloud"), option_text = i18n_catalog.i18nc("@action", "Don't ask me again for this printer."), @@ -482,8 +482,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): text = i18n_catalog.i18nc("@info:status", "You can now send and monitor print jobs from anywhere using your Ultimaker account."), lifetime = 30, image_source = QUrl.fromLocalFile(os.path.join( - PluginRegistry.getInstance().getPluginPath(self.getPluginId()), - "resources", "svg", "cloud-flow-completed.svg" + PluginRegistry.getPluginDirectory(), + "UM3NetworkPrinting", "resources", "svg", "cloud-flow-completed.svg" )), image_caption = i18n_catalog.i18nc("@info:status", "Connected!") ) From a74717ca3c4d7a137a768e058d94d024679fae99 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 4 Mar 2019 12:42:48 +0100 Subject: [PATCH 09/11] Get plugin path like most other plugins do Contributes to CL-1274 --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 4 ++-- plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py | 8 ++++---- plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py | 4 ++-- plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 4d5673effe..395741391a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -85,8 +85,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): # We use the Cura Connect monitor tab to get most functionality right away. self._monitor_view_qml_path = os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "qml", "MonitorStage.qml" ) # Trigger the printersChanged signal when the private signal is triggered. diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index 919788f10e..df668c2b20 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -66,8 +66,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._received_print_jobs = False # type: bool self._monitor_view_qml_path = os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "qml", "MonitorStage.qml" ) # Trigger the printersChanged signal when the private signal is triggered @@ -130,8 +130,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _spawnPrinterSelectionDialog(self): if self._printer_selection_dialog is None: path = os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "qml", "PrintWindow.qml" + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "qml", "PrintWindow.qml" ) self._printer_selection_dialog = self._application.createQmlComponent(path, {"OutputDevice": self}) if self._printer_selection_dialog is not None: diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py index ab4bcddaf4..dd100d7433 100644 --- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py @@ -78,8 +78,8 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self.setIconName("print") self._monitor_view_qml_path = os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "qml", "MonitorStage.qml" + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "qml", "MonitorStage.qml" ) self._output_controller = LegacyUM3PrinterOutputController(self) diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py index 10476d55b4..3fce903b1a 100644 --- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py +++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py @@ -458,8 +458,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): text = i18n_catalog.i18nc("@info:status", "Send and monitor print jobs from anywhere using your Ultimaker account."), lifetime = 0, image_source = QUrl.fromLocalFile(os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "svg", "cloud-flow-start.svg" + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "svg", "cloud-flow-start.svg" )), image_caption = i18n_catalog.i18nc("@info:status", "Connect to Ultimaker Cloud"), option_text = i18n_catalog.i18nc("@action", "Don't ask me again for this printer."), @@ -482,8 +482,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin): text = i18n_catalog.i18nc("@info:status", "You can now send and monitor print jobs from anywhere using your Ultimaker account."), lifetime = 30, image_source = QUrl.fromLocalFile(os.path.join( - PluginRegistry.getPluginDirectory(), - "UM3NetworkPrinting", "resources", "svg", "cloud-flow-completed.svg" + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "svg", "cloud-flow-completed.svg" )), image_caption = i18n_catalog.i18nc("@info:status", "Connected!") ) From 88fc7d0fba841dd19f26db8839d39f5a756d919b Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 4 Mar 2019 14:27:35 +0100 Subject: [PATCH 10/11] Don't try to get the plugin path when there's no plugin registry i.e. in tests Contributes to CL-1274 --- .../src/Cloud/CloudOutputDevice.py | 9 +++++---- .../src/ClusterUM3OutputDevice.py | 20 ++++++++++--------- .../src/LegacyUM3OutputDevice.py | 9 +++++---- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 395741391a..d052d925d2 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -84,10 +84,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice): self._account = api_client.account # We use the Cura Connect monitor tab to get most functionality right away. - self._monitor_view_qml_path = os.path.join( - PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), - "resources", "qml", "MonitorStage.qml" - ) + if PluginRegistry.getInstance() is not None: + self._monitor_view_qml_path = os.path.join( + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "qml", "MonitorStage.qml" + ) # Trigger the printersChanged signal when the private signal is triggered. self.printersChanged.connect(self._clusterPrintersChanged) diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py index df668c2b20..6ca6b0cd10 100644 --- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py @@ -65,10 +65,11 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): self._print_jobs = [] # type: List[UM3PrintJobOutputModel] self._received_print_jobs = False # type: bool - self._monitor_view_qml_path = os.path.join( - PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), - "resources", "qml", "MonitorStage.qml" - ) + if PluginRegistry.getInstance() is not None: + self._monitor_view_qml_path = os.path.join( + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "qml", "MonitorStage.qml" + ) # Trigger the printersChanged signal when the private signal is triggered self.printersChanged.connect(self._clusterPrintersChanged) @@ -129,11 +130,12 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice): def _spawnPrinterSelectionDialog(self): if self._printer_selection_dialog is None: - path = os.path.join( - PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), - "resources", "qml", "PrintWindow.qml" - ) - self._printer_selection_dialog = self._application.createQmlComponent(path, {"OutputDevice": self}) + if PluginRegistry.getInstance() is not None: + path = os.path.join( + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "qml", "PrintWindow.qml" + ) + self._printer_selection_dialog = self._application.createQmlComponent(path, {"OutputDevice": self}) if self._printer_selection_dialog is not None: self._printer_selection_dialog.show() diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py index dd100d7433..2c7c33d382 100644 --- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py @@ -77,10 +77,11 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self.setIconName("print") - self._monitor_view_qml_path = os.path.join( - PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), - "resources", "qml", "MonitorStage.qml" - ) + if PluginRegistry.getInstance() is not None: + self._monitor_view_qml_path = os.path.join( + PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"), + "resources", "qml", "MonitorStage.qml" + ) self._output_controller = LegacyUM3PrinterOutputController(self) From 4979b401b3f566fb8084634f6c719b7bdfe68e7a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 6 Mar 2019 11:02:53 +0100 Subject: [PATCH 11/11] Disable prime blob by default for CFFF CURA-6282 --- resources/definitions/fdmprinter.def.json | 2 +- resources/definitions/ultimaker3.def.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 04c69c9497..295108f27b 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -4581,7 +4581,7 @@ "description": "Whether to prime the filament with a blob before printing. Turning this setting on will ensure that the extruder will have material ready at the nozzle before printing. Printing Brim or Skirt can act like priming too, in which case turning this setting off saves some time.", "type": "bool", "resolve": "any(extruderValues('prime_blob_enable'))", - "default_value": true, + "default_value": false, "settable_per_mesh": false, "settable_per_extruder": true, "enabled": false diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json index 72756de2a5..9e017688a2 100644 --- a/resources/definitions/ultimaker3.def.json +++ b/resources/definitions/ultimaker3.def.json @@ -78,7 +78,7 @@ "prime_tower_position_x": { "value": "machine_depth - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) - 30" }, "prime_tower_wipe_enabled": { "default_value": false }, - "prime_blob_enable": { "enabled": true }, + "prime_blob_enable": { "enabled": true, "default_value": true }, "acceleration_enabled": { "value": "True" }, "acceleration_layer_0": { "value": "acceleration_topbottom" },