Revert "Revert CURA-8055 in the 4.10 branch. This should not have been merged in there."

This reverts commit 4d29de45796dc42f76c774a216a0601bb57cf790.
Effectively this re-applies the changes for CURA-8055 / #9957.
This commit is contained in:
Ghostkeeper 2021-06-24 14:20:38 +02:00
parent 84b5b19584
commit f82384d93c
No known key found for this signature in database
GPG Key ID: D2A8871EE34EC59A
6 changed files with 98 additions and 4 deletions

View File

@ -2,9 +2,10 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import copy # To duplicate materials. import copy # To duplicate materials.
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot # To allow the preference page proxy to be used from the actual preferences page. from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl
from typing import Any, Dict, Optional, TYPE_CHECKING from typing import Any, Dict, Optional, TYPE_CHECKING
import uuid # To generate new GUIDs for new materials. import uuid # To generate new GUIDs for new materials.
import zipfile # To export all materials in a .zip archive.
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Logger import Logger from UM.Logger import Logger
@ -24,6 +25,11 @@ class MaterialManagementModel(QObject):
This class handles the actions in that page, such as creating new materials, renaming them, etc. This class handles the actions in that page, such as creating new materials, renaming them, etc.
""" """
def __init__(self, parent: QObject) -> None:
super().__init__(parent)
cura_application = cura.CuraApplication.CuraApplication.getInstance()
self._preferred_export_all_path = None # type: Optional[QUrl] # Path to export all materials to. None if not yet initialised.
cura_application.getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
favoritesChanged = pyqtSignal(str) favoritesChanged = pyqtSignal(str)
"""Triggered when a favorite is added or removed. """Triggered when a favorite is added or removed.
@ -264,3 +270,52 @@ class MaterialManagementModel(QObject):
self.favoritesChanged.emit(material_base_file) self.favoritesChanged.emit(material_base_file)
except ValueError: # Material was not in the favorites list. except ValueError: # Material was not in the favorites list.
Logger.log("w", "Material {material_base_file} was already not a favorite material.".format(material_base_file = material_base_file)) Logger.log("w", "Material {material_base_file} was already not a favorite material.".format(material_base_file = material_base_file))
def _onOutputDevicesChanged(self) -> None:
"""
When the list of output devices changes, we may want to update the
preferred export path.
"""
cura_application = cura.CuraApplication.CuraApplication.getInstance()
device_manager = cura_application.getOutputDeviceManager()
devices = device_manager.getOutputDevices()
for device in devices:
if device.__class__.__name__ == "RemovableDriveOutputDevice":
self._preferred_export_all_path = QUrl.fromLocalFile(device.getId())
break
else: # No removable drives? Use local path.
self._preferred_export_all_path = cura_application.getDefaultPath("dialog_material_path")
self.outputDevicesChanged.emit()
outputDevicesChanged = pyqtSignal() # Triggered when adding or removing removable drives.
@pyqtProperty(QUrl, notify = outputDevicesChanged)
def preferredExportAllPath(self) -> QUrl:
"""
Get the preferred path to export materials to.
If there is a removable drive, that should be the preferred path. Otherwise it should be the most recent local
file path.
:return: The preferred path to export all materials to.
"""
if self._preferred_export_all_path is None: # Not initialised yet. Can happen when output devices changed before class got created.
self._onOutputDevicesChanged()
return self._preferred_export_all_path
@pyqtSlot(QUrl)
def exportAll(self, file_path: QUrl) -> None:
"""
Export all materials to a certain file path.
:param file_path: The path to export the materials to.
"""
registry = CuraContainerRegistry.getInstance()
archive = zipfile.ZipFile(file_path.toLocalFile(), "w", compression = zipfile.ZIP_DEFLATED)
for metadata in registry.findInstanceContainersMetadata(type = "material"):
if metadata["base_file"] != metadata["id"]: # Only process base files.
continue
if metadata["id"] == "empty_material": # Don't export the empty material.
continue
material = registry.findContainers(id = metadata["id"])[0]
suffix = registry.getMimeTypeForContainer(type(material)).preferredSuffix
filename = metadata["id"] + "." + suffix
archive.writestr(filename, material.serialize())

View File

@ -86,6 +86,14 @@ class GlobalStack(CuraContainerStack):
def supportsNetworkConnection(self): def supportsNetworkConnection(self):
return self.getMetaDataEntry("supports_network_connection", False) return self.getMetaDataEntry("supports_network_connection", False)
@pyqtProperty(bool, constant = True)
def supportsMaterialExport(self):
"""
Whether the printer supports Cura's export format of material profiles.
:return: ``True`` if it supports it, or ``False`` if not.
"""
return self.getMetaDataEntry("supports_material_export", False)
@classmethod @classmethod
def getLoadingPriority(cls) -> int: def getLoadingPriority(cls) -> int:
return 2 return 2

View File

@ -22,7 +22,8 @@
"0": "ultimaker2_plus_connect_extruder_0" "0": "ultimaker2_plus_connect_extruder_0"
}, },
"supports_usb_connection": false, "supports_usb_connection": false,
"supports_network_connection": true "supports_network_connection": true,
"supports_material_export": true
}, },
"overrides": { "overrides": {

View File

@ -27,6 +27,7 @@
"first_start_actions": [ "DiscoverUM3Action" ], "first_start_actions": [ "DiscoverUM3Action" ],
"supported_actions": [ "DiscoverUM3Action" ], "supported_actions": [ "DiscoverUM3Action" ],
"supports_usb_connection": false, "supports_usb_connection": false,
"supports_material_export": true,
"weight": -1, "weight": -1,
"firmware_update_info": { "firmware_update_info": {
"id": 213482, "id": 213482,

View File

@ -28,6 +28,7 @@
"supported_actions": [ "DiscoverUM3Action" ], "supported_actions": [ "DiscoverUM3Action" ],
"supports_usb_connection": false, "supports_usb_connection": false,
"supports_network_connection": true, "supports_network_connection": true,
"supports_material_export": true,
"weight": -2, "weight": -2,
"firmware_update_info": { "firmware_update_info": {
"id": 9051, "id": 9051,

View File

@ -1,5 +1,5 @@
// Copyright (c) 2018 Ultimaker B.V. // Copyright (c) 2021 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
@ -191,6 +191,20 @@ Item
} }
enabled: base.hasCurrentItem enabled: base.hasCurrentItem
} }
//Sync button.
Button
{
id: syncMaterialsButton
text: catalog.i18nc("@action:button Sending materials to printers", "Sync with Printers")
iconName: "sync-synchronizing"
onClicked:
{
forceActiveFocus();
exportAllMaterialsDialog.open();
}
visible: Cura.MachineManager.activeMachine.supportsMaterialExport
}
} }
Item { Item {
@ -368,6 +382,20 @@ Item
} }
} }
FileDialog
{
id: exportAllMaterialsDialog
title: catalog.i18nc("@title:window", "Export All Materials")
selectExisting: false
nameFilters: ["Material archives (*.umm)", "All files (*)"]
folder: base.materialManagementModel.preferredExportAllPath
onAccepted:
{
base.materialManagementModel.exportAll(fileUrl);
CuraApplication.setDefaultPath("dialog_material_path", folder);
}
}
MessageDialog MessageDialog
{ {
id: messageDialog id: messageDialog