mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-09 23:05:01 -06:00
Merge branch 'master' into layer_view3_cleanup
This commit is contained in:
commit
78de5412a2
95 changed files with 3279 additions and 683 deletions
|
@ -2,6 +2,7 @@
|
|||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Scene.Platform import Platform
|
||||
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
||||
|
@ -25,9 +26,6 @@ import numpy
|
|||
import copy
|
||||
import math
|
||||
|
||||
import UM.Settings.ContainerRegistry
|
||||
|
||||
|
||||
# Setting for clearance around the prime
|
||||
PRIME_CLEARANCE = 6.5
|
||||
|
||||
|
@ -796,7 +794,7 @@ class BuildVolume(SceneNode):
|
|||
stack = self._global_container_stack
|
||||
else:
|
||||
extruder_stack_id = ExtruderManager.getInstance().extruderIds[str(extruder_index)]
|
||||
stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
|
||||
value = stack.getProperty(setting_key, property)
|
||||
setting_type = stack.getProperty(setting_key, "type")
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
|
||||
from UM.Application import Application
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from UM.Math.Polygon import Polygon
|
||||
from . import ConvexHullNode
|
||||
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
import UM.Settings.ContainerRegistry
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from . import ConvexHullNode
|
||||
|
||||
import numpy
|
||||
|
||||
|
@ -308,11 +308,11 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
|||
extruder_stack_id = self._node.callDecoration("getActiveExtruder")
|
||||
if not extruder_stack_id: #Decoration doesn't exist.
|
||||
extruder_stack_id = ExtruderManager.getInstance().extruderIds["0"]
|
||||
extruder_stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
extruder_stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
return extruder_stack.getProperty(setting_key, property)
|
||||
else: #Limit_to_extruder is set. Use that one.
|
||||
extruder_stack_id = ExtruderManager.getInstance().extruderIds[str(extruder_index)]
|
||||
stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
return stack.getProperty(setting_key, property)
|
||||
|
||||
## Returns true if node is a descendant or the same as the root node.
|
||||
|
|
|
@ -12,10 +12,14 @@ from UM.Logger import Logger
|
|||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
try:
|
||||
from cura.CuraVersion import CuraDebugMode
|
||||
except ImportError:
|
||||
CuraDebugMode = False # [CodeStyle: Reflecting imported value]
|
||||
MYPY = False
|
||||
if MYPY:
|
||||
CuraDebugMode = False
|
||||
else:
|
||||
try:
|
||||
from cura.CuraVersion import CuraDebugMode
|
||||
except ImportError:
|
||||
CuraDebugMode = False # [CodeStyle: Reflecting imported value]
|
||||
|
||||
# List of exceptions that should be considered "fatal" and abort the program.
|
||||
# These are primarily some exception types that we simply cannot really recover from
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Copyright (c) 2015 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
from PyQt5.QtNetwork import QLocalServer
|
||||
from PyQt5.QtNetwork import QLocalSocket
|
||||
|
||||
from UM.Qt.QtApplication import QtApplication
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
|
@ -26,7 +28,6 @@ from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
|||
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
|
||||
from UM.Operations.GroupedOperation import GroupedOperation
|
||||
from UM.Operations.SetTransformOperation import SetTransformOperation
|
||||
from UM.Operations.TranslateOperation import TranslateOperation
|
||||
from cura.SetParentOperation import SetParentOperation
|
||||
from cura.SliceableObjectDecorator import SliceableObjectDecorator
|
||||
from cura.BlockSlicingDecorator import BlockSlicingDecorator
|
||||
|
@ -34,6 +35,11 @@ from cura.BlockSlicingDecorator import BlockSlicingDecorator
|
|||
from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.SettingFunction import SettingFunction
|
||||
from cura.Settings.MachineNameValidator import MachineNameValidator
|
||||
from cura.Settings.ProfilesModel import ProfilesModel
|
||||
from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel
|
||||
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
|
||||
from cura.Settings.UserProfilesModel import UserProfilesModel
|
||||
|
||||
from . import PlatformPhysics
|
||||
from . import BuildVolume
|
||||
|
@ -45,7 +51,14 @@ from . import CuraSplashScreen
|
|||
from . import CameraImageProvider
|
||||
from . import MachineActionManager
|
||||
|
||||
import cura.Settings
|
||||
from cura.Settings.MachineManager import MachineManager
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
||||
from cura.Settings.ExtrudersModel import ExtrudersModel
|
||||
from cura.Settings.ContainerSettingsModel import ContainerSettingsModel
|
||||
from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
|
||||
from cura.Settings.QualitySettingsModel import QualitySettingsModel
|
||||
from cura.Settings.ContainerManager import ContainerManager
|
||||
|
||||
from PyQt5.QtCore import QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
|
@ -59,15 +72,18 @@ import numpy
|
|||
import copy
|
||||
import urllib.parse
|
||||
import os
|
||||
|
||||
import argparse
|
||||
import json
|
||||
|
||||
numpy.seterr(all="ignore")
|
||||
|
||||
try:
|
||||
from cura.CuraVersion import CuraVersion, CuraBuildType
|
||||
except ImportError:
|
||||
CuraVersion = "master" # [CodeStyle: Reflecting imported value]
|
||||
CuraBuildType = ""
|
||||
MYPY = False
|
||||
if not MYPY:
|
||||
try:
|
||||
from cura.CuraVersion import CuraVersion, CuraBuildType
|
||||
except ImportError:
|
||||
CuraVersion = "master" # [CodeStyle: Reflecting imported value]
|
||||
CuraBuildType = ""
|
||||
|
||||
class CuraApplication(QtApplication):
|
||||
class ResourceTypes:
|
||||
|
@ -83,6 +99,7 @@ class CuraApplication(QtApplication):
|
|||
Q_ENUMS(ResourceTypes)
|
||||
|
||||
def __init__(self):
|
||||
|
||||
Resources.addSearchPath(os.path.join(QtApplication.getInstallPrefix(), "share", "cura", "resources"))
|
||||
if not hasattr(sys, "frozen"):
|
||||
Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "resources"))
|
||||
|
@ -107,9 +124,9 @@ class CuraApplication(QtApplication):
|
|||
|
||||
SettingDefinition.addSettingType("extruder", None, str, Validator)
|
||||
|
||||
SettingFunction.registerOperator("extruderValues", cura.Settings.ExtruderManager.getExtruderValues)
|
||||
SettingFunction.registerOperator("extruderValue", cura.Settings.ExtruderManager.getExtruderValue)
|
||||
SettingFunction.registerOperator("resolveOrValue", cura.Settings.ExtruderManager.getResolveOrValue)
|
||||
SettingFunction.registerOperator("extruderValues", ExtruderManager.getExtruderValues)
|
||||
SettingFunction.registerOperator("extruderValue", ExtruderManager.getExtruderValue)
|
||||
SettingFunction.registerOperator("resolveOrValue", ExtruderManager.getResolveOrValue)
|
||||
|
||||
## Add the 4 types of profiles to storage.
|
||||
Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality")
|
||||
|
@ -128,13 +145,14 @@ class CuraApplication(QtApplication):
|
|||
|
||||
## Initialise the version upgrade manager with Cura's storage paths.
|
||||
import UM.VersionUpgradeManager #Needs to be here to prevent circular dependencies.
|
||||
|
||||
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
|
||||
{
|
||||
("quality", UM.Settings.InstanceContainer.Version): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||
("machine_stack", UM.Settings.ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"),
|
||||
("extruder_train", UM.Settings.ContainerStack.Version): (self.ResourceTypes.ExtruderStack, "application/x-uranium-extruderstack"),
|
||||
("preferences", UM.Preferences.Version): (Resources.Preferences, "application/x-uranium-preferences"),
|
||||
("user", UM.Settings.InstanceContainer.Version): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer")
|
||||
("quality", UM.Settings.InstanceContainer.InstanceContainer.Version): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||
("machine_stack", UM.Settings.ContainerStack.ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"),
|
||||
("extruder_train", UM.Settings.ContainerStack.ContainerStack.Version): (self.ResourceTypes.ExtruderStack, "application/x-uranium-extruderstack"),
|
||||
("preferences", Preferences.Version): (Resources.Preferences, "application/x-uranium-preferences"),
|
||||
("user", UM.Settings.InstanceContainer.InstanceContainer.Version): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer")
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -401,7 +419,11 @@ class CuraApplication(QtApplication):
|
|||
|
||||
@pyqtSlot(str, str)
|
||||
def setDefaultPath(self, key, default_path):
|
||||
Preferences.getInstance().setValue("local_file/%s" % key, default_path)
|
||||
Preferences.getInstance().setValue("local_file/%s" % key, QUrl(default_path).toLocalFile())
|
||||
|
||||
@classmethod
|
||||
def getStaticVersion(cls):
|
||||
return CuraVersion
|
||||
|
||||
## Handle loading of all plugin types (and the backend explicitly)
|
||||
# \sa PluginRegistery
|
||||
|
@ -421,13 +443,107 @@ class CuraApplication(QtApplication):
|
|||
|
||||
self._plugins_loaded = True
|
||||
|
||||
@classmethod
|
||||
def addCommandLineOptions(self, parser):
|
||||
super().addCommandLineOptions(parser)
|
||||
parser.add_argument("file", nargs="*", help="Files to load after starting the application.")
|
||||
parser.add_argument("--single-instance", action="store_true", default=False)
|
||||
|
||||
# Set up a local socket server which listener which coordinates single instances Curas and accepts commands.
|
||||
def _setUpSingleInstanceServer(self):
|
||||
if self.getCommandLineOption("single_instance", False):
|
||||
self.__single_instance_server = QLocalServer()
|
||||
self.__single_instance_server.newConnection.connect(self._singleInstanceServerNewConnection)
|
||||
self.__single_instance_server.listen("ultimaker-cura")
|
||||
|
||||
def _singleInstanceServerNewConnection(self):
|
||||
Logger.log("i", "New connection recevied on our single-instance server")
|
||||
remote_cura_connection = self.__single_instance_server.nextPendingConnection()
|
||||
|
||||
if remote_cura_connection is not None:
|
||||
def readCommands():
|
||||
line = remote_cura_connection.readLine()
|
||||
while len(line) != 0: # There is also a .canReadLine()
|
||||
try:
|
||||
payload = json.loads(str(line, encoding="ASCII").strip())
|
||||
command = payload["command"]
|
||||
|
||||
# Command: Remove all models from the build plate.
|
||||
if command == "clear-all":
|
||||
self.deleteAll()
|
||||
|
||||
# Command: Load a model file
|
||||
elif command == "open":
|
||||
self._openFile(payload["filePath"])
|
||||
# WARNING ^ this method is async and we really should wait until
|
||||
# the file load is complete before processing more commands.
|
||||
|
||||
# Command: Activate the window and bring it to the top.
|
||||
elif command == "focus":
|
||||
# Operating systems these days prevent windows from moving around by themselves.
|
||||
# 'alert' or flashing the icon in the taskbar is the best thing we do now.
|
||||
self.getMainWindow().alert(0)
|
||||
|
||||
# Command: Close the socket connection. We're done.
|
||||
elif command == "close-connection":
|
||||
remote_cura_connection.close()
|
||||
|
||||
else:
|
||||
Logger.log("w", "Received an unrecognized command " + str(command))
|
||||
except json.decoder.JSONDecodeError as ex:
|
||||
Logger.log("w", "Unable to parse JSON command in _singleInstanceServerNewConnection(): " + repr(ex))
|
||||
line = remote_cura_connection.readLine()
|
||||
|
||||
remote_cura_connection.readyRead.connect(readCommands)
|
||||
|
||||
## Perform any checks before creating the main application.
|
||||
#
|
||||
# This should be called directly before creating an instance of CuraApplication.
|
||||
# \returns \type{bool} True if the whole Cura app should continue running.
|
||||
@classmethod
|
||||
def preStartUp(cls):
|
||||
# Peek the arguments and look for the 'single-instance' flag.
|
||||
parser = argparse.ArgumentParser(prog="cura") # pylint: disable=bad-whitespace
|
||||
CuraApplication.addCommandLineOptions(parser)
|
||||
parsed_command_line = vars(parser.parse_args())
|
||||
|
||||
if "single_instance" in parsed_command_line and parsed_command_line["single_instance"]:
|
||||
Logger.log("i", "Checking for the presence of an ready running Cura instance.")
|
||||
single_instance_socket = QLocalSocket()
|
||||
Logger.log("d", "preStartUp(): full server name: " + single_instance_socket.fullServerName())
|
||||
single_instance_socket.connectToServer("ultimaker-cura")
|
||||
single_instance_socket.waitForConnected()
|
||||
if single_instance_socket.state() == QLocalSocket.ConnectedState:
|
||||
Logger.log("i", "Connection has been made to the single-instance Cura socket.")
|
||||
|
||||
# Protocol is one line of JSON terminated with a carriage return.
|
||||
# "command" field is required and holds the name of the command to execute.
|
||||
# Other fields depend on the command.
|
||||
|
||||
payload = {"command": "clear-all"}
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
|
||||
payload = {"command": "focus"}
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
|
||||
if len(parsed_command_line["file"]) != 0:
|
||||
for filename in parsed_command_line["file"]:
|
||||
payload = {"command": "open", "filePath": filename}
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
|
||||
payload = {"command": "close-connection"}
|
||||
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ASCII"))
|
||||
|
||||
single_instance_socket.flush()
|
||||
single_instance_socket.waitForDisconnected()
|
||||
return False
|
||||
return True
|
||||
|
||||
def run(self):
|
||||
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up scene..."))
|
||||
|
||||
self._setUpSingleInstanceServer()
|
||||
|
||||
controller = self.getController()
|
||||
|
||||
controller.setActiveView("SolidView")
|
||||
|
@ -464,9 +580,11 @@ class CuraApplication(QtApplication):
|
|||
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface..."))
|
||||
|
||||
# Initialise extruder so as to listen to global container stack changes before the first global container stack is set.
|
||||
cura.Settings.ExtruderManager.getInstance()
|
||||
qmlRegisterSingletonType(cura.Settings.MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager)
|
||||
qmlRegisterSingletonType(cura.Settings.SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager", self.getSettingInheritanceManager)
|
||||
ExtruderManager.getInstance()
|
||||
qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager)
|
||||
qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager",
|
||||
self.getSettingInheritanceManager)
|
||||
|
||||
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
|
||||
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
||||
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
||||
|
@ -486,12 +604,12 @@ class CuraApplication(QtApplication):
|
|||
|
||||
def getMachineManager(self, *args):
|
||||
if self._machine_manager is None:
|
||||
self._machine_manager = cura.Settings.MachineManager.createMachineManager()
|
||||
self._machine_manager = MachineManager.createMachineManager()
|
||||
return self._machine_manager
|
||||
|
||||
def getSettingInheritanceManager(self, *args):
|
||||
if self._setting_inheritance_manager is None:
|
||||
self._setting_inheritance_manager = cura.Settings.SettingInheritanceManager.createSettingInheritanceManager()
|
||||
self._setting_inheritance_manager = SettingInheritanceManager.createSettingInheritanceManager()
|
||||
return self._setting_inheritance_manager
|
||||
|
||||
## Get the machine action manager
|
||||
|
@ -527,23 +645,23 @@ class CuraApplication(QtApplication):
|
|||
|
||||
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type")
|
||||
|
||||
qmlRegisterType(cura.Settings.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
|
||||
qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
|
||||
|
||||
qmlRegisterType(cura.Settings.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
|
||||
qmlRegisterSingletonType(cura.Settings.ProfilesModel, "Cura", 1, 0, "ProfilesModel", cura.Settings.ProfilesModel.createProfilesModel)
|
||||
qmlRegisterType(cura.Settings.QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel")
|
||||
qmlRegisterType(cura.Settings.UserProfilesModel, "Cura", 1, 0, "UserProfilesModel")
|
||||
qmlRegisterType(cura.Settings.MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
|
||||
qmlRegisterType(cura.Settings.QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel")
|
||||
qmlRegisterType(cura.Settings.MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
|
||||
qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
|
||||
qmlRegisterSingletonType(ProfilesModel, "Cura", 1, 0, "ProfilesModel", ProfilesModel.createProfilesModel)
|
||||
qmlRegisterType(QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel")
|
||||
qmlRegisterType(UserProfilesModel, "Cura", 1, 0, "UserProfilesModel")
|
||||
qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
|
||||
qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel")
|
||||
qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
|
||||
|
||||
qmlRegisterSingletonType(cura.Settings.ContainerManager, "Cura", 1, 0, "ContainerManager", cura.Settings.ContainerManager.createContainerManager)
|
||||
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.createContainerManager)
|
||||
|
||||
# As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work.
|
||||
actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")))
|
||||
qmlRegisterSingletonType(actions_url, "Cura", 1, 0, "Actions")
|
||||
|
||||
engine.rootContext().setContextProperty("ExtruderManager", cura.Settings.ExtruderManager.getInstance())
|
||||
engine.rootContext().setContextProperty("ExtruderManager", ExtruderManager.getInstance())
|
||||
|
||||
for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles):
|
||||
type_name = os.path.splitext(os.path.basename(path))[0]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from UM.Math.Color import Color
|
||||
from UM.Application import Application
|
||||
|
||||
from typing import Any
|
||||
import numpy
|
||||
|
||||
|
||||
|
@ -198,7 +198,7 @@ class LayerPolygon:
|
|||
|
||||
return normals
|
||||
|
||||
__color_map = None
|
||||
__color_map = None # type: numpy.ndarray[Any]
|
||||
|
||||
## Gets the instance of the VersionUpgradeManager, or creates one.
|
||||
@classmethod
|
||||
|
|
|
@ -7,9 +7,9 @@ from UM.FlameProfiler import pyqtSlot
|
|||
from UM.Application import Application
|
||||
from UM.Qt.Duration import Duration
|
||||
from UM.Preferences import Preferences
|
||||
from UM.Settings import ContainerRegistry
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
import cura.Settings.ExtruderManager
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
import math
|
||||
import os.path
|
||||
|
@ -124,7 +124,7 @@ class PrintInformation(QObject):
|
|||
|
||||
material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings"))
|
||||
|
||||
extruder_stacks = list(cura.Settings.ExtruderManager.getInstance().getMachineExtruders(Application.getInstance().getGlobalContainerStack().getId()))
|
||||
extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(Application.getInstance().getGlobalContainerStack().getId()))
|
||||
for index, amount in enumerate(self._material_amounts):
|
||||
## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some
|
||||
# list comprehension filtering to solve this for us.
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.OutputDevice.OutputDevice import OutputDevice
|
||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
import UM.Settings.ContainerRegistry
|
||||
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
from enum import IntEnum # For the connection state tracking.
|
||||
from UM.Logger import Logger
|
||||
from UM.Application import Application
|
||||
from UM.Signal import signalemitter
|
||||
|
||||
i18n_catalog = i18nCatalog("cura")
|
||||
|
@ -25,7 +28,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
def __init__(self, device_id, parent = None):
|
||||
super().__init__(device_id = device_id, parent = parent)
|
||||
|
||||
self._container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
self._container_registry = ContainerRegistry.getInstance()
|
||||
self._target_bed_temperature = 0
|
||||
self._bed_temperature = 0
|
||||
self._num_extruders = 1
|
||||
|
@ -45,6 +48,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
self._job_name = ""
|
||||
self._error_text = ""
|
||||
self._accepts_commands = True
|
||||
self._preheat_bed_timeout = 900 #Default time-out for pre-heating the bed, in seconds.
|
||||
|
||||
self._printer_state = ""
|
||||
self._printer_type = "unknown"
|
||||
|
@ -161,6 +165,17 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
self._job_name = name
|
||||
self.jobNameChanged.emit()
|
||||
|
||||
## Gives a human-readable address where the device can be found.
|
||||
@pyqtProperty(str, constant = True)
|
||||
def address(self):
|
||||
Logger.log("w", "address is not implemented by this output device.")
|
||||
|
||||
## A human-readable name for the device.
|
||||
@pyqtProperty(str, constant = True)
|
||||
def name(self):
|
||||
Logger.log("w", "name is not implemented by this output device.")
|
||||
return ""
|
||||
|
||||
@pyqtProperty(str, notify = errorTextChanged)
|
||||
def errorText(self):
|
||||
return self._error_text
|
||||
|
@ -199,6 +214,13 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
self._target_bed_temperature = temperature
|
||||
self.targetBedTemperatureChanged.emit()
|
||||
|
||||
## The duration of the time-out to pre-heat the bed, in seconds.
|
||||
#
|
||||
# \return The duration of the time-out to pre-heat the bed, in seconds.
|
||||
@pyqtProperty(int)
|
||||
def preheatBedTimeout(self):
|
||||
return self._preheat_bed_timeout
|
||||
|
||||
## Time the print has been printing.
|
||||
# Note that timeTotal - timeElapsed should give time remaining.
|
||||
@pyqtProperty(float, notify = timeElapsedChanged)
|
||||
|
@ -254,6 +276,22 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
def _setTargetBedTemperature(self, temperature):
|
||||
Logger.log("w", "_setTargetBedTemperature is not implemented by this output device")
|
||||
|
||||
## Pre-heats the heated bed of the printer.
|
||||
#
|
||||
# \param temperature The temperature to heat the bed to, in degrees
|
||||
# Celsius.
|
||||
# \param duration How long the bed should stay warm, in seconds.
|
||||
@pyqtSlot(float, float)
|
||||
def preheatBed(self, temperature, duration):
|
||||
Logger.log("w", "preheatBed is not implemented by this output device.")
|
||||
|
||||
## Cancels pre-heating the heated bed of the printer.
|
||||
#
|
||||
# If the bed is not pre-heated, nothing happens.
|
||||
@pyqtSlot()
|
||||
def cancelPreheatBed(self):
|
||||
Logger.log("w", "cancelPreheatBed is not implemented by this output device.")
|
||||
|
||||
## Protected setter for the current bed temperature.
|
||||
# This simply sets the bed temperature, but ensures that a signal is emitted.
|
||||
# /param temperature temperature of the bed.
|
||||
|
@ -323,6 +361,28 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
result.append(i18n_catalog.i18nc("@item:material", "Unknown material"))
|
||||
return result
|
||||
|
||||
## List of the colours of the currently loaded materials.
|
||||
#
|
||||
# The list is in order of extruders. If there is no material in an
|
||||
# extruder, the colour is shown as transparent.
|
||||
#
|
||||
# The colours are returned in hex-format AARRGGBB or RRGGBB
|
||||
# (e.g. #800000ff for transparent blue or #00ff00 for pure green).
|
||||
@pyqtProperty("QVariantList", notify = materialIdChanged)
|
||||
def materialColors(self):
|
||||
result = []
|
||||
for material_id in self._material_ids:
|
||||
if material_id is None:
|
||||
result.append("#00000000") #No material.
|
||||
continue
|
||||
|
||||
containers = self._container_registry.findInstanceContainers(type = "material", GUID = material_id)
|
||||
if containers:
|
||||
result.append(containers[0].getMetaDataEntry("color_code"))
|
||||
else:
|
||||
result.append("#00000000") #Unknown material.
|
||||
return result
|
||||
|
||||
## Protected setter for the current material id.
|
||||
# /param index Index of the extruder
|
||||
# /param material_id id of the material
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import UM.Application
|
||||
import cura.Settings.ExtruderManager
|
||||
import UM.Settings.ContainerRegistry
|
||||
|
||||
# This collects a lot of quality and quality changes related code which was split between ContainerManager
|
||||
# and the MachineManager and really needs to usable from both.
|
||||
from typing import List
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
|
||||
class QualityManager:
|
||||
|
||||
|
@ -18,7 +22,7 @@ class QualityManager:
|
|||
QualityManager.__instance = cls()
|
||||
return QualityManager.__instance
|
||||
|
||||
__instance = None
|
||||
__instance = None # type: "QualityManager"
|
||||
|
||||
## Find a quality by name for a specific machine definition and materials.
|
||||
#
|
||||
|
@ -121,14 +125,14 @@ class QualityManager:
|
|||
#
|
||||
# \param machine_definition \type{DefinitionContainer} the machine definition.
|
||||
# \return \type{List[InstanceContainer]} the list of quality changes
|
||||
def findAllQualityChangesForMachine(self, machine_definition):
|
||||
def findAllQualityChangesForMachine(self, machine_definition: DefinitionContainer) -> List[InstanceContainer]:
|
||||
if machine_definition.getMetaDataEntry("has_machine_quality"):
|
||||
definition_id = machine_definition.getId()
|
||||
else:
|
||||
definition_id = "fdmprinter"
|
||||
|
||||
filter_dict = { "type": "quality_changes", "extruder": None, "definition": definition_id }
|
||||
quality_changes_list = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**filter_dict)
|
||||
quality_changes_list = ContainerRegistry.getInstance().findInstanceContainers(**filter_dict)
|
||||
return quality_changes_list
|
||||
|
||||
## Find all usable qualities for a machine and extruders.
|
||||
|
@ -177,7 +181,7 @@ class QualityManager:
|
|||
if base_material:
|
||||
# There is a basic material specified
|
||||
criteria = { "type": "material", "name": base_material, "definition": definition_id }
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
||||
containers = [basic_material for basic_material in containers if
|
||||
basic_material.getMetaDataEntry("variant") == material_container.getMetaDataEntry(
|
||||
"variant")]
|
||||
|
@ -191,13 +195,13 @@ class QualityManager:
|
|||
def _getFilteredContainersForStack(self, machine_definition=None, material_containers=None, **kwargs):
|
||||
# Fill in any default values.
|
||||
if machine_definition is None:
|
||||
machine_definition = UM.Application.getInstance().getGlobalContainerStack().getBottom()
|
||||
machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
|
||||
quality_definition_id = machine_definition.getMetaDataEntry("quality_definition")
|
||||
if quality_definition_id is not None:
|
||||
machine_definition = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=quality_definition_id)[0]
|
||||
machine_definition = ContainerRegistry.getInstance().findDefinitionContainers(id=quality_definition_id)[0]
|
||||
|
||||
if material_containers is None:
|
||||
active_stacks = cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
|
||||
active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
|
||||
material_containers = [stack.findContainer(type="material") for stack in active_stacks]
|
||||
|
||||
criteria = kwargs
|
||||
|
@ -225,7 +229,7 @@ class QualityManager:
|
|||
material_ids.add(basic_material.getId())
|
||||
material_ids.add(material_instance.getId())
|
||||
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
||||
|
||||
result = []
|
||||
for container in containers:
|
||||
|
@ -241,8 +245,8 @@ class QualityManager:
|
|||
# an extruder definition.
|
||||
# \return \type{DefinitionContainer} the parent machine definition. If the given machine
|
||||
# definition doesn't have a parent then it is simply returned.
|
||||
def getParentMachineDefinition(self, machine_definition):
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
def getParentMachineDefinition(self, machine_definition: DefinitionContainer) -> DefinitionContainer:
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
|
||||
machine_entry = machine_definition.getMetaDataEntry("machine")
|
||||
if machine_entry is None:
|
||||
|
@ -277,6 +281,6 @@ class QualityManager:
|
|||
# This already is a 'global' machine definition.
|
||||
return machine_definition
|
||||
else:
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
whole_machine = container_registry.findDefinitionContainers(id=machine_entry)[0]
|
||||
return whole_machine
|
||||
|
|
|
@ -8,19 +8,25 @@ from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QUrl, QVariant
|
|||
from UM.FlameProfiler import pyqtSlot
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
|
||||
import UM.PluginRegistry
|
||||
import UM.Settings
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
import UM.SaveFile
|
||||
import UM.Platform
|
||||
import UM.MimeTypeDatabase
|
||||
import UM.Logger
|
||||
|
||||
import cura.Settings
|
||||
from UM.Logger import Logger
|
||||
from UM.Application import Application
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from cura.QualityManager import QualityManager
|
||||
|
||||
from UM.MimeTypeDatabase import MimeTypeNotFoundError
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
## Manager class that contains common actions to deal with containers in Cura.
|
||||
|
@ -32,9 +38,8 @@ class ContainerManager(QObject):
|
|||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
|
||||
self._container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
self._machine_manager = UM.Application.getInstance().getMachineManager()
|
||||
|
||||
self._container_registry = ContainerRegistry.getInstance()
|
||||
self._machine_manager = Application.getInstance().getMachineManager()
|
||||
self._container_name_filters = {}
|
||||
|
||||
## Create a duplicate of the specified container
|
||||
|
@ -49,7 +54,7 @@ class ContainerManager(QObject):
|
|||
def duplicateContainer(self, container_id):
|
||||
containers = self._container_registry.findContainers(None, id = container_id)
|
||||
if not containers:
|
||||
UM.Logger.log("w", "Could duplicate container %s because it was not found.", container_id)
|
||||
Logger.log("w", "Could duplicate container %s because it was not found.", container_id)
|
||||
return ""
|
||||
|
||||
container = containers[0]
|
||||
|
@ -81,7 +86,7 @@ class ContainerManager(QObject):
|
|||
def renameContainer(self, container_id, new_id, new_name):
|
||||
containers = self._container_registry.findContainers(None, id = container_id)
|
||||
if not containers:
|
||||
UM.Logger.log("w", "Could rename container %s because it was not found.", container_id)
|
||||
Logger.log("w", "Could rename container %s because it was not found.", container_id)
|
||||
return False
|
||||
|
||||
container = containers[0]
|
||||
|
@ -109,7 +114,7 @@ class ContainerManager(QObject):
|
|||
def removeContainer(self, container_id):
|
||||
containers = self._container_registry.findContainers(None, id = container_id)
|
||||
if not containers:
|
||||
UM.Logger.log("w", "Could remove container %s because it was not found.", container_id)
|
||||
Logger.log("w", "Could remove container %s because it was not found.", container_id)
|
||||
return False
|
||||
|
||||
self._container_registry.removeContainer(containers[0].getId())
|
||||
|
@ -129,20 +134,20 @@ class ContainerManager(QObject):
|
|||
def mergeContainers(self, merge_into_id, merge_id):
|
||||
containers = self._container_registry.findContainers(None, id = merge_into_id)
|
||||
if not containers:
|
||||
UM.Logger.log("w", "Could merge into container %s because it was not found.", merge_into_id)
|
||||
Logger.log("w", "Could merge into container %s because it was not found.", merge_into_id)
|
||||
return False
|
||||
|
||||
merge_into = containers[0]
|
||||
|
||||
containers = self._container_registry.findContainers(None, id = merge_id)
|
||||
if not containers:
|
||||
UM.Logger.log("w", "Could not merge container %s because it was not found", merge_id)
|
||||
Logger.log("w", "Could not merge container %s because it was not found", merge_id)
|
||||
return False
|
||||
|
||||
merge = containers[0]
|
||||
|
||||
if not isinstance(merge, type(merge_into)):
|
||||
UM.Logger.log("w", "Cannot merge two containers of different types")
|
||||
Logger.log("w", "Cannot merge two containers of different types")
|
||||
return False
|
||||
|
||||
self._performMerge(merge_into, merge)
|
||||
|
@ -158,11 +163,11 @@ class ContainerManager(QObject):
|
|||
def clearContainer(self, container_id):
|
||||
containers = self._container_registry.findContainers(None, id = container_id)
|
||||
if not containers:
|
||||
UM.Logger.log("w", "Could clear container %s because it was not found.", container_id)
|
||||
Logger.log("w", "Could clear container %s because it was not found.", container_id)
|
||||
return False
|
||||
|
||||
if containers[0].isReadOnly():
|
||||
UM.Logger.log("w", "Cannot clear read-only container %s", container_id)
|
||||
Logger.log("w", "Cannot clear read-only container %s", container_id)
|
||||
return False
|
||||
|
||||
containers[0].clear()
|
||||
|
@ -173,7 +178,7 @@ class ContainerManager(QObject):
|
|||
def getContainerMetaDataEntry(self, container_id, entry_name):
|
||||
containers = self._container_registry.findContainers(None, id=container_id)
|
||||
if not containers:
|
||||
UM.Logger.log("w", "Could not get metadata of container %s because it was not found.", container_id)
|
||||
Logger.log("w", "Could not get metadata of container %s because it was not found.", container_id)
|
||||
return ""
|
||||
|
||||
result = containers[0].getMetaDataEntry(entry_name)
|
||||
|
@ -198,13 +203,13 @@ class ContainerManager(QObject):
|
|||
def setContainerMetaDataEntry(self, container_id, entry_name, entry_value):
|
||||
containers = self._container_registry.findContainers(None, id = container_id)
|
||||
if not containers:
|
||||
UM.Logger.log("w", "Could not set metadata of container %s because it was not found.", container_id)
|
||||
Logger.log("w", "Could not set metadata of container %s because it was not found.", container_id)
|
||||
return False
|
||||
|
||||
container = containers[0]
|
||||
|
||||
if container.isReadOnly():
|
||||
UM.Logger.log("w", "Cannot set metadata of read-only container %s.", container_id)
|
||||
Logger.log("w", "Cannot set metadata of read-only container %s.", container_id)
|
||||
return False
|
||||
|
||||
entries = entry_name.split("/")
|
||||
|
@ -232,13 +237,13 @@ class ContainerManager(QObject):
|
|||
def setContainerName(self, container_id, new_name):
|
||||
containers = self._container_registry.findContainers(None, id = container_id)
|
||||
if not containers:
|
||||
UM.Logger.log("w", "Could not set name of container %s because it was not found.", container_id)
|
||||
Logger.log("w", "Could not set name of container %s because it was not found.", container_id)
|
||||
return False
|
||||
|
||||
container = containers[0]
|
||||
|
||||
if container.isReadOnly():
|
||||
UM.Logger.log("w", "Cannot set name of read-only container %s.", container_id)
|
||||
Logger.log("w", "Cannot set name of read-only container %s.", container_id)
|
||||
return False
|
||||
|
||||
container.setName(new_name)
|
||||
|
@ -262,11 +267,11 @@ class ContainerManager(QObject):
|
|||
|
||||
@pyqtSlot(str, result = bool)
|
||||
def isContainerUsed(self, container_id):
|
||||
UM.Logger.log("d", "Checking if container %s is currently used", container_id)
|
||||
Logger.log("d", "Checking if container %s is currently used", container_id)
|
||||
containers = self._container_registry.findContainerStacks()
|
||||
for stack in containers:
|
||||
if container_id in [child.getId() for child in stack.getContainers()]:
|
||||
UM.Logger.log("d", "The container is in use by %s", stack.getId())
|
||||
Logger.log("d", "The container is in use by %s", stack.getId())
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -382,7 +387,7 @@ class ContainerManager(QObject):
|
|||
except MimeTypeNotFoundError:
|
||||
return { "status": "error", "message": "Could not determine mime type of file" }
|
||||
|
||||
container_type = UM.Settings.ContainerRegistry.getContainerForMimeType(mime_type)
|
||||
container_type = self._container_registry.getContainerForMimeType(mime_type)
|
||||
if not container_type:
|
||||
return { "status": "error", "message": "Could not find a container to handle the specified file."}
|
||||
|
||||
|
@ -411,17 +416,17 @@ class ContainerManager(QObject):
|
|||
# \return \type{bool} True if successful, False if not.
|
||||
@pyqtSlot(result = bool)
|
||||
def updateQualityChanges(self):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return False
|
||||
|
||||
self._machine_manager.blurSettings.emit()
|
||||
|
||||
for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
||||
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
||||
# Find the quality_changes container for this stack and merge the contents of the top container into it.
|
||||
quality_changes = stack.findContainer(type = "quality_changes")
|
||||
if not quality_changes or quality_changes.isReadOnly():
|
||||
UM.Logger.log("e", "Could not update quality of a nonexistant or read only quality profile in stack %s", stack.getId())
|
||||
Logger.log("e", "Could not update quality of a nonexistant or read only quality profile in stack %s", stack.getId())
|
||||
continue
|
||||
|
||||
self._performMerge(quality_changes, stack.getTop())
|
||||
|
@ -438,7 +443,7 @@ class ContainerManager(QObject):
|
|||
send_emits_containers = []
|
||||
|
||||
# Go through global and extruder stacks and clear their topmost container (the user settings).
|
||||
for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
||||
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
||||
container = stack.getTop()
|
||||
container.clear()
|
||||
send_emits_containers.append(container)
|
||||
|
@ -455,13 +460,13 @@ class ContainerManager(QObject):
|
|||
# \return \type{bool} True if the operation was successfully, False if not.
|
||||
@pyqtSlot(str, result = bool)
|
||||
def createQualityChanges(self, base_name):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return False
|
||||
|
||||
active_quality_name = self._machine_manager.activeQualityName
|
||||
if active_quality_name == "":
|
||||
UM.Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
|
||||
Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
|
||||
return False
|
||||
|
||||
self._machine_manager.blurSettings.emit()
|
||||
|
@ -470,17 +475,17 @@ class ContainerManager(QObject):
|
|||
unique_name = self._container_registry.uniqueName(base_name)
|
||||
|
||||
# Go through the active stacks and create quality_changes containers from the user containers.
|
||||
for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
||||
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
||||
user_container = stack.getTop()
|
||||
quality_container = stack.findContainer(type = "quality")
|
||||
quality_changes_container = stack.findContainer(type = "quality_changes")
|
||||
if not quality_container or not quality_changes_container:
|
||||
UM.Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
|
||||
Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
|
||||
continue
|
||||
|
||||
extruder_id = None if stack is global_stack else QualityManager.getInstance().getParentMachineDefinition(stack.getBottom()).getId()
|
||||
new_changes = self._createQualityChanges(quality_container, unique_name,
|
||||
UM.Application.getInstance().getGlobalContainerStack().getBottom(),
|
||||
Application.getInstance().getGlobalContainerStack().getBottom(),
|
||||
extruder_id)
|
||||
self._performMerge(new_changes, quality_changes_container, clear_settings = False)
|
||||
self._performMerge(new_changes, user_container)
|
||||
|
@ -502,7 +507,7 @@ class ContainerManager(QObject):
|
|||
# \return \type{bool} True if successful, False if not.
|
||||
@pyqtSlot(str, result = bool)
|
||||
def removeQualityChanges(self, quality_name):
|
||||
UM.Logger.log("d", "Attempting to remove the quality change containers with name %s", quality_name)
|
||||
Logger.log("d", "Attempting to remove the quality change containers with name %s", quality_name)
|
||||
containers_found = False
|
||||
|
||||
if not quality_name:
|
||||
|
@ -512,7 +517,7 @@ class ContainerManager(QObject):
|
|||
activate_quality = quality_name == self._machine_manager.activeQualityName
|
||||
activate_quality_type = None
|
||||
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if not global_stack or not quality_name:
|
||||
return ""
|
||||
machine_definition = global_stack.getBottom()
|
||||
|
@ -524,7 +529,7 @@ class ContainerManager(QObject):
|
|||
self._container_registry.removeContainer(container.getId())
|
||||
|
||||
if not containers_found:
|
||||
UM.Logger.log("d", "Unable to remove quality containers, as we did not find any by the name of %s", quality_name)
|
||||
Logger.log("d", "Unable to remove quality containers, as we did not find any by the name of %s", quality_name)
|
||||
|
||||
elif activate_quality:
|
||||
definition_id = "fdmprinter" if not self._machine_manager.filterQualityByMachine else self._machine_manager.activeDefinitionId
|
||||
|
@ -547,15 +552,15 @@ class ContainerManager(QObject):
|
|||
# \return True if successful, False if not.
|
||||
@pyqtSlot(str, str, result = bool)
|
||||
def renameQualityChanges(self, quality_name, new_name):
|
||||
UM.Logger.log("d", "User requested QualityChanges container rename of %s to %s", quality_name, new_name)
|
||||
Logger.log("d", "User requested QualityChanges container rename of %s to %s", quality_name, new_name)
|
||||
if not quality_name or not new_name:
|
||||
return False
|
||||
|
||||
if quality_name == new_name:
|
||||
UM.Logger.log("w", "Unable to rename %s to %s, because they are the same.", quality_name, new_name)
|
||||
Logger.log("w", "Unable to rename %s to %s, because they are the same.", quality_name, new_name)
|
||||
return True
|
||||
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return False
|
||||
|
||||
|
@ -572,7 +577,7 @@ class ContainerManager(QObject):
|
|||
container_registry.renameContainer(container.getId(), new_name, self._createUniqueId(stack_id, new_name))
|
||||
|
||||
if not containers_to_rename:
|
||||
UM.Logger.log("e", "Unable to rename %s, because we could not find the profile", quality_name)
|
||||
Logger.log("e", "Unable to rename %s, because we could not find the profile", quality_name)
|
||||
|
||||
self._machine_manager.activeQualityChanged.emit()
|
||||
return True
|
||||
|
@ -588,12 +593,12 @@ class ContainerManager(QObject):
|
|||
# \return A string containing the name of the duplicated containers, or an empty string if it failed.
|
||||
@pyqtSlot(str, str, result = str)
|
||||
def duplicateQualityOrQualityChanges(self, quality_name, base_name):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if not global_stack or not quality_name:
|
||||
return ""
|
||||
machine_definition = global_stack.getBottom()
|
||||
|
||||
active_stacks = cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
|
||||
active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
|
||||
material_containers = [stack.findContainer(type="material") for stack in active_stacks]
|
||||
|
||||
result = self._duplicateQualityOrQualityChangesForMachineType(quality_name, base_name,
|
||||
|
@ -609,16 +614,16 @@ class ContainerManager(QObject):
|
|||
# \param material_instances \type{List[InstanceContainer]}
|
||||
# \return \type{str} the name of the newly created container.
|
||||
def _duplicateQualityOrQualityChangesForMachineType(self, quality_name, base_name, machine_definition, material_instances):
|
||||
UM.Logger.log("d", "Attempting to duplicate the quality %s", quality_name)
|
||||
Logger.log("d", "Attempting to duplicate the quality %s", quality_name)
|
||||
|
||||
if base_name is None:
|
||||
base_name = quality_name
|
||||
# Try to find a Quality with the name.
|
||||
container = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_instances)
|
||||
if container:
|
||||
UM.Logger.log("d", "We found a quality to duplicate.")
|
||||
Logger.log("d", "We found a quality to duplicate.")
|
||||
return self._duplicateQualityForMachineType(container, base_name, machine_definition)
|
||||
UM.Logger.log("d", "We found a quality_changes to duplicate.")
|
||||
Logger.log("d", "We found a quality_changes to duplicate.")
|
||||
# Assume it is a quality changes.
|
||||
return self._duplicateQualityChangesForMachineType(quality_name, base_name, machine_definition)
|
||||
|
||||
|
@ -665,11 +670,11 @@ class ContainerManager(QObject):
|
|||
def duplicateMaterial(self, material_id):
|
||||
containers = self._container_registry.findInstanceContainers(id=material_id)
|
||||
if not containers:
|
||||
UM.Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", material_id)
|
||||
Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", material_id)
|
||||
return ""
|
||||
|
||||
# Ensure all settings are saved.
|
||||
UM.Application.getInstance().saveSettings()
|
||||
Application.getInstance().saveSettings()
|
||||
|
||||
# Create a new ID & container to hold the data.
|
||||
new_id = self._container_registry.uniqueName(material_id)
|
||||
|
@ -692,7 +697,7 @@ class ContainerManager(QObject):
|
|||
ContainerManager.__instance = cls()
|
||||
return ContainerManager.__instance
|
||||
|
||||
__instance = None
|
||||
__instance = None # type: "ContainerManager"
|
||||
|
||||
# Factory function, used by QML
|
||||
@staticmethod
|
||||
|
@ -713,14 +718,14 @@ class ContainerManager(QObject):
|
|||
|
||||
def _updateContainerNameFilters(self):
|
||||
self._container_name_filters = {}
|
||||
for plugin_id, container_type in UM.Settings.ContainerRegistry.getContainerTypes():
|
||||
for plugin_id, container_type in self._container_registry.getContainerTypes():
|
||||
# Ignore default container types since those are not plugins
|
||||
if container_type in (UM.Settings.InstanceContainer, UM.Settings.ContainerStack, UM.Settings.DefinitionContainer):
|
||||
if container_type in (InstanceContainer, ContainerStack, DefinitionContainer):
|
||||
continue
|
||||
|
||||
serialize_type = ""
|
||||
try:
|
||||
plugin_metadata = UM.PluginRegistry.getInstance().getMetaData(plugin_id)
|
||||
plugin_metadata = PluginRegistry.getInstance().getMetaData(plugin_id)
|
||||
if plugin_metadata:
|
||||
serialize_type = plugin_metadata["settings_container"]["type"]
|
||||
else:
|
||||
|
@ -728,7 +733,7 @@ class ContainerManager(QObject):
|
|||
except KeyError as e:
|
||||
continue
|
||||
|
||||
mime_type = UM.Settings.ContainerRegistry.getMimeTypeForContainer(container_type)
|
||||
mime_type = self._container_registry.getMimeTypeForContainer(container_type)
|
||||
|
||||
entry = {
|
||||
"type": serialize_type,
|
||||
|
@ -791,7 +796,7 @@ class ContainerManager(QObject):
|
|||
base_id = machine_definition.getId() if extruder_id is None else extruder_id
|
||||
|
||||
# Create a new quality_changes container for the quality.
|
||||
quality_changes = UM.Settings.InstanceContainer(self._createUniqueId(base_id, new_name))
|
||||
quality_changes = InstanceContainer(self._createUniqueId(base_id, new_name))
|
||||
quality_changes.setName(new_name)
|
||||
quality_changes.addMetaDataEntry("type", "quality_changes")
|
||||
quality_changes.addMetaDataEntry("quality_type", quality_container.getMetaDataEntry("quality_type"))
|
||||
|
@ -826,7 +831,7 @@ class ContainerManager(QObject):
|
|||
if not path.endswith(".curaprofile"):
|
||||
continue
|
||||
|
||||
single_result = UM.Settings.ContainerRegistry.getInstance().importProfile(path)
|
||||
single_result = self._container_registry.importProfile(path)
|
||||
if single_result["status"] == "error":
|
||||
status = "error"
|
||||
results[single_result["status"]].append(single_result["message"])
|
||||
|
@ -843,7 +848,7 @@ class ContainerManager(QObject):
|
|||
path = file_url.toLocalFile()
|
||||
if not path:
|
||||
return
|
||||
return UM.Settings.ContainerRegistry.getInstance().importProfile(path)
|
||||
return self._container_registry.importProfile(path)
|
||||
|
||||
@pyqtSlot("QVariantList", QUrl, str)
|
||||
def exportProfile(self, instance_id, file_url, file_type):
|
||||
|
@ -852,4 +857,4 @@ class ContainerManager(QObject):
|
|||
path = file_url.toLocalFile()
|
||||
if not path:
|
||||
return
|
||||
UM.Settings.ContainerRegistry.getInstance().exportProfile(instance_id, path, file_type)
|
||||
self._container_registry.exportProfile(instance_id, path, file_type)
|
||||
|
|
|
@ -4,13 +4,16 @@
|
|||
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant #For communicating data and events to Qt.
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
|
||||
import UM.Application #To get the global container stack to find the current machine.
|
||||
import UM.Logger
|
||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator #To find which extruders are used in the scene.
|
||||
from UM.Scene.SceneNode import SceneNode #To find which extruders are used in the scene.
|
||||
import UM.Settings.ContainerRegistry #Finding containers by ID.
|
||||
import UM.Settings.SettingFunction
|
||||
|
||||
from UM.Application import Application #To get the global container stack to find the current machine.
|
||||
from UM.Logger import Logger
|
||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers by ID.
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from UM.Settings.SettingFunction import SettingFunction
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
from typing import Optional
|
||||
|
||||
## Manages all existing extruder stacks.
|
||||
#
|
||||
|
@ -31,7 +34,7 @@ class ExtruderManager(QObject):
|
|||
super().__init__(parent)
|
||||
self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs.
|
||||
self._active_extruder_index = 0
|
||||
UM.Application.getInstance().globalContainerStackChanged.connect(self.__globalContainerStackChanged)
|
||||
Application.getInstance().globalContainerStackChanged.connect(self.__globalContainerStackChanged)
|
||||
self._global_container_stack_definition_id = None
|
||||
self._addCurrentMachineExtruders()
|
||||
|
||||
|
@ -42,35 +45,35 @@ class ExtruderManager(QObject):
|
|||
#
|
||||
# \return The unique ID of the currently active extruder stack.
|
||||
@pyqtProperty(str, notify = activeExtruderChanged)
|
||||
def activeExtruderStackId(self):
|
||||
if not UM.Application.getInstance().getGlobalContainerStack():
|
||||
def activeExtruderStackId(self) -> Optional[str]:
|
||||
if not Application.getInstance().getGlobalContainerStack():
|
||||
return None # No active machine, so no active extruder.
|
||||
try:
|
||||
return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId()
|
||||
return self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId()
|
||||
except KeyError: # Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong.
|
||||
return None
|
||||
|
||||
## Return extruder count according to extruder trains.
|
||||
@pyqtProperty(int, notify = extrudersChanged)
|
||||
def extruderCount(self):
|
||||
if not UM.Application.getInstance().getGlobalContainerStack():
|
||||
if not Application.getInstance().getGlobalContainerStack():
|
||||
return 0 # No active machine, so no extruders.
|
||||
try:
|
||||
return len(self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()])
|
||||
return len(self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()])
|
||||
except KeyError:
|
||||
return 0
|
||||
|
||||
@pyqtProperty("QVariantMap", notify=extrudersChanged)
|
||||
def extruderIds(self):
|
||||
map = {}
|
||||
for position in self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()]:
|
||||
map[position] = self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][position].getId()
|
||||
for position in self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()]:
|
||||
map[position] = self._extruder_trains[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]
|
||||
def getQualityChangesIdByExtruderStackId(self, id: str) -> str:
|
||||
for position in self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()]:
|
||||
extruder = self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][position]
|
||||
if extruder.getId() == id:
|
||||
return extruder.findContainer(type = "quality_changes").getId()
|
||||
|
||||
|
@ -87,7 +90,7 @@ class ExtruderManager(QObject):
|
|||
#
|
||||
# \return The extruder manager.
|
||||
@classmethod
|
||||
def getInstance(cls):
|
||||
def getInstance(cls) -> "ExtruderManager":
|
||||
if not cls.__instance:
|
||||
cls.__instance = ExtruderManager()
|
||||
return cls.__instance
|
||||
|
@ -96,16 +99,27 @@ class ExtruderManager(QObject):
|
|||
#
|
||||
# \param index The index of the new active extruder.
|
||||
@pyqtSlot(int)
|
||||
def setActiveExtruderIndex(self, index):
|
||||
def setActiveExtruderIndex(self, index: int) -> None:
|
||||
self._active_extruder_index = index
|
||||
self.activeExtruderChanged.emit()
|
||||
|
||||
@pyqtProperty(int, notify = activeExtruderChanged)
|
||||
def activeExtruderIndex(self):
|
||||
def activeExtruderIndex(self) -> int:
|
||||
return self._active_extruder_index
|
||||
|
||||
def getActiveExtruderStack(self):
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
## Gets the extruder name of an extruder of the currently active machine.
|
||||
#
|
||||
# \param index The index of the extruder whose name to get.
|
||||
@pyqtSlot(int, result = str)
|
||||
def getExtruderName(self, index):
|
||||
try:
|
||||
return list(self.getActiveExtruderStacks())[index].getName()
|
||||
except IndexError:
|
||||
return ""
|
||||
|
||||
def getActiveExtruderStack(self) -> ContainerStack:
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
if global_container_stack:
|
||||
if global_container_stack.getId() in self._extruder_trains:
|
||||
if str(self._active_extruder_index) in self._extruder_trains[global_container_stack.getId()]:
|
||||
|
@ -114,7 +128,7 @@ class ExtruderManager(QObject):
|
|||
|
||||
## Get an extruder stack by index
|
||||
def getExtruderStack(self, index):
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
if global_container_stack.getId() in self._extruder_trains:
|
||||
if str(index) in self._extruder_trains[global_container_stack.getId()]:
|
||||
|
@ -126,19 +140,19 @@ class ExtruderManager(QObject):
|
|||
#
|
||||
# \param machine_definition The machine definition to add the extruders for.
|
||||
# \param machine_id The machine_id to add the extruders for.
|
||||
def addMachineExtruders(self, machine_definition, machine_id):
|
||||
def addMachineExtruders(self, machine_definition: DefinitionContainer, machine_id: str) -> None:
|
||||
changed = False
|
||||
machine_definition_id = machine_definition.getId()
|
||||
if machine_id not in self._extruder_trains:
|
||||
self._extruder_trains[machine_id] = { }
|
||||
changed = True
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
if container_registry:
|
||||
# Add the extruder trains that don't exist yet.
|
||||
for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition_id):
|
||||
position = extruder_definition.getMetaDataEntry("position", None)
|
||||
if not position:
|
||||
UM.Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId())
|
||||
Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId())
|
||||
if not container_registry.findContainerStacks(machine = machine_id, position = position): # Doesn't exist yet.
|
||||
self.createExtruderTrain(extruder_definition, machine_definition, position, machine_id)
|
||||
changed = True
|
||||
|
@ -149,7 +163,7 @@ class ExtruderManager(QObject):
|
|||
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train
|
||||
|
||||
# regardless of what the next stack is, we have to set it again, because of signal routing.
|
||||
extruder_train.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
|
||||
extruder_train.setNextStack(Application.getInstance().getGlobalContainerStack())
|
||||
changed = True
|
||||
if changed:
|
||||
self.extrudersChanged.emit(machine_id)
|
||||
|
@ -178,14 +192,15 @@ class ExtruderManager(QObject):
|
|||
# \param machine_definition The machine that the extruder train belongs to.
|
||||
# \param position The position of this extruder train in the extruder slots of the machine.
|
||||
# \param machine_id The id of the "global" stack this extruder is linked to.
|
||||
def createExtruderTrain(self, extruder_definition, machine_definition, position, machine_id):
|
||||
def createExtruderTrain(self, extruder_definition: DefinitionContainer, machine_definition: DefinitionContainer,
|
||||
position, machine_id: str) -> None:
|
||||
# Cache some things.
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
machine_definition_id = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(machine_definition)
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
machine_definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(machine_definition)
|
||||
|
||||
# Create a container stack for this extruder.
|
||||
extruder_stack_id = container_registry.uniqueName(extruder_definition.getId())
|
||||
container_stack = UM.Settings.ContainerStack(extruder_stack_id)
|
||||
container_stack = ContainerStack(extruder_stack_id)
|
||||
container_stack.setName(extruder_definition.getName()) # Take over the display name to display the stack with.
|
||||
container_stack.addMetaDataEntry("type", "extruder_train")
|
||||
container_stack.addMetaDataEntry("machine", machine_id)
|
||||
|
@ -205,7 +220,7 @@ class ExtruderManager(QObject):
|
|||
if len(preferred_variants) >= 1:
|
||||
variant = preferred_variants[0]
|
||||
else:
|
||||
UM.Logger.log("w", "The preferred variant \"%s\" of machine %s doesn't exist or is not a variant profile.", preferred_variant_id, machine_id)
|
||||
Logger.log("w", "The preferred variant \"%s\" of machine %s doesn't exist or is not a variant profile.", preferred_variant_id, machine_id)
|
||||
# And leave it at the default variant.
|
||||
container_stack.addContainer(variant)
|
||||
|
||||
|
@ -235,7 +250,7 @@ class ExtruderManager(QObject):
|
|||
if len(preferred_materials) >= 1:
|
||||
material = preferred_materials[0]
|
||||
else:
|
||||
UM.Logger.log("w", "The preferred material \"%s\" of machine %s doesn't exist or is not a material profile.", preferred_material_id, machine_id)
|
||||
Logger.log("w", "The preferred material \"%s\" of machine %s doesn't exist or is not a material profile.", preferred_material_id, machine_id)
|
||||
# And leave it at the default material.
|
||||
container_stack.addContainer(material)
|
||||
|
||||
|
@ -254,11 +269,11 @@ class ExtruderManager(QObject):
|
|||
if preferred_quality:
|
||||
search_criteria["id"] = preferred_quality
|
||||
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
if not containers and preferred_quality:
|
||||
UM.Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality, machine_id)
|
||||
Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality, machine_id)
|
||||
search_criteria.pop("id", None)
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
if containers:
|
||||
quality = containers[0]
|
||||
|
||||
|
@ -271,7 +286,7 @@ class ExtruderManager(QObject):
|
|||
if user_profile: # There was already a user profile, loaded from settings.
|
||||
user_profile = user_profile[0]
|
||||
else:
|
||||
user_profile = UM.Settings.InstanceContainer(extruder_stack_id + "_current_settings") # Add an empty user profile.
|
||||
user_profile = InstanceContainer(extruder_stack_id + "_current_settings") # Add an empty user profile.
|
||||
user_profile.addMetaDataEntry("type", "user")
|
||||
user_profile.addMetaDataEntry("extruder", extruder_stack_id)
|
||||
user_profile.setDefinition(machine_definition)
|
||||
|
@ -279,7 +294,7 @@ class ExtruderManager(QObject):
|
|||
container_stack.addContainer(user_profile)
|
||||
|
||||
# regardless of what the next stack is, we have to set it again, because of signal routing.
|
||||
container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
|
||||
container_stack.setNextStack(Application.getInstance().getGlobalContainerStack())
|
||||
|
||||
container_registry.addContainer(container_stack)
|
||||
|
||||
|
@ -292,14 +307,14 @@ class ExtruderManager(QObject):
|
|||
# \param property \type{str} The property to get.
|
||||
# \return \type{List} the list of results
|
||||
def getAllExtruderSettings(self, setting_key, property):
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack.getProperty("machine_extruder_count", "value") <= 1:
|
||||
return [global_container_stack.getProperty(setting_key, property)]
|
||||
|
||||
result = []
|
||||
for index in self.extruderIds:
|
||||
extruder_stack_id = self.extruderIds[str(index)]
|
||||
stack = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||
result.append(stack.getProperty(setting_key, property))
|
||||
return result
|
||||
|
||||
|
@ -314,8 +329,8 @@ class ExtruderManager(QObject):
|
|||
#
|
||||
# \return A list of extruder stacks.
|
||||
def getUsedExtruderStacks(self):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
|
||||
if global_stack.getProperty("machine_extruder_count", "value") <= 1: #For single extrusion.
|
||||
return [global_stack]
|
||||
|
@ -325,7 +340,7 @@ class ExtruderManager(QObject):
|
|||
#Get the extruders of all meshes in the scene.
|
||||
support_enabled = False
|
||||
support_interface_enabled = False
|
||||
scene_root = UM.Application.getInstance().getController().getScene().getRoot()
|
||||
scene_root = Application.getInstance().getController().getScene().getRoot()
|
||||
meshes = [node for node in DepthFirstIterator(scene_root) if type(node) is SceneNode and node.isSelectable()] #Only use the nodes that will be printed.
|
||||
for mesh in meshes:
|
||||
extruder_stack_id = mesh.callDecoration("getActiveExtruder")
|
||||
|
@ -356,7 +371,7 @@ class ExtruderManager(QObject):
|
|||
try:
|
||||
return [container_registry.findContainerStacks(id = stack_id)[0] for stack_id in used_extruder_stack_ids]
|
||||
except IndexError: # One or more of the extruders was not found.
|
||||
UM.Logger.log("e", "Unable to find one or more of the extruders in %s", used_extruder_stack_ids)
|
||||
Logger.log("e", "Unable to find one or more of the extruders in %s", used_extruder_stack_ids)
|
||||
return []
|
||||
|
||||
## Removes the container stack and user profile for the extruders for a specific machine.
|
||||
|
@ -364,27 +379,26 @@ class ExtruderManager(QObject):
|
|||
# \param machine_id The machine to remove the extruders for.
|
||||
def removeMachineExtruders(self, machine_id):
|
||||
for extruder in self.getMachineExtruders(machine_id):
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "user", extruder = extruder.getId())
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "user", extruder = extruder.getId())
|
||||
for container in containers:
|
||||
UM.Settings.ContainerRegistry.getInstance().removeContainer(container.getId())
|
||||
UM.Settings.ContainerRegistry.getInstance().removeContainer(extruder.getId())
|
||||
ContainerRegistry.getInstance().removeContainer(container.getId())
|
||||
ContainerRegistry.getInstance().removeContainer(extruder.getId())
|
||||
|
||||
## Returns extruders for a specific machine.
|
||||
#
|
||||
# \param machine_id The machine to get the extruders of.
|
||||
def getMachineExtruders(self, machine_id):
|
||||
if machine_id not in self._extruder_trains:
|
||||
UM.Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_id)
|
||||
return
|
||||
for name in self._extruder_trains[machine_id]:
|
||||
yield self._extruder_trains[machine_id][name]
|
||||
Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_id)
|
||||
return []
|
||||
return [self._extruder_trains[machine_id][name] for name in self._extruder_trains[machine_id]]
|
||||
|
||||
## Returns a list containing the global stack and active extruder stacks.
|
||||
#
|
||||
# The first element is the global container stack, followed by any extruder stacks.
|
||||
# \return \type{List[ContainerStack]}
|
||||
def getActiveGlobalAndExtruderStacks(self):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return None
|
||||
|
||||
|
@ -396,7 +410,7 @@ class ExtruderManager(QObject):
|
|||
#
|
||||
# \return \type{List[ContainerStack]} a list of
|
||||
def getActiveExtruderStacks(self):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
result = []
|
||||
if global_stack:
|
||||
|
@ -404,17 +418,17 @@ class ExtruderManager(QObject):
|
|||
result.append(self._extruder_trains[global_stack.getId()][extruder])
|
||||
return result
|
||||
|
||||
def __globalContainerStackChanged(self):
|
||||
def __globalContainerStackChanged(self) -> None:
|
||||
self._addCurrentMachineExtruders()
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack and global_container_stack.getBottom() and global_container_stack.getBottom().getId() != self._global_container_stack_definition_id:
|
||||
self._global_container_stack_definition_id = global_container_stack.getBottom().getId()
|
||||
self.globalContainerStackDefinitionChanged.emit()
|
||||
self.activeExtruderChanged.emit()
|
||||
|
||||
## Adds the extruders of the currently active machine.
|
||||
def _addCurrentMachineExtruders(self):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
def _addCurrentMachineExtruders(self) -> None:
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_stack and global_stack.getBottom():
|
||||
self.addMachineExtruders(global_stack.getBottom(), global_stack.getId())
|
||||
|
||||
|
@ -428,7 +442,7 @@ class ExtruderManager(QObject):
|
|||
# If no extruder has the value, the list will contain the global value.
|
||||
@staticmethod
|
||||
def getExtruderValues(key):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
result = []
|
||||
for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
|
||||
|
@ -437,7 +451,7 @@ class ExtruderManager(QObject):
|
|||
if value is None:
|
||||
continue
|
||||
|
||||
if isinstance(value, UM.Settings.SettingFunction):
|
||||
if isinstance(value, SettingFunction):
|
||||
value = value(extruder)
|
||||
|
||||
result.append(value)
|
||||
|
@ -473,10 +487,10 @@ class ExtruderManager(QObject):
|
|||
|
||||
if extruder:
|
||||
value = extruder.getRawProperty(key, "value")
|
||||
if isinstance(value, UM.Settings.SettingFunction):
|
||||
if isinstance(value, SettingFunction):
|
||||
value = value(extruder)
|
||||
else: #Just a value from global.
|
||||
value = UM.Application.getInstance().getGlobalContainerStack().getProperty(key, "value")
|
||||
value = Application.getInstance().getGlobalContainerStack().getProperty(key, "value")
|
||||
|
||||
return value
|
||||
|
||||
|
@ -489,7 +503,7 @@ class ExtruderManager(QObject):
|
|||
# \return The effective value
|
||||
@staticmethod
|
||||
def getResolveOrValue(key):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
resolved_value = global_stack.getProperty(key, "resolve")
|
||||
if resolved_value is not None:
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
|
||||
|
||||
import UM.Qt.ListModel
|
||||
from UM.Application import Application
|
||||
|
||||
from . import ExtruderManager
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
## Model that holds extruders.
|
||||
#
|
||||
|
@ -55,7 +56,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
|||
self._active_extruder_stack = None
|
||||
|
||||
#Listen to changes.
|
||||
UM.Application.getInstance().globalContainerStackChanged.connect(self._updateExtruders)
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._updateExtruders)
|
||||
manager = ExtruderManager.getInstance()
|
||||
|
||||
self._updateExtruders()
|
||||
|
@ -105,8 +106,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
|||
|
||||
def _onExtruderStackContainersChanged(self, container):
|
||||
# The ExtrudersModel needs to be updated when the material-name or -color changes, because the user identifies extruders by material-name
|
||||
if container.getMetaDataEntry("type") == "material":
|
||||
self._updateExtruders()
|
||||
self._updateExtruders()
|
||||
|
||||
modelChanged = pyqtSignal()
|
||||
|
||||
|
@ -121,7 +121,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
|||
|
||||
items = []
|
||||
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
if self._add_global:
|
||||
material = global_container_stack.findContainer({ "type": "material" })
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
from typing import Union
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
|
@ -11,11 +12,17 @@ from UM.Preferences import Preferences
|
|||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
|
||||
import UM.Settings
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from UM.Settings.SettingDefinition import SettingDefinition
|
||||
from UM.Settings.SettingFunction import SettingFunction
|
||||
from UM.Settings.Validator import ValidatorState
|
||||
from UM.Signal import postponeSignals
|
||||
|
||||
from cura.QualityManager import QualityManager
|
||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||
from . import ExtruderManager
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
@ -26,8 +33,8 @@ class MachineManager(QObject):
|
|||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
|
||||
self._active_container_stack = None
|
||||
self._global_container_stack = None
|
||||
self._active_container_stack = None # type: ContainerStack
|
||||
self._global_container_stack = None # type: ContainerStack
|
||||
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
|
||||
## When the global container is changed, active material probably needs to be updated.
|
||||
|
@ -36,10 +43,10 @@ class MachineManager(QObject):
|
|||
self.globalContainerChanged.connect(self.activeQualityChanged)
|
||||
|
||||
self._stacks_have_errors = None
|
||||
self._empty_variant_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id="empty_variant")[0]
|
||||
self._empty_material_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id="empty_material")[0]
|
||||
self._empty_quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id="empty_quality")[0]
|
||||
self._empty_quality_changes_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id="empty_quality_changes")[0]
|
||||
self._empty_variant_container = ContainerRegistry.getInstance().findInstanceContainers(id="empty_variant")[0]
|
||||
self._empty_material_container = ContainerRegistry.getInstance().findInstanceContainers(id="empty_material")[0]
|
||||
self._empty_quality_container = ContainerRegistry.getInstance().findInstanceContainers(id="empty_quality")[0]
|
||||
self._empty_quality_changes_container = ContainerRegistry.getInstance().findInstanceContainers(id="empty_quality_changes")[0]
|
||||
self._onGlobalContainerChanged()
|
||||
|
||||
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged)
|
||||
|
@ -91,7 +98,7 @@ class MachineManager(QObject):
|
|||
|
||||
outputDevicesChanged = pyqtSignal()
|
||||
|
||||
def _onOutputDevicesChanged(self):
|
||||
def _onOutputDevicesChanged(self) -> None:
|
||||
for printer_output_device in self._printer_output_devices:
|
||||
printer_output_device.hotendIdChanged.disconnect(self._onHotendIdChanged)
|
||||
printer_output_device.materialIdChanged.disconnect(self._onMaterialIdChanged)
|
||||
|
@ -112,16 +119,17 @@ class MachineManager(QObject):
|
|||
|
||||
@pyqtProperty(int, constant=True)
|
||||
def totalNumberOfSettings(self):
|
||||
return len(UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id="fdmprinter")[0].getAllKeys())
|
||||
return len(ContainerRegistry.getInstance().findDefinitionContainers(id="fdmprinter")[0].getAllKeys())
|
||||
|
||||
def _onHotendIdChanged(self, index, hotend_id):
|
||||
def _onHotendIdChanged(self, index: Union[str, int], hotend_id: str) -> None:
|
||||
if not self._global_container_stack:
|
||||
return
|
||||
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type="variant", definition=self._global_container_stack.getBottom().getId(), name=hotend_id)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type="variant", definition=self._global_container_stack.getBottom().getId(), name=hotend_id)
|
||||
if containers: # New material ID is known
|
||||
extruder_manager = ExtruderManager.getInstance()
|
||||
extruders = list(extruder_manager.getMachineExtruders(self.activeMachineId))
|
||||
machine_id = self.activeMachineId
|
||||
extruders = extruder_manager.getMachineExtruders(machine_id)
|
||||
matching_extruder = None
|
||||
for extruder in extruders:
|
||||
if str(index) == extruder.getMetaDataEntry("position"):
|
||||
|
@ -142,7 +150,7 @@ class MachineManager(QObject):
|
|||
if self._global_container_stack.getMetaDataEntry("has_machine_materials", False):
|
||||
definition_id = self.activeQualityDefinitionId
|
||||
extruder_manager = ExtruderManager.getInstance()
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition_id, GUID = material_id)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition_id, GUID = material_id)
|
||||
if containers: # New material ID is known
|
||||
extruders = list(extruder_manager.getMachineExtruders(self.activeMachineId))
|
||||
matching_extruder = None
|
||||
|
@ -220,6 +228,11 @@ class MachineManager(QObject):
|
|||
quality = self._global_container_stack.findContainer({"type": "quality"})
|
||||
quality.nameChanged.disconnect(self._onQualityNameChanged)
|
||||
|
||||
if self._global_container_stack.getProperty("machine_extruder_count", "value") > 1:
|
||||
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||
extruder_stack.propertyChanged.disconnect(self._onPropertyChanged)
|
||||
extruder_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
|
||||
|
||||
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
self._active_container_stack = self._global_container_stack
|
||||
|
||||
|
@ -243,6 +256,10 @@ class MachineManager(QObject):
|
|||
if global_material != self._empty_material_container:
|
||||
self._global_container_stack.replaceContainer(self._global_container_stack.getContainerIndex(global_material), self._empty_material_container)
|
||||
|
||||
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks(): #Listen for changes on all extruder stacks.
|
||||
extruder_stack.propertyChanged.connect(self._onPropertyChanged)
|
||||
extruder_stack.containersChanged.connect(self._onInstanceContainersChanged)
|
||||
|
||||
else:
|
||||
material = self._global_container_stack.findContainer({"type": "material"})
|
||||
material.nameChanged.connect(self._onMaterialNameChanged)
|
||||
|
@ -263,14 +280,8 @@ class MachineManager(QObject):
|
|||
self.blurSettings.emit() # Ensure no-one has focus.
|
||||
old_active_container_stack = self._active_container_stack
|
||||
|
||||
if self._active_container_stack and self._active_container_stack != self._global_container_stack:
|
||||
self._active_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
|
||||
self._active_container_stack.propertyChanged.disconnect(self._onPropertyChanged)
|
||||
self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack()
|
||||
if self._active_container_stack:
|
||||
self._active_container_stack.containersChanged.connect(self._onInstanceContainersChanged)
|
||||
self._active_container_stack.propertyChanged.connect(self._onPropertyChanged)
|
||||
else:
|
||||
if not self._active_container_stack:
|
||||
self._active_container_stack = self._global_container_stack
|
||||
|
||||
self._updateStacksHaveErrors()
|
||||
|
@ -282,13 +293,10 @@ class MachineManager(QObject):
|
|||
|
||||
def _onInstanceContainersChanged(self, container):
|
||||
container_type = container.getMetaDataEntry("type")
|
||||
|
||||
if container_type == "material":
|
||||
self.activeMaterialChanged.emit()
|
||||
elif container_type == "variant":
|
||||
self.activeVariantChanged.emit()
|
||||
elif container_type == "quality":
|
||||
self.activeQualityChanged.emit()
|
||||
|
||||
self.activeVariantChanged.emit()
|
||||
self.activeMaterialChanged.emit()
|
||||
self.activeQualityChanged.emit()
|
||||
|
||||
self._updateStacksHaveErrors()
|
||||
|
||||
|
@ -297,24 +305,29 @@ class MachineManager(QObject):
|
|||
# Notify UI items, such as the "changed" star in profile pull down menu.
|
||||
self.activeStackValueChanged.emit()
|
||||
|
||||
if property_name == "validationState":
|
||||
elif property_name == "validationState":
|
||||
if not self._stacks_have_errors:
|
||||
# fast update, we only have to look at the current changed property
|
||||
if self._active_container_stack.getProperty(key, "settable_per_extruder"):
|
||||
changed_validation_state = self._active_container_stack.getProperty(key, property_name)
|
||||
if self._global_container_stack.getProperty("machine_extruder_count", "value") > 1 and self._active_container_stack.getProperty(key, "settable_per_extruder"):
|
||||
extruder_index = int(self._active_container_stack.getProperty(key, "limit_to_extruder"))
|
||||
if extruder_index >= 0: #We have to look up the value from a different extruder.
|
||||
stack = ExtruderManager.getInstance().getExtruderStack(str(extruder_index))
|
||||
else:
|
||||
stack = self._active_container_stack
|
||||
else:
|
||||
changed_validation_state = self._global_container_stack.getProperty(key, property_name)
|
||||
stack = self._global_container_stack
|
||||
changed_validation_state = stack.getProperty(key, property_name)
|
||||
|
||||
if changed_validation_state is None:
|
||||
# Setting is not validated. This can happen if there is only a setting definition.
|
||||
# We do need to validate it, because a setting defintions value can be set by a function, which could
|
||||
# be an invalid setting.
|
||||
definition = self._active_container_stack.getSettingDefinition(key)
|
||||
validator_type = UM.Settings.SettingDefinition.getValidatorForType(definition.type)
|
||||
validator_type = SettingDefinition.getValidatorForType(definition.type)
|
||||
if validator_type:
|
||||
validator = validator_type(key)
|
||||
changed_validation_state = validator(self._active_container_stack)
|
||||
if changed_validation_state in (UM.Settings.ValidatorState.Exception, UM.Settings.ValidatorState.MaximumError, UM.Settings.ValidatorState.MinimumError):
|
||||
if changed_validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
|
||||
self._stacks_have_errors = True
|
||||
self.stacksValidationChanged.emit()
|
||||
else:
|
||||
|
@ -322,20 +335,20 @@ class MachineManager(QObject):
|
|||
self._updateStacksHaveErrors()
|
||||
|
||||
@pyqtSlot(str)
|
||||
def setActiveMachine(self, stack_id):
|
||||
def setActiveMachine(self, stack_id: str) -> None:
|
||||
self.blurSettings.emit() # Ensure no-one has focus.
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = stack_id)
|
||||
containers = ContainerRegistry.getInstance().findContainerStacks(id = stack_id)
|
||||
if containers:
|
||||
Application.getInstance().setGlobalContainerStack(containers[0])
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
def addMachine(self, name, definition_id):
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
def addMachine(self, name: str, definition_id: str) -> None:
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
definitions = container_registry.findDefinitionContainers(id = definition_id)
|
||||
if definitions:
|
||||
definition = definitions[0]
|
||||
name = self._createUniqueName("machine", "", name, definition.getName())
|
||||
new_global_stack = UM.Settings.ContainerStack(name)
|
||||
new_global_stack = ContainerStack(name)
|
||||
new_global_stack.addMetaDataEntry("type", "machine")
|
||||
container_registry.addContainer(new_global_stack)
|
||||
|
||||
|
@ -343,7 +356,7 @@ class MachineManager(QObject):
|
|||
material_instance_container = self._updateMaterialContainer(definition, variant_instance_container)
|
||||
quality_instance_container = self._updateQualityContainer(definition, variant_instance_container, material_instance_container)
|
||||
|
||||
current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings")
|
||||
current_settings_instance_container = InstanceContainer(name + "_current_settings")
|
||||
current_settings_instance_container.addMetaDataEntry("machine", name)
|
||||
current_settings_instance_container.addMetaDataEntry("type", "user")
|
||||
current_settings_instance_container.setDefinition(definitions[0])
|
||||
|
@ -371,17 +384,16 @@ class MachineManager(QObject):
|
|||
# \param new_name \type{string} Base name, which may not be unique
|
||||
# \param fallback_name \type{string} Name to use when (stripped) new_name is empty
|
||||
# \return \type{string} Name that is unique for the specified type and name/id
|
||||
def _createUniqueName(self, container_type, current_name, new_name, fallback_name):
|
||||
return UM.Settings.ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name)
|
||||
def _createUniqueName(self, container_type: str, current_name: str, new_name: str, fallback_name: str) -> str:
|
||||
return ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name)
|
||||
|
||||
def _checkStacksHaveErrors(self):
|
||||
if self._global_container_stack is not None and self._global_container_stack.hasErrors():
|
||||
return True
|
||||
|
||||
if self._global_container_stack is None:
|
||||
if self._global_container_stack is None: #No active machine.
|
||||
return False
|
||||
stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
|
||||
for stack in stacks:
|
||||
|
||||
if self._global_container_stack.hasErrors():
|
||||
return True
|
||||
for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()):
|
||||
if stack.hasErrors():
|
||||
return True
|
||||
|
||||
|
@ -463,35 +475,35 @@ class MachineManager(QObject):
|
|||
return bool(self._stacks_have_errors)
|
||||
|
||||
@pyqtProperty(str, notify = activeStackChanged)
|
||||
def activeUserProfileId(self):
|
||||
def activeUserProfileId(self) -> str:
|
||||
if self._active_container_stack:
|
||||
return self._active_container_stack.getTop().getId()
|
||||
|
||||
return ""
|
||||
|
||||
@pyqtProperty(str, notify = globalContainerChanged)
|
||||
def activeMachineName(self):
|
||||
def activeMachineName(self) -> str:
|
||||
if self._global_container_stack:
|
||||
return self._global_container_stack.getName()
|
||||
|
||||
return ""
|
||||
|
||||
@pyqtProperty(str, notify = globalContainerChanged)
|
||||
def activeMachineId(self):
|
||||
def activeMachineId(self) -> str:
|
||||
if self._global_container_stack:
|
||||
return self._global_container_stack.getId()
|
||||
|
||||
return ""
|
||||
|
||||
@pyqtProperty(str, notify = activeStackChanged)
|
||||
def activeStackId(self):
|
||||
def activeStackId(self) -> str:
|
||||
if self._active_container_stack:
|
||||
return self._active_container_stack.getId()
|
||||
|
||||
return ""
|
||||
|
||||
@pyqtProperty(str, notify = activeMaterialChanged)
|
||||
def activeMaterialName(self):
|
||||
def activeMaterialName(self) -> str:
|
||||
if self._active_container_stack:
|
||||
material = self._active_container_stack.findContainer({"type":"material"})
|
||||
if material:
|
||||
|
@ -521,7 +533,7 @@ class MachineManager(QObject):
|
|||
return result
|
||||
|
||||
@pyqtProperty(str, notify=activeMaterialChanged)
|
||||
def activeMaterialId(self):
|
||||
def activeMaterialId(self) -> str:
|
||||
if self._active_container_stack:
|
||||
material = self._active_container_stack.findContainer({"type": "material"})
|
||||
if material:
|
||||
|
@ -559,13 +571,13 @@ class MachineManager(QObject):
|
|||
quality_changes = self._global_container_stack.findContainer({"type": "quality_changes"})
|
||||
if quality_changes:
|
||||
value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = quality_changes.getId())
|
||||
if isinstance(value, UM.Settings.SettingFunction):
|
||||
if isinstance(value, SettingFunction):
|
||||
value = value(self._global_container_stack)
|
||||
return value
|
||||
quality = self._global_container_stack.findContainer({"type": "quality"})
|
||||
if quality:
|
||||
value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = quality.getId())
|
||||
if isinstance(value, UM.Settings.SettingFunction):
|
||||
if isinstance(value, SettingFunction):
|
||||
value = value(self._global_container_stack)
|
||||
return value
|
||||
|
||||
|
@ -574,7 +586,7 @@ class MachineManager(QObject):
|
|||
## Get the Material ID associated with the currently active material
|
||||
# \returns MaterialID (string) if found, empty string otherwise
|
||||
@pyqtProperty(str, notify=activeQualityChanged)
|
||||
def activeQualityMaterialId(self):
|
||||
def activeQualityMaterialId(self) -> str:
|
||||
if self._active_container_stack:
|
||||
quality = self._active_container_stack.findContainer({"type": "quality"})
|
||||
if quality:
|
||||
|
@ -664,8 +676,8 @@ class MachineManager(QObject):
|
|||
|
||||
## Check if a container is read_only
|
||||
@pyqtSlot(str, result = bool)
|
||||
def isReadOnly(self, container_id):
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id)
|
||||
def isReadOnly(self, container_id) -> bool:
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id = container_id)
|
||||
if not containers or not self._active_container_stack:
|
||||
return True
|
||||
return containers[0].isReadOnly()
|
||||
|
@ -687,134 +699,137 @@ class MachineManager(QObject):
|
|||
# Depending on from/to material+current variant, a quality profile is chosen and set.
|
||||
@pyqtSlot(str)
|
||||
def setActiveMaterial(self, material_id):
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = material_id)
|
||||
if not containers or not self._active_container_stack:
|
||||
return
|
||||
material_container = containers[0]
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = True):
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id = material_id)
|
||||
if not containers or not self._active_container_stack:
|
||||
return
|
||||
material_container = containers[0]
|
||||
|
||||
Logger.log("d", "Attempting to change the active material to %s", material_id)
|
||||
Logger.log("d", "Attempting to change the active material to %s", material_id)
|
||||
|
||||
old_material = self._active_container_stack.findContainer({"type": "material"})
|
||||
old_quality = self._active_container_stack.findContainer({"type": "quality"})
|
||||
old_quality_changes = self._active_container_stack.findContainer({"type": "quality_changes"})
|
||||
if not old_material:
|
||||
Logger.log("w", "While trying to set the active material, no material was found to replace it.")
|
||||
return
|
||||
old_material = self._active_container_stack.findContainer({"type": "material"})
|
||||
old_quality = self._active_container_stack.findContainer({"type": "quality"})
|
||||
old_quality_changes = self._active_container_stack.findContainer({"type": "quality_changes"})
|
||||
if not old_material:
|
||||
Logger.log("w", "While trying to set the active material, no material was found to replace it.")
|
||||
return
|
||||
|
||||
if old_quality_changes.getId() == "empty_quality_changes":
|
||||
old_quality_changes = None
|
||||
if old_quality_changes.getId() == "empty_quality_changes":
|
||||
old_quality_changes = None
|
||||
|
||||
self.blurSettings.emit()
|
||||
old_material.nameChanged.disconnect(self._onMaterialNameChanged)
|
||||
self.blurSettings.emit()
|
||||
old_material.nameChanged.disconnect(self._onMaterialNameChanged)
|
||||
|
||||
material_index = self._active_container_stack.getContainerIndex(old_material)
|
||||
self._active_container_stack.replaceContainer(material_index, material_container)
|
||||
Logger.log("d", "Active material changed")
|
||||
material_index = self._active_container_stack.getContainerIndex(old_material)
|
||||
self._active_container_stack.replaceContainer(material_index, material_container)
|
||||
Logger.log("d", "Active material changed")
|
||||
|
||||
material_container.nameChanged.connect(self._onMaterialNameChanged)
|
||||
material_container.nameChanged.connect(self._onMaterialNameChanged)
|
||||
|
||||
if material_container.getMetaDataEntry("compatible") == False:
|
||||
self._material_incompatible_message.show()
|
||||
else:
|
||||
self._material_incompatible_message.hide()
|
||||
if material_container.getMetaDataEntry("compatible") == False:
|
||||
self._material_incompatible_message.show()
|
||||
else:
|
||||
self._material_incompatible_message.hide()
|
||||
|
||||
new_quality_id = old_quality.getId()
|
||||
quality_type = old_quality.getMetaDataEntry("quality_type")
|
||||
if old_quality_changes:
|
||||
quality_type = old_quality_changes.getMetaDataEntry("quality_type")
|
||||
new_quality_id = old_quality_changes.getId()
|
||||
new_quality_id = old_quality.getId()
|
||||
quality_type = old_quality.getMetaDataEntry("quality_type")
|
||||
if old_quality_changes:
|
||||
quality_type = old_quality_changes.getMetaDataEntry("quality_type")
|
||||
new_quality_id = old_quality_changes.getId()
|
||||
|
||||
# See if the requested quality type is available in the new situation.
|
||||
machine_definition = self._active_container_stack.getBottom()
|
||||
quality_manager = QualityManager.getInstance()
|
||||
candidate_quality = quality_manager.findQualityByQualityType(quality_type,
|
||||
quality_manager.getWholeMachineDefinition(machine_definition),
|
||||
[material_container])
|
||||
if not candidate_quality or candidate_quality.getId() == "empty_quality":
|
||||
# Fall back to a quality
|
||||
new_quality = quality_manager.findQualityByQualityType(None,
|
||||
quality_manager.getWholeMachineDefinition(machine_definition),
|
||||
[material_container])
|
||||
if new_quality:
|
||||
new_quality_id = new_quality.getId()
|
||||
else:
|
||||
if not old_quality_changes:
|
||||
new_quality_id = candidate_quality.getId()
|
||||
# See if the requested quality type is available in the new situation.
|
||||
machine_definition = self._active_container_stack.getBottom()
|
||||
quality_manager = QualityManager.getInstance()
|
||||
candidate_quality = quality_manager.findQualityByQualityType(quality_type,
|
||||
quality_manager.getWholeMachineDefinition(machine_definition),
|
||||
[material_container])
|
||||
if not candidate_quality or candidate_quality.getId() == "empty_quality":
|
||||
# Fall back to a quality
|
||||
new_quality = quality_manager.findQualityByQualityType(None,
|
||||
quality_manager.getWholeMachineDefinition(machine_definition),
|
||||
[material_container])
|
||||
if new_quality:
|
||||
new_quality_id = new_quality.getId()
|
||||
else:
|
||||
if not old_quality_changes:
|
||||
new_quality_id = candidate_quality.getId()
|
||||
|
||||
self.setActiveQuality(new_quality_id)
|
||||
self.setActiveQuality(new_quality_id)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def setActiveVariant(self, variant_id):
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = variant_id)
|
||||
if not containers or not self._active_container_stack:
|
||||
return
|
||||
Logger.log("d", "Attempting to change the active variant to %s", variant_id)
|
||||
old_variant = self._active_container_stack.findContainer({"type": "variant"})
|
||||
old_material = self._active_container_stack.findContainer({"type": "material"})
|
||||
if old_variant:
|
||||
self.blurSettings.emit()
|
||||
variant_index = self._active_container_stack.getContainerIndex(old_variant)
|
||||
self._active_container_stack.replaceContainer(variant_index, containers[0])
|
||||
Logger.log("d", "Active variant changed")
|
||||
preferred_material = None
|
||||
if old_material:
|
||||
preferred_material_name = old_material.getName()
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = True):
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_id)
|
||||
if not containers or not self._active_container_stack:
|
||||
return
|
||||
Logger.log("d", "Attempting to change the active variant to %s", variant_id)
|
||||
old_variant = self._active_container_stack.findContainer({"type": "variant"})
|
||||
old_material = self._active_container_stack.findContainer({"type": "material"})
|
||||
if old_variant:
|
||||
self.blurSettings.emit()
|
||||
variant_index = self._active_container_stack.getContainerIndex(old_variant)
|
||||
self._active_container_stack.replaceContainer(variant_index, containers[0])
|
||||
Logger.log("d", "Active variant changed")
|
||||
preferred_material = None
|
||||
if old_material:
|
||||
preferred_material_name = old_material.getName()
|
||||
|
||||
self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0], preferred_material_name).id)
|
||||
else:
|
||||
Logger.log("w", "While trying to set the active variant, no variant was found to replace.")
|
||||
self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0], preferred_material_name).id)
|
||||
else:
|
||||
Logger.log("w", "While trying to set the active variant, no variant was found to replace.")
|
||||
|
||||
## set the active quality
|
||||
# \param quality_id The quality_id of either a quality or a quality_changes
|
||||
@pyqtSlot(str)
|
||||
def setActiveQuality(self, quality_id):
|
||||
self.blurSettings.emit()
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = True):
|
||||
self.blurSettings.emit()
|
||||
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id)
|
||||
if not containers or not self._global_container_stack:
|
||||
return
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id = quality_id)
|
||||
if not containers or not self._global_container_stack:
|
||||
return
|
||||
|
||||
Logger.log("d", "Attempting to change the active quality to %s", quality_id)
|
||||
Logger.log("d", "Attempting to change the active quality to %s", quality_id)
|
||||
|
||||
# Quality profile come in two flavours: type=quality and type=quality_changes
|
||||
# If we found a quality_changes profile then look up its parent quality profile.
|
||||
container_type = containers[0].getMetaDataEntry("type")
|
||||
quality_name = containers[0].getName()
|
||||
quality_type = containers[0].getMetaDataEntry("quality_type")
|
||||
# Quality profile come in two flavours: type=quality and type=quality_changes
|
||||
# If we found a quality_changes profile then look up its parent quality profile.
|
||||
container_type = containers[0].getMetaDataEntry("type")
|
||||
quality_name = containers[0].getName()
|
||||
quality_type = containers[0].getMetaDataEntry("quality_type")
|
||||
|
||||
# Get quality container and optionally the quality_changes container.
|
||||
if container_type == "quality":
|
||||
new_quality_settings_list = self.determineQualityAndQualityChangesForQualityType(quality_type)
|
||||
elif container_type == "quality_changes":
|
||||
new_quality_settings_list = self._determineQualityAndQualityChangesForQualityChanges(quality_name)
|
||||
else:
|
||||
Logger.log("e", "Tried to set quality to a container that is not of the right type")
|
||||
return
|
||||
# Get quality container and optionally the quality_changes container.
|
||||
if container_type == "quality":
|
||||
new_quality_settings_list = self.determineQualityAndQualityChangesForQualityType(quality_type)
|
||||
elif container_type == "quality_changes":
|
||||
new_quality_settings_list = self._determineQualityAndQualityChangesForQualityChanges(quality_name)
|
||||
else:
|
||||
Logger.log("e", "Tried to set quality to a container that is not of the right type")
|
||||
return
|
||||
|
||||
name_changed_connect_stacks = [] # Connect these stacks to the name changed callback
|
||||
for setting_info in new_quality_settings_list:
|
||||
stack = setting_info["stack"]
|
||||
stack_quality = setting_info["quality"]
|
||||
stack_quality_changes = setting_info["quality_changes"]
|
||||
name_changed_connect_stacks = [] # Connect these stacks to the name changed callback
|
||||
for setting_info in new_quality_settings_list:
|
||||
stack = setting_info["stack"]
|
||||
stack_quality = setting_info["quality"]
|
||||
stack_quality_changes = setting_info["quality_changes"]
|
||||
|
||||
name_changed_connect_stacks.append(stack_quality)
|
||||
name_changed_connect_stacks.append(stack_quality_changes)
|
||||
self._replaceQualityOrQualityChangesInStack(stack, stack_quality, postpone_emit = True)
|
||||
self._replaceQualityOrQualityChangesInStack(stack, stack_quality_changes, postpone_emit = True)
|
||||
name_changed_connect_stacks.append(stack_quality)
|
||||
name_changed_connect_stacks.append(stack_quality_changes)
|
||||
self._replaceQualityOrQualityChangesInStack(stack, stack_quality)
|
||||
self._replaceQualityOrQualityChangesInStack(stack, stack_quality_changes)
|
||||
|
||||
# Send emits that are postponed in replaceContainer.
|
||||
# Here the stacks are finished replacing and every value can be resolved based on the current state.
|
||||
for setting_info in new_quality_settings_list:
|
||||
setting_info["stack"].sendPostponedEmits()
|
||||
# Send emits that are postponed in replaceContainer.
|
||||
# Here the stacks are finished replacing and every value can be resolved based on the current state.
|
||||
for setting_info in new_quality_settings_list:
|
||||
setting_info["stack"].sendPostponedEmits()
|
||||
|
||||
# Connect to onQualityNameChanged
|
||||
for stack in name_changed_connect_stacks:
|
||||
stack.nameChanged.connect(self._onQualityNameChanged)
|
||||
# Connect to onQualityNameChanged
|
||||
for stack in name_changed_connect_stacks:
|
||||
stack.nameChanged.connect(self._onQualityNameChanged)
|
||||
|
||||
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
|
||||
self._askUserToKeepOrClearCurrentSettings()
|
||||
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
|
||||
self._askUserToKeepOrClearCurrentSettings()
|
||||
|
||||
self.activeQualityChanged.emit()
|
||||
self.activeQualityChanged.emit()
|
||||
|
||||
## Determine the quality and quality changes settings for the current machine for a quality name.
|
||||
#
|
||||
|
@ -1057,7 +1072,7 @@ class MachineManager(QObject):
|
|||
|
||||
@pyqtSlot(str, str)
|
||||
def renameMachine(self, machine_id, new_name):
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id)
|
||||
containers = ContainerRegistry.getInstance().findContainerStacks(id = machine_id)
|
||||
if containers:
|
||||
new_name = self._createUniqueName("machine", containers[0].getName(), new_name, containers[0].getBottom().getName())
|
||||
containers[0].setName(new_name)
|
||||
|
@ -1070,13 +1085,13 @@ class MachineManager(QObject):
|
|||
|
||||
ExtruderManager.getInstance().removeMachineExtruders(machine_id)
|
||||
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "user", machine = machine_id)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "user", machine = machine_id)
|
||||
for container in containers:
|
||||
UM.Settings.ContainerRegistry.getInstance().removeContainer(container.getId())
|
||||
UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id)
|
||||
ContainerRegistry.getInstance().removeContainer(container.getId())
|
||||
ContainerRegistry.getInstance().removeContainer(machine_id)
|
||||
|
||||
if activate_new_machine:
|
||||
stacks = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(type = "machine")
|
||||
stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
|
||||
if stacks:
|
||||
Application.getInstance().setGlobalContainerStack(stacks[0])
|
||||
|
||||
|
@ -1117,7 +1132,7 @@ class MachineManager(QObject):
|
|||
# \returns DefinitionID (string) if found, None otherwise
|
||||
@pyqtSlot(str, result = str)
|
||||
def getDefinitionByMachineId(self, machine_id):
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id=machine_id)
|
||||
containers = ContainerRegistry.getInstance().findContainerStacks(id=machine_id)
|
||||
if containers:
|
||||
return containers[0].getBottom().getId()
|
||||
|
||||
|
@ -1128,13 +1143,13 @@ class MachineManager(QObject):
|
|||
def _updateVariantContainer(self, definition):
|
||||
if not definition.getMetaDataEntry("has_variants"):
|
||||
return self._empty_variant_container
|
||||
machine_definition_id = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(definition)
|
||||
machine_definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(definition)
|
||||
containers = []
|
||||
preferred_variant = definition.getMetaDataEntry("preferred_variant")
|
||||
if preferred_variant:
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = machine_definition_id, id = preferred_variant)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = machine_definition_id, id = preferred_variant)
|
||||
if not containers:
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = machine_definition_id)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = machine_definition_id)
|
||||
|
||||
if containers:
|
||||
return containers[0]
|
||||
|
@ -1162,23 +1177,23 @@ class MachineManager(QObject):
|
|||
if preferred_material:
|
||||
search_criteria["id"] = preferred_material
|
||||
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
if containers:
|
||||
return containers[0]
|
||||
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
if "variant" in search_criteria or "id" in search_criteria:
|
||||
# If a material by this name can not be found, try a wider set of search criteria
|
||||
search_criteria.pop("variant", None)
|
||||
search_criteria.pop("id", None)
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||
if containers:
|
||||
return containers[0]
|
||||
Logger.log("w", "Unable to find a material container with provided criteria, returning an empty one instead.")
|
||||
return self._empty_material_container
|
||||
|
||||
def _updateQualityContainer(self, definition, variant_container, material_container = None, preferred_quality_name = None):
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
search_criteria = { "type": "quality" }
|
||||
|
||||
if definition.getMetaDataEntry("has_machine_quality"):
|
||||
|
@ -1261,7 +1276,7 @@ class MachineManager(QObject):
|
|||
# \param preferred_quality_changes_name The name of the quality-changes to
|
||||
# pick, if any such quality-changes profile is available.
|
||||
def _updateQualityChangesContainer(self, quality_type, preferred_quality_changes_name = None):
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance() # Cache.
|
||||
container_registry = ContainerRegistry.getInstance() # Cache.
|
||||
search_criteria = { "type": "quality_changes" }
|
||||
|
||||
search_criteria["quality"] = quality_type
|
||||
|
@ -1289,3 +1304,8 @@ class MachineManager(QObject):
|
|||
|
||||
def _onQualityNameChanged(self):
|
||||
self.activeQualityChanged.emit()
|
||||
|
||||
def _getContainerChangedSignals(self):
|
||||
stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||
stacks.append(self._global_container_stack)
|
||||
return [ s.containersChanged for s in stacks ]
|
||||
|
|
|
@ -7,8 +7,8 @@ import os #For statvfs.
|
|||
import urllib #To escape machine names for how they're saved to file.
|
||||
|
||||
import UM.Resources
|
||||
import UM.Settings.ContainerRegistry
|
||||
import UM.Settings.InstanceContainer
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
||||
## Are machine names valid?
|
||||
#
|
||||
|
@ -22,7 +22,7 @@ class MachineNameValidator(QObject):
|
|||
filename_max_length = os.statvfs(UM.Resources.getDataStoragePath()).f_namemax
|
||||
except AttributeError: #Doesn't support statvfs. Probably because it's not a Unix system.
|
||||
filename_max_length = 255 #Assume it's Windows on NTFS.
|
||||
machine_name_max_length = filename_max_length - len("_current_settings.") - len(UM.Settings.ContainerRegistry.getMimeTypeForContainer(UM.Settings.InstanceContainer).preferredSuffix)
|
||||
machine_name_max_length = filename_max_length - len("_current_settings.") - len(ContainerRegistry.getMimeTypeForContainer(InstanceContainer).preferredSuffix)
|
||||
# Characters that urllib.parse.quote_plus escapes count for 12! So now
|
||||
# we must devise a regex that allows only 12 normal characters or 1
|
||||
# special character, and that up to [machine_name_max_length / 12] times.
|
||||
|
@ -45,7 +45,7 @@ class MachineNameValidator(QObject):
|
|||
except AttributeError: #Doesn't support statvfs. Probably because it's not a Unix system.
|
||||
filename_max_length = 255 #Assume it's Windows on NTFS.
|
||||
escaped_name = urllib.parse.quote_plus(name)
|
||||
current_settings_filename = escaped_name + "_current_settings." + UM.Settings.ContainerRegistry.getMimeTypeForContainer(UM.Settings.InstanceContainer).preferredSuffix
|
||||
current_settings_filename = escaped_name + "_current_settings." + ContainerRegistry.getMimeTypeForContainer(InstanceContainer).preferredSuffix
|
||||
if len(current_settings_filename) > filename_max_length:
|
||||
return QValidator.Invalid
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Uranium is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import UM.Settings.Models
|
||||
from UM.Settings.Models.SettingVisibilityHandler import SettingVisibilityHandler
|
||||
|
||||
class MaterialSettingsVisibilityHandler(UM.Settings.Models.SettingVisibilityHandler):
|
||||
class MaterialSettingsVisibilityHandler(SettingVisibilityHandler):
|
||||
def __init__(self, parent = None, *args, **kwargs):
|
||||
super().__init__(parent = parent, *args, **kwargs)
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ class ProfilesModel(InstanceContainersModel):
|
|||
ProfilesModel.__instance = cls()
|
||||
return ProfilesModel.__instance
|
||||
|
||||
__instance = None
|
||||
__instance = None # type: "ProfilesModel"
|
||||
|
||||
## Fetch the list of containers to display.
|
||||
#
|
||||
|
|
|
@ -5,15 +5,14 @@ import collections
|
|||
|
||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
|
||||
|
||||
import UM.Application
|
||||
import UM.Logger
|
||||
import UM.Qt
|
||||
import UM.Settings
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Application import Application
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
import os
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
|
||||
class QualitySettingsModel(UM.Qt.ListModel.ListModel):
|
||||
KeyRole = Qt.UserRole + 1
|
||||
|
@ -27,7 +26,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel):
|
|||
def __init__(self, parent = None):
|
||||
super().__init__(parent = parent)
|
||||
|
||||
self._container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
self._container_registry = ContainerRegistry.getInstance()
|
||||
|
||||
self._extruder_id = None
|
||||
self._extruder_definition_id = None
|
||||
|
@ -94,7 +93,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel):
|
|||
items = []
|
||||
|
||||
settings = collections.OrderedDict()
|
||||
definition_container = UM.Application.getInstance().getGlobalContainerStack().getBottom()
|
||||
definition_container = Application.getInstance().getGlobalContainerStack().getBottom()
|
||||
|
||||
containers = self._container_registry.findInstanceContainers(id = self._quality_id)
|
||||
if not containers:
|
||||
|
@ -122,7 +121,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel):
|
|||
quality_container = quality_container[0]
|
||||
|
||||
quality_type = quality_container.getMetaDataEntry("quality_type")
|
||||
definition_id = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(quality_container.getDefinition())
|
||||
definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(quality_container.getDefinition())
|
||||
definition = quality_container.getDefinition()
|
||||
|
||||
# Check if the definition container has a translation file.
|
||||
|
@ -169,7 +168,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel):
|
|||
if self._extruder_definition_id != "":
|
||||
extruder_definitions = self._container_registry.findDefinitionContainers(id = self._extruder_definition_id)
|
||||
if extruder_definitions:
|
||||
criteria["extruder"] = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(extruder_definitions[0])
|
||||
criteria["extruder"] = Application.getInstance().getMachineManager().getQualityDefinitionId(extruder_definitions[0])
|
||||
criteria["name"] = quality_changes_container.getName()
|
||||
else:
|
||||
criteria["extruder"] = None
|
||||
|
@ -178,7 +177,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel):
|
|||
if changes:
|
||||
containers.extend(changes)
|
||||
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
is_multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
||||
|
||||
current_category = ""
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
|
||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
import UM.Settings
|
||||
from UM.Application import Application
|
||||
import cura.Settings
|
||||
from UM.Logger import Logger
|
||||
|
||||
|
||||
|
@ -14,6 +12,12 @@ from UM.Logger import Logger
|
|||
# because some profiles tend to have 'hardcoded' values that break our inheritance. A good example of that are the
|
||||
# speed settings. If all the children of print_speed have a single value override, changing the speed won't
|
||||
# actually do anything, as only the 'leaf' settings are used by the engine.
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.SettingFunction import SettingFunction
|
||||
from UM.Settings.SettingInstance import InstanceState
|
||||
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
class SettingInheritanceManager(QObject):
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
|
@ -23,7 +27,7 @@ class SettingInheritanceManager(QObject):
|
|||
self._active_container_stack = None
|
||||
self._onGlobalContainerChanged()
|
||||
|
||||
cura.Settings.ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged)
|
||||
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged)
|
||||
self._onActiveExtruderChanged()
|
||||
|
||||
settingsWithIntheritanceChanged = pyqtSignal()
|
||||
|
@ -46,7 +50,7 @@ class SettingInheritanceManager(QObject):
|
|||
multi_extrusion = self._global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
||||
if not multi_extrusion:
|
||||
return self._settings_with_inheritance_warning
|
||||
extruder = cura.Settings.ExtruderManager.getInstance().getExtruderStack(extruder_index)
|
||||
extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
|
||||
if not extruder:
|
||||
Logger.log("w", "Unable to find extruder for current machine with index %s", extruder_index)
|
||||
return []
|
||||
|
@ -73,7 +77,7 @@ class SettingInheritanceManager(QObject):
|
|||
self._update()
|
||||
|
||||
def _onActiveExtruderChanged(self):
|
||||
new_active_stack = cura.Settings.ExtruderManager.getInstance().getActiveExtruderStack()
|
||||
new_active_stack = ExtruderManager.getInstance().getActiveExtruderStack()
|
||||
if not new_active_stack:
|
||||
new_active_stack = self._global_container_stack
|
||||
|
||||
|
@ -139,14 +143,14 @@ class SettingInheritanceManager(QObject):
|
|||
return self._settings_with_inheritance_warning
|
||||
|
||||
## Check if a setting has an inheritance function that is overwritten
|
||||
def _settingIsOverwritingInheritance(self, key, stack = None):
|
||||
def _settingIsOverwritingInheritance(self, key: str, stack: ContainerStack = None) -> bool:
|
||||
has_setting_function = False
|
||||
if not stack:
|
||||
stack = self._active_container_stack
|
||||
containers = []
|
||||
|
||||
## Check if the setting has a user state. If not, it is never overwritten.
|
||||
has_user_state = stack.getProperty(key, "state") == UM.Settings.InstanceState.User
|
||||
has_user_state = stack.getProperty(key, "state") == InstanceState.User
|
||||
if not has_user_state:
|
||||
return False
|
||||
|
||||
|
@ -155,7 +159,7 @@ class SettingInheritanceManager(QObject):
|
|||
return False
|
||||
|
||||
## Also check if the top container is not a setting function (this happens if the inheritance is restored).
|
||||
if isinstance(stack.getTop().getProperty(key, "value"), UM.Settings.SettingFunction):
|
||||
if isinstance(stack.getTop().getProperty(key, "value"), SettingFunction):
|
||||
return False
|
||||
|
||||
## Mash all containers for all the stacks together.
|
||||
|
@ -170,7 +174,7 @@ class SettingInheritanceManager(QObject):
|
|||
continue
|
||||
if value is not None:
|
||||
# If a setting doesn't use any keys, it won't change it's value, so treat it as if it's a fixed value
|
||||
has_setting_function = isinstance(value, UM.Settings.SettingFunction)
|
||||
has_setting_function = isinstance(value, SettingFunction)
|
||||
if has_setting_function:
|
||||
for setting_key in value.getUsedSettingKeys():
|
||||
if setting_key in self._active_container_stack.getAllKeys():
|
||||
|
|
|
@ -10,10 +10,10 @@ from UM.Settings.InstanceContainer import InstanceContainer
|
|||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
import UM.Logger
|
||||
|
||||
import cura.Settings
|
||||
|
||||
from UM.Application import Application
|
||||
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding
|
||||
# the linked node. The Stack in question will refer to the global stack (so that settings that are not defined by
|
||||
# this stack still resolve.
|
||||
|
@ -29,8 +29,8 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||
self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer")
|
||||
self._stack.addContainer(self._instance)
|
||||
|
||||
if cura.Settings.ExtruderManager.getInstance().extruderCount > 1:
|
||||
self._extruder_stack = cura.Settings.ExtruderManager.getInstance().getExtruderStack(0).getId()
|
||||
if ExtruderManager.getInstance().extruderCount > 1:
|
||||
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
||||
else:
|
||||
self._extruder_stack = None
|
||||
|
||||
|
|
|
@ -1,18 +1,2 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from .MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
|
||||
from .ContainerManager import ContainerManager
|
||||
from .ContainerSettingsModel import ContainerSettingsModel
|
||||
from .CuraContainerRegistry import CuraContainerRegistry
|
||||
from .ExtruderManager import ExtruderManager
|
||||
from .ExtrudersModel import ExtrudersModel
|
||||
from .MachineManager import MachineManager
|
||||
from .MachineNameValidator import MachineNameValidator
|
||||
from .MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
|
||||
from .SettingOverrideDecorator import SettingOverrideDecorator
|
||||
from .QualitySettingsModel import QualitySettingsModel
|
||||
from .SettingInheritanceManager import SettingInheritanceManager
|
||||
from .ProfilesModel import ProfilesModel
|
||||
from .QualityAndUserProfilesModel import QualityAndUserProfilesModel
|
||||
from .UserProfilesModel import UserProfilesModel
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue