From a0f345285dbf0d54e50ce76b9d4569ef08202c8e Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Mon, 3 Oct 2016 15:06:38 +0200 Subject: [PATCH 1/3] Rename ProfilesPageModel.py to QualityAndUserProfilesModel.py. Step 1 of 2. Contributes to CURA-2414 Quality changes profiles are created incorrectly --- .../{ProfilesPageModel.py => QualityAndUserProfilesModel.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cura/Settings/{ProfilesPageModel.py => QualityAndUserProfilesModel.py} (100%) diff --git a/cura/Settings/ProfilesPageModel.py b/cura/Settings/QualityAndUserProfilesModel.py similarity index 100% rename from cura/Settings/ProfilesPageModel.py rename to cura/Settings/QualityAndUserProfilesModel.py From 5d1b77c55126d96c5b1bb5c5b5ee3c83bf6f74d1 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Mon, 3 Oct 2016 15:19:15 +0200 Subject: [PATCH 2/3] Rename ProfilesPageModel.py to QualityAndUserProfilesModel.py. Step 2 of 2. Contributes to CURA-2414 Quality changes profiles are created incorrectly --- cura/CuraApplication.py | 2 +- cura/Settings/QualityAndUserProfilesModel.py | 2 +- cura/Settings/__init__.py | 2 +- resources/qml/Preferences/ProfilesPage.qml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 77bc3bbc49..0725c6e48c 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -503,7 +503,7 @@ class CuraApplication(QtApplication): qmlRegisterType(cura.Settings.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel") qmlRegisterType(cura.Settings.ProfilesModel, "Cura", 1, 0, "ProfilesModel") - qmlRegisterType(cura.Settings.ProfilesPageModel, "Cura", 1, 0, "ProfilesPageModel") + qmlRegisterType(cura.Settings.QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel") qmlRegisterType(cura.Settings.MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler") qmlRegisterType(cura.Settings.QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel") diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py index 31caeeda4f..8aca66a994 100644 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ b/cura/Settings/QualityAndUserProfilesModel.py @@ -8,7 +8,7 @@ from cura.Settings.ProfilesModel import ProfilesModel ## QML Model for listing the current list of valid quality and quality changes profiles. # -class ProfilesPageModel(ProfilesModel): +class QualityAndUserProfilesModel(ProfilesModel): def __init__(self, parent = None): super().__init__(parent) diff --git a/cura/Settings/__init__.py b/cura/Settings/__init__.py index 6957e5031c..0fb2ef611c 100644 --- a/cura/Settings/__init__.py +++ b/cura/Settings/__init__.py @@ -13,4 +13,4 @@ from .SettingOverrideDecorator import SettingOverrideDecorator from .QualitySettingsModel import QualitySettingsModel from .SettingInheritanceManager import SettingInheritanceManager from .ProfilesModel import ProfilesModel -from .ProfilesPageModel import ProfilesPageModel +from .QualityAndUserProfilesModel import QualityAndUserProfilesModel diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 244e33f3f5..1809e06a36 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -15,7 +15,7 @@ UM.ManagementPage title: catalog.i18nc("@title:tab", "Profiles"); property var extrudersModel: Cura.ExtrudersModel{} - model: Cura.ProfilesPageModel { } + model: Cura.QualityAndUserProfilesModel { } section.property: "readOnly" section.delegate: Rectangle From 2f57d0fb6e0c5371aa77dd1a97e7ce46cf20d3df Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 3 Oct 2016 15:29:25 +0200 Subject: [PATCH 3/3] Import profiles for the current machine Takes into consideration printers that use quality-profiles from other printers, while gracefully handling mismatches in the number of extruders Fixes CURA-2500, contributes to CURA-2478 --- cura/Settings/ContainerManager.py | 10 +++++ cura/Settings/CuraContainerRegistry.py | 55 +++++++++++++++++++++----- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 9fdf037acb..7537bb3555 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -678,6 +678,16 @@ class ContainerManager(QObject): duplicated_container.setDirty(True) self._container_registry.addContainer(duplicated_container) + ## Get the singleton instance for this class. + @classmethod + def getInstance(cls): + # Note: Explicit use of class name to prevent issues with inheritance. + if ContainerManager.__instance is None: + ContainerManager.__instance = cls() + return ContainerManager.__instance + + __instance = None + # Factory function, used by QML @staticmethod def createContainerManager(engine, js_engine): diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 4de0133654..69951127b5 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -16,6 +16,9 @@ from UM.Platform import Platform from UM.PluginRegistry import PluginRegistry #For getting the possible profile writers to write with. from UM.Util import parseBool +from cura.Settings.ExtruderManager import ExtruderManager +from cura.Settings.ContainerManager import ContainerManager + from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -128,8 +131,14 @@ class CuraContainerRegistry(ContainerRegistry): return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from {0}: {1}", file_name, "Invalid path")} plugin_registry = PluginRegistry.getInstance() - container_registry = ContainerRegistry.getInstance() extension = file_name.split(".")[-1] + + global_container_stack = Application.getInstance().getGlobalContainerStack() + if not global_container_stack: + return + + machine_extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId())) + for plugin_id, meta_data in self._getIOPlugins("profile_reader"): if meta_data["profile_reader"][0]["extension"] != extension: continue @@ -148,13 +157,35 @@ class CuraContainerRegistry(ContainerRegistry): self._configureProfile(profile, name_seed) return { "status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile.getName()) } else: + profile_index = -1 + global_profile = None + for profile in profile_or_list: - extruder_id = profile.getMetaDataEntry("extruder") - if extruder_id: - profile_name = "%s_%s" % (extruder_id, name_seed) + if profile_index >= 0: + if len(machine_extruders) > profile_index: + extruder_id = machine_extruders[profile_index].getBottom().getId() + profile_name = "%s_%s" % (extruder_id, name_seed) + # Ensure the extruder profiles get non-conflicting names + # NB: these are not user-facing + if "extruder" in profile.getMetaData(): + profile.setMetaDataEntry("extruder", extruder_id) + else: + profile.addMetaDataEntry("extruder", extruder_id) + elif profile_index == 0: + # Importing a multiextrusion profile into a single extrusion machine; merge 1st extruder profile into global profile + profile._id = self.uniqueName("temporary_profile") + self.addContainer(profile) + ContainerManager.getInstance().mergeContainers(global_profile.getId(), profile.getId()) + self.removeContainer(profile.getId()) + continue + else: + # The imported composite profile has a profile for an extruder that this machine does not have. Ignore this extruder-profile + continue else: + global_profile = profile profile_name = name_seed - new_name = container_registry.uniqueName(profile_name) + new_name = self.uniqueName(profile_name) + profile.setDirty(True) # Ensure the profiles are correctly saved if "type" in profile.getMetaData(): profile.setMetaDataEntry("type", "quality_changes") @@ -163,6 +194,8 @@ class CuraContainerRegistry(ContainerRegistry): self._configureProfile(profile, profile_name) profile.setName(new_name) + profile_index += 1 + return {"status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile_or_list[0].getName())} # If it hasn't returned by now, none of the plugins loaded the profile successfully. @@ -175,7 +208,7 @@ class CuraContainerRegistry(ContainerRegistry): profile._id = new_id if self._machineHasOwnQualities(): - profile.setDefinition(self._activeDefinition()) + profile.setDefinition(self._activeQualityDefinition()) if self._machineHasOwnMaterials(): profile.addMetaDataEntry("material", self._activeMaterialId()) else: @@ -196,12 +229,14 @@ class CuraContainerRegistry(ContainerRegistry): result.append( (plugin_id, meta_data) ) return result - ## Gets the active definition - # \return the active definition object or None if there is no definition - def _activeDefinition(self): + ## Get the definition to use to select quality profiles for the active machine + # \return the active quality definition object or None if there is no quality definition + def _activeQualityDefinition(self): global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack: - definition = global_container_stack.getBottom() + definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(global_container_stack.getBottom()) + definition = self.findDefinitionContainers(id=definition_id)[0] + if definition: return definition return None