Cura/cura/Machines/Models/IntentSelectionModel.py
2023-11-28 10:07:16 +01:00

138 lines
5.8 KiB
Python

# Copyright (c) 2023 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher.
import collections
from typing import Optional
from PyQt6.QtCore import Qt, QTimer, QObject, QUrl
import cura
from UM import i18nCatalog
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
from UM.Resources import Resources
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.Interfaces import ContainerInterface
from cura.Machines.Models.IntentCategoryModel import IntentCategoryModel
from cura.Settings.IntentManager import IntentManager
catalog = i18nCatalog("cura")
class IntentSelectionModel(ListModel):
NameRole = Qt.ItemDataRole.UserRole + 1
IntentCategoryRole = Qt.ItemDataRole.UserRole + 2
WeightRole = Qt.ItemDataRole.UserRole + 3
DescriptionRole = Qt.ItemDataRole.UserRole + 4
IconRole = Qt.ItemDataRole.UserRole + 5
CustomIconRole = Qt.ItemDataRole.UserRole + 6
def __init__(self, parent: Optional[QObject] = None) -> None:
super().__init__(parent)
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.IntentCategoryRole, "intent_category")
self.addRoleName(self.WeightRole, "weight")
self.addRoleName(self.DescriptionRole, "description")
self.addRoleName(self.IconRole, "icon")
self.addRoleName(self.CustomIconRole, "custom_icon")
application = cura.CuraApplication.CuraApplication.getInstance()
ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChange)
ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChange)
machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
machine_manager.activeMaterialChanged.connect(self._update)
machine_manager.activeVariantChanged.connect(self._update)
machine_manager.extruderChanged.connect(self._update)
extruder_manager = application.getExtruderManager()
extruder_manager.extrudersChanged.connect(self._update)
self._update_timer: QTimer = QTimer()
self._update_timer.setInterval(100)
self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._update)
self._onChange()
_default_intent_categories = ["default", "visual", "engineering", "quick", "annealing", "solid"]
_icons = {"default": "GearCheck", "visual": "Visual", "engineering": "Nut", "quick": "SpeedOMeter",
"annealing": "Anneal", "solid": "Hammer"}
def _onContainerChange(self, container: ContainerInterface) -> None:
"""Updates the list of intents if an intent profile was added or removed."""
if container.getMetaDataEntry("type") == "intent":
self._update()
def _onChange(self) -> None:
self._update_timer.start()
def _update(self) -> None:
Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
cura_application = cura.CuraApplication.CuraApplication.getInstance()
global_stack = cura_application.getGlobalContainerStack()
if global_stack is None:
self.setItems([])
Logger.log("d", "No active GlobalStack, set quality profile model as empty.")
return
# Check for material compatibility
if not cura_application.getMachineManager().activeMaterialsCompatible():
Logger.log("d", "No active material compatibility, set quality profile model as empty.")
self.setItems([])
return
available_categories = IntentManager.getInstance().currentAvailableIntentCategories()
result = []
for category in available_categories:
if category in self._default_intent_categories:
result.append({
"name": IntentCategoryModel.translation(category, "name", category.title()),
"description": IntentCategoryModel.translation(category, "description", None),
"icon": self._icons[category],
"custom_icon": None,
"intent_category": category,
"weight": self._default_intent_categories.index(category),
})
else:
# There can be multiple intents with the same category, use one of these
# intent-metadata's for the icon/description defintions for the intent
intent_metadata = cura_application.getContainerRegistry().findContainersMetadata(type="intent",
definition=global_stack.findInstanceContainerDefinitionId(global_stack.definition),
intent_category=category)[0]
intent_name = intent_metadata.get("name", category.title())
icon = intent_metadata.get("icon", None)
description = intent_metadata.get("description", None)
if icon is not None and icon != '':
try:
icon = QUrl.fromLocalFile(
Resources.getPath(cura.CuraApplication.CuraApplication.ResourceTypes.ImageFiles, icon))
except (FileNotFoundError, NotADirectoryError, PermissionError):
Logger.log("e", f"Icon file for intent {intent_name} not found.")
icon = None
result.append({
"name": intent_name,
"description": description,
"custom_icon": icon,
"icon": None,
"intent_category": category,
"weight": 5,
})
result.sort(key=lambda k: k["weight"])
self.setItems(result)