mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-10 23:35:07 -06:00
Merge branch 'master' of https://github.com/Ultimaker/Cura
This commit is contained in:
commit
482bc21a9f
12 changed files with 118 additions and 112 deletions
|
@ -351,6 +351,7 @@ class CuraApplication(QtApplication):
|
||||||
|
|
||||||
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface..."))
|
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface..."))
|
||||||
|
|
||||||
|
ExtruderManager.ExtruderManager.getInstance() #Initialise extruder so as to listen to global container stack changes before the first global container stack is set.
|
||||||
qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager",
|
qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager",
|
||||||
MachineManagerModel.createMachineManagerModel)
|
MachineManagerModel.createMachineManagerModel)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Copyright (c) 2016 Ultimaker B.V.
|
# Copyright (c) 2016 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject #For communicating data and events to Qt.
|
from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject, QVariant #For communicating data and events to Qt.
|
||||||
|
|
||||||
import UM.Application #To get the global container stack to find the current machine.
|
import UM.Application #To get the global container stack to find the current machine.
|
||||||
import UM.Logger
|
import UM.Logger
|
||||||
|
@ -13,7 +13,7 @@ import UM.Settings.ContainerRegistry #Finding containers by ID.
|
||||||
# This keeps a list of extruder stacks for each machine.
|
# This keeps a list of extruder stacks for each machine.
|
||||||
class ExtruderManager(QObject):
|
class ExtruderManager(QObject):
|
||||||
## Signal to notify other components when the list of extruders changes.
|
## Signal to notify other components when the list of extruders changes.
|
||||||
extrudersChanged = pyqtSignal()
|
extrudersChanged = pyqtSignal(QVariant)
|
||||||
|
|
||||||
## Notify when the user switches the currently active extruder.
|
## Notify when the user switches the currently active extruder.
|
||||||
activeExtruderChanged = pyqtSignal()
|
activeExtruderChanged = pyqtSignal()
|
||||||
|
@ -21,8 +21,9 @@ class ExtruderManager(QObject):
|
||||||
## Registers listeners and such to listen to changes to the extruders.
|
## Registers listeners and such to listen to changes to the extruders.
|
||||||
def __init__(self, parent = None):
|
def __init__(self, parent = None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._extruder_trains = { } #Extruders for the current machine.
|
self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs.
|
||||||
self._active_extruder_index = 0
|
self._active_extruder_index = 0
|
||||||
|
UM.Application.getInstance().globalContainerStackChanged.connect(self._addCurrentMachineExtruders)
|
||||||
|
|
||||||
## Gets the unique identifier of the currently active extruder stack.
|
## Gets the unique identifier of the currently active extruder stack.
|
||||||
#
|
#
|
||||||
|
@ -39,7 +40,18 @@ class ExtruderManager(QObject):
|
||||||
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.
|
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 None
|
||||||
|
|
||||||
|
## The instance of the singleton pattern.
|
||||||
|
#
|
||||||
|
# It's None if the extruder manager hasn't been created yet.
|
||||||
__instance = None
|
__instance = None
|
||||||
|
|
||||||
|
## Gets an instance of the extruder manager, or creates one if no instance
|
||||||
|
# exists yet.
|
||||||
|
#
|
||||||
|
# This is an implementation of singleton. If an extruder manager already
|
||||||
|
# exists, it is re-used.
|
||||||
|
#
|
||||||
|
# \return The extruder manager.
|
||||||
@classmethod
|
@classmethod
|
||||||
def getInstance(cls):
|
def getInstance(cls):
|
||||||
if not cls.__instance:
|
if not cls.__instance:
|
||||||
|
@ -68,7 +80,7 @@ class ExtruderManager(QObject):
|
||||||
for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition.getId()):
|
for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition.getId()):
|
||||||
position = extruder_definition.getMetaDataEntry("position", None)
|
position = extruder_definition.getMetaDataEntry("position", None)
|
||||||
if not position:
|
if not position:
|
||||||
UM.Logger.Log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId())
|
UM.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.
|
if not container_registry.findContainerStacks(machine = machine_id, position = position): #Doesn't exist yet.
|
||||||
name = container_registry.uniqueName(extruder_definition.getId()) #Make a name based on the ID of the definition.
|
name = container_registry.uniqueName(extruder_definition.getId()) #Make a name based on the ID of the definition.
|
||||||
self.createExtruderTrain(extruder_definition, machine_definition, name, position)
|
self.createExtruderTrain(extruder_definition, machine_definition, name, position)
|
||||||
|
@ -78,24 +90,7 @@ class ExtruderManager(QObject):
|
||||||
for extruder_train in extruder_trains:
|
for extruder_train in extruder_trains:
|
||||||
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId()
|
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId()
|
||||||
if extruder_trains:
|
if extruder_trains:
|
||||||
self.extrudersChanged.emit()
|
self.extrudersChanged.emit(machine_definition)
|
||||||
|
|
||||||
## (Re)populates the collections of extruders by machine.
|
|
||||||
def _repopulate(self):
|
|
||||||
self._extruder_trains = { }
|
|
||||||
if not UM.Application.getInstance().getGlobalContainerStack(): #No machine has been added yet.
|
|
||||||
self.extrudersChanged.emit() #Yes, we just cleared the _extruders list!
|
|
||||||
return #Then leave them empty!
|
|
||||||
|
|
||||||
extruder_trains = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(type = "extruder_train")
|
|
||||||
for extruder_train in extruder_trains:
|
|
||||||
machine_id = extruder_train.getMetaDataEntry("machine")
|
|
||||||
if not machine_id:
|
|
||||||
continue
|
|
||||||
if machine_id not in self._extruder_trains:
|
|
||||||
self._extruder_trains[machine_id] = { }
|
|
||||||
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId()
|
|
||||||
self.extrudersChanged.emit()
|
|
||||||
|
|
||||||
def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position):
|
def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position):
|
||||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||||
|
@ -162,3 +157,23 @@ class ExtruderManager(QObject):
|
||||||
container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
|
container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
|
||||||
|
|
||||||
container_registry.addContainer(container_stack)
|
container_registry.addContainer(container_stack)
|
||||||
|
|
||||||
|
## Generates extruders for a specific machine.
|
||||||
|
def getMachineExtruders(self, machine_definition):
|
||||||
|
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||||
|
machine_id = machine_definition.getId()
|
||||||
|
if not machine_id 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 _,extruder_train_id in self._extruder_trains[machine_id].items():
|
||||||
|
extruder_train = container_registry.findContainerStacks(id = extruder_train_id)
|
||||||
|
if extruder_train:
|
||||||
|
yield extruder_train[0]
|
||||||
|
else:
|
||||||
|
UM.Logger.log("w", "Machine %s refers to an extruder train with ID %s, which doesn't exist.", machine_id, extruder_train_id)
|
||||||
|
|
||||||
|
## Adds the extruders of the currently active machine.
|
||||||
|
def _addCurrentMachineExtruders(self):
|
||||||
|
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||||
|
if global_stack and global_stack.getBottom():
|
||||||
|
self.addMachineExtruders(global_stack.getBottom())
|
|
@ -9,7 +9,8 @@ import UM.Qt.ListModel
|
||||||
## Model that holds extruders.
|
## Model that holds extruders.
|
||||||
#
|
#
|
||||||
# This model is designed for use by any list of extruders, but specifically
|
# This model is designed for use by any list of extruders, but specifically
|
||||||
# intended for drop-down lists of extruders in place of settings.
|
# intended for drop-down lists of the current machine's extruders in place of
|
||||||
|
# settings.
|
||||||
class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
## Human-readable name of the extruder.
|
## Human-readable name of the extruder.
|
||||||
NameRole = Qt.UserRole + 1
|
NameRole = Qt.UserRole + 1
|
||||||
|
@ -37,7 +38,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
|
|
||||||
#Listen to changes.
|
#Listen to changes.
|
||||||
manager = cura.ExtruderManager.ExtruderManager.getInstance()
|
manager = cura.ExtruderManager.ExtruderManager.getInstance()
|
||||||
manager.extrudersChanged.connect(self._updateExtruders)
|
manager.extrudersChanged.connect(self._updateExtruders) #When the list of extruders changes in general.
|
||||||
|
UM.Application.globalContainerStackChanged.connect(self._updateExtruders) #When the current machine changes.
|
||||||
self._updateExtruders()
|
self._updateExtruders()
|
||||||
|
|
||||||
## Update the list of extruders.
|
## Update the list of extruders.
|
||||||
|
@ -46,10 +48,15 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
def _updateExtruders(self):
|
def _updateExtruders(self):
|
||||||
self.clear()
|
self.clear()
|
||||||
manager = cura.ExtruderManager.ExtruderManager.getInstance()
|
manager = cura.ExtruderManager.ExtruderManager.getInstance()
|
||||||
for index, extruder in enumerate(manager):
|
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||||
|
if not global_container_stack:
|
||||||
|
return #There is no machine to get the extruders of.
|
||||||
|
for index, extruder in enumerate(manager.getMachineExtruders(global_container_stack.getBottom())):
|
||||||
|
material = extruder.findContainer({ "type": "material" })
|
||||||
|
colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00"
|
||||||
item = { #Construct an item with only the relevant information.
|
item = { #Construct an item with only the relevant information.
|
||||||
"name": extruder.name,
|
"name": extruder.getName(),
|
||||||
"colour": extruder.material.getMetaDataEntry("color_code", default = "#FFFF00"),
|
"colour": colour,
|
||||||
"index": index
|
"index": index
|
||||||
}
|
}
|
||||||
self.appendItem(item)
|
self.appendItem(item)
|
||||||
|
|
|
@ -9,6 +9,7 @@ from UM.Logger import Logger
|
||||||
import UM.Settings
|
import UM.Settings
|
||||||
from UM.Settings.Validator import ValidatorState
|
from UM.Settings.Validator import ValidatorState
|
||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
from UM.Settings.InstanceContainer import InstanceContainer
|
||||||
|
from UM.Settings.ContainerStack import ContainerStack
|
||||||
from . import ExtruderManager
|
from . import ExtruderManager
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
@ -35,8 +36,6 @@ class MachineManagerModel(QObject):
|
||||||
|
|
||||||
active_machine_id = Preferences.getInstance().getValue("cura/active_machine")
|
active_machine_id = Preferences.getInstance().getValue("cura/active_machine")
|
||||||
|
|
||||||
self._active_extruder_index = 0
|
|
||||||
|
|
||||||
if active_machine_id != "":
|
if active_machine_id != "":
|
||||||
# An active machine was saved, so restore it.
|
# An active machine was saved, so restore it.
|
||||||
self.setActiveMachine(active_machine_id)
|
self.setActiveMachine(active_machine_id)
|
||||||
|
@ -105,12 +104,11 @@ class MachineManagerModel(QObject):
|
||||||
Application.getInstance().setGlobalContainerStack(containers[0])
|
Application.getInstance().setGlobalContainerStack(containers[0])
|
||||||
|
|
||||||
@pyqtSlot(str, str)
|
@pyqtSlot(str, str)
|
||||||
def addMachine(self,name, definition_id):
|
def addMachine(self, name, definition_id):
|
||||||
definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id)
|
definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id)
|
||||||
if definitions:
|
if definitions:
|
||||||
definition = definitions[0]
|
definition = definitions[0]
|
||||||
name = self._createUniqueName("machine", name, definition.getName())
|
name = self._createUniqueName("machine", "", name, definition.getName())
|
||||||
|
|
||||||
new_global_stack = UM.Settings.ContainerStack(name)
|
new_global_stack = UM.Settings.ContainerStack(name)
|
||||||
new_global_stack.addMetaDataEntry("type", "machine")
|
new_global_stack.addMetaDataEntry("type", "machine")
|
||||||
UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack)
|
UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack)
|
||||||
|
@ -139,31 +137,39 @@ class MachineManagerModel(QObject):
|
||||||
|
|
||||||
Application.getInstance().setGlobalContainerStack(new_global_stack)
|
Application.getInstance().setGlobalContainerStack(new_global_stack)
|
||||||
|
|
||||||
# Create a name that is not empty and unique
|
## Create a name that is not empty and unique
|
||||||
def _createUniqueName(self, object_type, name, fallback_name):
|
# \param container_type \type{string} Type of the container (machine, quality, ...)
|
||||||
name = name.strip()
|
# \param current_name \type{} Current name of the container, which may be an acceptable option
|
||||||
num_check = re.compile("(.*?)\s*#\d+$").match(name)
|
# \param new_name \type{string} Base name, which may not be unique
|
||||||
if(num_check):
|
# \param fallback_name \type{string} Name to use when (stripped) new_name is empty
|
||||||
name = num_check.group(1)
|
# \return \type{string} Name that is unique for the specified type and name/id
|
||||||
if name == "":
|
def _createUniqueName(self, container_type, current_name, new_name, fallback_name):
|
||||||
name = fallback_name
|
new_name = new_name.strip()
|
||||||
unique_name = name
|
num_check = re.compile("(.*?)\s*#\d+$").match(new_name)
|
||||||
i = 1
|
if num_check:
|
||||||
|
new_name = num_check.group(1)
|
||||||
|
if new_name == "":
|
||||||
|
new_name = fallback_name
|
||||||
|
|
||||||
# Check both the id and the name, because they may not be the same and it is better if they are both unique
|
unique_name = new_name
|
||||||
if object_type == "machine":
|
i = 1
|
||||||
while UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = unique_name, type = "machine") or \
|
# In case we are renaming, the current name of the container is also a valid end-result
|
||||||
UM.Settings.ContainerRegistry.getInstance().findContainerStacks(name = unique_name, type = "machine"):
|
while self._containerExists(container_type, unique_name) and unique_name != current_name:
|
||||||
i += 1
|
i += 1
|
||||||
unique_name = "%s #%d" % (name, i)
|
unique_name = "%s #%d" % (new_name, i)
|
||||||
else:
|
|
||||||
while UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = unique_name, type = object_type) or \
|
|
||||||
UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = unique_name, type = object_type):
|
|
||||||
i += 1
|
|
||||||
unique_name = "%s #%d" % (name, i)
|
|
||||||
|
|
||||||
return unique_name
|
return unique_name
|
||||||
|
|
||||||
|
## Check if a container with of a certain type and a certain name or id exists
|
||||||
|
# Both the id and the name are checked, because they may not be the same and it is better if they are both unique
|
||||||
|
# \param container_type \type{string} Type of the container (machine, quality, ...)
|
||||||
|
# \param container_name \type{string} Name to check
|
||||||
|
def _containerExists(self, container_type, container_name):
|
||||||
|
container_class = ContainerStack if container_type == "machine" else InstanceContainer
|
||||||
|
|
||||||
|
return UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, id = container_name, type = container_type) or \
|
||||||
|
UM.Settings.ContainerRegistry.getInstance().findContainers(container_class, name = container_name, type = container_type)
|
||||||
|
|
||||||
## Convenience function to check if a stack has errors.
|
## Convenience function to check if a stack has errors.
|
||||||
def _checkStackForErrors(self, stack):
|
def _checkStackForErrors(self, stack):
|
||||||
if stack is None:
|
if stack is None:
|
||||||
|
@ -260,9 +266,9 @@ class MachineManagerModel(QObject):
|
||||||
if not self._global_container_stack:
|
if not self._global_container_stack:
|
||||||
return
|
return
|
||||||
|
|
||||||
name = self._createUniqueName("quality", self.activeQualityName, catalog.i18nc("@label", "Custom profile"))
|
|
||||||
user_settings = self._global_container_stack.getTop()
|
|
||||||
new_quality_container = InstanceContainer("")
|
new_quality_container = InstanceContainer("")
|
||||||
|
name = self._createUniqueName("quality", "", self.activeQualityName, catalog.i18nc("@label", "Custom profile"))
|
||||||
|
user_settings = self._global_container_stack.getTop()
|
||||||
|
|
||||||
## Copy all values
|
## Copy all values
|
||||||
new_quality_container.deserialize(user_settings.serialize())
|
new_quality_container.deserialize(user_settings.serialize())
|
||||||
|
@ -290,7 +296,7 @@ class MachineManagerModel(QObject):
|
||||||
return
|
return
|
||||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id)
|
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=container_id)
|
||||||
if containers:
|
if containers:
|
||||||
new_name = self._createUniqueName("quality", containers[0].getName(), catalog.i18nc("@label", "Custom profile"))
|
new_name = self._createUniqueName("quality", "", containers[0].getName(), catalog.i18nc("@label", "Custom profile"))
|
||||||
|
|
||||||
new_container = InstanceContainer("")
|
new_container = InstanceContainer("")
|
||||||
|
|
||||||
|
@ -310,9 +316,9 @@ class MachineManagerModel(QObject):
|
||||||
def renameQualityContainer(self, container_id, new_name):
|
def renameQualityContainer(self, container_id, new_name):
|
||||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality")
|
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality")
|
||||||
if containers:
|
if containers:
|
||||||
new_name = self._createUniqueName("machine", new_name, catalog.i18nc("@label", "Custom profile"))
|
new_name = self._createUniqueName("quality", containers[0].getName(), new_name, catalog.i18nc("@label", "Custom profile"))
|
||||||
containers[0].setName(new_name)
|
containers[0].setName(new_name)
|
||||||
UM.Settings.ContainerRegistry.getInstance().containerChanged.emit(containers[0])
|
self.activeQualityChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
|
@ -327,11 +333,11 @@ class MachineManagerModel(QObject):
|
||||||
UM.Settings.ContainerRegistry.getInstance().removeContainer(container_id)
|
UM.Settings.ContainerRegistry.getInstance().removeContainer(container_id)
|
||||||
|
|
||||||
if activate_new_container:
|
if activate_new_container:
|
||||||
old_container = self._global_container_stack.findInstanceContainers({"type": "quality"})
|
definition_id = "fdmprinter" if not self.filterQualityByMachine else self.activeDefinitionId
|
||||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = container_type)
|
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition_id)
|
||||||
if containers and old_container:
|
if containers:
|
||||||
container_index = self._global_container_stack.getContainerIndex(old_container)
|
self.setActiveQuality(containers[0].getId())
|
||||||
self._global_container_stack.replaceContainer(container_index, containers[0])
|
self.activeQualityChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
|
@ -413,7 +419,7 @@ class MachineManagerModel(QObject):
|
||||||
def renameMachine(self, machine_id, new_name):
|
def renameMachine(self, machine_id, new_name):
|
||||||
containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id)
|
containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id)
|
||||||
if containers:
|
if containers:
|
||||||
new_name = self._createUniqueName("machine", new_name, containers[0].getBottom().getName())
|
new_name = self._createUniqueName("machine", containers[0].getName(), new_name, containers[0].getBottom().getName())
|
||||||
containers[0].setName(new_name)
|
containers[0].setName(new_name)
|
||||||
self.globalContainerChanged.emit()
|
self.globalContainerChanged.emit()
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._stack = ContainerStack(stack_id = id(self))
|
self._stack = ContainerStack(stack_id = id(self))
|
||||||
|
self._stack.setDirty(False) # This stack does not need to be saved.
|
||||||
self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer")
|
self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer")
|
||||||
self._stack.addContainer(self._instance)
|
self._stack.addContainer(self._instance)
|
||||||
|
|
||||||
|
@ -28,10 +29,10 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
||||||
def __deepcopy__(self, memo):
|
def __deepcopy__(self, memo):
|
||||||
## Create a fresh decorator object
|
## Create a fresh decorator object
|
||||||
deep_copy = SettingOverrideDecorator()
|
deep_copy = SettingOverrideDecorator()
|
||||||
## Copy the stack
|
## Copy the instance
|
||||||
deep_copy._stack = copy.deepcopy(self._stack, memo)
|
deep_copy._instance = copy.deepcopy(self._instance, memo)
|
||||||
## Ensure that the id is unique.
|
## Set the copied instance as the first (and only) instance container of the stack.
|
||||||
deep_copy._stack._id = id(deep_copy)
|
deep_copy._stack.replaceContainer(0, deep_copy._instance)
|
||||||
return deep_copy
|
return deep_copy
|
||||||
|
|
||||||
def _onSettingChanged(self, instance, property):
|
def _onSettingChanged(self, instance, property):
|
||||||
|
|
|
@ -61,7 +61,7 @@ Item {
|
||||||
onLoaded: {
|
onLoaded: {
|
||||||
settingLoader.item.showRevertButton = false
|
settingLoader.item.showRevertButton = false
|
||||||
settingLoader.item.showInheritButton = false
|
settingLoader.item.showInheritButton = false
|
||||||
settingLoader.item.doDepthIdentation = false
|
settingLoader.item.doDepthIndentation = false
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceComponent:
|
sourceComponent:
|
||||||
|
@ -120,7 +120,7 @@ Item {
|
||||||
|
|
||||||
containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
|
containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
|
||||||
key: model.key
|
key: model.key
|
||||||
watchedProperties: [ "value", "enabled", "state", "validationState" ]
|
watchedProperties: [ "value", "enabled", "validationState" ]
|
||||||
storeIndex: 0
|
storeIndex: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2138,6 +2138,7 @@
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value": "machine_extruder_count - 1",
|
"maximum_value": "machine_extruder_count - 1",
|
||||||
|
"enabled": "support_enable",
|
||||||
"global_only": "True",
|
"global_only": "True",
|
||||||
"children": {
|
"children": {
|
||||||
"support_infill_extruder_nr":
|
"support_infill_extruder_nr":
|
||||||
|
|
|
@ -237,7 +237,7 @@ UM.ManagementPage
|
||||||
folder: base.model.getDefaultPath()
|
folder: base.model.getDefaultPath()
|
||||||
onAccepted:
|
onAccepted:
|
||||||
{
|
{
|
||||||
var result = base.model.exportProfile(base.currentItem.id, base.currentItem.name, fileUrl, selectedNameFilter)
|
var result = base.model.exportProfile(base.currentItem.id, fileUrl)
|
||||||
if(result && result.status == "error")
|
if(result && result.status == "error")
|
||||||
{
|
{
|
||||||
messageDialog.icon = StandardIcon.Critical
|
messageDialog.icon = StandardIcon.Critical
|
||||||
|
|
|
@ -143,7 +143,7 @@ Item{
|
||||||
UM.SimpleButton {
|
UM.SimpleButton {
|
||||||
id: customisedSettings
|
id: customisedSettings
|
||||||
|
|
||||||
visible: UM.ActiveProfile.hasCustomisedValues
|
visible: Cura.MachineManager.hasUserSettings
|
||||||
height: parent.height * 0.6
|
height: parent.height * 0.6
|
||||||
width: parent.height * 0.6
|
width: parent.height * 0.6
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,11 @@ Item {
|
||||||
|
|
||||||
property var showRevertButton: true
|
property var showRevertButton: true
|
||||||
property var showInheritButton: true
|
property var showInheritButton: true
|
||||||
property var doDepthIdentation: true
|
property var doDepthIndentation: true
|
||||||
|
|
||||||
// Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise)
|
// Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise)
|
||||||
property var state: propertyProvider.properties.state
|
property var state: propertyProvider.properties.state
|
||||||
property var stackLevel: propertyProvider.stackLevel
|
property var stackLevel: propertyProvider.stackLevels[0]
|
||||||
|
|
||||||
signal contextMenuRequested()
|
signal contextMenuRequested()
|
||||||
signal showTooltip(string text);
|
signal showTooltip(string text);
|
||||||
|
@ -101,7 +101,7 @@ Item {
|
||||||
id: label;
|
id: label;
|
||||||
|
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: doDepthIdentation ? (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) : 0
|
anchors.leftMargin: doDepthIndentation ? (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) : 0
|
||||||
anchors.right: settingControls.left;
|
anchors.right: settingControls.left;
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
@ -166,7 +166,15 @@ Item {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
focus = true;
|
focus = true;
|
||||||
propertyProvider.removeFromContainer(base.stackLevel)
|
// Get the deepest entry of this setting that we can find. TODO: This is a bit naive, in some cases
|
||||||
|
// there might be multiple profiles saying something about the same setting. There is no strategy
|
||||||
|
// how to handle this as of yet.
|
||||||
|
var last_entry = propertyProvider.stackLevels.slice(-1)[0]
|
||||||
|
// Put that entry into the "top" instance container.
|
||||||
|
// This ensures that the value in any of the deeper containers need not be removed, which is
|
||||||
|
// needed for the reset button (which deletes the top value) to correctly go back to profile
|
||||||
|
// defaults.
|
||||||
|
propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry))
|
||||||
}
|
}
|
||||||
|
|
||||||
backgroundColor: UM.Theme.getColor("setting_control");
|
backgroundColor: UM.Theme.getColor("setting_control");
|
||||||
|
|
|
@ -90,21 +90,11 @@ SettingItem
|
||||||
|
|
||||||
Keys.onReleased:
|
Keys.onReleased:
|
||||||
{
|
{
|
||||||
// text = text.replace(",", ".") // User convenience. We use dots for decimal values
|
|
||||||
// if(parseFloat(text) != base.parentValue)
|
|
||||||
// {
|
|
||||||
// base.valueChanged(parseFloat(text));
|
|
||||||
// }
|
|
||||||
|
|
||||||
propertyProvider.setPropertyValue("value", text)
|
propertyProvider.setPropertyValue("value", text)
|
||||||
}
|
}
|
||||||
|
|
||||||
onEditingFinished:
|
onEditingFinished:
|
||||||
{
|
{
|
||||||
// if(parseFloat(text) != base.parentValue)
|
|
||||||
// {
|
|
||||||
// base.valueChanged(parseFloat(text));
|
|
||||||
// }
|
|
||||||
propertyProvider.setPropertyValue("value", text)
|
propertyProvider.setPropertyValue("value", text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,33 +111,9 @@ SettingItem
|
||||||
{
|
{
|
||||||
target: input
|
target: input
|
||||||
property: "text"
|
property: "text"
|
||||||
value: control.format(propertyProvider.properties.value)
|
value: propertyProvider.properties.value
|
||||||
when: !input.activeFocus
|
when: !input.activeFocus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Rounds a floating point number to 4 decimals. This prevents floating
|
|
||||||
//point rounding errors.
|
|
||||||
//
|
|
||||||
//input: The number to round.
|
|
||||||
//decimals: The number of decimals (digits after the radix) to round to.
|
|
||||||
//return: The rounded number.
|
|
||||||
function roundFloat(input, decimals)
|
|
||||||
{
|
|
||||||
//First convert to fixed-point notation to round the number to 4 decimals and not introduce new floating point errors.
|
|
||||||
//Then convert to a string (is implicit). The fixed-point notation will be something like "3.200".
|
|
||||||
//Then remove any trailing zeroes and the radix.
|
|
||||||
return input.toFixed(decimals).replace(/\.?0*$/, ""); //Match on periods, if any ( \.? ), followed by any number of zeros ( 0* ), then the end of string ( $ ).
|
|
||||||
}
|
|
||||||
|
|
||||||
//Formats a value for display in the text field.
|
|
||||||
//
|
|
||||||
//This correctly handles formatting of float values.
|
|
||||||
//
|
|
||||||
//input: The string value to format.
|
|
||||||
//return: The formatted string.
|
|
||||||
function format(inputValue) {
|
|
||||||
return parseFloat(inputValue) ? roundFloat(parseFloat(inputValue), 4) : inputValue //If it's a float, round to four decimals.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,8 @@ ScrollView
|
||||||
model: UM.SettingDefinitionsModel {
|
model: UM.SettingDefinitionsModel {
|
||||||
id: definitionsModel;
|
id: definitionsModel;
|
||||||
containerId: Cura.MachineManager.activeDefinitionId
|
containerId: Cura.MachineManager.activeDefinitionId
|
||||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
|
exclude: ["machine_settings"]
|
||||||
|
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Loader
|
delegate: Loader
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue