mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-13 09:47:50 -06:00
Merge branch 'CURA-7609_Pick_any_printer_when_opening_a_project_file_single_dropdown' of github.com:Ultimaker/Cura
This commit is contained in:
commit
ebdab94b98
4 changed files with 179 additions and 87 deletions
|
@ -133,12 +133,10 @@ 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._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._id_mapping = {}
|
self._id_mapping = {}
|
||||||
self._old_new_materials = {}
|
self._old_new_materials = {}
|
||||||
self._machine_info = None
|
self._machine_info = None
|
||||||
|
@ -229,6 +227,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
# Read definition containers
|
# Read definition containers
|
||||||
#
|
#
|
||||||
machine_definition_id = None
|
machine_definition_id = None
|
||||||
|
updatable_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)]
|
||||||
|
@ -245,6 +244,9 @@ 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
|
||||||
|
machine_definition_containers = self._container_registry.findDefinitionContainers(id = machine_definition_id)
|
||||||
|
if machine_definition_containers:
|
||||||
|
updatable_machines = [machine for machine in self._container_registry.findContainerStacks(type = "machine") if machine.definition == machine_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 +388,8 @@ 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
|
|
||||||
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 +402,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
|
|
||||||
|
if updatable_machines and not containers_found_dict["machine"]:
|
||||||
|
containers_found_dict["machine"] = True
|
||||||
|
|
||||||
# Get quality type
|
# Get quality type
|
||||||
parser = ConfigParser(interpolation = None)
|
parser = ConfigParser(interpolation = None)
|
||||||
|
@ -485,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
|
||||||
|
|
||||||
|
@ -555,9 +559,6 @@ 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:
|
|
||||||
machine_conflict = False
|
|
||||||
|
|
||||||
is_printer_group = False
|
is_printer_group = False
|
||||||
if machine_conflict:
|
if machine_conflict:
|
||||||
group_name = existing_global_stack.getMetaDataEntry("group_name")
|
group_name = existing_global_stack.getMetaDataEntry("group_name")
|
||||||
|
@ -578,6 +579,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.setUpdatableMachines(updatable_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)
|
||||||
|
@ -658,8 +660,8 @@ 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 there are no machines of the same type, create a new machine.
|
||||||
if not self._is_same_machine_type or self._resolve_strategies["machine"] != "override":
|
if self._resolve_strategies["machine"] != "override" or self._dialog.updatableMachinesModel.count <= 1:
|
||||||
# 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)
|
||||||
|
|
||||||
|
@ -669,10 +671,12 @@ 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()
|
||||||
self.setWorkspaceName("")
|
self.setWorkspaceName("")
|
||||||
return [], {}
|
return [], {}
|
||||||
|
|
43
plugins/3MFReader/UpdatableMachinesModel.py
Normal file
43
plugins/3MFReader/UpdatableMachinesModel.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# Copyright (c) 2020 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
from PyQt5.QtCore import Qt
|
||||||
|
|
||||||
|
from UM.Qt.ListModel import ListModel
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
|
||||||
|
create_new_list_item = {
|
||||||
|
"id": "new",
|
||||||
|
"name": "Create new",
|
||||||
|
"displayName": "Create new",
|
||||||
|
"type": "default_option" # to make sure we are not mixing the "Create new" option with a printer with id "new"
|
||||||
|
} # type: Dict[str, str]
|
||||||
|
|
||||||
|
|
||||||
|
class UpdatableMachinesModel(ListModel):
|
||||||
|
"""Model that holds cura packages.
|
||||||
|
|
||||||
|
By setting the filter property the instances held by this model can be changed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, parent = None) -> None:
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.addRoleName(Qt.UserRole + 1, "id")
|
||||||
|
self.addRoleName(Qt.UserRole + 2, "name")
|
||||||
|
self.addRoleName(Qt.UserRole + 3, "displayName")
|
||||||
|
self.addRoleName(Qt.UserRole + 4, "type") # Either "default_option" or "machine"
|
||||||
|
|
||||||
|
def update(self, machines: List[GlobalStack]) -> None:
|
||||||
|
items = [create_new_list_item] # type: List[Dict[str, str]]
|
||||||
|
|
||||||
|
for machine in sorted(machines, key = lambda printer: printer.name):
|
||||||
|
items.append({
|
||||||
|
"id": machine.id,
|
||||||
|
"name": machine.name,
|
||||||
|
"displayName": "Update " + machine.name,
|
||||||
|
"type": "machine"
|
||||||
|
})
|
||||||
|
self.setItems(items)
|
|
@ -1,5 +1,6 @@
|
||||||
# Copyright (c) 2016 Ultimaker B.V.
|
# Copyright (c) 2020 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
from typing import List, Optional, Dict, cast
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication
|
from PyQt5.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication
|
||||||
from UM.FlameProfiler import pyqtSlot
|
from UM.FlameProfiler import pyqtSlot
|
||||||
|
@ -7,10 +8,15 @@ from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
from .UpdatableMachinesModel import UpdatableMachinesModel
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
i18n_catalog = i18nCatalog("cura")
|
i18n_catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +35,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)
|
||||||
|
|
||||||
|
@ -51,6 +58,7 @@ class WorkspaceDialog(QObject):
|
||||||
self._extruders = []
|
self._extruders = []
|
||||||
self._objects_on_plate = False
|
self._objects_on_plate = False
|
||||||
self._is_printer_group = False
|
self._is_printer_group = False
|
||||||
|
self._updatable_machines_model = UpdatableMachinesModel(self)
|
||||||
|
|
||||||
machineConflictChanged = pyqtSignal()
|
machineConflictChanged = pyqtSignal()
|
||||||
qualityChangesConflictChanged = pyqtSignal()
|
qualityChangesConflictChanged = pyqtSignal()
|
||||||
|
@ -63,6 +71,7 @@ class WorkspaceDialog(QObject):
|
||||||
qualityTypeChanged = pyqtSignal()
|
qualityTypeChanged = pyqtSignal()
|
||||||
intentNameChanged = pyqtSignal()
|
intentNameChanged = pyqtSignal()
|
||||||
machineNameChanged = pyqtSignal()
|
machineNameChanged = pyqtSignal()
|
||||||
|
updatableMachinesChanged = pyqtSignal()
|
||||||
materialLabelsChanged = pyqtSignal()
|
materialLabelsChanged = pyqtSignal()
|
||||||
objectsOnPlateChanged = pyqtSignal()
|
objectsOnPlateChanged = pyqtSignal()
|
||||||
numUserSettingsChanged = pyqtSignal()
|
numUserSettingsChanged = pyqtSignal()
|
||||||
|
@ -81,33 +90,33 @@ class WorkspaceDialog(QObject):
|
||||||
self.isPrinterGroupChanged.emit()
|
self.isPrinterGroupChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, notify=variantTypeChanged)
|
@pyqtProperty(str, notify=variantTypeChanged)
|
||||||
def variantType(self):
|
def variantType(self) -> str:
|
||||||
return self._variant_type
|
return self._variant_type
|
||||||
|
|
||||||
def setVariantType(self, variant_type):
|
def setVariantType(self, variant_type: str) -> None:
|
||||||
if self._variant_type != variant_type:
|
if self._variant_type != variant_type:
|
||||||
self._variant_type = variant_type
|
self._variant_type = variant_type
|
||||||
self.variantTypeChanged.emit()
|
self.variantTypeChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, notify=machineTypeChanged)
|
@pyqtProperty(str, notify=machineTypeChanged)
|
||||||
def machineType(self):
|
def machineType(self) -> str:
|
||||||
return self._machine_type
|
return self._machine_type
|
||||||
|
|
||||||
def setMachineType(self, machine_type):
|
def setMachineType(self, machine_type: str) -> None:
|
||||||
self._machine_type = machine_type
|
self._machine_type = machine_type
|
||||||
self.machineTypeChanged.emit()
|
self.machineTypeChanged.emit()
|
||||||
|
|
||||||
def setNumUserSettings(self, num_user_settings):
|
def setNumUserSettings(self, num_user_settings: int) -> None:
|
||||||
if self._num_user_settings != num_user_settings:
|
if self._num_user_settings != num_user_settings:
|
||||||
self._num_user_settings = num_user_settings
|
self._num_user_settings = num_user_settings
|
||||||
self.numVisibleSettingsChanged.emit()
|
self.numVisibleSettingsChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(int, notify=numUserSettingsChanged)
|
@pyqtProperty(int, notify=numUserSettingsChanged)
|
||||||
def numUserSettings(self):
|
def numUserSettings(self) -> int:
|
||||||
return self._num_user_settings
|
return self._num_user_settings
|
||||||
|
|
||||||
@pyqtProperty(bool, notify=objectsOnPlateChanged)
|
@pyqtProperty(bool, notify=objectsOnPlateChanged)
|
||||||
def hasObjectsOnPlate(self):
|
def hasObjectsOnPlate(self) -> bool:
|
||||||
return self._objects_on_plate
|
return self._objects_on_plate
|
||||||
|
|
||||||
def setHasObjectsOnPlate(self, objects_on_plate):
|
def setHasObjectsOnPlate(self, objects_on_plate):
|
||||||
|
@ -116,10 +125,10 @@ class WorkspaceDialog(QObject):
|
||||||
self.objectsOnPlateChanged.emit()
|
self.objectsOnPlateChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty("QVariantList", notify = materialLabelsChanged)
|
@pyqtProperty("QVariantList", notify = materialLabelsChanged)
|
||||||
def materialLabels(self):
|
def materialLabels(self) -> List[str]:
|
||||||
return self._material_labels
|
return self._material_labels
|
||||||
|
|
||||||
def setMaterialLabels(self, material_labels):
|
def setMaterialLabels(self, material_labels: List[str]) -> None:
|
||||||
if self._material_labels != material_labels:
|
if self._material_labels != material_labels:
|
||||||
self._material_labels = material_labels
|
self._material_labels = material_labels
|
||||||
self.materialLabelsChanged.emit()
|
self.materialLabelsChanged.emit()
|
||||||
|
@ -134,36 +143,44 @@ class WorkspaceDialog(QObject):
|
||||||
self.extrudersChanged.emit()
|
self.extrudersChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, notify = machineNameChanged)
|
@pyqtProperty(str, notify = machineNameChanged)
|
||||||
def machineName(self):
|
def machineName(self) -> str:
|
||||||
return self._machine_name
|
return self._machine_name
|
||||||
|
|
||||||
def setMachineName(self, machine_name):
|
def setMachineName(self, machine_name: str) -> None:
|
||||||
if self._machine_name != machine_name:
|
if self._machine_name != machine_name:
|
||||||
self._machine_name = machine_name
|
self._machine_name = machine_name
|
||||||
self.machineNameChanged.emit()
|
self.machineNameChanged.emit()
|
||||||
|
|
||||||
|
@pyqtProperty(QObject, notify = updatableMachinesChanged)
|
||||||
|
def updatableMachinesModel(self) -> UpdatableMachinesModel:
|
||||||
|
return cast(UpdatableMachinesModel, self._updatable_machines_model)
|
||||||
|
|
||||||
|
def setUpdatableMachines(self, updatable_machines: List[GlobalStack]) -> None:
|
||||||
|
self._updatable_machines_model.update(updatable_machines)
|
||||||
|
self.updatableMachinesChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, notify=qualityTypeChanged)
|
@pyqtProperty(str, notify=qualityTypeChanged)
|
||||||
def qualityType(self):
|
def qualityType(self) -> str:
|
||||||
return self._quality_type
|
return self._quality_type
|
||||||
|
|
||||||
def setQualityType(self, quality_type):
|
def setQualityType(self, quality_type: str) -> None:
|
||||||
if self._quality_type != quality_type:
|
if self._quality_type != quality_type:
|
||||||
self._quality_type = quality_type
|
self._quality_type = quality_type
|
||||||
self.qualityTypeChanged.emit()
|
self.qualityTypeChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(int, notify=numSettingsOverridenByQualityChangesChanged)
|
@pyqtProperty(int, notify=numSettingsOverridenByQualityChangesChanged)
|
||||||
def numSettingsOverridenByQualityChanges(self):
|
def numSettingsOverridenByQualityChanges(self) -> int:
|
||||||
return self._num_settings_overridden_by_quality_changes
|
return self._num_settings_overridden_by_quality_changes
|
||||||
|
|
||||||
def setNumSettingsOverriddenByQualityChanges(self, num_settings_overridden_by_quality_changes):
|
def setNumSettingsOverriddenByQualityChanges(self, num_settings_overridden_by_quality_changes: int) -> None:
|
||||||
self._num_settings_overridden_by_quality_changes = num_settings_overridden_by_quality_changes
|
self._num_settings_overridden_by_quality_changes = num_settings_overridden_by_quality_changes
|
||||||
self.numSettingsOverridenByQualityChangesChanged.emit()
|
self.numSettingsOverridenByQualityChangesChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, notify=qualityNameChanged)
|
@pyqtProperty(str, notify=qualityNameChanged)
|
||||||
def qualityName(self):
|
def qualityName(self) -> str:
|
||||||
return self._quality_name
|
return self._quality_name
|
||||||
|
|
||||||
def setQualityName(self, quality_name):
|
def setQualityName(self, quality_name: str) -> None:
|
||||||
if self._quality_name != quality_name:
|
if self._quality_name != quality_name:
|
||||||
self._quality_name = quality_name
|
self._quality_name = quality_name
|
||||||
self.qualityNameChanged.emit()
|
self.qualityNameChanged.emit()
|
||||||
|
@ -178,80 +195,87 @@ class WorkspaceDialog(QObject):
|
||||||
self.intentNameChanged.emit()
|
self.intentNameChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, notify=activeModeChanged)
|
@pyqtProperty(str, notify=activeModeChanged)
|
||||||
def activeMode(self):
|
def activeMode(self) -> str:
|
||||||
return self._active_mode
|
return self._active_mode
|
||||||
|
|
||||||
def setActiveMode(self, active_mode):
|
def setActiveMode(self, active_mode: int) -> None:
|
||||||
if active_mode == 0:
|
if active_mode == 0:
|
||||||
self._active_mode = i18n_catalog.i18nc("@title:tab", "Recommended")
|
self._active_mode = i18n_catalog.i18nc("@title:tab", "Recommended")
|
||||||
else:
|
else:
|
||||||
self._active_mode = i18n_catalog.i18nc("@title:tab", "Custom")
|
self._active_mode = i18n_catalog.i18nc("@title:tab", "Custom")
|
||||||
self.activeModeChanged.emit()
|
self.activeModeChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(int, notify = hasVisibleSettingsFieldChanged)
|
@pyqtProperty(bool, notify = hasVisibleSettingsFieldChanged)
|
||||||
def hasVisibleSettingsField(self):
|
def hasVisibleSettingsField(self) -> bool:
|
||||||
return self._has_visible_settings_field
|
return self._has_visible_settings_field
|
||||||
|
|
||||||
def setHasVisibleSettingsField(self, has_visible_settings_field):
|
def setHasVisibleSettingsField(self, has_visible_settings_field: bool) -> None:
|
||||||
self._has_visible_settings_field = has_visible_settings_field
|
self._has_visible_settings_field = has_visible_settings_field
|
||||||
self.hasVisibleSettingsFieldChanged.emit()
|
self.hasVisibleSettingsFieldChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(int, constant = True)
|
@pyqtProperty(int, constant = True)
|
||||||
def totalNumberOfSettings(self):
|
def totalNumberOfSettings(self) -> int:
|
||||||
general_definition_containers = ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")
|
general_definition_containers = ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")
|
||||||
if not general_definition_containers:
|
if not general_definition_containers:
|
||||||
return 0
|
return 0
|
||||||
return len(general_definition_containers[0].getAllKeys())
|
return len(general_definition_containers[0].getAllKeys())
|
||||||
|
|
||||||
@pyqtProperty(int, notify = numVisibleSettingsChanged)
|
@pyqtProperty(int, notify = numVisibleSettingsChanged)
|
||||||
def numVisibleSettings(self):
|
def numVisibleSettings(self) -> int:
|
||||||
return self._num_visible_settings
|
return self._num_visible_settings
|
||||||
|
|
||||||
def setNumVisibleSettings(self, num_visible_settings):
|
def setNumVisibleSettings(self, num_visible_settings: int) -> None:
|
||||||
if self._num_visible_settings != num_visible_settings:
|
if self._num_visible_settings != num_visible_settings:
|
||||||
self._num_visible_settings = num_visible_settings
|
self._num_visible_settings = num_visible_settings
|
||||||
self.numVisibleSettingsChanged.emit()
|
self.numVisibleSettingsChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(bool, notify = machineConflictChanged)
|
@pyqtProperty(bool, notify = machineConflictChanged)
|
||||||
def machineConflict(self):
|
def machineConflict(self) -> bool:
|
||||||
return self._has_machine_conflict
|
return self._has_machine_conflict
|
||||||
|
|
||||||
@pyqtProperty(bool, notify=qualityChangesConflictChanged)
|
@pyqtProperty(bool, notify=qualityChangesConflictChanged)
|
||||||
def qualityChangesConflict(self):
|
def qualityChangesConflict(self) -> bool:
|
||||||
return self._has_quality_changes_conflict
|
return self._has_quality_changes_conflict
|
||||||
|
|
||||||
@pyqtProperty(bool, notify=materialConflictChanged)
|
@pyqtProperty(bool, notify=materialConflictChanged)
|
||||||
def materialConflict(self):
|
def materialConflict(self) -> bool:
|
||||||
return self._has_material_conflict
|
return self._has_material_conflict
|
||||||
|
|
||||||
@pyqtSlot(str, str)
|
@pyqtSlot(str, str)
|
||||||
def setResolveStrategy(self, key, strategy):
|
def setResolveStrategy(self, key: str, strategy: Optional[str]) -> None:
|
||||||
if key in self._result:
|
if key in self._result:
|
||||||
self._result[key] = strategy
|
self._result[key] = strategy
|
||||||
|
|
||||||
|
def getMachineToOverride(self) -> str:
|
||||||
|
return self._override_machine
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def setMachineToOverride(self, machine_name: str) -> None:
|
||||||
|
self._override_machine = machine_name
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def closeBackend(self):
|
def closeBackend(self) -> None:
|
||||||
"""Close the backend: otherwise one could end up with "Slicing..."""
|
"""Close the backend: otherwise one could end up with "Slicing..."""
|
||||||
|
|
||||||
Application.getInstance().getBackend().close()
|
Application.getInstance().getBackend().close()
|
||||||
|
|
||||||
def setMaterialConflict(self, material_conflict):
|
def setMaterialConflict(self, material_conflict: bool) -> None:
|
||||||
if self._has_material_conflict != material_conflict:
|
if self._has_material_conflict != material_conflict:
|
||||||
self._has_material_conflict = material_conflict
|
self._has_material_conflict = material_conflict
|
||||||
self.materialConflictChanged.emit()
|
self.materialConflictChanged.emit()
|
||||||
|
|
||||||
def setMachineConflict(self, machine_conflict):
|
def setMachineConflict(self, machine_conflict: bool) -> None:
|
||||||
if self._has_machine_conflict != machine_conflict:
|
if self._has_machine_conflict != machine_conflict:
|
||||||
self._has_machine_conflict = machine_conflict
|
self._has_machine_conflict = machine_conflict
|
||||||
self.machineConflictChanged.emit()
|
self.machineConflictChanged.emit()
|
||||||
|
|
||||||
def setQualityChangesConflict(self, quality_changes_conflict):
|
def setQualityChangesConflict(self, quality_changes_conflict: bool) -> None:
|
||||||
if self._has_quality_changes_conflict != quality_changes_conflict:
|
if self._has_quality_changes_conflict != quality_changes_conflict:
|
||||||
self._has_quality_changes_conflict = quality_changes_conflict
|
self._has_quality_changes_conflict = quality_changes_conflict
|
||||||
self.qualityChangesConflictChanged.emit()
|
self.qualityChangesConflictChanged.emit()
|
||||||
|
|
||||||
def getResult(self):
|
def getResult(self) -> Dict[str, Optional[str]]:
|
||||||
if "machine" in self._result and not self._has_machine_conflict:
|
if "machine" in self._result and self.updatableMachinesModel.count <= 1:
|
||||||
self._result["machine"] = None
|
self._result["machine"] = None
|
||||||
if "quality_changes" in self._result and not self._has_quality_changes_conflict:
|
if "quality_changes" in self._result and not self._has_quality_changes_conflict:
|
||||||
self._result["quality_changes"] = None
|
self._result["quality_changes"] = None
|
||||||
|
@ -267,11 +291,13 @@ class WorkspaceDialog(QObject):
|
||||||
|
|
||||||
return self._result
|
return self._result
|
||||||
|
|
||||||
def _createViewFromQML(self):
|
def _createViewFromQML(self) -> None:
|
||||||
path = os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url)
|
three_mf_reader_path = PluginRegistry.getInstance().getPluginPath("3MFReader")
|
||||||
self._view = Application.getInstance().createQmlComponent(path, {"manager": self})
|
if three_mf_reader_path:
|
||||||
|
path = os.path.join(three_mf_reader_path, self._qml_url)
|
||||||
|
self._view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
|
||||||
|
|
||||||
def show(self):
|
def show(self) -> None:
|
||||||
# Emit signal so the right thread actually shows the view.
|
# Emit signal so the right thread actually shows the view.
|
||||||
if threading.current_thread() != threading.main_thread():
|
if threading.current_thread() != threading.main_thread():
|
||||||
self._lock.acquire()
|
self._lock.acquire()
|
||||||
|
@ -284,7 +310,7 @@ class WorkspaceDialog(QObject):
|
||||||
self.showDialogSignal.emit()
|
self.showDialogSignal.emit()
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def notifyClosed(self):
|
def notifyClosed(self) -> None:
|
||||||
"""Used to notify the dialog so the lock can be released."""
|
"""Used to notify the dialog so the lock can be released."""
|
||||||
|
|
||||||
self._result = {} # The result should be cleared before hide, because after it is released the main thread lock
|
self._result = {} # The result should be cleared before hide, because after it is released the main thread lock
|
||||||
|
@ -294,7 +320,7 @@ class WorkspaceDialog(QObject):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def hide(self):
|
def hide(self) -> None:
|
||||||
self._visible = False
|
self._visible = False
|
||||||
self._view.hide()
|
self._view.hide()
|
||||||
try:
|
try:
|
||||||
|
@ -303,7 +329,7 @@ class WorkspaceDialog(QObject):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@pyqtSlot(bool)
|
@pyqtSlot(bool)
|
||||||
def _onVisibilityChanged(self, visible):
|
def _onVisibilityChanged(self, visible: bool) -> None:
|
||||||
if not visible:
|
if not visible:
|
||||||
try:
|
try:
|
||||||
self._lock.release()
|
self._lock.release()
|
||||||
|
@ -311,17 +337,17 @@ class WorkspaceDialog(QObject):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def onOkButtonClicked(self):
|
def onOkButtonClicked(self) -> None:
|
||||||
self._view.hide()
|
self._view.hide()
|
||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def onCancelButtonClicked(self):
|
def onCancelButtonClicked(self) -> None:
|
||||||
self._result = {}
|
self._result = {}
|
||||||
self._view.hide()
|
self._view.hide()
|
||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
def waitForClose(self):
|
def waitForClose(self) -> None:
|
||||||
"""Block thread until the dialog is closed."""
|
"""Block thread until the dialog is closed."""
|
||||||
|
|
||||||
if self._visible:
|
if self._visible:
|
||||||
|
@ -334,7 +360,7 @@ class WorkspaceDialog(QObject):
|
||||||
time.sleep(1 / 50)
|
time.sleep(1 / 50)
|
||||||
QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
|
QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
|
||||||
|
|
||||||
def __show(self):
|
def __show(self) -> None:
|
||||||
if self._view is None:
|
if self._view is None:
|
||||||
self._createViewFromQML()
|
self._createViewFromQML()
|
||||||
if self._view:
|
if self._view:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.10
|
import QtQuick 2.10
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 2.3
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Window 2.2
|
import QtQuick.Window 2.2
|
||||||
|
|
||||||
|
@ -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 int doubleSpacerHeight: 20 * screenScaleFactor
|
||||||
|
|
||||||
onClosing: manager.notifyClosed()
|
onClosing: manager.notifyClosed()
|
||||||
onVisibleChanged:
|
onVisibleChanged:
|
||||||
|
@ -35,7 +36,7 @@ UM.Dialog
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 20 * screenScaleFactor
|
anchors.margins: 10 * screenScaleFactor
|
||||||
|
|
||||||
UM.I18nCatalog
|
UM.I18nCatalog
|
||||||
{
|
{
|
||||||
|
@ -79,7 +80,7 @@ UM.Dialog
|
||||||
}
|
}
|
||||||
Item // Spacer
|
Item // Spacer
|
||||||
{
|
{
|
||||||
height: spacerHeight
|
height: doubleSpacerHeight
|
||||||
width: height
|
width: height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,35 +102,53 @@ 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: base.visible && machineResolveComboBox.model.count > 1
|
||||||
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
|
||||||
{
|
{
|
||||||
model: ListModel
|
|
||||||
{
|
|
||||||
Component.onCompleted:
|
|
||||||
{
|
|
||||||
append({"key": "override", "label": catalog.i18nc("@action:ComboBox option", "Update") + " " + manager.machineName});
|
|
||||||
append({"key": "new", "label": catalog.i18nc("@action:ComboBox option", "Create new")});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Connections
|
|
||||||
{
|
|
||||||
target: manager
|
|
||||||
onMachineNameChanged:
|
|
||||||
{
|
|
||||||
machineResolveComboBox.model.get(0).label = catalog.i18nc("@action:ComboBox option", "Update") + " " + manager.machineName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
textRole: "label"
|
|
||||||
id: machineResolveComboBox
|
id: machineResolveComboBox
|
||||||
|
model: manager.updatableMachinesModel
|
||||||
|
visible: machineResolveStrategyTooltip.visible
|
||||||
|
textRole: "displayName"
|
||||||
width: parent.width
|
width: parent.width
|
||||||
onActivated:
|
onCurrentIndexChanged:
|
||||||
{
|
{
|
||||||
manager.setResolveStrategy("machine", resolveStrategiesModel.get(index).key)
|
if (model.getItem(currentIndex).id == "new"
|
||||||
|
&& model.getItem(currentIndex).type == "default_option")
|
||||||
|
{
|
||||||
|
manager.setResolveStrategy("machine", "new")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
manager.setResolveStrategy("machine", "override")
|
||||||
|
manager.setMachineToOverride(model.getItem(currentIndex).id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged:
|
||||||
|
{
|
||||||
|
if (!visible) {return}
|
||||||
|
|
||||||
|
currentIndex = 0
|
||||||
|
// If the project printer exists in Cura, set it as the default dropdown menu option.
|
||||||
|
// No need to check object 0, which is the "Create new" option
|
||||||
|
for (var i = 1; i < model.count; i++)
|
||||||
|
{
|
||||||
|
if (model.getItem(i).name == manager.machineName)
|
||||||
|
{
|
||||||
|
currentIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The project printer does not exist in Cura. If there is at least one printer of the same
|
||||||
|
// type, select the first one, else set the index to "Create new"
|
||||||
|
if (currentIndex == 0 && model.count > 1)
|
||||||
|
{
|
||||||
|
currentIndex = 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +187,7 @@ UM.Dialog
|
||||||
|
|
||||||
Item // Spacer
|
Item // Spacer
|
||||||
{
|
{
|
||||||
height: spacerHeight
|
height: doubleSpacerHeight
|
||||||
width: height
|
width: height
|
||||||
}
|
}
|
||||||
Row
|
Row
|
||||||
|
@ -271,7 +290,7 @@ UM.Dialog
|
||||||
}
|
}
|
||||||
Item // Spacer
|
Item // Spacer
|
||||||
{
|
{
|
||||||
height: spacerHeight
|
height: doubleSpacerHeight
|
||||||
width: height
|
width: height
|
||||||
}
|
}
|
||||||
Row
|
Row
|
||||||
|
@ -333,7 +352,7 @@ UM.Dialog
|
||||||
|
|
||||||
Item // Spacer
|
Item // Spacer
|
||||||
{
|
{
|
||||||
height: spacerHeight
|
height: doubleSpacerHeight
|
||||||
width: height
|
width: height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue