Allow picking any printer of the same type when opening project file

A ComboBox was added under the "Update existing" combobox which will display all the available
printers that are of the same type with the printer in the project file. With this feature, the
user will be able to select any same-type preexisting printer in Cura to be updated, instead of
always create a new one when the project file's printer is not in Cura.

CURA-7609
This commit is contained in:
Kostas Karmas 2020-07-29 13:02:34 +02:00
parent f9c6bbb092
commit 98cc87d1cf
3 changed files with 82 additions and 24 deletions

View file

@ -133,12 +133,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# In Cura 2.5 and 2.6, the empty profiles used to have those long names # In Cura 2.5 and 2.6, the empty profiles used to have those long names
self._old_empty_profile_id_dict = {"empty_%s" % k: "empty" for k in ["material", "variant"]} self._old_empty_profile_id_dict = {"empty_%s" % k: "empty" for k in ["material", "variant"]}
self._is_same_machine_type = False # self._is_same_machine_type = False
self._old_new_materials = {} # type: Dict[str, str] self._old_new_materials = {} # type: Dict[str, str]
self._machine_info = None self._machine_info = None
def _clearState(self): def _clearState(self):
self._is_same_machine_type = False # self._is_same_machine_type = False
self._id_mapping = {} self._id_mapping = {}
self._old_new_materials = {} self._old_new_materials = {}
self._machine_info = None self._machine_info = None
@ -229,6 +229,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# Read definition containers # Read definition containers
# #
machine_definition_id = None machine_definition_id = None
available_machines = []
machine_definition_container_count = 0 machine_definition_container_count = 0
extruder_definition_container_count = 0 extruder_definition_container_count = 0
definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)] definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)]
@ -244,7 +245,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
definition_container_type = definition_container.get("type") definition_container_type = definition_container.get("type")
if definition_container_type == "machine": if definition_container_type == "machine":
machine_definition_id = container_id machine_definition_id = container_id # TODO
my_definition_containers = self._container_registry.findDefinitionContainers(id = machine_definition_id)
available_machines = [i.name for i in self._container_registry.findContainerStacks(type = "machine") if
i.definition == my_definition_containers[0]]
machine_type = definition_container["name"] machine_type = definition_container["name"]
variant_type_name = definition_container.get("variants_name", variant_type_name) variant_type_name = definition_container.get("variants_name", variant_type_name)
@ -386,8 +390,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
machine_definition_id = id_list[7] machine_definition_id = id_list[7]
stacks = self._container_registry.findContainerStacks(name = machine_name, type = "machine") stacks = self._container_registry.findContainerStacks(name = machine_name, type = "machine")
self._is_same_machine_type = True # self._is_same_machine_type = True
existing_global_stack = None existing_global_stack = None
global_stack = None
if stacks: if stacks:
global_stack = stacks[0] global_stack = stacks[0]
@ -400,7 +405,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if global_stack.getContainer(index).getId() != container_id: if global_stack.getContainer(index).getId() != container_id:
machine_conflict = True machine_conflict = True
break break
self._is_same_machine_type = global_stack.definition.getId() == machine_definition_id elif available_machines:
containers_found_dict["machine"] = True
# self._is_same_machine_type = global_stack.definition.getId() == machine_definition_id
# Get quality type # Get quality type
parser = ConfigParser(interpolation = None) parser = ConfigParser(interpolation = None)
@ -482,7 +489,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if intent_id not in ("empty", "empty_intent"): if intent_id not in ("empty", "empty_intent"):
extruder_info.intent_info = instance_container_info_dict[intent_id] extruder_info.intent_info = instance_container_info_dict[intent_id]
if not machine_conflict and containers_found_dict["machine"]: if not machine_conflict and containers_found_dict["machine"] and global_stack:
if int(position) >= len(global_stack.extruderList): if int(position) >= len(global_stack.extruderList):
continue continue
@ -548,8 +555,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._machine_info.custom_quality_name = quality_name self._machine_info.custom_quality_name = quality_name
self._machine_info.intent_category = intent_category self._machine_info.intent_category = intent_category
if machine_conflict and not self._is_same_machine_type: # if machine_conflict and not self._is_same_machine_type:
machine_conflict = False # machine_conflict = False
is_printer_group = False is_printer_group = False
if machine_conflict: if machine_conflict:
@ -571,6 +578,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._dialog.setNumSettingsOverriddenByQualityChanges(num_settings_overridden_by_quality_changes) self._dialog.setNumSettingsOverriddenByQualityChanges(num_settings_overridden_by_quality_changes)
self._dialog.setNumUserSettings(num_user_settings) self._dialog.setNumUserSettings(num_user_settings)
self._dialog.setActiveMode(active_mode) self._dialog.setActiveMode(active_mode)
self._dialog.setAvailableMachines(available_machines)
self._dialog.setMachineName(machine_name) self._dialog.setMachineName(machine_name)
self._dialog.setMaterialLabels(material_labels) self._dialog.setMaterialLabels(material_labels)
self._dialog.setMachineType(machine_type) self._dialog.setMachineType(machine_type)
@ -652,7 +660,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
application.expandedCategoriesChanged.emit() # Notify the GUI of the change application.expandedCategoriesChanged.emit() # Notify the GUI of the change
# If a machine with the same name is of a different type, always create a new one. # If a machine with the same name is of a different type, always create a new one.
if not self._is_same_machine_type or self._resolve_strategies["machine"] != "override": if self._resolve_strategies["machine"] != "override" or not self._dialog.availableMachines:
# We need to create a new machine # We need to create a new machine
machine_name = self._container_registry.uniqueName(self._machine_info.name) machine_name = self._container_registry.uniqueName(self._machine_info.name)
@ -662,8 +670,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._container_registry.addContainer(global_stack) self._container_registry.addContainer(global_stack)
else: else:
# Find the machine # Find the machine which will be overridden
global_stacks = self._container_registry.findContainerStacks(name = self._machine_info.name, type = "machine") global_stacks = self._container_registry.findContainerStacks(name = self._dialog.getMachineToOverride(), type = "machine")
if not global_stacks: if not global_stacks:
message = Message(i18n_catalog.i18nc("@info:error Don't translate the XML tag <filename>!", "Project file <filename>{0}</filename> is made using profiles that are unknown to this version of Ultimaker Cura.", file_name)) message = Message(i18n_catalog.i18nc("@info:error Don't translate the XML tag <filename>!", "Project file <filename>{0}</filename> is made using profiles that are unknown to this version of Ultimaker Cura.", file_name))
message.show() message.show()

View file

@ -29,6 +29,7 @@ class WorkspaceDialog(QObject):
"quality_changes": self._default_strategy, "quality_changes": self._default_strategy,
"definition_changes": self._default_strategy, "definition_changes": self._default_strategy,
"material": self._default_strategy} "material": self._default_strategy}
self._override_machine = None
self._visible = False self._visible = False
self.showDialogSignal.connect(self.__show) self.showDialogSignal.connect(self.__show)
@ -45,6 +46,7 @@ class WorkspaceDialog(QObject):
self._quality_type = "" self._quality_type = ""
self._intent_name = "" self._intent_name = ""
self._machine_name = "" self._machine_name = ""
self._available_machines = []
self._machine_type = "" self._machine_type = ""
self._variant_type = "" self._variant_type = ""
self._material_labels = [] self._material_labels = []
@ -63,6 +65,7 @@ class WorkspaceDialog(QObject):
qualityTypeChanged = pyqtSignal() qualityTypeChanged = pyqtSignal()
intentNameChanged = pyqtSignal() intentNameChanged = pyqtSignal()
machineNameChanged = pyqtSignal() machineNameChanged = pyqtSignal()
availableMachinesChanged = pyqtSignal()
materialLabelsChanged = pyqtSignal() materialLabelsChanged = pyqtSignal()
objectsOnPlateChanged = pyqtSignal() objectsOnPlateChanged = pyqtSignal()
numUserSettingsChanged = pyqtSignal() numUserSettingsChanged = pyqtSignal()
@ -142,6 +145,19 @@ class WorkspaceDialog(QObject):
self._machine_name = machine_name self._machine_name = machine_name
self.machineNameChanged.emit() self.machineNameChanged.emit()
@pyqtProperty("QVariantList", notify = availableMachinesChanged)
def availableMachines(self):
return self._available_machines
def setAvailableMachines(self, available_machines):
if self._available_machines != available_machines:
self._available_machines = sorted(available_machines)
self.availableMachinesChanged.emit()
@pyqtProperty(int, notify = availableMachinesChanged)
def availableMachinesCount(self):
return len(self._available_machines)
@pyqtProperty(str, notify=qualityTypeChanged) @pyqtProperty(str, notify=qualityTypeChanged)
def qualityType(self): def qualityType(self):
return self._quality_type return self._quality_type
@ -229,6 +245,13 @@ class WorkspaceDialog(QObject):
if key in self._result: if key in self._result:
self._result[key] = strategy self._result[key] = strategy
def getMachineToOverride(self):
return self._override_machine
@pyqtSlot(str)
def setMachineToOverride(self, machine_name):
self._override_machine = machine_name
@pyqtSlot() @pyqtSlot()
def closeBackend(self): def closeBackend(self):
"""Close the backend: otherwise one could end up with "Slicing...""" """Close the backend: otherwise one could end up with "Slicing..."""

View file

@ -20,6 +20,7 @@ UM.Dialog
property int comboboxHeight: 15 * screenScaleFactor property int comboboxHeight: 15 * screenScaleFactor
property int spacerHeight: 10 * screenScaleFactor property int spacerHeight: 10 * screenScaleFactor
property string machineResolveStrategyCurrentKey: "override"
onClosing: manager.notifyClosed() onClosing: manager.notifyClosed()
onVisibleChanged: onVisibleChanged:
@ -101,34 +102,27 @@ UM.Dialog
} }
UM.TooltipArea UM.TooltipArea
{ {
id: machineResolveTooltip id: machineResolveStrategyTooltip
width: (parent.width / 3) | 0 width: (parent.width / 3) | 0
height: visible ? comboboxHeight : 0 height: visible ? comboboxHeight : 0
visible: manager.machineConflict visible: manager.availableMachinesCount != 0
text: catalog.i18nc("@info:tooltip", "How should the conflict in the machine be resolved?") text: catalog.i18nc("@info:tooltip", "How should the conflict in the machine be resolved?")
ComboBox ComboBox
{ {
id: machineResolveComboBox
model: ListModel model: ListModel
{ {
Component.onCompleted: Component.onCompleted:
{ {
append({"key": "override", "label": catalog.i18nc("@action:ComboBox option", "Update") + " " + manager.machineName}); append({"key": "override", "label": catalog.i18nc("@action:ComboBox option", "Update existing printer")});
append({"key": "new", "label": catalog.i18nc("@action:ComboBox option", "Create new")}); append({"key": "new", "label": catalog.i18nc("@action:ComboBox option", "Create new printer")});
}
}
Connections
{
target: manager
onMachineNameChanged:
{
machineResolveComboBox.model.get(0).label = catalog.i18nc("@action:ComboBox option", "Update") + " " + manager.machineName;
} }
} }
textRole: "label" textRole: "label"
id: machineResolveComboBox
width: parent.width width: parent.width
onActivated: onActivated:
{ {
machineResolveStrategyCurrentKey = resolveStrategiesModel.get(index).key
manager.setResolveStrategy("machine", resolveStrategiesModel.get(index).key) manager.setResolveStrategy("machine", resolveStrategiesModel.get(index).key)
} }
} }
@ -164,6 +158,39 @@ UM.Dialog
text: manager.machineName text: manager.machineName
width: (parent.width / 3) | 0 width: (parent.width / 3) | 0
} }
UM.TooltipArea
{
id: machineResolveTooltip
width: (parent.width / 3) | 0
height: visible ? comboboxHeight : 0
visible: base.visible && manager.availableMachinesCount != 0 && machineResolveStrategyCurrentKey == "override"
text: catalog.i18nc("@info:tooltip", "Which machine of the same type should be overriden?")
ComboBox
{
id: selectMachineComboBox
model: manager.availableMachines
width: parent.width
onCurrentIndexChanged:
{
manager.setMachineToOverride(model[currentIndex])
}
onVisibleChanged:
{
if (visible)
{
currentIndex = 0
for (var i = 0; i < count; i++)
{
if (model[i] == manager.machineName)
{
currentIndex = i
break
}
}
}
}
}
}
} }
Item // Spacer Item // Spacer