diff --git a/cura/ProfileWriter.py b/cura/ProfileWriter.py index 6c719205ec..276e2b80a3 100644 --- a/cura/ProfileWriter.py +++ b/cura/ProfileWriter.py @@ -18,8 +18,8 @@ class ProfileWriter(PluginObject): # The profile writer may write its own file format to the specified file. # # \param path \type{string} The file to output to. - # \param profile \type{Profile} The profile to write to the file. + # \param profiles \type{Profile} or \type{List} The profile(s) to write to the file. # \return \code True \endcode if the writing was successful, or \code # False \endcode if it wasn't. - def write(self, path, node): + def write(self, path, profiles): raise NotImplementedError("Profile writer plugin was not correctly implemented. No write was specified.") diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index ed7cf3c430..c87e8f699c 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -58,12 +58,10 @@ class CuraContainerRegistry(ContainerRegistry): ## Exports an profile to a file # - # \param instance_id \type{str} the ID of the profile to export. + # \param instance_ids \type{list} the IDs of the profiles to export. # \param file_name \type{str} the full path and filename to export to. # \param file_type \type{str} the file type with the format " (*.)" - def exportProfile(self, instance_id, file_name, file_type): - Logger.log('d', 'exportProfile instance_id: '+str(instance_id)) - + def exportProfile(self, instance_ids, file_name, file_type): # Parse the fileType to deduce what plugin can save the file format. # fileType has the format " (*.)" split = file_type.rfind(" (*.") # Find where the description ends and the extension starts. @@ -82,16 +80,16 @@ class CuraContainerRegistry(ContainerRegistry): catalog.i18nc("@label", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_name)) if result == QMessageBox.No: return - - containers = ContainerRegistry.getInstance().findInstanceContainers(id=instance_id) - if not containers: - return - container = containers[0] + found_containers = [] + for instance_id in instance_ids: + containers = ContainerRegistry.getInstance().findInstanceContainers(id=instance_id) + if containers: + found_containers.append(containers[0]) profile_writer = self._findProfileWriter(extension, description) try: - success = profile_writer.write(file_name, container) + success = profile_writer.write(file_name, found_containers) except Exception as e: Logger.log("e", "Failed to export profile to %s: %s", file_name, str(e)) m = Message(catalog.i18nc("@info:status", "Failed to export profile to {0}: {1}", file_name, str(e)), lifetime = 0) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index c9895be697..1359ab77b6 100644 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -55,6 +55,13 @@ class ExtruderManager(QObject): map[position] = self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][position].getId() return map + @pyqtSlot(str, result = str) + def getQualityChangesIdByExtruderStackId(self, id): + for position in self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()]: + extruder = self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][position] + if extruder.getId() == id: + return extruder.findContainer(type = "quality_changes").getId() + ## The instance of the singleton pattern. # # It's None if the extruder manager hasn't been created yet. diff --git a/plugins/CuraProfileWriter/CuraProfileWriter.py b/plugins/CuraProfileWriter/CuraProfileWriter.py index 86b4f7dc89..cd3681b86f 100644 --- a/plugins/CuraProfileWriter/CuraProfileWriter.py +++ b/plugins/CuraProfileWriter/CuraProfileWriter.py @@ -5,22 +5,31 @@ from UM.Logger import Logger from UM.SaveFile import SaveFile from cura.ProfileWriter import ProfileWriter - +import zipfile ## Writes profiles to Cura's own profile format with config files. class CuraProfileWriter(ProfileWriter): ## Writes a profile to the specified file path. # # \param path \type{string} The file to output to. - # \param profile \type{Profile} The profile to write to that file. + # \param profiles \type{Profile} \type{List} The profile(s) to write to that file. # \return \code True \endcode if the writing was successful, or \code # False \endcode if it wasn't. - def write(self, path, profile): - serialized = profile.serialize() + def write(self, path, profiles): + if type(profiles) != list: + profiles = [profiles] + + stream = open(path, "wb") # Open file for writing in binary. + archive = zipfile.ZipFile(stream, "w", compression=zipfile.ZIP_DEFLATED) try: - with SaveFile(path, "wt", -1, "utf-8") as f: # Open the specified file. - f.write(serialized) + # Open the specified file. + for profile in profiles: + serialized = profile.serialize() + profile_file = zipfile.ZipInfo(profile.getId()) + archive.writestr(profile_file, serialized) except Exception as e: Logger.log("e", "Failed to write profile to %s: %s", path, str(e)) return False + finally: + archive.close() return True diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index f84c7c62b9..569cc9f7f0 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -13,6 +13,8 @@ UM.ManagementPage id: base; title: catalog.i18nc("@title:tab", "Profiles"); + property var extrudersModel: Cura.ExtrudersModel{} + //Cura.ExtrudersModel { id: extrudersModel} model: UM.InstanceContainersModel { @@ -113,8 +115,7 @@ UM.ManagementPage text: catalog.i18nc("@action:button", "Export") iconName: "document-export" onClicked: exportDialog.open() -// enabled: currentItem != null - enabled: false + enabled: currentItem != null } ] @@ -206,7 +207,7 @@ UM.ManagementPage Repeater { - model: Cura.ExtrudersModel { } + model: base.extrudersModel ProfileTab { @@ -299,7 +300,12 @@ UM.ManagementPage folder: CuraApplication.getDefaultPath("dialog_profile_path") onAccepted: { - var result = base.model.exportProfile(base.currentItem.id, fileUrl, selectedNameFilter) + var profiles_to_export = [base.currentItem.id] + for(var extruder_nr in base.extrudersModel.items) + { + profiles_to_export.push(ExtruderManager.getQualityChangesIdByExtruderStackId(base.extrudersModel.items[extruder_nr].id)) + } + var result = base.model.exportProfile(profiles_to_export, fileUrl, selectedNameFilter) if(result && result.status == "error") { messageDialog.icon = StandardIcon.Critical