From de8a58f0d7e2ca5cc9e4b7966d6a7d6201118b0b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2022 09:50:44 +0200 Subject: [PATCH 1/7] Fix imports, especially not using plugins folder as module When running from source, 'import plugins' works since it's working from the directory where the plug-ins directory is located. However in a build this doesn't work since the source code is in a different location there. --- plugins/Marketplace/InstallMissingPackagesDialog.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/Marketplace/InstallMissingPackagesDialog.py b/plugins/Marketplace/InstallMissingPackagesDialog.py index 282dc54492..bd7c08d9b9 100644 --- a/plugins/Marketplace/InstallMissingPackagesDialog.py +++ b/plugins/Marketplace/InstallMissingPackagesDialog.py @@ -1,16 +1,17 @@ +# Copyright (c) 2022 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + import os -from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty, QUrl -from PyQt6.QtGui import QDesktopServices +from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty from typing import Optional, List, Dict, cast, Callable from cura.CuraApplication import CuraApplication from UM.PluginRegistry import PluginRegistry from cura.CuraPackageManager import CuraPackageManager -from UM.Message import Message from UM.i18n import i18nCatalog from UM.FlameProfiler import pyqtSlot -from plugins.Marketplace.MissingPackageList import MissingPackageList +from .MissingPackageList import MissingPackageList i18n_catalog = i18nCatalog("cura") From 0f12b012cfa5bfd1f6b30828421e891289e029c3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2022 10:17:39 +0200 Subject: [PATCH 2/7] Create InstallMissingPackageDialog with newly-exposed function from Marketplace This adds a new function to the API of the Marketplace plug-in. It's not pretty, but it's going to be how it is for a while. Done to fix a critical build issue. The 'import plugins' thing works from source but not on the build. --- plugins/3MFReader/WorkspaceDialog.py | 25 ++++++++++++++----------- plugins/Marketplace/Marketplace.py | 18 +++++++++++++++--- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/plugins/3MFReader/WorkspaceDialog.py b/plugins/3MFReader/WorkspaceDialog.py index 419f1fe69c..0a8f7784b2 100644 --- a/plugins/3MFReader/WorkspaceDialog.py +++ b/plugins/3MFReader/WorkspaceDialog.py @@ -1,19 +1,20 @@ -# Copyright (c) 2020 Ultimaker B.V. +# Copyright (c) 2022 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import List, Optional, Dict, cast from PyQt6.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication, QUrl from PyQt6.QtGui import QDesktopServices +from typing import List, Optional, Dict, cast -from UM.FlameProfiler import pyqtSlot -from UM.PluginRegistry import PluginRegistry -from UM.Application import Application -from UM.i18n import i18nCatalog -from UM.Settings.ContainerRegistry import ContainerRegistry from cura.Settings.GlobalStack import GlobalStack -from plugins.Marketplace.InstallMissingPackagesDialog import InstallMissingPackageDialog -from .UpdatableMachinesModel import UpdatableMachinesModel +from UM.Application import Application +from UM.FlameProfiler import pyqtSlot +from UM.i18n import i18nCatalog +from UM.Logger import Logger from UM.Message import Message +from UM.PluginRegistry import PluginRegistry +from UM.Settings.ContainerRegistry import ContainerRegistry + +from .UpdatableMachinesModel import UpdatableMachinesModel import os import threading @@ -292,8 +293,10 @@ class WorkspaceDialog(QObject): @pyqtSlot() def installMissingPackages(self) -> None: - self._install_missing_package_dialog = InstallMissingPackageDialog(self._missing_package_metadata, self.showMissingMaterialsWarning) - self._install_missing_package_dialog.show() + marketplace_plugin = PluginRegistry.getInstance().getPluginObject("Marketplace") + if not marketplace_plugin: + Logger.warning("Could not show dialog to install missing plug-ins. Is Marketplace plug-in not available?") + marketplace_plugin.showInstallMissingPackageDialog(self._missing_package_metadata, self.showMissingMaterialsWarning) # type: ignore def getResult(self) -> Dict[str, Optional[str]]: if "machine" in self._result and self.updatableMachinesModel.count <= 1: diff --git a/plugins/Marketplace/Marketplace.py b/plugins/Marketplace/Marketplace.py index e856245c3d..06fed6ec0b 100644 --- a/plugins/Marketplace/Marketplace.py +++ b/plugins/Marketplace/Marketplace.py @@ -3,15 +3,15 @@ import os.path from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject -from typing import Optional, cast +from typing import Callable, cast, Dict, List, Optional from cura.CuraApplication import CuraApplication # Creating QML objects and managing packages. - from UM.Extension import Extension # We are implementing the main object of an extension here. from UM.PluginRegistry import PluginRegistry # To find out where we are stored (the proper way). -from .RemotePackageList import RemotePackageList # To register this type with QML. +from .InstallMissingPackagesDialog import InstallMissingPackageDialog # To allow creating this dialogue from outside of the plug-in. from .LocalPackageList import LocalPackageList # To register this type with QML. +from .RemotePackageList import RemotePackageList # To register this type with QML. class Marketplace(Extension, QObject): @@ -118,3 +118,15 @@ class Marketplace(Extension, QObject): @pyqtProperty(bool, notify=showRestartNotificationChanged) def showRestartNotification(self) -> bool: return self._restart_needed + + def showInstallMissingPackageDialog(self, packages_metadata: List[Dict[str, str]], ignore_warning_callback: Callable[[], None]) -> None: + """ + Show a dialog that prompts the user to install certain packages. + + The dialog is worded for packages that are missing and required for a certain operation. + :param packages_metadata: The metadata of the packages that are missing. + :param ignore_warning_callback: A callback that gets executed when the user ignores the pop-up, to show them a + warning. + """ + dialog = InstallMissingPackageDialog(packages_metadata, ignore_warning_callback) + dialog.show() From 4a08b88f31955e625a87801c9830caa5d87c0474 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 8 Jun 2022 11:24:46 +0200 Subject: [PATCH 3/7] Allow setting metadata subentries that don't exist yet Otherwise it crashes here. The ContainerManager should be flexible enough to allow that sort of thing. It works with plain entries, but crashed with subentries (like 'properties/diameter') if those weren't present yet in the metadata. Fixes Sentry issue CURA-3FH. --- cura/Settings/ContainerManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 67a1643d0b..676cdd6c65 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -114,7 +114,7 @@ class ContainerManager(QObject): for _ in range(len(entries)): item = item.get(entries.pop(0), {}) - if item[entry_name] != entry_value: + if entry_name not in item or item[entry_name] != entry_value: sub_item_changed = True item[entry_name] = entry_value From f9ea517e054d1779af6043c5c7e771d49e090007 Mon Sep 17 00:00:00 2001 From: "j.delarago" Date: Wed, 8 Jun 2022 11:51:54 +0200 Subject: [PATCH 4/7] If package.json metadata file is missing from 3mf file output warning instead of error. CURA-8610 --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 7456ce2b95..3c096318b5 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -1255,8 +1255,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader): try: package_metadata = json.loads(archive.open("Metadata/packages.json").read().decode("utf-8")) return package_metadata["packages"] + except KeyError: + Logger.warning("No package metadata was found in .3mf file.") except Exception: Logger.error("Failed to load packes metadata from .3mf file") + return [] From d5511a078c0f227828158a544560e0af8e9f2e0b Mon Sep 17 00:00:00 2001 From: "j.delarago" Date: Wed, 8 Jun 2022 12:19:36 +0200 Subject: [PATCH 5/7] Dialog was immediately being destroyed because a reference to it was not being stored in memory. Added a missingPackageDialog variable to WorkspaceDialog to fix this. Swapped the loading order of Marketplace extensions so SyncOrchestractor is not fetched by PluginRegistry.getInstance().getPluginObject("Marketplace") in WorkspaceDialog. CURA-8610 --- plugins/Marketplace/Marketplace.py | 5 +++-- plugins/Marketplace/__init__.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/Marketplace/Marketplace.py b/plugins/Marketplace/Marketplace.py index 06fed6ec0b..b2c729c2cd 100644 --- a/plugins/Marketplace/Marketplace.py +++ b/plugins/Marketplace/Marketplace.py @@ -41,6 +41,7 @@ class Marketplace(Extension, QObject): self._tab_shown: int = 0 self._restart_needed = False + self.missingPackageDialog = None def getTabShown(self) -> int: return self._tab_shown @@ -128,5 +129,5 @@ class Marketplace(Extension, QObject): :param ignore_warning_callback: A callback that gets executed when the user ignores the pop-up, to show them a warning. """ - dialog = InstallMissingPackageDialog(packages_metadata, ignore_warning_callback) - dialog.show() + self.missingPackageDialog = InstallMissingPackageDialog(packages_metadata, ignore_warning_callback) + self.missingPackageDialog.show() diff --git a/plugins/Marketplace/__init__.py b/plugins/Marketplace/__init__.py index ef1beab33e..655cf6bf84 100644 --- a/plugins/Marketplace/__init__.py +++ b/plugins/Marketplace/__init__.py @@ -14,4 +14,4 @@ def register(app): """ Register the plug-in object with Uranium. """ - return { "extension": [Marketplace(), SyncOrchestrator(app)] } + return { "extension": [SyncOrchestrator(app), Marketplace()] } From e57af7556c58dcacb8252b2f2676746062c4f3b8 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2022 13:54:03 +0200 Subject: [PATCH 6/7] Remove incorrect maximum_value for bridge_skin_density Whoops. That should have already been removed. Fixes #12455 --- resources/definitions/fdmprinter.def.json | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 6763cbb7f2..b223bbbfa8 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -7654,7 +7654,6 @@ "default_value": 100, "type": "float", "minimum_value": "5", - "maximum_value": "100", "minimum_value_warning": "20", "maximum_value_warning": "100", "enabled": "bridge_settings_enabled", From 739749726094488d132d051d2cc75261fc3c05ea Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 10 Jun 2022 16:00:23 +0200 Subject: [PATCH 7/7] Add quality_name and quality_changes_name to replacement patterns CURA-9375 Fixes #12447 --- plugins/CuraEngineBackend/StartSliceJob.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index be30a9f81c..64216f373f 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -369,6 +369,9 @@ class StartSliceJob(Job): result["material_name"] = stack.material.getMetaDataEntry("name", "") result["material_brand"] = stack.material.getMetaDataEntry("brand", "") + result["quality_name"] = stack.quality.getMetaDataEntry("name", "") + result["quality_changes_name"] = stack.qualityChanges.getMetaDataEntry("name") + # Renamed settings. result["print_bed_temperature"] = result["material_bed_temperature"] result["print_temperature"] = result["material_print_temperature"]