123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- # Copyright (c) 2017 Ultimaker B.V.
- # Cura is released under the terms of the LGPLv3 or higher.
- import collections
- from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
- from UM.Logger import Logger
- import UM.Qt
- 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
- LabelRole = Qt.UserRole + 2
- UnitRole = Qt.UserRole + 3
- ProfileValueRole = Qt.UserRole + 4
- ProfileValueSourceRole = Qt.UserRole + 5
- UserValueRole = Qt.UserRole + 6
- CategoryRole = Qt.UserRole + 7
- def __init__(self, parent = None):
- super().__init__(parent = parent)
- self._container_registry = ContainerRegistry.getInstance()
- self._extruder_id = None
- self._extruder_definition_id = None
- self._quality_id = None
- self._material_id = None
- self._i18n_catalog = None
- self.addRoleName(self.KeyRole, "key")
- self.addRoleName(self.LabelRole, "label")
- self.addRoleName(self.UnitRole, "unit")
- self.addRoleName(self.ProfileValueRole, "profile_value")
- self.addRoleName(self.ProfileValueSourceRole, "profile_value_source")
- self.addRoleName(self.UserValueRole, "user_value")
- self.addRoleName(self.CategoryRole, "category")
- def setExtruderId(self, extruder_id):
- if extruder_id != self._extruder_id:
- self._extruder_id = extruder_id
- self._update()
- self.extruderIdChanged.emit()
- extruderIdChanged = pyqtSignal()
- @pyqtProperty(str, fset = setExtruderId, notify = extruderIdChanged)
- def extruderId(self):
- return self._extruder_id
- def setExtruderDefinition(self, extruder_definition):
- if extruder_definition != self._extruder_definition_id:
- self._extruder_definition_id = extruder_definition
- self._update()
- self.extruderDefinitionChanged.emit()
- extruderDefinitionChanged = pyqtSignal()
- @pyqtProperty(str, fset = setExtruderDefinition, notify = extruderDefinitionChanged)
- def extruderDefinition(self):
- return self._extruder_definition_id
- def setQuality(self, quality):
- if quality != self._quality_id:
- self._quality_id = quality
- self._update()
- self.qualityChanged.emit()
- qualityChanged = pyqtSignal()
- @pyqtProperty(str, fset = setQuality, notify = qualityChanged)
- def quality(self):
- return self._quality_id
- def setMaterial(self, material):
- if material != self._material_id:
- self._material_id = material
- self._update()
- self.materialChanged.emit()
- materialChanged = pyqtSignal()
- @pyqtProperty(str, fset = setMaterial, notify = materialChanged)
- def material(self):
- return self._material_id
- def _update(self):
- if not self._quality_id:
- return
- items = []
- settings = collections.OrderedDict()
- definition_container = Application.getInstance().getGlobalContainerStack().getBottom()
- containers = self._container_registry.findInstanceContainers(id = self._quality_id)
- if not containers:
- Logger.log("w", "Could not find a quality container with id %s", self._quality_id)
- return
- quality_container = None
- quality_changes_container = None
- if containers[0].getMetaDataEntry("type") == "quality":
- quality_container = containers[0]
- else:
- quality_changes_container = containers[0]
- criteria = {
- "type": "quality",
- "quality_type": quality_changes_container.getMetaDataEntry("quality_type"),
- "definition": quality_changes_container.getDefinition().getId()
- }
- quality_container = self._container_registry.findInstanceContainers(**criteria)
- if not quality_container:
- Logger.log("w", "Could not find a quality container matching quality changes %s", quality_changes_container.getId())
- return
- quality_container = quality_container[0]
- quality_type = quality_container.getMetaDataEntry("quality_type")
- definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(quality_container.getDefinition())
- definition = quality_container.getDefinition()
- # Check if the definition container has a translation file.
- definition_suffix = ContainerRegistry.getMimeTypeForContainer(type(definition)).preferredSuffix
- catalog = i18nCatalog(os.path.basename(definition_id + "." + definition_suffix))
- if catalog.hasTranslationLoaded():
- self._i18n_catalog = catalog
- for file_name in quality_container.getDefinition().getInheritedFiles():
- catalog = i18nCatalog(os.path.basename(file_name))
- if catalog.hasTranslationLoaded():
- self._i18n_catalog = catalog
- criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id}
- if self._material_id and self._material_id != "empty_material":
- criteria["material"] = self._material_id
- criteria["extruder"] = self._extruder_id
- containers = self._container_registry.findInstanceContainers(**criteria)
- if not containers:
- # Try again, this time without extruder
- new_criteria = criteria.copy()
- new_criteria.pop("extruder")
- containers = self._container_registry.findInstanceContainers(**new_criteria)
- if not containers and "material" in criteria:
- # Try again, this time without material
- criteria.pop("material", None)
- containers = self._container_registry.findInstanceContainers(**criteria)
- if not containers:
- # Try again, this time without material or extruder
- criteria.pop("extruder") # "material" has already been popped
- containers = self._container_registry.findInstanceContainers(**criteria)
- if not containers:
- Logger.log("w", "Could not find any quality containers matching the search criteria %s" % str(criteria))
- return
- if quality_changes_container:
- criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()}
- if self._extruder_definition_id != "":
- extruder_definitions = self._container_registry.findDefinitionContainers(id = self._extruder_definition_id)
- if extruder_definitions:
- criteria["extruder"] = Application.getInstance().getMachineManager().getQualityDefinitionId(extruder_definitions[0])
- criteria["name"] = quality_changes_container.getName()
- else:
- criteria["extruder"] = None
- changes = self._container_registry.findInstanceContainers(**criteria)
- if changes:
- containers.extend(changes)
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- is_multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
- current_category = ""
- for definition in definition_container.findDefinitions():
- if definition.type == "category":
- current_category = definition.label
- if self._i18n_catalog:
- current_category = self._i18n_catalog.i18nc(definition.key + " label", definition.label)
- continue
- profile_value = None
- profile_value_source = ""
- for container in containers:
- new_value = container.getProperty(definition.key, "value")
- if new_value is not None:
- profile_value_source = container.getMetaDataEntry("type")
- profile_value = new_value
- # Global tab should use resolve (if there is one)
- if not self._extruder_id:
- resolve_value = global_container_stack.getProperty(definition.key, "resolve")
- if resolve_value is not None and profile_value is not None and profile_value_source != "quality_changes":
- profile_value = resolve_value
- user_value = None
- if not self._extruder_id:
- user_value = global_container_stack.getTop().getProperty(definition.key, "value")
- else:
- extruder_stack = self._container_registry.findContainerStacks(id = self._extruder_id)
- if extruder_stack:
- user_value = extruder_stack[0].getTop().getProperty(definition.key, "value")
- if profile_value is None and user_value is None:
- continue
- if is_multi_extrusion:
- settable_per_extruder = global_container_stack.getProperty(definition.key, "settable_per_extruder")
- # If a setting is not settable per extruder (global) and we're looking at an extruder tab, don't show this value.
- if self._extruder_id != "" and not settable_per_extruder:
- continue
- # If a setting is settable per extruder (not global) and we're looking at global tab, don't show this value.
- if self._extruder_id == "" and settable_per_extruder:
- continue
- label = definition.label
- if self._i18n_catalog:
- label = self._i18n_catalog.i18nc(definition.key + " label", label)
- items.append({
- "key": definition.key,
- "label": label,
- "unit": definition.unit,
- "profile_value": "" if profile_value is None else str(profile_value), # it is for display only
- "profile_value_source": profile_value_source,
- "user_value": "" if user_value is None else str(user_value),
- "category": current_category
- })
- self.setItems(items)
|