mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-06-26 01:15:28 -06:00
Allow for custom descriptions/icons in packaged intents
CURA-9709
This commit is contained in:
parent
af12166595
commit
27cc89ff89
6 changed files with 72 additions and 54 deletions
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import enum
|
||||
import os
|
||||
|
@ -147,6 +147,7 @@ class CuraApplication(QtApplication):
|
|||
DefinitionChangesContainer = Resources.UserType + 10
|
||||
SettingVisibilityPreset = Resources.UserType + 11
|
||||
IntentInstanceContainer = Resources.UserType + 12
|
||||
ImageFiles = Resources.UserType + 13
|
||||
|
||||
pyqtEnum(ResourceTypes)
|
||||
|
||||
|
@ -425,6 +426,7 @@ class CuraApplication(QtApplication):
|
|||
Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
|
||||
Resources.addStorageType(self.ResourceTypes.SettingVisibilityPreset, "setting_visibility")
|
||||
Resources.addStorageType(self.ResourceTypes.IntentInstanceContainer, "intent")
|
||||
Resources.addStorageType(self.ResourceTypes.ImageFiles, "images")
|
||||
|
||||
self._container_registry.addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality")
|
||||
self._container_registry.addResourceType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes")
|
||||
|
@ -435,6 +437,7 @@ class CuraApplication(QtApplication):
|
|||
self._container_registry.addResourceType(self.ResourceTypes.MachineStack, "machine")
|
||||
self._container_registry.addResourceType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
|
||||
self._container_registry.addResourceType(self.ResourceTypes.IntentInstanceContainer, "intent")
|
||||
self._container_registry.addResourceType(self.ResourceTypes.ImageFiles, "images")
|
||||
|
||||
Resources.addType(self.ResourceTypes.QmlFiles, "qml")
|
||||
Resources.addType(self.ResourceTypes.Firmware, "firmware")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import glob
|
||||
import os
|
||||
|
@ -55,7 +55,9 @@ class CuraPackageManager(PackageManager):
|
|||
def initialize(self) -> None:
|
||||
self._installation_dirs_dict["materials"] = Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer)
|
||||
self._installation_dirs_dict["qualities"] = Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer)
|
||||
self._installation_dirs_dict["variants"] = Resources.getStoragePath(CuraApplication.ResourceTypes.VariantInstanceContainer)
|
||||
self._installation_dirs_dict["variants"] = Resources.getStoragePath(
|
||||
CuraApplication.ResourceTypes.VariantInstanceContainer)
|
||||
self._installation_dirs_dict["images"] = Resources.getStoragePath(CuraApplication.ResourceTypes.ImageFiles)
|
||||
|
||||
# Due to a bug in Cura 5.1.0 we needed to change the directory structure of the curapackage on the server side (See SD-3871).
|
||||
# Although the material intent profiles will be installed in the `intent` folder, the curapackage from the server side will
|
||||
|
|
|
@ -1,29 +1,32 @@
|
|||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import collections
|
||||
from typing import OrderedDict, Optional
|
||||
from typing import Optional
|
||||
|
||||
from PyQt6.QtCore import Qt, QTimer, QObject
|
||||
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)
|
||||
|
@ -33,6 +36,7 @@ class IntentSelectionModel(ListModel):
|
|||
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()
|
||||
|
||||
|
@ -53,30 +57,8 @@ class IntentSelectionModel(ListModel):
|
|||
|
||||
self._onChange()
|
||||
|
||||
@staticmethod
|
||||
def _getDefaultProfileInformation() -> OrderedDict[str, dict]:
|
||||
""" Default information user-visible string. Ordered by weight. """
|
||||
default_profile_information = collections.OrderedDict()
|
||||
default_profile_information["default"] = {
|
||||
"name": catalog.i18nc("@label", "Default"),
|
||||
"icon": "GearCheck"
|
||||
}
|
||||
default_profile_information["visual"] = {
|
||||
"name": catalog.i18nc("@label", "Visual"),
|
||||
"description": catalog.i18nc("@text", "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality."),
|
||||
"icon" : "Visual"
|
||||
}
|
||||
default_profile_information["engineering"] = {
|
||||
"name": catalog.i18nc("@label", "Engineering"),
|
||||
"description": catalog.i18nc("@text", "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances."),
|
||||
"icon": "Nut"
|
||||
}
|
||||
default_profile_information["quick"] = {
|
||||
"name": catalog.i18nc("@label", "Draft"),
|
||||
"description": catalog.i18nc("@text", "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction."),
|
||||
"icon": "SpeedOMeter"
|
||||
}
|
||||
return default_profile_information
|
||||
_default_intent_categories = ["default", "visual", "engineering", "quick"]
|
||||
_icons = {"default": "GearCheck", "visual": "Visual", "engineering": "Nut", "quick": "SpeedOMeter"}
|
||||
|
||||
def _onContainerChange(self, container: ContainerInterface) -> None:
|
||||
"""Updates the list of intents if an intent profile was added or removed."""
|
||||
|
@ -102,25 +84,42 @@ class IntentSelectionModel(ListModel):
|
|||
self.setItems([])
|
||||
return
|
||||
|
||||
default_profile_info = self._getDefaultProfileInformation()
|
||||
|
||||
available_categories = IntentManager.getInstance().currentAvailableIntentCategories()
|
||||
|
||||
result = []
|
||||
for i, category in enumerate(available_categories):
|
||||
profile_info = default_profile_info.get(category, {})
|
||||
for category in available_categories:
|
||||
|
||||
try:
|
||||
weight = list(default_profile_info.keys()).index(category)
|
||||
except ValueError:
|
||||
weight = len(available_categories) + i
|
||||
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.CuraApplication.CuraApplication \
|
||||
.getInstance() \
|
||||
.getContainerRegistry() \
|
||||
.findContainersMetadata(type="intent", definition=global_stack.definition.getId(),
|
||||
intent_category=category)[0]
|
||||
|
||||
result.append({
|
||||
"name": profile_info.get("name", category.title()),
|
||||
"description": profile_info.get("description", None),
|
||||
"icon" : profile_info.get("icon", ""),
|
||||
"intent_category": category,
|
||||
"weight": weight,
|
||||
})
|
||||
icon = intent_metadata.get("icon", None)
|
||||
if icon is not None:
|
||||
icon = QUrl.fromLocalFile(
|
||||
Resources.getPath(cura.CuraApplication.CuraApplication.ResourceTypes.ImageFiles, icon))
|
||||
|
||||
result.append({
|
||||
"name": intent_metadata.get("name", category.title()),
|
||||
"description": intent_metadata.get("description", None),
|
||||
"custom_icon": icon,
|
||||
"icon": None,
|
||||
"intent_category": category,
|
||||
"weight": 5,
|
||||
})
|
||||
|
||||
result.sort(key=lambda k: k["weight"])
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2021 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from UM.Settings.SQLQueryFactory import SQLQueryFactory
|
||||
|
@ -10,8 +10,8 @@ class IntentDatabaseHandler(DatabaseMetadataContainerController):
|
|||
"""The Database handler for Intent containers"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(SQLQueryFactory(table = "intent",
|
||||
fields = {
|
||||
super().__init__(SQLQueryFactory(table="intent",
|
||||
fields={
|
||||
"id": "text",
|
||||
"name": "text",
|
||||
"quality_type": "text",
|
||||
|
@ -20,6 +20,8 @@ class IntentDatabaseHandler(DatabaseMetadataContainerController):
|
|||
"definition": "text",
|
||||
"material": "text",
|
||||
"version": "text",
|
||||
"setting_version": "text"
|
||||
"setting_version": "text",
|
||||
"icon": "text",
|
||||
"description": "text",
|
||||
}))
|
||||
self._container_type = InstanceContainer
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2022 Ultimaker B.V.
|
||||
// Copyright (c) 2023 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
|
@ -32,6 +32,7 @@ Item
|
|||
{
|
||||
profileName: model.name
|
||||
icon: model.icon
|
||||
custom_icon: model.custom_icon
|
||||
tooltipText: model.description ? model.description : ""
|
||||
|
||||
selected: Cura.MachineManager.activeIntentCategory == model.intent_category
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2022 Ultimaker B.V.
|
||||
// Copyright (c) 2023 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
|
@ -19,6 +19,7 @@ Rectangle
|
|||
property bool selected: false
|
||||
property string profileName: ""
|
||||
property string icon: ""
|
||||
property string custom_icon: ""
|
||||
property alias tooltipText: tooltip.text
|
||||
|
||||
signal clicked()
|
||||
|
@ -55,22 +56,32 @@ Rectangle
|
|||
id: intentIcon
|
||||
width: UM.Theme.getSize("recommended_button_icon").width
|
||||
height: UM.Theme.getSize("recommended_button_icon").height
|
||||
|
||||
UM.ColorImage
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
visible: icon != ""
|
||||
visible: icon !== ""
|
||||
source: UM.Theme.getIcon(icon)
|
||||
color: UM.Theme.getColor("icon")
|
||||
}
|
||||
|
||||
UM.ColorImage
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
visible: custom_icon !== ""
|
||||
source: custom_icon
|
||||
color: UM.Theme.getColor("icon")
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: circle
|
||||
anchors.fill: parent
|
||||
radius: width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: icon == ""
|
||||
visible: icon === "" && custom_icon === ""
|
||||
border.width: UM.Theme.getSize("thick_lining").width
|
||||
border.color: UM.Theme.getColor("text")
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue