diff --git a/.gitignore b/.gitignore
index 5cc60c2f4c..0a66b6eb33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@ LC_MESSAGES
*.lprof
*~
*.qm
+.directory
.idea
cura.desktop
diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py
index 39d16bf04b..dbc675a279 100755
--- a/cura/CuraApplication.py
+++ b/cura/CuraApplication.py
@@ -67,9 +67,9 @@ from cura.Machines.Models.NozzleModel import NozzleModel
from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel
from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel
from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
-from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel
+from cura.Machines.Models.FavoriteMaterialsModel import FavoriteMaterialsModel
from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel
-from cura.Machines.Models.BrandMaterialsModel import BrandMaterialsModel
+from cura.Machines.Models.MaterialBrandsModel import MaterialBrandsModel
from cura.Machines.Models.QualityManagementModel import QualityManagementModel
from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel
from cura.Machines.Models.MachineManagementModel import MachineManagementModel
@@ -481,7 +481,9 @@ class CuraApplication(QtApplication):
preferences.addPreference("view/filter_current_build_plate", False)
preferences.addPreference("cura/sidebar_collapsed", False)
- self._need_to_show_user_agreement = not self.getPreferences().getValue("general/accepted_user_agreement")
+ preferences.addPreference("cura/favorite_materials", ";".join([]))
+
+ self._need_to_show_user_agreement = not preferences.getValue("general/accepted_user_agreement")
for key in [
"dialog_load_path", # dialog_save_path is in LocalFileOutputDevicePlugin
@@ -913,9 +915,9 @@ class CuraApplication(QtApplication):
qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer")
qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
+ qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel")
qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel")
- qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel")
- qmlRegisterType(MaterialManagementModel, "Cura", 1, 0, "MaterialManagementModel")
+ qmlRegisterType(MaterialBrandsModel, "Cura", 1, 0, "MaterialBrandsModel")
qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel")
qmlRegisterType(MachineManagementModel, "Cura", 1, 0, "MachineManagementModel")
diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py
index 9766e0c82a..f33934de0c 100644
--- a/cura/LayerPolygon.py
+++ b/cura/LayerPolygon.py
@@ -21,7 +21,7 @@ class LayerPolygon:
__number_of_types = 11
__jump_map = numpy.logical_or(numpy.logical_or(numpy.arange(__number_of_types) == NoneType, numpy.arange(__number_of_types) == MoveCombingType), numpy.arange(__number_of_types) == MoveRetractionType)
-
+
## LayerPolygon, used in ProcessSlicedLayersJob
# \param extruder
# \param line_types array with line_types
diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py
index d5a7d5d089..1463f2e40e 100644
--- a/cura/Machines/MaterialManager.py
+++ b/cura/Machines/MaterialManager.py
@@ -4,6 +4,7 @@
from collections import defaultdict, OrderedDict
import copy
import uuid
+import json
from typing import Dict, Optional, TYPE_CHECKING
from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot
@@ -38,7 +39,8 @@ if TYPE_CHECKING:
#
class MaterialManager(QObject):
- materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated.
+ materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated.
+ favoritesUpdated = pyqtSignal() # Emitted whenever the favorites are changed
def __init__(self, container_registry, parent = None):
super().__init__(parent)
@@ -75,6 +77,8 @@ class MaterialManager(QObject):
self._container_registry.containerAdded.connect(self._onContainerMetadataChanged)
self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged)
+ self._favorites = set()
+
def initialize(self):
# Find all materials and put them in a matrix for quick search.
material_metadatas = {metadata["id"]: metadata for metadata in
@@ -194,6 +198,11 @@ class MaterialManager(QObject):
self.materialsUpdated.emit()
+ favorites = self._application.getPreferences().getValue("cura/favorite_materials")
+ for item in favorites.split(";"):
+ self._favorites.add(item)
+ self.favoritesUpdated.emit()
+
def __addMaterialMetadataIntoLookupTree(self, material_metadata: dict) -> None:
material_id = material_metadata["id"]
@@ -608,3 +617,25 @@ class MaterialManager(QObject):
new_base_id = new_id,
new_metadata = new_metadata)
return new_id
+
+ @pyqtSlot(str)
+ def addFavorite(self, root_material_id: str):
+ self._favorites.add(root_material_id)
+ self.favoritesUpdated.emit()
+
+ # Ensure all settings are saved.
+ self._application.getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites)))
+ self._application.saveSettings()
+
+ @pyqtSlot(str)
+ def removeFavorite(self, root_material_id: str):
+ self._favorites.remove(root_material_id)
+ self.favoritesUpdated.emit()
+
+ # Ensure all settings are saved.
+ self._application.getPreferences().setValue("cura/favorite_materials", ";".join(list(self._favorites)))
+ self._application.saveSettings()
+
+ @pyqtSlot()
+ def getFavorites(self):
+ return self._favorites
\ No newline at end of file
diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py
index 4759c8b5b0..1b20e1188c 100644
--- a/cura/Machines/Models/BaseMaterialsModel.py
+++ b/cura/Machines/Models/BaseMaterialsModel.py
@@ -2,45 +2,63 @@
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
-
-from UM.Application import Application
from UM.Qt.ListModel import ListModel
-#
-# This is the base model class for GenericMaterialsModel and BrandMaterialsModel
-# Those 2 models are used by the material drop down menu to show generic materials and branded materials separately.
-# The extruder position defined here is being used to bound a menu to the correct extruder. This is used in the top
-# bar menu "Settings" -> "Extruder nr" -> "Material" -> this menu
-#
+## This is the base model class for GenericMaterialsModel and MaterialBrandsModel.
+# Those 2 models are used by the material drop down menu to show generic materials and branded materials separately.
+# The extruder position defined here is being used to bound a menu to the correct extruder. This is used in the top
+# bar menu "Settings" -> "Extruder nr" -> "Material" -> this menu
class BaseMaterialsModel(ListModel):
- RootMaterialIdRole = Qt.UserRole + 1
- IdRole = Qt.UserRole + 2
- NameRole = Qt.UserRole + 3
- BrandRole = Qt.UserRole + 4
- MaterialRole = Qt.UserRole + 5
- ColorRole = Qt.UserRole + 6
- ContainerNodeRole = Qt.UserRole + 7
extruderPositionChanged = pyqtSignal()
def __init__(self, parent = None):
super().__init__(parent)
- self._application = Application.getInstance()
- self._machine_manager = self._application.getMachineManager()
- self.addRoleName(self.RootMaterialIdRole, "root_material_id")
- self.addRoleName(self.IdRole, "id")
- self.addRoleName(self.NameRole, "name")
- self.addRoleName(self.BrandRole, "brand")
- self.addRoleName(self.MaterialRole, "material")
- self.addRoleName(self.ColorRole, "color_name")
- self.addRoleName(self.ContainerNodeRole, "container_node")
+ from cura.CuraApplication import CuraApplication
+
+ self._application = CuraApplication.getInstance()
+
+ # Make these managers available to all material models
+ self._container_registry = self._application.getInstance().getContainerRegistry()
+ self._machine_manager = self._application.getMachineManager()
+ self._material_manager = self._application.getMaterialManager()
+
+ # Update the stack and the model data when the machine changes
+ self._machine_manager.globalContainerChanged.connect(self._updateExtruderStack)
+
+ # Update this model when switching machines
+ self._machine_manager.activeStackChanged.connect(self._update)
+
+ # Update this model when list of materials changes
+ self._material_manager.materialsUpdated.connect(self._update)
+
+ # Update this model when list of favorites changes
+ self._material_manager.favoritesUpdated.connect(self._update)
+
+ self.addRoleName(Qt.UserRole + 1, "root_material_id")
+ self.addRoleName(Qt.UserRole + 2, "id")
+ self.addRoleName(Qt.UserRole + 3, "GUID")
+ self.addRoleName(Qt.UserRole + 4, "name")
+ self.addRoleName(Qt.UserRole + 5, "brand")
+ self.addRoleName(Qt.UserRole + 6, "description")
+ self.addRoleName(Qt.UserRole + 7, "material")
+ self.addRoleName(Qt.UserRole + 8, "color_name")
+ self.addRoleName(Qt.UserRole + 9, "color_code")
+ self.addRoleName(Qt.UserRole + 10, "density")
+ self.addRoleName(Qt.UserRole + 11, "diameter")
+ self.addRoleName(Qt.UserRole + 12, "approximate_diameter")
+ self.addRoleName(Qt.UserRole + 13, "adhesion_info")
+ self.addRoleName(Qt.UserRole + 14, "is_read_only")
+ self.addRoleName(Qt.UserRole + 15, "container_node")
+ self.addRoleName(Qt.UserRole + 16, "is_favorite")
self._extruder_position = 0
self._extruder_stack = None
- # Update the stack and the model data when the machine changes
- self._machine_manager.globalContainerChanged.connect(self._updateExtruderStack)
+
+ self._available_materials = None
+ self._favorite_ids = None
def _updateExtruderStack(self):
global_stack = self._machine_manager.activeMachine
@@ -65,8 +83,55 @@ class BaseMaterialsModel(ListModel):
def extruderPosition(self) -> int:
return self._extruder_position
- #
- # This is an abstract method that needs to be implemented by
- #
+ ## This is an abstract method that needs to be implemented by the specific
+ # models themselves.
def _update(self):
pass
+
+ ## This method is used by all material models in the beginning of the
+ # _update() method in order to prevent errors. It's the same in all models
+ # so it's placed here for easy access.
+ def _canUpdate(self):
+ global_stack = self._machine_manager.activeMachine
+
+ if global_stack is None:
+ return False
+
+ extruder_position = str(self._extruder_position)
+
+ if extruder_position not in global_stack.extruders:
+ return False
+
+ extruder_stack = global_stack.extruders[extruder_position]
+
+ self._available_materials = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack, extruder_stack)
+ if self._available_materials is None:
+ return False
+
+ return True
+
+ ## This is another convenience function which is shared by all material
+ # models so it's put here to avoid having so much duplicated code.
+ def _createMaterialItem(self, root_material_id, container_node):
+ metadata = container_node.metadata
+ item = {
+ "root_material_id": root_material_id,
+ "id": metadata["id"],
+ "container_id": metadata["id"], # TODO: Remove duplicate in material manager qml
+ "GUID": metadata["GUID"],
+ "name": metadata["name"],
+ "brand": metadata["brand"],
+ "description": metadata["description"],
+ "material": metadata["material"],
+ "color_name": metadata["color_name"],
+ "color_code": metadata.get("color_code", ""),
+ "density": metadata.get("properties", {}).get("density", ""),
+ "diameter": metadata.get("properties", {}).get("diameter", ""),
+ "approximate_diameter": metadata["approximate_diameter"],
+ "adhesion_info": metadata["adhesion_info"],
+ "is_read_only": self._container_registry.isReadOnly(metadata["id"]),
+ "container_node": container_node,
+ "is_favorite": root_material_id in self._favorite_ids
+ }
+ return item
+
diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py
deleted file mode 100644
index ad48b3ea21..0000000000
--- a/cura/Machines/Models/BrandMaterialsModel.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
-
-from UM.Qt.ListModel import ListModel
-from UM.Logger import Logger
-from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
-
-
-#
-# This is an intermediate model to group materials with different colours for a same brand and type.
-#
-class MaterialsModelGroupedByType(ListModel):
- NameRole = Qt.UserRole + 1
- ColorsRole = Qt.UserRole + 2
-
- def __init__(self, parent = None):
- super().__init__(parent)
-
- self.addRoleName(self.NameRole, "name")
- self.addRoleName(self.ColorsRole, "colors")
-
-
-#
-# This model is used to show branded materials in the material drop down menu.
-# The structure of the menu looks like this:
-# Brand -> Material Type -> list of materials
-#
-# To illustrate, a branded material menu may look like this:
-# Ultimaker -> PLA -> Yellow PLA
-# -> Black PLA
-# -> ...
-# -> ABS -> White ABS
-# ...
-#
-class BrandMaterialsModel(ListModel):
- NameRole = Qt.UserRole + 1
- MaterialsRole = Qt.UserRole + 2
-
- extruderPositionChanged = pyqtSignal()
-
- def __init__(self, parent = None):
- super().__init__(parent)
-
- self.addRoleName(self.NameRole, "name")
- self.addRoleName(self.MaterialsRole, "materials")
-
- self._extruder_position = 0
- self._extruder_stack = None
-
- from cura.CuraApplication import CuraApplication
- self._machine_manager = CuraApplication.getInstance().getMachineManager()
- self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
- self._material_manager = CuraApplication.getInstance().getMaterialManager()
-
- self._machine_manager.globalContainerChanged.connect(self._updateExtruderStack)
- self._machine_manager.activeStackChanged.connect(self._update) #Update when switching machines.
- self._material_manager.materialsUpdated.connect(self._update) #Update when the list of materials changes.
- self._update()
-
- def _updateExtruderStack(self):
- global_stack = self._machine_manager.activeMachine
- if global_stack is None:
- return
-
- if self._extruder_stack is not None:
- self._extruder_stack.pyqtContainersChanged.disconnect(self._update)
- self._extruder_stack = global_stack.extruders.get(str(self._extruder_position))
- if self._extruder_stack is not None:
- self._extruder_stack.pyqtContainersChanged.connect(self._update)
- # Force update the model when the extruder stack changes
- self._update()
-
- def setExtruderPosition(self, position: int):
- if self._extruder_stack is None or self._extruder_position != position:
- self._extruder_position = position
- self._updateExtruderStack()
- self.extruderPositionChanged.emit()
-
- @pyqtProperty(int, fset=setExtruderPosition, notify=extruderPositionChanged)
- def extruderPosition(self) -> int:
- return self._extruder_position
-
- def _update(self):
- Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
- global_stack = self._machine_manager.activeMachine
- if global_stack is None:
- self.setItems([])
- return
- extruder_position = str(self._extruder_position)
- if extruder_position not in global_stack.extruders:
- self.setItems([])
- return
- extruder_stack = global_stack.extruders[str(self._extruder_position)]
-
- available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
- extruder_stack)
- if available_material_dict is None:
- self.setItems([])
- return
-
- brand_item_list = []
- brand_group_dict = {}
- for root_material_id, container_node in available_material_dict.items():
- metadata = container_node.metadata
- brand = metadata["brand"]
- # Only add results for generic materials
- if brand.lower() == "generic":
- continue
-
- # Do not include the materials from a to-be-removed package
- if bool(metadata.get("removed", False)):
- continue
-
- if brand not in brand_group_dict:
- brand_group_dict[brand] = {}
-
- material_type = metadata["material"]
- if material_type not in brand_group_dict[brand]:
- brand_group_dict[brand][material_type] = []
-
- item = {"root_material_id": root_material_id,
- "id": metadata["id"],
- "name": metadata["name"],
- "brand": metadata["brand"],
- "material": metadata["material"],
- "color_name": metadata["color_name"],
- "container_node": container_node
- }
- brand_group_dict[brand][material_type].append(item)
-
- for brand, material_dict in brand_group_dict.items():
- brand_item = {"name": brand,
- "materials": MaterialsModelGroupedByType(self)}
-
- material_type_item_list = []
- for material_type, material_list in material_dict.items():
- material_type_item = {"name": material_type,
- "colors": BaseMaterialsModel(self)}
- material_type_item["colors"].clear()
-
- # Sort materials by name
- material_list = sorted(material_list, key = lambda x: x["name"].upper())
- material_type_item["colors"].setItems(material_list)
-
- material_type_item_list.append(material_type_item)
-
- # Sort material type by name
- material_type_item_list = sorted(material_type_item_list, key = lambda x: x["name"].upper())
- brand_item["materials"].setItems(material_type_item_list)
-
- brand_item_list.append(brand_item)
-
- # Sort brand by name
- brand_item_list = sorted(brand_item_list, key = lambda x: x["name"].upper())
- self.setItems(brand_item_list)
diff --git a/cura/Machines/Models/FavoriteMaterialsModel.py b/cura/Machines/Models/FavoriteMaterialsModel.py
new file mode 100644
index 0000000000..be3f0f605f
--- /dev/null
+++ b/cura/Machines/Models/FavoriteMaterialsModel.py
@@ -0,0 +1,42 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from UM.Logger import Logger
+from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
+
+class FavoriteMaterialsModel(BaseMaterialsModel):
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+ self._update()
+
+ def _update(self):
+
+ # Perform standard check and reset if the check fails
+ if not self._canUpdate():
+ self.setItems([])
+ return
+
+ # Get updated list of favorites
+ self._favorite_ids = self._material_manager.getFavorites()
+
+ item_list = []
+
+ for root_material_id, container_node in self._available_materials.items():
+ metadata = container_node.metadata
+
+ # Do not include the materials from a to-be-removed package
+ if bool(metadata.get("removed", False)):
+ continue
+
+ # Only add results for favorite materials
+ if root_material_id not in self._favorite_ids:
+ continue
+
+ item = self._createMaterialItem(root_material_id, container_node)
+ item_list.append(item)
+
+ # Sort the item list alphabetically by name
+ item_list = sorted(item_list, key = lambda d: d["brand"].upper())
+
+ self.setItems(item_list)
diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py
index f14b039c91..27e6fdfd7c 100644
--- a/cura/Machines/Models/GenericMaterialsModel.py
+++ b/cura/Machines/Models/GenericMaterialsModel.py
@@ -4,63 +4,39 @@
from UM.Logger import Logger
from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
-
class GenericMaterialsModel(BaseMaterialsModel):
def __init__(self, parent = None):
super().__init__(parent)
-
- from cura.CuraApplication import CuraApplication
- self._machine_manager = CuraApplication.getInstance().getMachineManager()
- self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
- self._material_manager = CuraApplication.getInstance().getMaterialManager()
-
- self._machine_manager.activeStackChanged.connect(self._update) #Update when switching machines.
- self._material_manager.materialsUpdated.connect(self._update) #Update when the list of materials changes.
self._update()
def _update(self):
- Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
- global_stack = self._machine_manager.activeMachine
- if global_stack is None:
+ # Perform standard check and reset if the check fails
+ if not self._canUpdate():
self.setItems([])
return
- extruder_position = str(self._extruder_position)
- if extruder_position not in global_stack.extruders:
- self.setItems([])
- return
- extruder_stack = global_stack.extruders[extruder_position]
- available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
- extruder_stack)
- if available_material_dict is None:
- self.setItems([])
- return
+ # Get updated list of favorites
+ self._favorite_ids = self._material_manager.getFavorites()
item_list = []
- for root_material_id, container_node in available_material_dict.items():
- metadata = container_node.metadata
- # Only add results for generic materials
- if metadata["brand"].lower() != "generic":
- continue
+ for root_material_id, container_node in self._available_materials.items():
+ metadata = container_node.metadata
# Do not include the materials from a to-be-removed package
if bool(metadata.get("removed", False)):
continue
- item = {"root_material_id": root_material_id,
- "id": metadata["id"],
- "name": metadata["name"],
- "brand": metadata["brand"],
- "material": metadata["material"],
- "color_name": metadata["color_name"],
- "container_node": container_node
- }
+ # Only add results for generic materials
+ if metadata["brand"].lower() != "generic":
+ continue
+
+ item = self._createMaterialItem(root_material_id, container_node)
item_list.append(item)
- # Sort the item list by material name alphabetically
+ # Sort the item list alphabetically by name
item_list = sorted(item_list, key = lambda d: d["name"].upper())
self.setItems(item_list)
diff --git a/cura/Machines/Models/MaterialBrandsModel.py b/cura/Machines/Models/MaterialBrandsModel.py
new file mode 100644
index 0000000000..3f917abb16
--- /dev/null
+++ b/cura/Machines/Models/MaterialBrandsModel.py
@@ -0,0 +1,107 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
+from UM.Qt.ListModel import ListModel
+from UM.Logger import Logger
+from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
+
+class MaterialTypesModel(ListModel):
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self.addRoleName(Qt.UserRole + 1, "name")
+ self.addRoleName(Qt.UserRole + 2, "colors")
+
+class MaterialBrandsModel(BaseMaterialsModel):
+
+ extruderPositionChanged = pyqtSignal()
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self.addRoleName(Qt.UserRole + 1, "name")
+ self.addRoleName(Qt.UserRole + 2, "material_types")
+
+ self._update()
+
+ def _update(self):
+
+ # Perform standard check and reset if the check fails
+ if not self._canUpdate():
+ self.setItems([])
+ return
+
+ # Get updated list of favorites
+ self._favorite_ids = self._material_manager.getFavorites()
+
+ brand_item_list = []
+ brand_group_dict = {}
+
+ # Part 1: Generate the entire tree of brands -> material types -> spcific materials
+ for root_material_id, container_node in self._available_materials.items():
+ metadata = container_node.metadata
+
+ # Do not include the materials from a to-be-removed package
+ if bool(metadata.get("removed", False)):
+ continue
+
+ # Add brands we haven't seen yet to the dict, skipping generics
+ brand = metadata["brand"]
+ if brand.lower() == "generic":
+ continue
+ if brand not in brand_group_dict:
+ brand_group_dict[brand] = {}
+
+ # Add material types we haven't seen yet to the dict
+ material_type = metadata["material"]
+ if material_type not in brand_group_dict[brand]:
+ brand_group_dict[brand][material_type] = []
+
+ # Now handle the individual materials
+ item = self._createMaterialItem(root_material_id, container_node)
+ brand_group_dict[brand][material_type].append(item)
+
+ # Part 2: Organize the tree into models
+ #
+ # Normally, the structure of the menu looks like this:
+ # Brand -> Material Type -> Specific Material
+ #
+ # To illustrate, a branded material menu may look like this:
+ # Ultimaker ┳ PLA ┳ Yellow PLA
+ # ┃ ┣ Black PLA
+ # ┃ ┗ ...
+ # ┃
+ # ┗ ABS ┳ White ABS
+ # ┗ ...
+ for brand, material_dict in brand_group_dict.items():
+
+ material_type_item_list = []
+ brand_item = {
+ "name": brand,
+ "material_types": MaterialTypesModel(self)
+ }
+
+ for material_type, material_list in material_dict.items():
+ material_type_item = {
+ "name": material_type,
+ "colors": BaseMaterialsModel(self)
+ }
+ material_type_item["colors"].clear()
+
+ # Sort materials by name
+ material_list = sorted(material_list, key = lambda x: x["name"].upper())
+ material_type_item["colors"].setItems(material_list)
+
+ material_type_item_list.append(material_type_item)
+
+ # Sort material type by name
+ material_type_item_list = sorted(material_type_item_list, key = lambda x: x["name"].upper())
+ brand_item["material_types"].setItems(material_type_item_list)
+
+ brand_item_list.append(brand_item)
+
+ # Sort brand by name
+ brand_item_list = sorted(brand_item_list, key = lambda x: x["name"].upper())
+ self.setItems(brand_item_list)
diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py
deleted file mode 100644
index 46e9cb887a..0000000000
--- a/cura/Machines/Models/MaterialManagementModel.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from PyQt5.QtCore import Qt
-
-from UM.Logger import Logger
-from UM.Qt.ListModel import ListModel
-
-
-#
-# This model is for the Material management page.
-#
-class MaterialManagementModel(ListModel):
- RootMaterialIdRole = Qt.UserRole + 1
- DisplayNameRole = Qt.UserRole + 2
- BrandRole = Qt.UserRole + 3
- MaterialTypeRole = Qt.UserRole + 4
- ColorNameRole = Qt.UserRole + 5
- ColorCodeRole = Qt.UserRole + 6
- ContainerNodeRole = Qt.UserRole + 7
- ContainerIdRole = Qt.UserRole + 8
-
- DescriptionRole = Qt.UserRole + 9
- AdhesionInfoRole = Qt.UserRole + 10
- ApproximateDiameterRole = Qt.UserRole + 11
- GuidRole = Qt.UserRole + 12
- DensityRole = Qt.UserRole + 13
- DiameterRole = Qt.UserRole + 14
- IsReadOnlyRole = Qt.UserRole + 15
-
- def __init__(self, parent = None):
- super().__init__(parent)
-
- self.addRoleName(self.RootMaterialIdRole, "root_material_id")
- self.addRoleName(self.DisplayNameRole, "name")
- self.addRoleName(self.BrandRole, "brand")
- self.addRoleName(self.MaterialTypeRole, "material")
- self.addRoleName(self.ColorNameRole, "color_name")
- self.addRoleName(self.ColorCodeRole, "color_code")
- self.addRoleName(self.ContainerNodeRole, "container_node")
- self.addRoleName(self.ContainerIdRole, "container_id")
-
- self.addRoleName(self.DescriptionRole, "description")
- self.addRoleName(self.AdhesionInfoRole, "adhesion_info")
- self.addRoleName(self.ApproximateDiameterRole, "approximate_diameter")
- self.addRoleName(self.GuidRole, "guid")
- self.addRoleName(self.DensityRole, "density")
- self.addRoleName(self.DiameterRole, "diameter")
- self.addRoleName(self.IsReadOnlyRole, "is_read_only")
-
- from cura.CuraApplication import CuraApplication
- self._container_registry = CuraApplication.getInstance().getContainerRegistry()
- self._machine_manager = CuraApplication.getInstance().getMachineManager()
- self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
- self._material_manager = CuraApplication.getInstance().getMaterialManager()
-
- self._machine_manager.globalContainerChanged.connect(self._update)
- self._extruder_manager.activeExtruderChanged.connect(self._update)
- self._material_manager.materialsUpdated.connect(self._update)
-
- self._update()
-
- def _update(self):
- Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
-
- global_stack = self._machine_manager.activeMachine
- if global_stack is None:
- self.setItems([])
- return
- active_extruder_stack = self._machine_manager.activeStack
-
- available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
- active_extruder_stack)
- if available_material_dict is None:
- self.setItems([])
- return
-
- material_list = []
- for root_material_id, container_node in available_material_dict.items():
- keys_to_fetch = ("name",
- "brand",
- "material",
- "color_name",
- "color_code",
- "description",
- "adhesion_info",
- "approximate_diameter",)
-
- item = {"root_material_id": container_node.metadata["base_file"],
- "container_node": container_node,
- "guid": container_node.metadata["GUID"],
- "container_id": container_node.metadata["id"],
- "density": container_node.metadata.get("properties", {}).get("density", ""),
- "diameter": container_node.metadata.get("properties", {}).get("diameter", ""),
- "is_read_only": self._container_registry.isReadOnly(container_node.metadata["id"]),
- }
-
- for key in keys_to_fetch:
- item[key] = container_node.metadata.get(key, "")
-
- material_list.append(item)
-
- material_list = sorted(material_list, key = lambda k: (k["brand"].upper(), k["name"].upper()))
- self.setItems(material_list)
diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py
index df3bec0827..cb2776429f 100644
--- a/cura/Machines/QualityManager.py
+++ b/cura/Machines/QualityManager.py
@@ -259,8 +259,12 @@ class QualityManager(QObject):
# 2. machine-nozzle-and-material-specific qualities if exist
# 3. machine-nozzle-specific qualities if exist
# 4. machine-material-specific qualities if exist
- # 5. machine-specific qualities if exist
- # 6. generic qualities if exist
+ # 5. machine-specific global qualities if exist, otherwise generic global qualities
+ # NOTE: We DO NOT fail back to generic global qualities if machine-specific global qualities exist.
+ # This is because when a machine defines its own global qualities such as Normal, Fine, etc.,
+ # it is intended to maintain those specific qualities ONLY. If we still fail back to the generic
+ # global qualities, there can be unimplemented quality types e.g. "coarse", and this is not
+ # correct.
# Each points above can be represented as a node in the lookup tree, so here we simply put those nodes into
# the list with priorities as the order. Later, we just need to loop over each node in this list and fetch
# qualities from there.
@@ -289,7 +293,13 @@ class QualityManager(QObject):
addNodesToCheck(machine_node, nodes_to_check, node_info_list_0, 0)
- nodes_to_check += [machine_node, default_machine_node]
+ # The last fall back will be the global qualities (either from the machine-specific node or the generic
+ # node), but we only use one. For details see the overview comments above.
+ if machine_node.quality_type_map:
+ nodes_to_check += [machine_node]
+ else:
+ nodes_to_check += [default_machine_node]
+
for node in nodes_to_check:
if node and node.quality_type_map:
if has_variant_materials:
diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py
index 21e2040dc1..8527da1b8a 100644
--- a/cura/PrintInformation.py
+++ b/cura/PrintInformation.py
@@ -300,7 +300,7 @@ class PrintInformation(QObject):
def _updateJobName(self):
if self._base_name == "":
- self._job_name = "unnamed"
+ self._job_name = "Untitled"
self._is_user_specified_job_name = False
self.jobNameChanged.emit()
return
diff --git a/plugins/3MFReader/plugin.json b/plugins/3MFReader/plugin.json
index 5d15123017..5e41975752 100644
--- a/plugins/3MFReader/plugin.json
+++ b/plugins/3MFReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for reading 3MF files.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/3MFWriter/plugin.json b/plugins/3MFWriter/plugin.json
index 22d18b2cf1..9ec4fb0c20 100644
--- a/plugins/3MFWriter/plugin.json
+++ b/plugins/3MFWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for writing 3MF files.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/ChangeLogPlugin/plugin.json b/plugins/ChangeLogPlugin/plugin.json
index e9414b9b71..e09a08564a 100644
--- a/plugins/ChangeLogPlugin/plugin.json
+++ b/plugins/ChangeLogPlugin/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Shows changes since latest checked version.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py
index 0ebcafdbb2..1295390c22 100644
--- a/plugins/CuraEngineBackend/StartSliceJob.py
+++ b/plugins/CuraEngineBackend/StartSliceJob.py
@@ -220,8 +220,10 @@ class StartSliceJob(Job):
stack = global_stack
skip_group = False
for node in group:
+ # Only check if the printing extruder is enabled for printing meshes
+ is_non_printing_mesh = node.callDecoration("evaluateIsNonPrintingMesh")
extruder_position = node.callDecoration("getActiveExtruderPosition")
- if not extruders_enabled[extruder_position]:
+ if not is_non_printing_mesh and not extruders_enabled[extruder_position]:
skip_group = True
has_model_with_disabled_extruders = True
associated_disabled_extruders.add(extruder_position)
diff --git a/plugins/CuraEngineBackend/plugin.json b/plugins/CuraEngineBackend/plugin.json
index e5df06f228..111698d8d1 100644
--- a/plugins/CuraEngineBackend/plugin.json
+++ b/plugins/CuraEngineBackend/plugin.json
@@ -2,7 +2,7 @@
"name": "CuraEngine Backend",
"author": "Ultimaker B.V.",
"description": "Provides the link to the CuraEngine slicing backend.",
- "api": 4,
+ "api": 5,
"version": "1.0.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/CuraProfileReader/plugin.json b/plugins/CuraProfileReader/plugin.json
index 004a1ade4d..66a2a6a56b 100644
--- a/plugins/CuraProfileReader/plugin.json
+++ b/plugins/CuraProfileReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for importing Cura profiles.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/CuraProfileWriter/plugin.json b/plugins/CuraProfileWriter/plugin.json
index d9accce770..16c8c34152 100644
--- a/plugins/CuraProfileWriter/plugin.json
+++ b/plugins/CuraProfileWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for exporting Cura profiles.",
- "api": 4,
+ "api": 5,
"i18n-catalog":"cura"
}
diff --git a/plugins/FirmwareUpdateChecker/plugin.json b/plugins/FirmwareUpdateChecker/plugin.json
index d6a9f9fbd7..cbbd41e420 100644
--- a/plugins/FirmwareUpdateChecker/plugin.json
+++ b/plugins/FirmwareUpdateChecker/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Checks for firmware updates.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeGzReader/plugin.json b/plugins/GCodeGzReader/plugin.json
index e9f14724e0..3bd6a4097d 100644
--- a/plugins/GCodeGzReader/plugin.json
+++ b/plugins/GCodeGzReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Reads g-code from a compressed archive.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeGzWriter/plugin.json b/plugins/GCodeGzWriter/plugin.json
index 9774e9a25c..4c6497317b 100644
--- a/plugins/GCodeGzWriter/plugin.json
+++ b/plugins/GCodeGzWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Writes g-code to a compressed archive.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeProfileReader/plugin.json b/plugins/GCodeProfileReader/plugin.json
index f8f7d4c291..9677628c85 100644
--- a/plugins/GCodeProfileReader/plugin.json
+++ b/plugins/GCodeProfileReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for importing profiles from g-code files.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeReader/plugin.json b/plugins/GCodeReader/plugin.json
index f72a8cc12c..75b4d0cd4f 100644
--- a/plugins/GCodeReader/plugin.json
+++ b/plugins/GCodeReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Victor Larchenko",
"version": "1.0.0",
"description": "Allows loading and displaying G-code files.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeWriter/plugin.json b/plugins/GCodeWriter/plugin.json
index 5fcb1a3bd7..3bbbab8b95 100644
--- a/plugins/GCodeWriter/plugin.json
+++ b/plugins/GCodeWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Writes g-code to a file.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/ImageReader/plugin.json b/plugins/ImageReader/plugin.json
index 2752c6e8f4..08195863e8 100644
--- a/plugins/ImageReader/plugin.json
+++ b/plugins/ImageReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Enables ability to generate printable geometry from 2D image files.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/LegacyProfileReader/plugin.json b/plugins/LegacyProfileReader/plugin.json
index 2dc71511a9..179f5444e0 100644
--- a/plugins/LegacyProfileReader/plugin.json
+++ b/plugins/LegacyProfileReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for importing profiles from legacy Cura versions.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/MachineSettingsAction/plugin.json b/plugins/MachineSettingsAction/plugin.json
index 703a145deb..571658e40a 100644
--- a/plugins/MachineSettingsAction/plugin.json
+++ b/plugins/MachineSettingsAction/plugin.json
@@ -3,6 +3,6 @@
"author": "fieldOfView",
"version": "1.0.0",
"description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/ModelChecker/plugin.json b/plugins/ModelChecker/plugin.json
index a9190adcaa..3753c0cc88 100644
--- a/plugins/ModelChecker/plugin.json
+++ b/plugins/ModelChecker/plugin.json
@@ -2,7 +2,7 @@
"name": "Model Checker",
"author": "Ultimaker B.V.",
"version": "0.1",
- "api": 4,
+ "api": 5,
"description": "Checks models and print configuration for possible printing issues and give suggestions.",
"i18n-catalog": "cura"
}
diff --git a/plugins/MonitorStage/plugin.json b/plugins/MonitorStage/plugin.json
index cb3f55a80d..88b53840e0 100644
--- a/plugins/MonitorStage/plugin.json
+++ b/plugins/MonitorStage/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides a monitor stage in Cura.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/PerObjectSettingsTool/plugin.json b/plugins/PerObjectSettingsTool/plugin.json
index 3254662d33..15fde63387 100644
--- a/plugins/PerObjectSettingsTool/plugin.json
+++ b/plugins/PerObjectSettingsTool/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides the Per Model Settings.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
index da971a8e61..b28a028325 100644
--- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py
+++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
@@ -1,5 +1,6 @@
-# Copyright (c) 2015 Jaime van Kessel, Ultimaker B.V.
+# Copyright (c) 2018 Jaime van Kessel, Ultimaker B.V.
# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
+
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
from UM.PluginRegistry import PluginRegistry
@@ -260,6 +261,9 @@ class PostProcessingPlugin(QObject, Extension):
# Create the plugin dialog component
path = os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "PostProcessingPlugin.qml")
self._view = Application.getInstance().createQmlComponent(path, {"manager": self})
+ if self._view is None:
+ Logger.log("e", "Not creating PostProcessing button near save button because the QML component failed to be created.")
+ return
Logger.log("d", "Post processing view created.")
# Create the save button component
@@ -269,6 +273,9 @@ class PostProcessingPlugin(QObject, Extension):
def showPopup(self):
if self._view is None:
self._createView()
+ if self._view is None:
+ Logger.log("e", "Not creating PostProcessing window since the QML component failed to be created.")
+ return
self._view.show()
## Property changed: trigger re-slice
diff --git a/plugins/PostProcessingPlugin/plugin.json b/plugins/PostProcessingPlugin/plugin.json
index ebfef8145a..fea061e93b 100644
--- a/plugins/PostProcessingPlugin/plugin.json
+++ b/plugins/PostProcessingPlugin/plugin.json
@@ -2,7 +2,7 @@
"name": "Post Processing",
"author": "Ultimaker",
"version": "2.2",
- "api": 4,
+ "api": 5,
"description": "Extension that allows for user created scripts for post processing",
"catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/PrepareStage/plugin.json b/plugins/PrepareStage/plugin.json
index 4fd55e955e..f0464313c7 100644
--- a/plugins/PrepareStage/plugin.json
+++ b/plugins/PrepareStage/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides a prepare stage in Cura.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/RemovableDriveOutputDevice/plugin.json b/plugins/RemovableDriveOutputDevice/plugin.json
index df11644256..36bb9ae186 100644
--- a/plugins/RemovableDriveOutputDevice/plugin.json
+++ b/plugins/RemovableDriveOutputDevice/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"description": "Provides removable drive hotplugging and writing support.",
"version": "1.0.0",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/SimulationView/plugin.json b/plugins/SimulationView/plugin.json
index 0e7bec0626..93df98068f 100644
--- a/plugins/SimulationView/plugin.json
+++ b/plugins/SimulationView/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides the Simulation view.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/SliceInfoPlugin/plugin.json b/plugins/SliceInfoPlugin/plugin.json
index d1c643266b..939e5ff235 100644
--- a/plugins/SliceInfoPlugin/plugin.json
+++ b/plugins/SliceInfoPlugin/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Submits anonymous slice info. Can be disabled through preferences.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/SolidView/plugin.json b/plugins/SolidView/plugin.json
index 6d6bda96f0..e70ec224dd 100644
--- a/plugins/SolidView/plugin.json
+++ b/plugins/SolidView/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides a normal solid mesh view.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/SupportEraser/plugin.json b/plugins/SupportEraser/plugin.json
index 5ccb639913..7af35e0fb5 100644
--- a/plugins/SupportEraser/plugin.json
+++ b/plugins/SupportEraser/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Creates an eraser mesh to block the printing of support in certain places",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/Toolbox/plugin.json b/plugins/Toolbox/plugin.json
index 12d4042b6b..2557185524 100644
--- a/plugins/Toolbox/plugin.json
+++ b/plugins/Toolbox/plugin.json
@@ -2,6 +2,6 @@
"name": "Toolbox",
"author": "Ultimaker B.V.",
"version": "1.0.0",
- "api": 4,
+ "api": 5,
"description": "Find, manage and install new Cura packages."
}
diff --git a/plugins/UFPWriter/UFPWriter.py b/plugins/UFPWriter/UFPWriter.py
index ceb9d79087..a85ee489cb 100644
--- a/plugins/UFPWriter/UFPWriter.py
+++ b/plugins/UFPWriter/UFPWriter.py
@@ -13,6 +13,7 @@ from UM.PluginRegistry import PluginRegistry #To get the g-code writer.
from PyQt5.QtCore import QBuffer
from cura.Snapshot import Snapshot
+from cura.Utils.Threading import call_on_qt_thread
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
@@ -29,6 +30,11 @@ class UFPWriter(MeshWriter):
Logger.log("d", "Creating thumbnail image...")
self._snapshot = Snapshot.snapshot(width = 300, height = 300)
+ # This needs to be called on the main thread (Qt thread) because the serialization of material containers can
+ # trigger loading other containers. Because those loaded containers are QtObjects, they must be created on the
+ # Qt thread. The File read/write operations right now are executed on separated threads because they are scheduled
+ # by the Job class.
+ @call_on_qt_thread
def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode):
archive = VirtualFile()
archive.openStream(stream, "application/x-ufp", OpenMode.WriteOnly)
@@ -60,5 +66,50 @@ class UFPWriter(MeshWriter):
else:
Logger.log("d", "Thumbnail not created, cannot save it")
+ # Store the material.
+ application = Application.getInstance()
+ machine_manager = application.getMachineManager()
+ material_manager = application.getMaterialManager()
+ global_stack = machine_manager.activeMachine
+
+ material_extension = "xml.fdm_material"
+ material_mime_type = "application/x-ultimaker-material-profile"
+
+ try:
+ archive.addContentType(extension = material_extension, mime_type = material_mime_type)
+ except:
+ Logger.log("w", "The material extension: %s was already added", material_extension)
+
+ added_materials = []
+ for extruder_stack in global_stack.extruders.values():
+ material = extruder_stack.material
+ material_file_name = material.getMetaData()["base_file"] + ".xml.fdm_material"
+ material_file_name = "/Materials/" + material_file_name
+
+ #Same material cannot be added
+ if material_file_name in added_materials:
+ continue
+
+ material_root_id = material.getMetaDataEntry("base_file")
+ material_group = material_manager.getMaterialGroup(material_root_id)
+ if material_group is None:
+ Logger.log("e", "Cannot find material container with root id [%s]", material_root_id)
+ return False
+
+ material_container = material_group.root_material_node.getContainer()
+ try:
+ serialized_material = material_container.serialize()
+ except NotImplementedError:
+ Logger.log("e", "Unable serialize material container with root id: %s", material_root_id)
+ return False
+
+ material_file = archive.getStream(material_file_name)
+ material_file.write(serialized_material.encode("UTF-8"))
+ archive.addRelation(virtual_path = material_file_name,
+ relation_type = "http://schemas.ultimaker.org/package/2018/relationships/material",
+ origin = "/3D/model.gcode")
+
+ added_materials.append(material_file_name)
+
archive.close()
return True
diff --git a/plugins/UFPWriter/plugin.json b/plugins/UFPWriter/plugin.json
index 7d10b89ad4..ab590353e0 100644
--- a/plugins/UFPWriter/plugin.json
+++ b/plugins/UFPWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for writing Ultimaker Format Packages.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml
index 127b3c35bd..b5b80a3010 100644
--- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml
+++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml
@@ -364,7 +364,6 @@ Cura.MachineAction
{
id: addressField
width: parent.width
- maximumLength: 40
validator: RegExpValidator
{
regExp: /[a-zA-Z0-9\.\-\_]*/
diff --git a/plugins/UM3NetworkPrinting/plugin.json b/plugins/UM3NetworkPrinting/plugin.json
index e7b59fadd6..d415338374 100644
--- a/plugins/UM3NetworkPrinting/plugin.json
+++ b/plugins/UM3NetworkPrinting/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"description": "Manages network connections to Ultimaker 3 printers.",
"version": "1.0.0",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/USBPrinting/plugin.json b/plugins/USBPrinting/plugin.json
index 27e07c45b2..3484c8a48a 100644
--- a/plugins/USBPrinting/plugin.json
+++ b/plugins/USBPrinting/plugin.json
@@ -2,7 +2,7 @@
"name": "USB printing",
"author": "Ultimaker B.V.",
"version": "1.0.0",
- "api": 4,
+ "api": 5,
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
"i18n-catalog": "cura"
}
diff --git a/plugins/UltimakerMachineActions/plugin.json b/plugins/UltimakerMachineActions/plugin.json
index 57b3e6bc8f..b60c7df88e 100644
--- a/plugins/UltimakerMachineActions/plugin.json
+++ b/plugins/UltimakerMachineActions/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/UserAgreement/plugin.json b/plugins/UserAgreement/plugin.json
index b10abc5640..50a2aa0441 100644
--- a/plugins/UserAgreement/plugin.json
+++ b/plugins/UserAgreement/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Ask the user once if he/she agrees with our license.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json
index 79115f931e..463fcdc941 100644
--- a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json
index d213042ad2..e7a0b1c559 100644
--- a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json
index 759b6368fd..3029539887 100644
--- a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
index 3c3d7fff8c..225da67235 100644
--- a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json
index 3df84ff7e6..9a139851ec 100644
--- a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 2.7 to Cura 3.0.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json
index d80b820976..cf42b3f6cd 100644
--- a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 3.0 to Cura 3.1.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
index fbce09c807..f9cc968dae 100644
--- a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json
index 164b79d504..f5ba7235d1 100644
--- a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 3.3 to Cura 3.4.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade34to40/plugin.json b/plugins/VersionUpgrade/VersionUpgrade34to40/plugin.json
index 1059ca3e57..c07ae31c0a 100644
--- a/plugins/VersionUpgrade/VersionUpgrade34to40/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade34to40/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 3.4 to Cura 4.0.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/X3DReader/plugin.json b/plugins/X3DReader/plugin.json
index f18c7f033d..9ee09e43df 100644
--- a/plugins/X3DReader/plugin.json
+++ b/plugins/X3DReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Seva Alekseyev",
"version": "0.5.0",
"description": "Provides support for reading X3D files.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/XRayView/plugin.json b/plugins/XRayView/plugin.json
index 4e89690c13..576dec4656 100644
--- a/plugins/XRayView/plugin.json
+++ b/plugins/XRayView/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides the X-Ray view.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/plugins/XmlMaterialProfile/plugin.json b/plugins/XmlMaterialProfile/plugin.json
index 17056dcb3e..4b2901c375 100644
--- a/plugins/XmlMaterialProfile/plugin.json
+++ b/plugins/XmlMaterialProfile/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides capabilities to read and write XML-based material profiles.",
- "api": 4,
+ "api": 5,
"i18n-catalog": "cura"
}
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index 3eb7cb1c32..610ee1473e 100644
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -1819,9 +1819,9 @@
"unit": "mm",
"type": "float",
"default_value": 0.1,
- "minimum_value": "resolveOrValue('layer_height')",
+ "minimum_value": "resolveOrValue('layer_height') if infill_line_distance > 0 else -999999",
"maximum_value_warning": "0.75 * machine_nozzle_size",
- "maximum_value": "resolveOrValue('layer_height') * (1.45 if spaghetti_infill_enabled else 8)",
+ "maximum_value": "resolveOrValue('layer_height') * (1.45 if spaghetti_infill_enabled else 8) if infill_line_distance > 0 else 999999",
"value": "resolveOrValue('layer_height')",
"enabled": "infill_sparse_density > 0 and not spaghetti_infill_enabled",
"limit_to_extruder": "infill_extruder_nr",
diff --git a/resources/definitions/peopoly_moai.def.json b/resources/definitions/peopoly_moai.def.json
index 5c03444d49..a578cc4240 100644
--- a/resources/definitions/peopoly_moai.def.json
+++ b/resources/definitions/peopoly_moai.def.json
@@ -4,13 +4,14 @@
"inherits": "fdmprinter",
"metadata": {
"visible": true,
- "author": "fieldOfView",
+ "author": "Peopoly",
"manufacturer": "Peopoly",
"file_formats": "text/x-gcode",
"has_machine_quality": true,
"has_materials": false,
- "machine_extruder_trains":
- {
+ "platform": "moai.obj",
+ "platform_texture": "moai.jpg",
+ "machine_extruder_trains": {
"0": "peopoly_moai_extruder_0"
}
},
@@ -46,7 +47,6 @@
"machine_end_gcode": {
"default_value": "M104 S0\nM140 S0\nG28 X0 Y0\nM84"
},
-
"line_width": {
"minimum_value_warning": "machine_nozzle_size"
},
@@ -75,7 +75,14 @@
"value": "0.1"
},
"top_bottom_thickness": {
- "minimum_value_warning": "0.1"
+ "minimum_value_warning": "0.1",
+ "value": "0.1"
+ },
+ "top_thickness": {
+ "minimum_value_warning": "resolveOrValue('layer_height')"
+ },
+ "bottom_thickness": {
+ "minimum_value_warning": "resolveOrValue('layer_height')"
},
"infill_sparse_thickness": {
"maximum_value_warning": "0.5"
@@ -102,24 +109,23 @@
"value": "speed_print"
},
"speed_travel": {
- "value": "300"
+ "value": 150
},
"speed_travel_layer_0": {
- "value": "300"
+ "value": 150
},
"speed_layer_0": {
- "value": "5"
+ "value": 5
},
"speed_slowdown_layers": {
- "value": "2"
+ "value": 3
},
"infill_overlap": {
- "value": "15"
+ "value": 15
},
"adhesion_type": {
- "value": "\"none\""
+ "value": "'none'"
},
-
"acceleration_enabled": {
"value": "False"
},
@@ -139,6 +145,10 @@
"enabled": false,
"value": "False"
},
+ "cool_fan_speed_min": {
+ "enabled": false,
+ "value": 0
+ },
"retraction_enable": {
"enabled": false,
"value": "False"
@@ -148,7 +158,8 @@
"value": "'off'"
},
"retract_at_layer_change": {
- "enabled": false
+ "enabled": false,
+ "value": false
},
"cool_min_layer_time_fan_speed_max": {
"enabled": false
@@ -158,6 +169,117 @@
},
"cool_fan_full_layer": {
"enabled": false
+ },
+ "minimum_polygon_circumference": {
+ "value": "0.1"
+ },
+ "meshfix_maximum_resolution": {
+ "value": "0.005"
+ },
+ "skin_outline_count": {
+ "value": 0
+ },
+ "travel_compensate_overlapping_walls_enabled": {
+ "value": "False"
+ },
+ "travel_compensate_overlapping_walls_0_enabled": {
+ "value": "False"
+ },
+ "travel_compensate_overlapping_walls_x_enabled": {
+ "value": "False"
+ },
+ "wall_0_wipe_dist": {
+ "value": "machine_nozzle_size / 3"
+ },
+ "wall_thickness": {
+ "value": 0.5
+ },
+ "infill_sparse_density": {
+ "value": 70
+ },
+ "infill_pattern": {
+ "value": "'lines'"
+ },
+ "infill_angles": {
+ "value": "[0,90]"
+ },
+ "cool_min_layer_time": {
+ "enabled": false,
+ "value": 0
+ },
+ "cool_min_speed": {
+ "enabled": false,
+ "value": 0
+ },
+ "cool_lift_head": {
+ "enabled": false,
+ "value": "False"
+ },
+ "material_flow": {
+ "enabled": false
+ },
+ "material_flow_layer_0": {
+ "enabled": false
+ },
+ "speed_equalize_flow_enabled": {
+ "enabled": false,
+ "value": "False"
+ },
+ "draft_shield_enabled": {
+ "enabled": false,
+ "value": "False"
+ },
+ "z_seam_corner": {
+ "value": "'z_seam_corner_none'"
+ },
+ "z_seam_type": {
+ "value": "'shortest'"
+ },
+ "skin_no_small_gaps_heuristic": {
+ "value": "False"
+ },
+ "ironing_enabled": {
+ "enabled": false,
+ "value": "False"
+ },
+ "skin_overlap": {
+ "value": 5
+ },
+ "infill_wipe_dist": {
+ "value": 0
+ },
+ "expand_skins_expand_distance": {
+ "value": "( wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x ) / 2"
+ },
+ "max_feedrate_z_override": {
+ "value": 0,
+ "enabled": false
+ },
+ "flow_rate_max_extrusion_offset": {
+ "enabled": false
+ },
+ "flow_rate_extrusion_offset_factor": {
+ "enabled": false
+ },
+ "adaptive_layer_height_enabled": {
+ "value": "False",
+ "enabled": false
+ },
+ "bridge_settings_enabled": {
+ "value": "False",
+ "enabled": false
+ },
+ "acceleration_enabled": {
+ "value": "False",
+ "enabled": false
+ },
+ "relative_extrusion": {
+ "value": "False",
+ "enabled": false
+ },
+ "coasting_enable": {
+ "value": "False",
+ "enabled": false
}
}
}
diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json
index 08fe01a76b..b75d12ce44 100644
--- a/resources/definitions/ultimaker3.def.json
+++ b/resources/definitions/ultimaker3.def.json
@@ -90,7 +90,7 @@
"infill_overlap": { "value": "0" },
"infill_pattern": { "value": "'triangles'" },
"infill_wipe_dist": { "value": "0" },
- "initial_layer_line_width_factor": { "value": "120" },
+ "initial_layer_line_width_factor": { "value": "120" },
"jerk_enabled": { "value": "True" },
"jerk_layer_0": { "value": "jerk_topbottom" },
"jerk_prime_tower": { "value": "math.ceil(jerk_print * 15 / 25)" },
diff --git a/resources/extruders/builder_premium_large_front.def.json b/resources/extruders/builder_premium_large_front.def.json
index 059f7ef8a7..4834bc8fd9 100644
--- a/resources/extruders/builder_premium_large_front.def.json
+++ b/resources/extruders/builder_premium_large_front.def.json
@@ -16,13 +16,13 @@
"machine_nozzle_offset_x": { "default_value": 0.0 },
"machine_nozzle_offset_y": { "default_value": 0.0 },
"material_diameter": { "default_value": 1.75 },
-
- "machine_extruder_start_pos_abs": { "default_value": true },
+
+ "machine_extruder_start_pos_abs": { "default_value": true },
"machine_extruder_start_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_start_pos_y": { "value": "prime_tower_position_y" },
"machine_extruder_end_pos_abs": { "default_value": true },
"machine_extruder_end_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_end_pos_y": { "value": "prime_tower_position_y" },
- "extruder_prime_pos_abs": { "default_value": true }
+ "extruder_prime_pos_abs": { "default_value": true }
}
}
diff --git a/resources/extruders/builder_premium_large_rear.def.json b/resources/extruders/builder_premium_large_rear.def.json
index 769178a8b4..f257749ea4 100644
--- a/resources/extruders/builder_premium_large_rear.def.json
+++ b/resources/extruders/builder_premium_large_rear.def.json
@@ -20,9 +20,9 @@
"machine_extruder_start_pos_abs": { "default_value": true },
"machine_extruder_start_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_start_pos_y": { "value": "prime_tower_position_y" },
- "machine_extruder_end_pos_abs": { "default_value": true },
+ "machine_extruder_end_pos_abs": { "default_value": true },
"machine_extruder_end_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_end_pos_y": { "value": "prime_tower_position_y" },
- "extruder_prime_pos_abs": { "default_value": true }
+ "extruder_prime_pos_abs": { "default_value": true }
}
}
diff --git a/resources/extruders/builder_premium_medium_front.def.json b/resources/extruders/builder_premium_medium_front.def.json
index bd735fbe25..05dcb3d49f 100644
--- a/resources/extruders/builder_premium_medium_front.def.json
+++ b/resources/extruders/builder_premium_medium_front.def.json
@@ -16,13 +16,13 @@
"machine_nozzle_offset_x": { "default_value": 0.0 },
"machine_nozzle_offset_y": { "default_value": 0.0 },
"material_diameter": { "default_value": 1.75 },
-
- "machine_extruder_start_pos_abs": { "default_value": true },
+
+ "machine_extruder_start_pos_abs": { "default_value": true },
"machine_extruder_start_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_start_pos_y": { "value": "prime_tower_position_y" },
"machine_extruder_end_pos_abs": { "default_value": true },
"machine_extruder_end_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_end_pos_y": { "value": "prime_tower_position_y" },
- "extruder_prime_pos_abs": { "default_value": true }
+ "extruder_prime_pos_abs": { "default_value": true }
}
}
diff --git a/resources/extruders/builder_premium_medium_rear.def.json b/resources/extruders/builder_premium_medium_rear.def.json
index 59e688ff71..3461e07f09 100644
--- a/resources/extruders/builder_premium_medium_rear.def.json
+++ b/resources/extruders/builder_premium_medium_rear.def.json
@@ -20,9 +20,9 @@
"machine_extruder_start_pos_abs": { "default_value": true },
"machine_extruder_start_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_start_pos_y": { "value": "prime_tower_position_y" },
- "machine_extruder_end_pos_abs": { "default_value": true },
+ "machine_extruder_end_pos_abs": { "default_value": true },
"machine_extruder_end_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_end_pos_y": { "value": "prime_tower_position_y" },
- "extruder_prime_pos_abs": { "default_value": true }
+ "extruder_prime_pos_abs": { "default_value": true }
}
}
diff --git a/resources/extruders/builder_premium_small_front.def.json b/resources/extruders/builder_premium_small_front.def.json
index 17fb914a42..7a1c352c73 100644
--- a/resources/extruders/builder_premium_small_front.def.json
+++ b/resources/extruders/builder_premium_small_front.def.json
@@ -16,13 +16,13 @@
"machine_nozzle_offset_x": { "default_value": 0.0 },
"machine_nozzle_offset_y": { "default_value": 0.0 },
"material_diameter": { "default_value": 1.75 },
-
- "machine_extruder_start_pos_abs": { "default_value": true },
+
+ "machine_extruder_start_pos_abs": { "default_value": true },
"machine_extruder_start_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_start_pos_y": { "value": "prime_tower_position_y" },
"machine_extruder_end_pos_abs": { "default_value": true },
"machine_extruder_end_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_end_pos_y": { "value": "prime_tower_position_y" },
- "extruder_prime_pos_abs": { "default_value": true }
+ "extruder_prime_pos_abs": { "default_value": true }
}
}
diff --git a/resources/extruders/builder_premium_small_rear.def.json b/resources/extruders/builder_premium_small_rear.def.json
index 70a2dbf1aa..7085236a5c 100644
--- a/resources/extruders/builder_premium_small_rear.def.json
+++ b/resources/extruders/builder_premium_small_rear.def.json
@@ -20,9 +20,9 @@
"machine_extruder_start_pos_abs": { "default_value": true },
"machine_extruder_start_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_start_pos_y": { "value": "prime_tower_position_y" },
- "machine_extruder_end_pos_abs": { "default_value": true },
+ "machine_extruder_end_pos_abs": { "default_value": true },
"machine_extruder_end_pos_x": { "value": "prime_tower_position_x" },
"machine_extruder_end_pos_y": { "value": "prime_tower_position_y" },
- "extruder_prime_pos_abs": { "default_value": true }
+ "extruder_prime_pos_abs": { "default_value": true }
}
}
diff --git a/resources/extruders/peopoly_moai_extruder_0.def.json b/resources/extruders/peopoly_moai_extruder_0.def.json
index 7940002926..bbffd4ac4d 100644
--- a/resources/extruders/peopoly_moai_extruder_0.def.json
+++ b/resources/extruders/peopoly_moai_extruder_0.def.json
@@ -11,6 +11,9 @@
"overrides": {
"extruder_nr": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.067 },
- "material_diameter": { "default_value": 1.75 }
+ "material_diameter": {
+ "enabled": false,
+ "default_value": 1.75
+ }
}
}
diff --git a/resources/images/moai.jpg b/resources/images/moai.jpg
new file mode 100644
index 0000000000..54c6c7561e
Binary files /dev/null and b/resources/images/moai.jpg differ
diff --git a/resources/meshes/moai.obj b/resources/meshes/moai.obj
new file mode 100644
index 0000000000..f13f30d6f4
--- /dev/null
+++ b/resources/meshes/moai.obj
@@ -0,0 +1,32 @@
+# OBJ written from C:\Users\Flo\Desktop\Cura_FILES\moai.obj
+mtllib moai.mtl
+# Units millimeters
+
+g Mesh
+v 65 -65 0
+v -65 -65 0
+v -65 65 0
+v 65 65 0
+v 65 -65 0
+v -65 -65 0
+v -65 65 0
+v 65 65 0
+v -65 65 18.8383
+v 65 65 18.8383
+vn 0 0 1
+vn 1 0 0
+vn -1 0 0
+vt 0.0975501 1
+vt 1 1
+vt 1 0.0977239
+vt 0.0975501 0.0977239
+vt 0.0186426 0.870052
+vt 0.0736426 0.870052
+vt 0.0186426 0.815052
+vt 0.0214764 0.912057
+vt 0.0764764 0.967057
+vt 0.0214764 0.967057
+usemtl red
+f 1/1/1 4/2/1 3/3/1 2/4/1
+f 7/5/2 9/6/2 6/7/2
+f 5/8/3 10/9/3 8/10/3
diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml
index 21e6eebf58..d5572298f7 100644
--- a/resources/qml/Actions.qml
+++ b/resources/qml/Actions.qml
@@ -110,35 +110,35 @@ Item
Action
{
id: view3DCameraAction;
- text: catalog.i18nc("@action:inmenu menubar:view","&3D View");
+ text: catalog.i18nc("@action:inmenu menubar:view","3D View");
onTriggered: UM.Controller.rotateView("3d", 0);
}
Action
{
id: viewFrontCameraAction;
- text: catalog.i18nc("@action:inmenu menubar:view","&Front View");
+ text: catalog.i18nc("@action:inmenu menubar:view","Front View");
onTriggered: UM.Controller.rotateView("home", 0);
}
Action
{
id: viewTopCameraAction;
- text: catalog.i18nc("@action:inmenu menubar:view","&Top View");
+ text: catalog.i18nc("@action:inmenu menubar:view","Top View");
onTriggered: UM.Controller.rotateView("y", 90);
}
Action
{
id: viewLeftSideCameraAction;
- text: catalog.i18nc("@action:inmenu menubar:view","&Left Side View");
+ text: catalog.i18nc("@action:inmenu menubar:view","Left Side View");
onTriggered: UM.Controller.rotateView("x", 90);
}
Action
{
id: viewRightSideCameraAction;
- text: catalog.i18nc("@action:inmenu menubar:view","&Right Side View");
+ text: catalog.i18nc("@action:inmenu menubar:view","Right Side View");
onTriggered: UM.Controller.rotateView("x", -90);
}
@@ -229,7 +229,7 @@ Item
Action
{
id: deleteSelectionAction;
- text: catalog.i18ncp("@action:inmenu menubar:edit", "Delete &Selected Model", "Delete &Selected Models", UM.Selection.selectionCount);
+ text: catalog.i18ncp("@action:inmenu menubar:edit", "Delete Selected Model", "Delete Selected Models", UM.Selection.selectionCount);
enabled: UM.Controller.toolsEnabled && UM.Selection.hasSelection;
iconName: "edit-delete";
shortcut: StandardKey.Delete;
@@ -239,7 +239,7 @@ Item
Action //Also add backspace as the same function as delete because on Macintosh keyboards the button called "delete" is actually a backspace, and the user expects it to function as a delete.
{
id: backspaceSelectionAction
- text: catalog.i18ncp("@action:inmenu menubar:edit", "Delete &Selected Model", "Delete &Selected Models", UM.Selection.selectionCount)
+ text: catalog.i18ncp("@action:inmenu menubar:edit", "Delete Selected Model", "Delete Selected Models", UM.Selection.selectionCount)
enabled: UM.Controller.toolsEnabled && UM.Selection.hasSelection
iconName: "edit-delete"
shortcut: StandardKey.Backspace
@@ -328,7 +328,7 @@ Item
Action
{
id: selectAllAction;
- text: catalog.i18nc("@action:inmenu menubar:edit","&Select All Models");
+ text: catalog.i18nc("@action:inmenu menubar:edit","Select All Models");
enabled: UM.Controller.toolsEnabled;
iconName: "edit-select-all";
shortcut: "Ctrl+A";
@@ -386,7 +386,7 @@ Item
Action
{
id: resetAllAction;
- text: catalog.i18nc("@action:inmenu menubar:edit","Reset All Model &Transformations");
+ text: catalog.i18nc("@action:inmenu menubar:edit","Reset All Model Transformations");
onTriggered: CuraApplication.resetAll();
}
diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml
index 046a887a71..33e456c758 100644
--- a/resources/qml/Cura.qml
+++ b/resources/qml/Cura.qml
@@ -117,7 +117,7 @@ UM.MainWindow
MenuItem
{
id: saveWorkspaceMenu
- text: catalog.i18nc("@title:menu menubar:file","&Save...")
+ text: catalog.i18nc("@title:menu menubar:file","Save...")
onTriggered:
{
var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/x-curaproject+xml" };
@@ -541,7 +541,7 @@ UM.MainWindow
insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("Preferences/MachinesPage.qml"));
- insertPage(3, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml"));
+ insertPage(3, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/Materials/MaterialsPage.qml"));
insertPage(4, catalog.i18nc("@title:tab", "Profiles"), Qt.resolvedUrl("Preferences/ProfilesPage.qml"));
diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml
index 20ec8ce289..31ca84d66e 100644
--- a/resources/qml/JobSpecs.qml
+++ b/resources/qml/JobSpecs.qml
@@ -81,7 +81,7 @@ Item {
text: PrintInformation.jobName
horizontalAlignment: TextInput.AlignRight
onEditingFinished: {
- var new_name = text == "" ? catalog.i18nc("@text Print job name", "unnamed") : text;
+ var new_name = text == "" ? catalog.i18nc("@text Print job name", "Untitled") : text;
PrintInformation.setJobName(new_name, true);
printJobTextfield.focus = false;
}
diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml
index 64b3130724..f9e343d2dd 100644
--- a/resources/qml/Menus/MaterialMenu.qml
+++ b/resources/qml/Menus/MaterialMenu.qml
@@ -10,28 +10,74 @@ import Cura 1.0 as Cura
Menu
{
id: menu
- title: "Material"
+ title: catalog.i18nc("@label:category menu label", "Material")
property int extruderIndex: 0
+ Cura.FavoriteMaterialsModel
+ {
+ id: favoriteMaterialsModel
+ extruderPosition: menu.extruderIndex
+ }
+
+ Cura.GenericMaterialsModel
+ {
+ id: genericMaterialsModel
+ extruderPosition: menu.extruderIndex
+ }
+
+ Cura.MaterialBrandsModel
+ {
+ id: brandModel
+ extruderPosition: menu.extruderIndex
+ }
+
+ MenuItem
+ {
+ text: catalog.i18nc("@label:category menu label", "Favorites")
+ enabled: false
+ visible: favoriteMaterialsModel.items.length > 0
+ }
Instantiator
{
- model: genericMaterialsModel
- MenuItem
+ model: favoriteMaterialsModel
+ delegate: MenuItem
{
- text: model.name
+ text: model.brand + " " + model.name
checkable: true
checked: model.root_material_id == Cura.MachineManager.currentRootMaterialId[extruderIndex]
+ onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node)
exclusiveGroup: group
- onTriggered:
- {
- Cura.MachineManager.setMaterial(extruderIndex, model.container_node);
- }
}
onObjectAdded: menu.insertItem(index, object)
- onObjectRemoved: menu.removeItem(object)
+ onObjectRemoved: menu.removeItem(object) // TODO: This ain't gonna work, removeItem() takes an index, not object
}
- MenuSeparator { }
+
+ MenuSeparator {}
+
+ Menu
+ {
+ id: genericMenu
+ title: catalog.i18nc("@label:category menu label", "Generic")
+
+ Instantiator
+ {
+ model: genericMaterialsModel
+ delegate: MenuItem
+ {
+ text: model.name
+ checkable: true
+ checked: model.root_material_id == Cura.MachineManager.currentRootMaterialId[extruderIndex]
+ exclusiveGroup: group
+ onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node)
+ }
+ onObjectAdded: genericMenu.insertItem(index, object)
+ onObjectRemoved: genericMenu.removeItem(object) // TODO: This ain't gonna work, removeItem() takes an index, not object
+ }
+ }
+
+ MenuSeparator {}
+
Instantiator
{
model: brandModel
@@ -40,12 +86,12 @@ Menu
id: brandMenu
title: brandName
property string brandName: model.name
- property var brandMaterials: model.materials
+ property var brandMaterials: model.material_types
Instantiator
{
model: brandMaterials
- Menu
+ delegate: Menu
{
id: brandMaterialsMenu
title: materialName
@@ -55,16 +101,13 @@ Menu
Instantiator
{
model: brandMaterialColors
- MenuItem
+ delegate: MenuItem
{
text: model.name
checkable: true
checked: model.id == Cura.MachineManager.allActiveMaterialIds[Cura.ExtruderManager.extruderIds[extruderIndex]]
exclusiveGroup: group
- onTriggered:
- {
- Cura.MachineManager.setMaterial(extruderIndex, model.container_node);
- }
+ onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node)
}
onObjectAdded: brandMaterialsMenu.insertItem(index, object)
onObjectRemoved: brandMaterialsMenu.removeItem(object)
@@ -78,21 +121,14 @@ Menu
onObjectRemoved: menu.removeItem(object)
}
- Cura.GenericMaterialsModel
- {
- id: genericMaterialsModel
- extruderPosition: menu.extruderIndex
+ ExclusiveGroup {
+ id: group
}
- Cura.BrandMaterialsModel
+ MenuSeparator {}
+
+ MenuItem
{
- id: brandModel
- extruderPosition: menu.extruderIndex
+ action: Cura.Actions.manageMaterials
}
-
- ExclusiveGroup { id: group }
-
- MenuSeparator { }
-
- MenuItem { action: Cura.Actions.manageMaterials }
}
diff --git a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml
new file mode 100644
index 0000000000..1077cbff6f
--- /dev/null
+++ b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml
@@ -0,0 +1,100 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Uranium is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.7
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.3
+import QtQuick.Dialogs 1.2
+
+import UM 1.2 as UM
+import Cura 1.0 as Cura
+
+Rectangle
+{
+ id: brand_section
+ property var expanded: base.collapsed_brands.indexOf(model.name) > -1
+ property var types_model: model.material_types
+ height: childrenRect.height
+ width: parent.width
+ Rectangle
+ {
+ id: brand_header_background
+ color: UM.Theme.getColor("favorites_header_bar")
+ anchors.fill: brand_header
+ }
+ Row
+ {
+ id: brand_header
+ width: parent.width
+ Label
+ {
+ id: brand_name
+ text: model.name
+ height: UM.Theme.getSize("favorites_row").height
+ width: parent.width - UM.Theme.getSize("favorites_button").width
+ verticalAlignment: Text.AlignVCenter
+ leftPadding: 4
+ }
+ Button
+ {
+ text: ""
+ implicitWidth: UM.Theme.getSize("favorites_button").width
+ implicitHeight: UM.Theme.getSize("favorites_button").height
+ UM.RecolorImage {
+ anchors
+ {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ width: UM.Theme.getSize("standard_arrow").width
+ height: UM.Theme.getSize("standard_arrow").height
+ sourceSize.width: width
+ sourceSize.height: height
+ color: "black"
+ source: brand_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
+ }
+ style: ButtonStyle
+ {
+ background: Rectangle
+ {
+ anchors.fill: parent
+ color: "transparent"
+ }
+ }
+ }
+ }
+ MouseArea
+ {
+ anchors.fill: brand_header
+ onPressed:
+ {
+ const i = base.collapsed_brands.indexOf(model.name)
+ if (i > -1)
+ {
+ // Remove it
+ base.collapsed_brands.splice(i, 1)
+ brand_section.expanded = false
+ }
+ else
+ {
+ // Add it
+ base.collapsed_brands.push(model.name)
+ brand_section.expanded = true
+ }
+ }
+ }
+ Column
+ {
+ anchors.top: brand_header.bottom
+ width: parent.width
+ anchors.left: parent.left
+ height: brand_section.expanded ? childrenRect.height : 0
+ visible: brand_section.expanded
+ Repeater
+ {
+ model: types_model
+ delegate: MaterialsTypeSection {}
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml b/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml
new file mode 100644
index 0000000000..ad9f0e3766
--- /dev/null
+++ b/resources/qml/Preferences/Materials/MaterialsDetailsPanel.qml
@@ -0,0 +1,102 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Uranium is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.7
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.3
+import QtQuick.Dialogs 1.2
+
+import UM 1.2 as UM
+import Cura 1.0 as Cura
+
+Item
+{
+ id: detailsPanel
+
+ property var currentItem: base.currentItem
+
+ onCurrentItemChanged: { updateMaterialPropertiesObject(currentItem) }
+
+ function updateMaterialPropertiesObject( currentItem )
+ {
+ materialProperties.name = currentItem.name || "Unknown"
+ materialProperties.guid = currentItem.GUID;
+ materialProperties.container_id = currentItem.id
+ materialProperties.brand = currentItem.brand || "Unknown"
+ materialProperties.material = currentItem.material || "Unknown"
+ materialProperties.color_name = currentItem.color_name || "Yellow"
+ materialProperties.color_code = currentItem.color_code || "yellow"
+ materialProperties.description = currentItem.description || ""
+ materialProperties.adhesion_info = currentItem.adhesion_info || "";
+ materialProperties.density = currentItem.density || 0.0
+ materialProperties.diameter = currentItem.diameter || 0.0
+ materialProperties.approximate_diameter = currentItem.approximate_diameter || "0"
+ }
+
+ Item
+ {
+ anchors.fill: parent
+
+ Item // Material title Label
+ {
+ id: profileName
+
+ width: parent.width
+ height: childrenRect.height
+
+ Label {
+ text: materialProperties.name
+ font: UM.Theme.getFont("large")
+ }
+ }
+
+ MaterialsView // Material detailed information view below the title Label
+ {
+ id: materialDetailsView
+ anchors
+ {
+ left: parent.left
+ right: parent.right
+ top: profileName.bottom
+ topMargin: UM.Theme.getSize("default_margin").height
+ bottom: parent.bottom
+ }
+
+ editingEnabled: base.currentItem != null && !base.currentItem.is_read_only
+
+ properties: materialProperties
+ containerId: base.currentItem != null ? base.currentItem.id : ""
+ currentMaterialNode: base.currentItem.container_node
+
+
+ }
+
+ QtObject
+ {
+ id: materialProperties
+
+ property string guid: "00000000-0000-0000-0000-000000000000"
+ property string container_id: "Unknown";
+ property string name: "Unknown";
+ property string profile_type: "Unknown";
+ property string brand: "Unknown";
+ property string material: "Unknown"; // This needs to be named as "material" to be consistent with
+ // the material container's metadata entry
+
+ property string color_name: "Yellow";
+ property color color_code: "yellow";
+
+ property real density: 0.0;
+ property real diameter: 0.0;
+ property string approximate_diameter: "0";
+
+ property real spool_cost: 0.0;
+ property real spool_weight: 0.0;
+ property real spool_length: 0.0;
+ property real cost_per_meter: 0.0;
+
+ property string description: "";
+ property string adhesion_info: "";
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/qml/Preferences/Materials/MaterialsList.qml b/resources/qml/Preferences/Materials/MaterialsList.qml
new file mode 100644
index 0000000000..4a1a330ed6
--- /dev/null
+++ b/resources/qml/Preferences/Materials/MaterialsList.qml
@@ -0,0 +1,199 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Uranium is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.7
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.3
+import QtQuick.Dialogs 1.2
+
+import UM 1.2 as UM
+import Cura 1.0 as Cura
+
+Item
+{
+ id: materialList
+ width: materialScrollView.width - 17
+ height: childrenRect.height
+
+ // Children
+ UM.I18nCatalog { id: catalog; name: "cura"; }
+ Cura.MaterialBrandsModel { id: materialsModel }
+ Cura.FavoriteMaterialsModel { id: favoriteMaterialsModel }
+ Cura.GenericMaterialsModel { id: genericMaterialsModel }
+ Column
+ {
+ Rectangle
+ {
+ property var expanded: true
+
+ id: favorites_section
+ height: childrenRect.height
+ width: materialList.width
+ Rectangle
+ {
+ id: favorites_header_background
+ color: UM.Theme.getColor("favorites_header_bar")
+ anchors.fill: favorites_header
+ }
+ Row
+ {
+ id: favorites_header
+ Label
+ {
+ id: favorites_name
+ text: "Favorites"
+ height: UM.Theme.getSize("favorites_row").height
+ width: materialList.width - UM.Theme.getSize("favorites_button").width
+ verticalAlignment: Text.AlignVCenter
+ leftPadding: 4
+ }
+ Button
+ {
+ text: ""
+ implicitWidth: UM.Theme.getSize("favorites_button").width
+ implicitHeight: UM.Theme.getSize("favorites_button").height
+ UM.RecolorImage {
+ anchors
+ {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ width: UM.Theme.getSize("standard_arrow").width
+ height: UM.Theme.getSize("standard_arrow").height
+ sourceSize.width: width
+ sourceSize.height: height
+ color: "black"
+ source: favorites_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
+ }
+ style: ButtonStyle
+ {
+ background: Rectangle
+ {
+ anchors.fill: parent
+ color: "transparent"
+ }
+ }
+ }
+ }
+ MouseArea
+ {
+ anchors.fill: favorites_header
+ onPressed:
+ {
+ favorites_section.expanded = !favorites_section.expanded
+ }
+ }
+ Column
+ {
+ anchors.top: favorites_header.bottom
+ anchors.left: parent.left
+ width: materialList.width
+ height: favorites_section.expanded ? childrenRect.height : 0
+ visible: favorites_section.expanded
+ Repeater
+ {
+ model: favoriteMaterialsModel
+ delegate: MaterialsSlot {
+ material: model
+ }
+ }
+ }
+ }
+ Rectangle
+ {
+ property var expanded: base.collapsed_brands.indexOf("Generic") > -1
+
+ id: generic_section
+ height: childrenRect.height
+ width: materialList.width
+ Rectangle
+ {
+ id: generic_header_background
+ color: UM.Theme.getColor("favorites_header_bar")
+ anchors.fill: generic_header
+ }
+ Row
+ {
+ id: generic_header
+ Label
+ {
+ id: generic_name
+ text: "Generic"
+ height: UM.Theme.getSize("favorites_row").height
+ width: materialList.width - UM.Theme.getSize("favorites_button").width
+ verticalAlignment: Text.AlignVCenter
+ leftPadding: 4
+ }
+ Button
+ {
+ text: ""
+ implicitWidth: UM.Theme.getSize("favorites_button").width
+ implicitHeight: UM.Theme.getSize("favorites_button").height
+ UM.RecolorImage {
+ anchors
+ {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ width: UM.Theme.getSize("standard_arrow").width
+ height: UM.Theme.getSize("standard_arrow").height
+ sourceSize.width: width
+ sourceSize.height: height
+ color: "black"
+ source: generic_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
+ }
+ style: ButtonStyle
+ {
+ background: Rectangle
+ {
+ anchors.fill: parent
+ color: "transparent"
+ }
+ }
+ }
+ }
+ MouseArea
+ {
+ anchors.fill: generic_header
+ onPressed:
+ {
+ const i = base.collapsed_brands.indexOf("Generic")
+ if (i > -1)
+ {
+ // Remove it
+ base.collapsed_brands.splice(i, 1)
+ generic_section.expanded = false
+ }
+ else
+ {
+ // Add it
+ base.collapsed_brands.push("Generic")
+ generic_section.expanded = true
+ }
+ }
+ }
+ Column
+ {
+ anchors.top: generic_header.bottom
+ width: materialList.width
+ anchors.left: parent.left
+ height: generic_section.expanded ? childrenRect.height : 0
+ visible: generic_section.expanded
+ Repeater
+ {
+ model: genericMaterialsModel
+ delegate: MaterialsSlot {
+ material: model
+ }
+ }
+ }
+ }
+ Repeater
+ {
+ id: brand_list
+ model: materialsModel
+ delegate: MaterialsBrandSection {}
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/Materials/MaterialsPage.qml
similarity index 56%
rename from resources/qml/Preferences/MaterialsPage.qml
rename to resources/qml/Preferences/Materials/MaterialsPage.qml
index e2e3edec2f..0b81df5fa1 100644
--- a/resources/qml/Preferences/MaterialsPage.qml
+++ b/resources/qml/Preferences/Materials/MaterialsPage.qml
@@ -9,25 +9,110 @@ import QtQuick.Dialogs 1.2
import UM 1.2 as UM
import Cura 1.0 as Cura
-
Item
{
id: base
property QtObject materialManager: CuraApplication.getMaterialManager()
- property var resetEnabled: false // Keep PreferencesDialog happy
-
- UM.I18nCatalog { id: catalog; name: "cura"; }
-
- Cura.MaterialManagementModel
+ // Keep PreferencesDialog happy
+ property var resetEnabled: false
+ property var currentItem: null
+ property var isCurrentItemActivated:
{
- id: materialsModel
+ const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
+ const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
+ return base.currentItem.root_material_id == root_material_id;
+ }
+ property string newRootMaterialIdToSwitchTo: ""
+ property bool toActivateNewMaterial: false
+
+ // TODO: Save these to preferences
+ property var collapsed_brands: []
+ property var collapsed_types: []
+
+ UM.I18nCatalog
+ {
+ id: catalog
+ name: "cura"
+ }
+ Cura.MaterialBrandsModel { id: materialsModel }
+
+ function findModelByRootId( search_root_id )
+ {
+ for (var i = 0; i < materialsModel.rowCount(); i++)
+ {
+ var types_model = materialsModel.getItem(i).material_types;
+ for (var j = 0; j < types_model.rowCount(); j++)
+ {
+ var colors_model = types_model.getItem(j).colors;
+ for (var k = 0; k < colors_model.rowCount(); k++)
+ {
+ var material = colors_model.getItem(k);
+ if (material.root_material_id == search_root_id)
+ {
+ return material
+ }
+ }
+ }
+ }
+ }
+ Component.onCompleted:
+ {
+ // Select the activated material when this page shows up
+ const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
+ const active_root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
+ console.log("goign to search for", active_root_material_id)
+ base.currentItem = findModelByRootId(active_root_material_id)
}
+ onCurrentItemChanged: { MaterialsDetailsPanel.currentItem = currentItem }
+ Connections
+ {
+ target: materialsModel
+ onItemsChanged:
+ {
+ var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id;
+ var position = Cura.ExtruderManager.activeExtruderIndex;
+
+ // try to pick the currently selected item; it may have been moved
+ if (base.newRootMaterialIdToSwitchTo == "")
+ {
+ base.newRootMaterialIdToSwitchTo = currentItemId;
+ }
+
+ for (var idx = 0; idx < materialsModel.rowCount(); ++idx)
+ {
+ var item = materialsModel.getItem(idx);
+ if (item.root_material_id == base.newRootMaterialIdToSwitchTo)
+ {
+ // Switch to the newly created profile if needed
+ materialListView.currentIndex = idx;
+ materialListView.activateDetailsWithIndex(materialListView.currentIndex);
+ if (base.toActivateNewMaterial)
+ {
+ Cura.MachineManager.setMaterial(position, item.container_node);
+ }
+ base.newRootMaterialIdToSwitchTo = "";
+ base.toActivateNewMaterial = false;
+ return
+ }
+ }
+
+ materialListView.currentIndex = 0;
+ materialListView.activateDetailsWithIndex(materialListView.currentIndex);
+ if (base.toActivateNewMaterial)
+ {
+ Cura.MachineManager.setMaterial(position, materialsModel.getItem(0).container_node);
+ }
+ base.newRootMaterialIdToSwitchTo = "";
+ base.toActivateNewMaterial = false;
+ }
+ }
+
+ // Main layout
Label
{
id: titleLabel
-
anchors
{
top: parent.top
@@ -35,45 +120,12 @@ Item
right: parent.right
margins: 5 * screenScaleFactor
}
-
font.pointSize: 18
text: catalog.i18nc("@title:tab", "Materials")
}
- property var hasCurrentItem: materialListView.currentItem != null
-
- property var currentItem:
- { // is soon to be overwritten
- var current_index = materialListView.currentIndex;
- return materialsModel.getItem(current_index);
- }
-
- property var isCurrentItemActivated:
- {
- const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
- const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
- return base.currentItem.root_material_id == root_material_id;
- }
-
- Component.onCompleted:
- {
- // Select the activated material when this page shows up
- const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
- const active_root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
- var itemIndex = -1;
- for (var i = 0; i < materialsModel.rowCount(); ++i)
- {
- var item = materialsModel.getItem(i);
- if (item.root_material_id == active_root_material_id)
- {
- itemIndex = i;
- break;
- }
- }
- materialListView.currentIndex = itemIndex;
- }
-
- Row // Button Row
+ // Button Row
+ Row
{
id: buttonRow
anchors
@@ -166,63 +218,102 @@ Item
}
}
- property string newRootMaterialIdToSwitchTo: ""
- property bool toActivateNewMaterial: false
-
- // This connection makes sure that we will switch to the new
- Connections
- {
- target: materialsModel
- onItemsChanged:
+ Item {
+ id: contentsItem
+ anchors
{
- var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id;
- var position = Cura.ExtruderManager.activeExtruderIndex;
+ top: titleLabel.bottom
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ margins: 5 * screenScaleFactor
+ bottomMargin: 0
+ }
+ clip: true
+ }
- // try to pick the currently selected item; it may have been moved
- if (base.newRootMaterialIdToSwitchTo == "")
+ Item
+ {
+ anchors
+ {
+ top: buttonRow.bottom
+ topMargin: UM.Theme.getSize("default_margin").height
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
+
+ SystemPalette { id: palette }
+
+ Label
+ {
+ id: captionLabel
+ anchors
{
- base.newRootMaterialIdToSwitchTo = currentItemId;
+ top: parent.top
+ left: parent.left
}
-
- for (var idx = 0; idx < materialsModel.rowCount(); ++idx)
+ visible: text != ""
+ text:
{
- var item = materialsModel.getItem(idx);
- if (item.root_material_id == base.newRootMaterialIdToSwitchTo)
+ var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName;
+ if (Cura.MachineManager.hasVariants)
{
- // Switch to the newly created profile if needed
- materialListView.currentIndex = idx;
- materialListView.activateDetailsWithIndex(materialListView.currentIndex);
- if (base.toActivateNewMaterial)
- {
- Cura.MachineManager.setMaterial(position, item.container_node);
- }
- base.newRootMaterialIdToSwitchTo = "";
- base.toActivateNewMaterial = false;
- return
+ caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName;
}
+ return caption;
+ }
+ width: materialScrollView.width
+ elide: Text.ElideRight
+ }
+
+ ScrollView
+ {
+ id: materialScrollView
+ anchors
+ {
+ top: captionLabel.visible ? captionLabel.bottom : parent.top
+ topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0
+ bottom: parent.bottom
+ left: parent.left
}
- materialListView.currentIndex = 0;
- materialListView.activateDetailsWithIndex(materialListView.currentIndex);
- if (base.toActivateNewMaterial)
+ Rectangle
{
- Cura.MachineManager.setMaterial(position, materialsModel.getItem(0).container_node);
+ parent: viewport
+ anchors.fill: parent
+ color: palette.light
+ }
+
+ width: true ? (parent.width * 0.4) | 0 : parent.width
+ frameVisible: true
+ verticalScrollBarPolicy: Qt.ScrollBarAlwaysOn
+
+ MaterialsList {}
+ }
+
+ MaterialsDetailsPanel
+ {
+ anchors
+ {
+ left: materialScrollView.right
+ leftMargin: UM.Theme.getSize("default_margin").width
+ top: parent.top
+ bottom: parent.bottom
+ right: parent.right
}
- base.newRootMaterialIdToSwitchTo = "";
- base.toActivateNewMaterial = false;
}
}
+ // Dialogs
MessageDialog
{
id: confirmRemoveMaterialDialog
-
icon: StandardIcon.Question;
title: catalog.i18nc("@title:window", "Confirm Remove")
text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(base.currentItem.name)
standardButtons: StandardButton.Yes | StandardButton.No
modality: Qt.ApplicationModal
-
onYes:
{
base.materialManager.removeMaterial(base.currentItem.container_node);
@@ -292,281 +383,4 @@ Item
{
id: messageDialog
}
-
-
- Item {
- id: contentsItem
-
- anchors
- {
- top: titleLabel.bottom
- left: parent.left
- right: parent.right
- bottom: parent.bottom
- margins: 5 * screenScaleFactor
- bottomMargin: 0
- }
-
- clip: true
- }
-
- Item
- {
- anchors
- {
- top: buttonRow.bottom
- topMargin: UM.Theme.getSize("default_margin").height
- left: parent.left
- right: parent.right
- bottom: parent.bottom
- }
-
- SystemPalette { id: palette }
-
- Label
- {
- id: captionLabel
- anchors
- {
- top: parent.top
- left: parent.left
- }
- visible: text != ""
- text:
- {
- var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName;
- if (Cura.MachineManager.hasVariants)
- {
- caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName;
- }
- return caption;
- }
- width: materialScrollView.width
- elide: Text.ElideRight
- }
-
- ScrollView
- {
- id: materialScrollView
- anchors
- {
- top: captionLabel.visible ? captionLabel.bottom : parent.top
- topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0
- bottom: parent.bottom
- left: parent.left
- }
-
- Rectangle
- {
- parent: viewport
- anchors.fill: parent
- color: palette.light
- }
-
- width: true ? (parent.width * 0.4) | 0 : parent.width
- frameVisible: true
-
- ListView
- {
- id: materialListView
-
- model: materialsModel
-
- section.property: "brand"
- section.criteria: ViewSection.FullString
- section.delegate: Rectangle
- {
- width: materialScrollView.width
- height: childrenRect.height
- color: palette.light
-
- Label
- {
- anchors.left: parent.left
- anchors.leftMargin: UM.Theme.getSize("default_lining").width
- text: section
- font.bold: true
- color: palette.text
- }
- }
-
- delegate: Rectangle
- {
- width: materialScrollView.width
- height: childrenRect.height
- color: ListView.isCurrentItem ? palette.highlight : (model.index % 2) ? palette.base : palette.alternateBase
-
- Row
- {
- id: materialRow
- spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
- anchors.left: parent.left
- anchors.leftMargin: UM.Theme.getSize("default_margin").width
- anchors.right: parent.right
-
- property bool isCurrentItem: parent.ListView.isCurrentItem
-
- property bool isItemActivated:
- {
- const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
- const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
- return model.root_material_id == root_material_id;
- }
-
- Rectangle
- {
- width: Math.floor(parent.height * 0.8)
- height: Math.floor(parent.height * 0.8)
- color: model.color_code
- border.color: materialRow.isCurrentItem ? palette.highlightedText : palette.text;
- anchors.verticalCenter: parent.verticalCenter
- }
- Label
- {
- width: Math.floor((parent.width * 0.3))
- text: model.material
- elide: Text.ElideRight
- font.italic: materialRow.isItemActivated
- color: materialRow.isCurrentItem ? palette.highlightedText : palette.text;
- }
- Label
- {
- text: (model.name != model.material) ? model.name : ""
- elide: Text.ElideRight
- font.italic: materialRow.isItemActivated
- color: materialRow.isCurrentItem ? palette.highlightedText : palette.text;
- }
- }
-
- MouseArea
- {
- anchors.fill: parent
- onClicked:
- {
- parent.ListView.view.currentIndex = model.index;
- }
- }
- }
-
- function activateDetailsWithIndex(index)
- {
- var model = materialsModel.getItem(index);
- base.currentItem = model;
- materialDetailsView.containerId = model.container_id;
- materialDetailsView.currentMaterialNode = model.container_node;
-
- detailsPanel.updateMaterialPropertiesObject();
- }
-
- onCurrentIndexChanged:
- {
- forceActiveFocus(); // causes the changed fields to be saved
- activateDetailsWithIndex(currentIndex);
- }
- }
- }
-
-
- Item
- {
- id: detailsPanel
-
- anchors
- {
- left: materialScrollView.right
- leftMargin: UM.Theme.getSize("default_margin").width
- top: parent.top
- bottom: parent.bottom
- right: parent.right
- }
-
- function updateMaterialPropertiesObject()
- {
- var currentItem = materialsModel.getItem(materialListView.currentIndex);
-
- materialProperties.name = currentItem.name ? currentItem.name : "Unknown";
- materialProperties.guid = currentItem.guid;
- materialProperties.container_id = currentItem.container_id;
-
- materialProperties.brand = currentItem.brand ? currentItem.brand : "Unknown";
- materialProperties.material = currentItem.material ? currentItem.material : "Unknown";
- materialProperties.color_name = currentItem.color_name ? currentItem.color_name : "Yellow";
- materialProperties.color_code = currentItem.color_code ? currentItem.color_code : "yellow";
-
- materialProperties.description = currentItem.description ? currentItem.description : "";
- materialProperties.adhesion_info = currentItem.adhesion_info ? currentItem.adhesion_info : "";
-
- materialProperties.density = currentItem.density ? currentItem.density : 0.0;
- materialProperties.diameter = currentItem.diameter ? currentItem.diameter : 0.0;
- materialProperties.approximate_diameter = currentItem.approximate_diameter ? currentItem.approximate_diameter : "0";
- }
-
- Item
- {
- anchors.fill: parent
-
- Item // Material title Label
- {
- id: profileName
-
- width: parent.width
- height: childrenRect.height
-
- Label {
- text: materialProperties.name
- font: UM.Theme.getFont("large")
- }
- }
-
- MaterialView // Material detailed information view below the title Label
- {
- id: materialDetailsView
- anchors
- {
- left: parent.left
- right: parent.right
- top: profileName.bottom
- topMargin: UM.Theme.getSize("default_margin").height
- bottom: parent.bottom
- }
-
- editingEnabled: base.currentItem != null && !base.currentItem.is_read_only
-
- properties: materialProperties
- containerId: base.currentItem != null ? base.currentItem.container_id : ""
- currentMaterialNode: base.currentItem.container_node
-
- property alias pane: base
- }
-
- QtObject
- {
- id: materialProperties
-
- property string guid: "00000000-0000-0000-0000-000000000000"
- property string container_id: "Unknown";
- property string name: "Unknown";
- property string profile_type: "Unknown";
- property string brand: "Unknown";
- property string material: "Unknown"; // This needs to be named as "material" to be consistent with
- // the material container's metadata entry
-
- property string color_name: "Yellow";
- property color color_code: "yellow";
-
- property real density: 0.0;
- property real diameter: 0.0;
- property string approximate_diameter: "0";
-
- property real spool_cost: 0.0;
- property real spool_weight: 0.0;
- property real spool_length: 0.0;
- property real cost_per_meter: 0.0;
-
- property string description: "";
- property string adhesion_info: "";
- }
- }
- }
- }
}
diff --git a/resources/qml/Preferences/Materials/MaterialsSlot.qml b/resources/qml/Preferences/Materials/MaterialsSlot.qml
new file mode 100644
index 0000000000..ab0dd23750
--- /dev/null
+++ b/resources/qml/Preferences/Materials/MaterialsSlot.qml
@@ -0,0 +1,120 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Uranium is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.7
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.3
+import QtQuick.Dialogs 1.2
+
+import UM 1.2 as UM
+import Cura 1.0 as Cura
+
+Rectangle
+{
+ id: material_slot
+ property var material
+ property var hovered: false
+ property var is_favorite: material.is_favorite
+
+ height: UM.Theme.getSize("favorites_row").height
+ width: parent.width
+ color: base.currentItem == model ? UM.Theme.getColor("favorites_row_selected") : "transparent"
+
+ Item
+ {
+ height: parent.height
+ width: parent.width
+ Rectangle
+ {
+ id: swatch
+ color: material.color_code
+ border.width: UM.Theme.getSize("default_lining").width
+ border.color: "black"
+ width: UM.Theme.getSize("favorites_button_icon").width
+ height: UM.Theme.getSize("favorites_button_icon").height
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ anchors.leftMargin: UM.Theme.getSize("default_margin").width
+ }
+ Label
+ {
+ text: material.brand + " " + material.name
+ verticalAlignment: Text.AlignVCenter
+ height: parent.height
+ anchors.left: swatch.right
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.leftMargin: UM.Theme.getSize("narrow_margin").width
+ }
+ MouseArea
+ {
+ anchors.fill: parent
+ onClicked: { base.currentItem = material }
+ hoverEnabled: true
+ onEntered: { material_slot.hovered = true }
+ onExited: { material_slot.hovered = false }
+ }
+ Button
+ {
+ id: favorite_button
+ text: ""
+ implicitWidth: UM.Theme.getSize("favorites_button").width
+ implicitHeight: UM.Theme.getSize("favorites_button").height
+ visible: material_slot.hovered || material_slot.is_favorite || favorite_button.hovered
+ anchors
+ {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ onClicked:
+ {
+ if (material_slot.is_favorite) {
+ base.materialManager.removeFavorite(material.root_material_id)
+ material_slot.is_favorite = false
+ return
+ }
+ base.materialManager.addFavorite(material.root_material_id)
+ material_slot.is_favorite = true
+ return
+ }
+ style: ButtonStyle
+ {
+ background: Rectangle
+ {
+ anchors.fill: parent
+ color: "transparent"
+ }
+ }
+ UM.RecolorImage {
+ anchors
+ {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ width: UM.Theme.getSize("favorites_button_icon").width
+ height: UM.Theme.getSize("favorites_button_icon").height
+ sourceSize.width: width
+ sourceSize.height: height
+ color:
+ {
+ if (favorite_button.hovered)
+ {
+ return UM.Theme.getColor("primary_hover")
+ }
+ else
+ {
+ if (material_slot.is_favorite)
+ {
+ return UM.Theme.getColor("primary")
+ }
+ else
+ {
+ UM.Theme.getColor("text_inactive")
+ }
+ }
+ }
+ source: material_slot.is_favorite ? UM.Theme.getIcon("favorites_star_full") : UM.Theme.getIcon("favorites_star_empty")
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml
new file mode 100644
index 0000000000..11bf2385e1
--- /dev/null
+++ b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml
@@ -0,0 +1,109 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Uranium is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.7
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.3
+import QtQuick.Dialogs 1.2
+
+import UM 1.2 as UM
+import Cura 1.0 as Cura
+
+Rectangle
+{
+ id: material_type_section
+ property var expanded: base.collapsed_types.indexOf(model.brand + "_" + model.name) > -1
+ property var colors_model: model.colors
+ height: childrenRect.height
+ width: parent.width
+ Rectangle
+ {
+ id: material_type_header_background
+ color: UM.Theme.getColor("lining")
+ anchors.bottom: material_type_header.bottom
+ anchors.left: material_type_header.left
+ height: UM.Theme.getSize("default_lining").height
+ width: material_type_header.width
+ }
+ Row
+ {
+ id: material_type_header
+ width: parent.width - 8
+ anchors
+ {
+ left: parent.left
+ leftMargin: 8
+ }
+ Label
+ {
+ text: model.name
+ height: UM.Theme.getSize("favorites_row").height
+ width: parent.width - UM.Theme.getSize("favorites_button").width
+ id: material_type_name
+ verticalAlignment: Text.AlignVCenter
+ }
+ Button
+ {
+ text: ""
+ implicitWidth: UM.Theme.getSize("favorites_button").width
+ implicitHeight: UM.Theme.getSize("favorites_button").height
+ UM.RecolorImage {
+ anchors
+ {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ width: UM.Theme.getSize("standard_arrow").width
+ height: UM.Theme.getSize("standard_arrow").height
+ sourceSize.width: width
+ sourceSize.height: height
+ color: "black"
+ source: material_type_section.expanded ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left")
+ }
+ style: ButtonStyle
+ {
+ background: Rectangle
+ {
+ anchors.fill: parent
+ color: "transparent"
+ }
+ }
+ }
+ }
+ MouseArea
+ {
+ anchors.fill: material_type_header
+ onPressed:
+ {
+ const i = base.collapsed_types.indexOf(model.brand + "_" + model.name)
+ if (i > -1)
+ {
+ // Remove it
+ base.collapsed_types.splice(i, 1)
+ material_type_section.expanded = false
+ }
+ else
+ {
+ // Add it
+ base.collapsed_types.push(model.brand + "_" + model.name)
+ material_type_section.expanded = true
+ }
+ }
+ }
+ Column
+ {
+ height: material_type_section.expanded ? childrenRect.height : 0
+ visible: material_type_section.expanded
+ width: parent.width
+ anchors.top: material_type_header.bottom
+ anchors.left: parent.left
+ Repeater
+ {
+ model: colors_model
+ delegate: MaterialsSlot {
+ material: model
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/Materials/MaterialsView.qml
similarity index 99%
rename from resources/qml/Preferences/MaterialView.qml
rename to resources/qml/Preferences/Materials/MaterialsView.qml
index 97184ab558..a03e5c48d7 100644
--- a/resources/qml/Preferences/MaterialView.qml
+++ b/resources/qml/Preferences/Materials/MaterialsView.qml
@@ -8,6 +8,8 @@ import QtQuick.Dialogs 1.2
import UM 1.2 as UM
import Cura 1.0 as Cura
+import ".." // Access to ReadOnlyTextArea.qml
+
TabView
{
id: base
@@ -38,7 +40,7 @@ TabView
{
return ""
}
- var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.currentMaterialNode, true);
+ var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.currentItem.container_node, true);
if (linkedMaterials.length == 0)
{
return ""
diff --git a/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg
new file mode 100644
index 0000000000..ac4f9ee81d
--- /dev/null
+++ b/resources/quality/peopoly_moai/peopoly_moai_coarse.inst.cfg
@@ -0,0 +1,17 @@
+[general]
+version = 4
+name = Coarse
+definition = peopoly_moai
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = coarse
+weight = 3
+
+[values]
+layer_height = 0.08
+speed_print = 90
+speed_travel = 120
+speed_travel_layer_0 = 100
+speed_wall = 90
diff --git a/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg
new file mode 100644
index 0000000000..2d21b1f7e0
--- /dev/null
+++ b/resources/quality/peopoly_moai/peopoly_moai_draft.inst.cfg
@@ -0,0 +1,18 @@
+[general]
+version = 4
+name = Draft
+definition = peopoly_moai
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = draft
+weight = 4
+
+[values]
+layer_height = 0.1
+speed_print = 85
+speed_travel = 120
+speed_travel_layer_0 = 100
+speed_wall = 85
+speed_slowdown_layers = 2
diff --git a/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg
new file mode 100644
index 0000000000..796c2cff3c
--- /dev/null
+++ b/resources/quality/peopoly_moai/peopoly_moai_extra_high.inst.cfg
@@ -0,0 +1,18 @@
+[general]
+version = 4
+name = Extra High
+definition = peopoly_moai
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = extra_high
+weight = 0
+
+[values]
+layer_height = 0.02
+speed_print = 185
+speed_travel = 185
+speed_travel_layer_0 = 100
+speed_wall = 185
+speed_slowdown_layers = 5
diff --git a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg
index 36b5f21ff8..b36163d9f1 100644
--- a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg
+++ b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg
@@ -1,6 +1,6 @@
[general]
version = 4
-name = Extra Fine
+name = High
definition = peopoly_moai
[metadata]
@@ -10,8 +10,9 @@ quality_type = high
weight = 1
[values]
-infill_sparse_density = 70
-layer_height = 0.05
-top_bottom_thickness = 0.4
-wall_thickness = 0.4
-speed_print = 150
+layer_height = 0.04
+speed_print = 140
+speed_travel = 140
+speed_travel_layer_0 = 100
+speed_wall = 140
+speed_slowdown_layers = 4
diff --git a/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg
deleted file mode 100644
index 48ffd07f33..0000000000
--- a/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg
+++ /dev/null
@@ -1,17 +0,0 @@
-[general]
-version = 4
-name = Maximum Quality
-definition = peopoly_moai
-
-[metadata]
-setting_version = 5
-type = quality
-quality_type = extra_high
-weight = 2
-
-[values]
-infill_sparse_density = 70
-layer_height = 0.025
-top_bottom_thickness = 0.4
-wall_thickness = 0.4
-speed_print = 200
diff --git a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg
index f5fe799ac3..cf67591ab2 100644
--- a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg
+++ b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg
@@ -1,17 +1,17 @@
[general]
version = 4
-name = Fine
+name = Normal
definition = peopoly_moai
[metadata]
setting_version = 5
type = quality
quality_type = normal
-weight = 0
+weight = 2
[values]
-infill_sparse_density = 70
-layer_height = 0.1
-top_bottom_thickness = 0.4
-wall_thickness = 0.4
-speed_print = 100
+layer_height = 0.06
+speed_print = 120
+speed_travel = 120
+speed_travel_layer_0 = 100
+speed_wall = 120
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg
new file mode 100644
index 0000000000..c8d64f9dcb
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Draft_Print.inst.cfg
@@ -0,0 +1,36 @@
+[general]
+version = 4
+name = Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = draft
+weight = -2
+material = generic_abs
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_print_temperature = =default_material_print_temperature + 20
+material_initial_print_temperature = =material_print_temperature - 15
+material_final_print_temperature = =material_print_temperature - 20
+prime_tower_enable = False
+skin_overlap = 20
+speed_print = 60
+speed_layer_0 = 20
+speed_topbottom = =math.ceil(speed_print * 35 / 60)
+speed_wall = =math.ceil(speed_print * 45 / 60)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
+wall_thickness = 1
+
+infill_line_width = =round(line_width * 0.4 / 0.35, 2)
+speed_infill = =math.ceil(speed_print * 50 / 60)
+
+material_bed_temperature_layer_0 = 100
+default_material_bed_temperature = 90
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg
new file mode 100644
index 0000000000..c7fa604e89
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Fast_Print.inst.cfg
@@ -0,0 +1,35 @@
+[general]
+version = 4
+name = Normal
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = fast
+weight = -1
+material = generic_abs
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+cool_min_speed = 7
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_print_temperature = =default_material_print_temperature + 15
+material_initial_print_temperature = =material_print_temperature - 15
+material_final_print_temperature = =material_print_temperature - 20
+prime_tower_enable = False
+speed_print = 60
+speed_layer_0 = 20
+speed_topbottom = =math.ceil(speed_print * 30 / 60)
+speed_wall = =math.ceil(speed_print * 40 / 60)
+speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
+
+infill_line_width = =round(line_width * 0.4 / 0.35, 2)
+speed_infill = =math.ceil(speed_print * 45 / 60)
+
+material_bed_temperature_layer_0 = 100
+default_material_bed_temperature = 90
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg
index 9a3eef5762..187023d3c0 100644
--- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_High_Quality.inst.cfg
@@ -14,21 +14,21 @@ buildplate = Aluminum
[values]
cool_min_speed = 12
-layer_height_0 = 0.17
machine_nozzle_cool_down_speed = 0.8
machine_nozzle_heat_up_speed = 1.5
-material_bed_temperature = 90
-material_bed_temperature_layer_0 = 100
material_print_temperature = =default_material_print_temperature + 5
material_initial_print_temperature = =material_print_temperature - 15
material_final_print_temperature = =material_print_temperature - 20
-prime_blob_enable = False
prime_tower_enable = False
speed_print = 50
-speed_layer_0 = =math.ceil(speed_print * 20 / 50)
+speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 50)
speed_wall = =math.ceil(speed_print * 30 / 50)
infill_line_width = =round(line_width * 0.4 / 0.35, 2)
speed_infill = =math.ceil(speed_print * 40 / 50)
+material_bed_temperature_layer_0 = 100
+default_material_bed_temperature = 90
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg
new file mode 100644
index 0000000000..81cb27f060
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_ABS_Normal_Quality.inst.cfg
@@ -0,0 +1,34 @@
+[general]
+version = 4
+name = Fine
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = normal
+weight = 0
+material = generic_abs
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_print_temperature = =default_material_print_temperature + 10
+material_initial_print_temperature = =material_print_temperature - 15
+material_final_print_temperature = =material_print_temperature - 20
+prime_tower_enable = False
+speed_print = 55
+speed_layer_0 = 20
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+speed_wall = =math.ceil(speed_print * 30 / 55)
+
+infill_line_width = =round(line_width * 0.4 / 0.35, 2)
+speed_infill = =math.ceil(speed_print * 40 / 55)
+
+material_bed_temperature_layer_0 = 100
+default_material_bed_temperature = 90
+prime_blob_enable = False
+layer_height_0 = 0.17
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg
new file mode 100644
index 0000000000..46e3483a6a
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Draft_Print.inst.cfg
@@ -0,0 +1,54 @@
+[general]
+version = 4
+name = Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = draft
+weight = -2
+material = generic_cpe_plus
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+acceleration_enabled = True
+acceleration_print = 4000
+cool_fan_speed_max = 80
+cool_min_speed = 5
+infill_line_width = =round(line_width * 0.35 / 0.35, 2)
+infill_overlap = 0
+infill_wipe_dist = 0
+jerk_enabled = True
+jerk_print = 25
+machine_min_cool_heat_time_window = 15
+material_final_print_temperature = =material_print_temperature - 10
+material_initial_print_temperature = =material_print_temperature - 5
+material_print_temperature = =default_material_print_temperature + 10
+material_print_temperature_layer_0 = =material_print_temperature
+multiple_mesh_overlap = 0
+prime_tower_enable = True
+prime_tower_wipe_enabled = True
+retraction_combing = off
+retraction_extrusion_window = 1
+retraction_hop = 0.2
+retraction_hop_enabled = False
+retraction_hop_only_when_collides = True
+skin_overlap = 20
+speed_layer_0 = 20
+speed_print = 50
+speed_topbottom = =math.ceil(speed_print * 40 / 50)
+
+speed_wall = =math.ceil(speed_print * 50 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 40 / 50)
+support_bottom_distance = =support_z_distance
+support_z_distance = =layer_height
+wall_0_inset = 0
+wall_thickness = 1
+
+material_bed_temperature_layer_0 = 115
+default_material_bed_temperature = 105
+prime_blob_enable = False
+layer_height_0 = 0.17
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg
new file mode 100644
index 0000000000..5c235b656a
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Fast_Print.inst.cfg
@@ -0,0 +1,52 @@
+[general]
+version = 4
+name = Normal
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = fast
+weight = -1
+material = generic_cpe_plus
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+acceleration_enabled = True
+acceleration_print = 4000
+cool_fan_speed_max = 80
+cool_min_speed = 6
+infill_line_width = =round(line_width * 0.35 / 0.35, 2)
+infill_overlap = 0
+infill_wipe_dist = 0
+jerk_enabled = True
+jerk_print = 25
+machine_min_cool_heat_time_window = 15
+material_final_print_temperature = =material_print_temperature - 10
+material_initial_print_temperature = =material_print_temperature - 5
+material_print_temperature = =default_material_print_temperature + 10
+material_print_temperature_layer_0 = =material_print_temperature
+multiple_mesh_overlap = 0
+prime_tower_enable = True
+prime_tower_wipe_enabled = True
+retraction_combing = off
+retraction_extrusion_window = 1
+retraction_hop = 0.2
+retraction_hop_enabled = False
+retraction_hop_only_when_collides = True
+skin_overlap = 20
+speed_layer_0 = 20
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 35 / 45)
+
+speed_wall = =math.ceil(speed_print * 45 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
+support_bottom_distance = =support_z_distance
+support_z_distance = =layer_height
+wall_0_inset = 0
+
+material_bed_temperature_layer_0 = 115
+default_material_bed_temperature = 105
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg
index 8b0b08f731..326a730fe4 100644
--- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_High_Quality.inst.cfg
@@ -22,18 +22,14 @@ infill_overlap = 0
infill_wipe_dist = 0
jerk_enabled = True
jerk_print = 25
-layer_height_0 = 0.17
machine_min_cool_heat_time_window = 15
machine_nozzle_cool_down_speed = 0.85
machine_nozzle_heat_up_speed = 1.5
-material_bed_temperature = 105
-material_bed_temperature_layer_0 = 115
material_final_print_temperature = =material_print_temperature - 10
material_initial_print_temperature = =material_print_temperature - 5
material_print_temperature = =default_material_print_temperature + 2
material_print_temperature_layer_0 = =material_print_temperature
multiple_mesh_overlap = 0
-prime_blob_enable = False
prime_tower_enable = True
prime_tower_wipe_enabled = True
retraction_combing = off
@@ -42,7 +38,7 @@ retraction_hop = 0.2
retraction_hop_enabled = False
retraction_hop_only_when_collides = True
skin_overlap = 20
-speed_layer_0 = =math.ceil(speed_print * 20 / 40)
+speed_layer_0 = 20
speed_print = 40
speed_topbottom = =math.ceil(speed_print * 30 / 35)
@@ -51,3 +47,9 @@ speed_wall_0 = =math.ceil(speed_wall * 30 / 35)
support_bottom_distance = =support_z_distance
support_z_distance = =layer_height
wall_0_inset = 0
+
+material_bed_temperature_layer_0 = 115
+default_material_bed_temperature = 105
+prime_blob_enable = False
+layer_height_0 = 0.17
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg
new file mode 100644
index 0000000000..d40b2db90e
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPEP_Normal_Quality.inst.cfg
@@ -0,0 +1,54 @@
+[general]
+version = 4
+name = Fine
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = normal
+weight = 0
+material = generic_cpe_plus
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+acceleration_enabled = True
+acceleration_print = 4000
+cool_fan_speed_max = 50
+cool_min_speed = 7
+infill_line_width = =round(line_width * 0.35 / 0.35, 2)
+infill_overlap = 0
+infill_wipe_dist = 0
+jerk_enabled = True
+jerk_print = 25
+machine_min_cool_heat_time_window = 15
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 10
+material_initial_print_temperature = =material_print_temperature - 5
+material_print_temperature = =default_material_print_temperature + 5
+material_print_temperature_layer_0 = =material_print_temperature
+multiple_mesh_overlap = 0
+prime_tower_enable = True
+prime_tower_wipe_enabled = True
+retraction_combing = off
+retraction_extrusion_window = 1
+retraction_hop = 0.2
+retraction_hop_enabled = False
+retraction_hop_only_when_collides = True
+skin_overlap = 20
+speed_layer_0 = 20
+speed_print = 40
+speed_topbottom = =math.ceil(speed_print * 30 / 35)
+
+speed_wall = =math.ceil(speed_print * 35 / 40)
+speed_wall_0 = =math.ceil(speed_wall * 30 / 35)
+support_bottom_distance = =support_z_distance
+support_z_distance = =layer_height
+wall_0_inset = 0
+
+material_bed_temperature_layer_0 = 115
+default_material_bed_temperature = 105
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg
new file mode 100644
index 0000000000..c812066e0c
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Draft_Print.inst.cfg
@@ -0,0 +1,35 @@
+[general]
+version = 4
+name = Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = draft
+weight = -2
+material = generic_cpe
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+material_print_temperature = =default_material_print_temperature + 10
+material_initial_print_temperature = =material_print_temperature - 5
+material_final_print_temperature = =material_print_temperature - 10
+skin_overlap = 20
+speed_print = 60
+speed_layer_0 = 20
+speed_topbottom = =math.ceil(speed_print * 35 / 60)
+speed_wall = =math.ceil(speed_print * 45 / 60)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
+wall_thickness = 1
+
+
+infill_pattern = zigzag
+speed_infill = =math.ceil(speed_print * 50 / 60)
+prime_tower_purge_volume = 1
+
+material_bed_temperature_layer_0 = 90
+default_material_bed_temperature = 80
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg
new file mode 100644
index 0000000000..ef634316da
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Fast_Print.inst.cfg
@@ -0,0 +1,33 @@
+[general]
+version = 4
+name = Normal
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = fast
+weight = -1
+material = generic_cpe
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+cool_min_speed = 7
+material_print_temperature = =default_material_print_temperature + 5
+material_initial_print_temperature = =material_print_temperature - 5
+material_final_print_temperature = =material_print_temperature - 10
+speed_print = 60
+speed_layer_0 = 20
+speed_topbottom = =math.ceil(speed_print * 30 / 60)
+speed_wall = =math.ceil(speed_print * 40 / 60)
+speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
+
+infill_pattern = zigzag
+speed_infill = =math.ceil(speed_print * 50 / 60)
+prime_tower_purge_volume = 1
+
+material_bed_temperature_layer_0 = 90
+default_material_bed_temperature = 80
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg
index 6299071194..cda97e6ab3 100644
--- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_High_Quality.inst.cfg
@@ -14,19 +14,21 @@ buildplate = Aluminum
[values]
cool_min_speed = 12
-layer_height_0 = 0.17
machine_nozzle_cool_down_speed = 0.85
machine_nozzle_heat_up_speed = 1.5
-material_bed_temperature = 80
-material_bed_temperature_layer_0 = 90
material_print_temperature = =default_material_print_temperature - 5
material_initial_print_temperature = =material_print_temperature - 5
material_final_print_temperature = =material_print_temperature - 10
-prime_blob_enable = False
speed_print = 50
-speed_layer_0 = =math.ceil(speed_print * 20 / 50)
+speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 50)
speed_wall = =math.ceil(speed_print * 30 / 50)
infill_pattern = zigzag
-speed_infill = =math.ceil(speed_print * 40 / 50)
\ No newline at end of file
+speed_infill = =math.ceil(speed_print * 40 / 50)
+prime_tower_purge_volume = 1
+
+material_bed_temperature_layer_0 = 90
+default_material_bed_temperature = 80
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg
new file mode 100644
index 0000000000..5a75f3b6e3
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_CPE_Normal_Quality.inst.cfg
@@ -0,0 +1,32 @@
+[general]
+version = 4
+name = Fine
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = normal
+weight = 0
+material = generic_cpe
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_initial_print_temperature = =material_print_temperature - 5
+material_final_print_temperature = =material_print_temperature - 10
+speed_print = 55
+speed_layer_0 = 20
+speed_topbottom = =math.ceil(speed_print * 30 / 55)
+speed_wall = =math.ceil(speed_print * 30 / 55)
+
+infill_pattern = zigzag
+speed_infill = =math.ceil(speed_print * 45 / 55)
+prime_tower_purge_volume = 1
+
+material_bed_temperature_layer_0 = 90
+default_material_bed_temperature = 80
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg
new file mode 100644
index 0000000000..f05ecddc25
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Draft_Print.inst.cfg
@@ -0,0 +1,69 @@
+[general]
+version = 4
+name = Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = draft
+weight = -2
+material = generic_pc
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+acceleration_enabled = True
+acceleration_print = 4000
+adhesion_type = brim
+brim_width = 20
+cool_fan_full_at_height = =layer_height_0 + layer_height
+cool_fan_speed_max = 90
+cool_min_layer_time_fan_speed_max = 5
+cool_min_speed = 6
+infill_line_width = =round(line_width * 0.4 / 0.35, 2)
+infill_overlap = 0
+infill_overlap_mm = 0.05
+infill_pattern = triangles
+infill_wipe_dist = 0.1
+jerk_enabled = True
+jerk_print = 25
+machine_min_cool_heat_time_window = 15
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 10
+material_initial_print_temperature = =material_print_temperature - 5
+material_print_temperature = =default_material_print_temperature + 10
+material_standby_temperature = 100
+multiple_mesh_overlap = 0
+ooze_shield_angle = 40
+prime_tower_enable = True
+prime_tower_wipe_enabled = True
+raft_airgap = 0.25
+raft_interface_thickness = =max(layer_height * 1.5, 0.225)
+retraction_count_max = 80
+retraction_extrusion_window = 1
+retraction_hop = 2
+retraction_hop_only_when_collides = True
+retraction_min_travel = 0.8
+retraction_prime_speed = 15
+skin_overlap = 30
+speed_layer_0 = 25
+speed_print = 50
+speed_topbottom = 25
+speed_wall = =math.ceil(speed_print * 40 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 25 / 40)
+support_bottom_distance = =support_z_distance
+support_interface_density = 87.5
+support_interface_pattern = lines
+switch_extruder_prime_speed = 15
+switch_extruder_retraction_amount = 20
+switch_extruder_retraction_speeds = 35
+wall_0_inset = 0
+wall_line_width_x = =round(line_width * 0.4 / 0.35, 2)
+wall_thickness = 1.2
+
+material_bed_temperature_layer_0 = 125
+default_material_bed_temperature = 115
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg
new file mode 100644
index 0000000000..6103519f1c
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Fast_Print.inst.cfg
@@ -0,0 +1,69 @@
+[general]
+version = 4
+name = Normal
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pc
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+acceleration_enabled = True
+acceleration_print = 4000
+adhesion_type = brim
+brim_width = 20
+cool_fan_full_at_height = =layer_height_0 + layer_height
+cool_fan_speed_max = 85
+cool_min_layer_time_fan_speed_max = 5
+cool_min_speed = 7
+infill_line_width = =round(line_width * 0.4 / 0.35, 2)
+infill_overlap_mm = 0.05
+infill_pattern = triangles
+infill_wipe_dist = 0.1
+jerk_enabled = True
+jerk_print = 25
+machine_min_cool_heat_time_window = 15
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 10
+material_initial_print_temperature = =material_print_temperature - 5
+material_print_temperature = =default_material_print_temperature + 10
+material_standby_temperature = 100
+multiple_mesh_overlap = 0
+ooze_shield_angle = 40
+prime_tower_enable = True
+prime_tower_wipe_enabled = True
+raft_airgap = 0.25
+raft_interface_thickness = =max(layer_height * 1.5, 0.225)
+retraction_count_max = 80
+retraction_extrusion_window = 1
+retraction_hop = 2
+retraction_hop_only_when_collides = True
+retraction_min_travel = 0.8
+retraction_prime_speed = 15
+skin_overlap = 30
+speed_layer_0 = 25
+speed_print = 50
+speed_topbottom = 25
+
+speed_wall = =math.ceil(speed_print * 40 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 25 / 40)
+support_bottom_distance = =support_z_distance
+support_interface_density = 87.5
+support_interface_pattern = lines
+switch_extruder_prime_speed = 15
+switch_extruder_retraction_amount = 20
+switch_extruder_retraction_speeds = 35
+wall_0_inset = 0
+wall_line_width_x = =round(line_width * 0.4 / 0.35, 2)
+wall_thickness = 1.2
+
+material_bed_temperature_layer_0 = 125
+default_material_bed_temperature = 115
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg
index 2afaf21de1..130afb8c91 100644
--- a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_High_Quality.inst.cfg
@@ -16,7 +16,7 @@ buildplate = Aluminum
acceleration_enabled = True
acceleration_print = 4000
adhesion_type = brim
-brim_width = 10
+brim_width = 20
cool_fan_full_at_height = =layer_height_0 + layer_height
cool_fan_speed_max = 50
cool_min_layer_time_fan_speed_max = 5
@@ -28,19 +28,15 @@ infill_pattern = triangles
infill_wipe_dist = 0.1
jerk_enabled = True
jerk_print = 25
-layer_height_0 = 0.17
machine_min_cool_heat_time_window = 15
machine_nozzle_cool_down_speed = 0.85
machine_nozzle_heat_up_speed = 1.5
-material_bed_temperature = 115
-material_bed_temperature_layer_0 = 125
material_final_print_temperature = =material_print_temperature - 10
material_initial_print_temperature = =material_print_temperature - 5
material_print_temperature = =default_material_print_temperature - 10
material_standby_temperature = 100
multiple_mesh_overlap = 0
ooze_shield_angle = 40
-prime_blob_enable = False
prime_tower_enable = True
prime_tower_wipe_enabled = True
raft_airgap = 0.25
@@ -52,9 +48,9 @@ retraction_hop_only_when_collides = True
retraction_min_travel = 0.8
retraction_prime_speed = 15
skin_overlap = 30
-speed_layer_0 = =math.ceil(speed_print * 25 / 50)
+speed_layer_0 = 25
speed_print = 50
-speed_topbottom = =math.ceil(speed_print * 25 / 50)
+speed_topbottom = 25
speed_wall = =math.ceil(speed_print * 40 / 50)
speed_wall_0 = =math.ceil(speed_wall * 25 / 40)
@@ -68,4 +64,7 @@ wall_0_inset = 0
wall_line_width_x = =round(line_width * 0.4 / 0.35, 2)
wall_thickness = 1.2
-
+material_bed_temperature_layer_0 = 125
+default_material_bed_temperature = 115
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg
new file mode 100644
index 0000000000..9e1bf394d4
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PC_Normal_Quality.inst.cfg
@@ -0,0 +1,68 @@
+[general]
+version = 4
+name = Fine
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pc
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+acceleration_enabled = True
+acceleration_print = 4000
+adhesion_type = brim
+brim_width = 20
+cool_fan_full_at_height = =layer_height_0 + layer_height
+cool_fan_speed_max = 50
+cool_min_layer_time_fan_speed_max = 5
+cool_min_speed = 5
+infill_line_width = =round(line_width * 0.4 / 0.35, 2)
+infill_overlap = 0
+infill_pattern = triangles
+infill_wipe_dist = 0.1
+jerk_enabled = True
+jerk_print = 25
+machine_min_cool_heat_time_window = 15
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_final_print_temperature = =material_print_temperature - 10
+material_initial_print_temperature = =material_print_temperature - 5
+material_standby_temperature = 100
+multiple_mesh_overlap = 0
+ooze_shield_angle = 40
+prime_tower_enable = True
+prime_tower_wipe_enabled = True
+raft_airgap = 0.25
+raft_interface_thickness = =max(layer_height * 1.5, 0.225)
+retraction_count_max = 80
+retraction_extrusion_window = 1
+retraction_hop = 2
+retraction_hop_only_when_collides = True
+retraction_min_travel = 0.8
+retraction_prime_speed = 15
+skin_overlap = 30
+speed_layer_0 = 25
+speed_print = 50
+speed_topbottom = 25
+
+speed_wall = =math.ceil(speed_print * 40 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 25 / 40)
+support_bottom_distance = =support_z_distance
+support_interface_density = 87.5
+support_interface_pattern = lines
+switch_extruder_prime_speed = 15
+switch_extruder_retraction_amount = 20
+switch_extruder_retraction_speeds = 35
+wall_0_inset = 0
+wall_line_width_x = =round(line_width * 0.4 / 0.35, 2)
+wall_thickness = 1.2
+
+material_bed_temperature_layer_0 = 125
+default_material_bed_temperature = 115
+prime_blob_enable = False
+layer_height_0 = 0.17
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg
new file mode 100644
index 0000000000..6124dff257
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Draft_Print.inst.cfg
@@ -0,0 +1,65 @@
+[general]
+version = 4
+name = Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = draft
+weight = -2
+material = generic_pp
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+acceleration_enabled = True
+acceleration_print = 4000
+brim_width = 20
+cool_fan_speed_max = 100
+cool_min_layer_time = 7
+cool_min_layer_time_fan_speed_max = 7
+cool_min_speed = 2.5
+infill_line_width = =round(line_width * 0.38 / 0.38, 2)
+infill_overlap = 0
+infill_pattern = tetrahedral
+infill_wipe_dist = 0.1
+jerk_enabled = True
+jerk_print = 25
+line_width = =machine_nozzle_size * 0.95
+machine_min_cool_heat_time_window = 15
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_bed_temperature_layer_0 = =material_bed_temperature
+material_final_print_temperature = =material_print_temperature - 10
+material_initial_print_temperature = =material_print_temperature - 5
+material_print_temperature = =default_material_print_temperature - 5
+material_print_temperature_layer_0 = =material_print_temperature + 5
+material_standby_temperature = 100
+multiple_mesh_overlap = 0
+prime_tower_enable = False
+prime_tower_size = 16
+prime_tower_wipe_enabled = True
+retraction_count_max = 12
+retraction_extra_prime_amount = 0.8
+retraction_extrusion_window = 1
+retraction_hop = 2
+retraction_hop_only_when_collides = True
+retraction_min_travel = 0.8
+retraction_prime_speed = 18
+speed_equalize_flow_enabled = True
+speed_layer_0 = 15
+speed_print = 25
+speed_topbottom = =math.ceil(speed_print * 25 / 25)
+speed_travel_layer_0 = 50
+speed_wall = =math.ceil(speed_print * 25 / 25)
+speed_wall_0 = =math.ceil(speed_wall * 25 / 25)
+support_angle = 50
+switch_extruder_prime_speed = 15
+switch_extruder_retraction_amount = 20
+switch_extruder_retraction_speeds = 35
+wall_0_inset = 0
+wall_line_width_x = =line_width
+wall_thickness = =line_width * 3
+
+default_material_bed_temperature = 95
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg
new file mode 100644
index 0000000000..2791e9f5d5
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Fast_Print.inst.cfg
@@ -0,0 +1,67 @@
+[general]
+version = 4
+name = Normal
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pp
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+acceleration_enabled = True
+acceleration_print = 4000
+brim_width = 20
+cool_fan_speed_max = 100
+cool_min_layer_time = 7
+cool_min_layer_time_fan_speed_max = 7
+cool_min_speed = 2.5
+infill_line_width = =round(line_width * 0.38 / 0.38, 2)
+infill_overlap = 0
+infill_pattern = tetrahedral
+infill_wipe_dist = 0.1
+jerk_enabled = True
+jerk_print = 25
+line_width = =machine_nozzle_size * 0.95
+machine_min_cool_heat_time_window = 15
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_bed_temperature_layer_0 = =material_bed_temperature
+material_final_print_temperature = =material_print_temperature - 12
+material_initial_print_temperature = =material_print_temperature - 2
+material_print_temperature = =default_material_print_temperature - 13
+material_print_temperature_layer_0 = =material_print_temperature + 3
+material_standby_temperature = 100
+multiple_mesh_overlap = 0
+prime_tower_enable = False
+prime_tower_size = 16
+prime_tower_wipe_enabled = True
+retraction_count_max = 12
+retraction_extra_prime_amount = 0.8
+retraction_extrusion_window = 1
+retraction_hop = 2
+retraction_hop_only_when_collides = True
+retraction_min_travel = 0.8
+retraction_prime_speed = 18
+speed_equalize_flow_enabled = True
+speed_layer_0 = 15
+speed_print = 25
+speed_topbottom = =math.ceil(speed_print * 25 / 25)
+
+speed_travel_layer_0 = 50
+speed_wall = =math.ceil(speed_print * 25 / 25)
+speed_wall_0 = =math.ceil(speed_wall * 25 / 25)
+support_angle = 50
+switch_extruder_prime_speed = 15
+switch_extruder_retraction_amount = 20
+switch_extruder_retraction_speeds = 35
+top_bottom_thickness = 1.1
+wall_0_inset = 0
+wall_line_width_x = =line_width
+wall_thickness = =line_width * 3
+
+default_material_bed_temperature = 95
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg
new file mode 100644
index 0000000000..f78b4048fb
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.4_aluminum_PP_Normal_Quality.inst.cfg
@@ -0,0 +1,68 @@
+[general]
+version = 4
+name = Fine
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pp
+variant = AA 0.4
+buildplate = Aluminum
+
+[values]
+acceleration_enabled = True
+acceleration_print = 4000
+brim_width = 20
+cool_fan_speed_max = 100
+cool_min_layer_time = 7
+cool_min_layer_time_fan_speed_max = 7
+cool_min_speed = 2.5
+infill_line_width = =round(line_width * 0.38 / 0.38, 2)
+infill_overlap = 0
+infill_pattern = tetrahedral
+infill_wipe_dist = 0.1
+jerk_enabled = True
+jerk_print = 25
+line_width = =machine_nozzle_size * 0.95
+machine_min_cool_heat_time_window = 15
+machine_nozzle_cool_down_speed = 0.85
+machine_nozzle_heat_up_speed = 1.5
+material_bed_temperature_layer_0 = =material_bed_temperature
+material_final_print_temperature = =material_print_temperature - 10
+material_initial_print_temperature = =material_print_temperature - 5
+material_print_temperature = =default_material_print_temperature - 15
+material_print_temperature_layer_0 = =material_print_temperature + 3
+material_standby_temperature = 100
+multiple_mesh_overlap = 0
+prime_tower_enable = False
+prime_tower_size = 16
+prime_tower_wipe_enabled = True
+retraction_count_max = 12
+retraction_extra_prime_amount = 0.8
+retraction_extrusion_window = 1
+retraction_hop = 2
+retraction_hop_only_when_collides = True
+retraction_min_travel = 0.8
+retraction_prime_speed = 18
+speed_equalize_flow_enabled = True
+speed_layer_0 = 15
+speed_print = 25
+speed_topbottom = =math.ceil(speed_print * 25 / 25)
+
+speed_travel_layer_0 = 50
+speed_wall = =math.ceil(speed_print * 25 / 25)
+speed_wall_0 = =math.ceil(speed_wall * 25 / 25)
+support_angle = 50
+switch_extruder_prime_speed = 15
+switch_extruder_retraction_amount = 20
+switch_extruder_retraction_speeds = 35
+top_bottom_thickness = 1
+wall_0_inset = 0
+wall_line_width_x = =line_width
+wall_thickness = =line_width * 3
+
+default_material_bed_temperature = 95
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg
index 3d984e1dff..37dceff349 100644
--- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Draft_Print.inst.cfg
@@ -13,15 +13,16 @@ variant = AA 0.8
buildplate = Aluminum
[values]
-layer_height_0 = 0.3
line_width = =machine_nozzle_size * 0.875
-material_bed_temperature = 90
-material_bed_temperature_layer_0 = 100
material_print_temperature = =default_material_print_temperature + 20
material_standby_temperature = 100
-prime_blob_enable = False
speed_print = 50
speed_topbottom = =math.ceil(speed_print * 30 / 50)
speed_wall = =math.ceil(speed_print * 40 / 50)
speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
retract_at_layer_change = False
+
+material_bed_temperature_layer_0 = 100
+default_material_bed_temperature = 90
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg
new file mode 100644
index 0000000000..eac339baa8
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Superdraft_Print.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Sprint
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = superdraft
+weight = -4
+material = generic_abs
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+line_width = =machine_nozzle_size * 0.875
+material_print_temperature = =default_material_print_temperature + 25
+material_standby_temperature = 100
+speed_print = 50
+speed_topbottom = =math.ceil(speed_print * 30 / 50)
+speed_wall = =math.ceil(speed_print * 40 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
+retract_at_layer_change = False
+
+material_bed_temperature_layer_0 = 100
+default_material_bed_temperature = 90
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg
new file mode 100644
index 0000000000..590496df0f
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_ABS_Verydraft_Print.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Extra Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = verydraft
+weight = -3
+material = generic_abs
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+line_width = =machine_nozzle_size * 0.875
+material_print_temperature = =default_material_print_temperature + 22
+material_standby_temperature = 100
+speed_print = 50
+speed_topbottom = =math.ceil(speed_print * 30 / 50)
+speed_wall = =math.ceil(speed_print * 40 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
+retract_at_layer_change = False
+
+material_bed_temperature_layer_0 = 100
+default_material_bed_temperature = 90
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg
index 6fd60c197a..3e74390840 100644
--- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Fast_Print.inst.cfg
@@ -16,22 +16,18 @@ buildplate = Aluminum
brim_width = 14
cool_fan_full_at_height = =layer_height_0 + 14 * layer_height
infill_before_walls = True
-layer_height_0 = 0.3
line_width = =machine_nozzle_size * 0.9375
machine_nozzle_cool_down_speed = 0.9
machine_nozzle_heat_up_speed = 1.4
-material_bed_temperature = 105
-material_bed_temperature_layer_0 = 115
material_print_temperature = =default_material_print_temperature - 10
material_print_temperature_layer_0 = =material_print_temperature
material_standby_temperature = 100
-prime_blob_enable = False
prime_tower_enable = True
retraction_combing = off
retraction_hop = 0.1
retraction_hop_enabled = False
skin_overlap = 0
-speed_layer_0 = =math.ceil(speed_print * 15 / 50)
+speed_layer_0 = 15
speed_print = 50
speed_slowdown_layers = 15
speed_topbottom = =math.ceil(speed_print * 35 / 50)
@@ -41,3 +37,8 @@ support_bottom_distance = =support_z_distance
support_line_width = =round(line_width * 0.6 / 0.7, 2)
support_z_distance = =layer_height
top_bottom_thickness = 1.2
+
+material_bed_temperature_layer_0 = 115
+default_material_bed_temperature = 105
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg
new file mode 100644
index 0000000000..4c1b807430
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Superdraft_Print.inst.cfg
@@ -0,0 +1,44 @@
+[general]
+version = 4
+name = Sprint
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = superdraft
+weight = -4
+material = generic_cpe_plus
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+brim_width = 14
+cool_fan_full_at_height = =layer_height_0 + 7 * layer_height
+infill_before_walls = True
+line_width = =machine_nozzle_size * 0.9375
+machine_nozzle_cool_down_speed = 0.9
+machine_nozzle_heat_up_speed = 1.4
+material_print_temperature = =default_material_print_temperature - 5
+material_print_temperature_layer_0 = =material_print_temperature
+material_standby_temperature = 100
+prime_tower_enable = True
+retraction_combing = off
+retraction_hop = 0.1
+retraction_hop_enabled = False
+skin_overlap = 0
+speed_layer_0 = 15
+speed_print = 50
+speed_slowdown_layers = 8
+speed_topbottom = =math.ceil(speed_print * 35 / 50)
+speed_wall = =math.ceil(speed_print * 40 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+support_bottom_distance = =support_z_distance
+support_line_width = =round(line_width * 0.6 / 0.7, 2)
+support_z_distance = =layer_height
+top_bottom_thickness = 1.2
+
+material_bed_temperature_layer_0 = 115
+default_material_bed_temperature = 105
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg
new file mode 100644
index 0000000000..11aefc90cd
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPEP_Verydraft_Print.inst.cfg
@@ -0,0 +1,44 @@
+[general]
+version = 4
+name = Extra Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = verydraft
+weight = -3
+material = generic_cpe_plus
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+brim_width = 14
+cool_fan_full_at_height = =layer_height_0 + 9 * layer_height
+infill_before_walls = True
+line_width = =machine_nozzle_size * 0.9375
+machine_nozzle_cool_down_speed = 0.9
+machine_nozzle_heat_up_speed = 1.4
+material_print_temperature = =default_material_print_temperature - 7
+material_print_temperature_layer_0 = =material_print_temperature
+material_standby_temperature = 100
+prime_tower_enable = True
+retraction_combing = off
+retraction_hop = 0.1
+retraction_hop_enabled = False
+skin_overlap = 0
+speed_layer_0 = 15
+speed_print = 50
+speed_slowdown_layers = 10
+speed_topbottom = =math.ceil(speed_print * 35 / 50)
+speed_wall = =math.ceil(speed_print * 40 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
+support_bottom_distance = =support_z_distance
+support_line_width = =round(line_width * 0.6 / 0.7, 2)
+support_z_distance = =layer_height
+top_bottom_thickness = 1.2
+
+material_bed_temperature_layer_0 = 115
+default_material_bed_temperature = 105
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg
index 37aa25f9d8..80c0585061 100644
--- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Draft_Print.inst.cfg
@@ -14,16 +14,18 @@ buildplate = Aluminum
[values]
brim_width = 15
-layer_height_0 = 0.3
line_width = =machine_nozzle_size * 0.875
-material_bed_temperature = 80
-material_bed_temperature_layer_0 = 90
material_print_temperature = =default_material_print_temperature + 15
material_standby_temperature = 100
-prime_blob_enable = False
prime_tower_enable = True
speed_print = 40
speed_topbottom = =math.ceil(speed_print * 25 / 40)
speed_wall = =math.ceil(speed_print * 30 / 40)
-jerk_travel = 50
\ No newline at end of file
+jerk_travel = 50
+prime_tower_purge_volume = 1
+
+material_bed_temperature_layer_0 = 90
+default_material_bed_temperature = 80
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg
new file mode 100644
index 0000000000..5dcc454173
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Superdraft_Print.inst.cfg
@@ -0,0 +1,32 @@
+[general]
+version = 4
+name = Sprint
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = superdraft
+weight = -4
+material = generic_cpe
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+brim_width = 15
+line_width = =machine_nozzle_size * 0.875
+material_print_temperature = =default_material_print_temperature + 20
+material_standby_temperature = 100
+prime_tower_enable = True
+speed_print = 45
+speed_topbottom = =math.ceil(speed_print * 30 / 45)
+speed_wall = =math.ceil(speed_print * 40 / 45)
+speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
+
+jerk_travel = 50
+prime_tower_purge_volume = 1
+
+material_bed_temperature_layer_0 = 90
+default_material_bed_temperature = 80
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg
new file mode 100644
index 0000000000..8423e109e8
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_CPE_Verydraft_Print.inst.cfg
@@ -0,0 +1,31 @@
+[general]
+version = 4
+name = Extra Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = verydraft
+weight = -3
+material = generic_cpe
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+brim_width = 15
+line_width = =machine_nozzle_size * 0.875
+material_print_temperature = =default_material_print_temperature + 17
+material_standby_temperature = 100
+prime_tower_enable = True
+speed_print = 40
+speed_topbottom = =math.ceil(speed_print * 25 / 40)
+speed_wall = =math.ceil(speed_print * 30 / 40)
+
+jerk_travel = 50
+prime_tower_purge_volume = 1
+
+material_bed_temperature_layer_0 = 90
+default_material_bed_temperature = 80
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg
index 9ebf2ea151..747e2fe8a5 100644
--- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Fast_Print.inst.cfg
@@ -16,21 +16,22 @@ buildplate = Aluminum
brim_width = 10
cool_fan_full_at_height = =layer_height_0 + 14 * layer_height
infill_before_walls = True
-layer_height_0 = 0.3
line_width = =machine_nozzle_size * 0.875
-material_bed_temperature = 115
-material_bed_temperature_layer_0 = 125
material_print_temperature = =default_material_print_temperature - 5
material_print_temperature_layer_0 = =material_print_temperature
material_standby_temperature = 100
-prime_blob_enable = False
raft_airgap = 0.5
raft_margin = 15
skin_overlap = 0
-speed_layer_0 = =math.ceil(speed_print * 15 / 50)
+speed_layer_0 = 15
speed_print = 50
speed_slowdown_layers = 15
speed_topbottom = =math.ceil(speed_print * 25 / 50)
speed_wall = =math.ceil(speed_print * 40 / 50)
speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
support_line_width = =round(line_width * 0.6 / 0.7, 2)
+
+material_bed_temperature_layer_0 = 125
+default_material_bed_temperature = 115
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg
new file mode 100644
index 0000000000..689652dc06
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Superdraft_Print.inst.cfg
@@ -0,0 +1,36 @@
+[general]
+version = 4
+name = Sprint
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = superdraft
+weight = -2
+material = generic_pc
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+brim_width = 10
+cool_fan_full_at_height = =layer_height_0 + 7 * layer_height
+infill_before_walls = True
+line_width = =machine_nozzle_size * 0.875
+material_print_temperature_layer_0 = =material_print_temperature
+material_standby_temperature = 100
+raft_airgap = 0.5
+raft_margin = 15
+skin_overlap = 0
+speed_layer_0 = 15
+speed_print = 50
+speed_slowdown_layers = 8
+speed_topbottom = =math.ceil(speed_print * 25 / 50)
+speed_wall = =math.ceil(speed_print * 40 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
+support_line_width = =round(line_width * 0.6 / 0.7, 2)
+
+material_bed_temperature_layer_0 = 125
+default_material_bed_temperature = 115
+prime_blob_enable = False
+layer_height_0 = 0.3
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg
new file mode 100644
index 0000000000..0480ee5620
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PC_Verydraft_Print.inst.cfg
@@ -0,0 +1,38 @@
+[general]
+version = 4
+name = Extra Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = verydraft
+weight = -1
+material = generic_pc
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+brim_width = 10
+cool_fan_full_at_height = =layer_height_0 + 9 * layer_height
+infill_before_walls = True
+line_width = =machine_nozzle_size * 0.875
+material_print_temperature = =default_material_print_temperature - 2
+material_print_temperature_layer_0 = =material_print_temperature
+material_standby_temperature = 100
+raft_airgap = 0.5
+raft_margin = 15
+skin_overlap = 0
+speed_layer_0 = 15
+speed_print = 50
+speed_slowdown_layers = 10
+speed_topbottom = =math.ceil(speed_print * 25 / 50)
+speed_wall = =math.ceil(speed_print * 40 / 50)
+speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
+support_line_width = =round(line_width * 0.6 / 0.7, 2)
+
+material_bed_temperature_layer_0 = 125
+default_material_bed_temperature = 115
+prime_blob_enable = False
+layer_height_0 = 0.3
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg
index 94bede16bd..b80af1b75f 100644
--- a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Draft_Print.inst.cfg
@@ -23,14 +23,14 @@ infill_pattern = tetrahedral
jerk_prime_tower = =math.ceil(jerk_print * 25 / 25)
jerk_support = =math.ceil(jerk_print * 25 / 25)
jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
-material_bed_temperature_layer_0 = =material_bed_temperature + 5
+material_bed_temperature_layer_0 = =material_bed_temperature
material_print_temperature = =default_material_print_temperature - 2
material_print_temperature_layer_0 = =default_material_print_temperature + 2
material_standby_temperature = 100
multiple_mesh_overlap = 0.2
prime_tower_enable = True
prime_tower_flow = 100
-prime_tower_min_volume = 10
+prime_tower_wall_thickness = =prime_tower_line_width * 2
retract_at_layer_change = False
retraction_count_max = 12
retraction_extra_prime_amount = 0.5
@@ -51,3 +51,5 @@ travel_compensate_overlapping_walls_0_enabled = False
wall_0_wipe_dist = =line_width * 2
wall_line_width_x = =round(line_width * 0.8 / 0.8, 2)
wall_thickness = 1.6
+
+default_material_bed_temperature = 95
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg
new file mode 100644
index 0000000000..970e0971a9
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Superdraft_Print.inst.cfg
@@ -0,0 +1,56 @@
+[general]
+version = 4
+name = Sprint
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = superdraft
+weight = -4
+material = generic_pp
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+brim_width = 25
+cool_min_layer_time_fan_speed_max = 6
+cool_min_speed = 17
+top_skin_expand_distance = =line_width * 2
+infill_before_walls = True
+infill_line_width = =round(line_width * 0.7 / 0.8, 2)
+infill_pattern = tetrahedral
+jerk_prime_tower = =math.ceil(jerk_print * 25 / 25)
+jerk_support = =math.ceil(jerk_print * 25 / 25)
+jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
+material_bed_temperature_layer_0 = =material_bed_temperature
+material_print_temperature = =default_material_print_temperature + 2
+material_print_temperature_layer_0 = =default_material_print_temperature + 2
+material_standby_temperature = 100
+multiple_mesh_overlap = 0.2
+prime_tower_enable = True
+prime_tower_flow = 100
+prime_tower_wall_thickness = =prime_tower_line_width * 2
+retract_at_layer_change = False
+retraction_count_max = 12
+retraction_extra_prime_amount = 0.5
+retraction_hop = 0.5
+retraction_min_travel = 1.5
+retraction_prime_speed = 15
+skin_line_width = =round(line_width * 0.78 / 0.8, 2)
+
+speed_wall_x = =math.ceil(speed_wall * 30 / 30)
+support_bottom_distance = =support_z_distance
+support_line_width = =round(line_width * 0.7 / 0.8, 2)
+support_offset = =line_width
+switch_extruder_prime_speed = 15
+switch_extruder_retraction_amount = 20
+switch_extruder_retraction_speeds = 45
+top_bottom_thickness = 1.6
+travel_compensate_overlapping_walls_0_enabled = False
+wall_0_wipe_dist = =line_width * 2
+wall_line_width_x = =round(line_width * 0.8 / 0.8, 2)
+wall_thickness = 1.6
+
+default_material_bed_temperature = 95
+
diff --git a/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg
new file mode 100644
index 0000000000..e51ba3207b
--- /dev/null
+++ b/resources/quality/ultimaker_s5/um_s5_aa0.8_aluminum_PP_Verydraft_Print.inst.cfg
@@ -0,0 +1,54 @@
+[general]
+version = 4
+name = Extra Fast
+definition = ultimaker_s5
+
+[metadata]
+setting_version = 5
+type = quality
+quality_type = verydraft
+weight = -3
+material = generic_pp
+variant = AA 0.8
+buildplate = Aluminum
+
+[values]
+brim_width = 25
+cool_min_layer_time_fan_speed_max = 6
+cool_min_speed = 17
+top_skin_expand_distance = =line_width * 2
+infill_before_walls = True
+infill_line_width = =round(line_width * 0.7 / 0.8, 2)
+infill_pattern = tetrahedral
+jerk_prime_tower = =math.ceil(jerk_print * 25 / 25)
+jerk_support = =math.ceil(jerk_print * 25 / 25)
+jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
+material_bed_temperature_layer_0 = =material_bed_temperature
+material_print_temperature_layer_0 = =default_material_print_temperature + 2
+material_standby_temperature = 100
+multiple_mesh_overlap = 0.2
+prime_tower_enable = True
+prime_tower_flow = 100
+prime_tower_wall_thickness = =prime_tower_line_width * 2
+retract_at_layer_change = False
+retraction_count_max = 12
+retraction_extra_prime_amount = 0.5
+retraction_hop = 0.5
+retraction_min_travel = 1.5
+retraction_prime_speed = 15
+skin_line_width = =round(line_width * 0.78 / 0.8, 2)
+
+speed_wall_x = =math.ceil(speed_wall * 30 / 30)
+support_bottom_distance = =support_z_distance
+support_line_width = =round(line_width * 0.7 / 0.8, 2)
+support_offset = =line_width
+switch_extruder_prime_speed = 15
+switch_extruder_retraction_amount = 20
+switch_extruder_retraction_speeds = 45
+top_bottom_thickness = 1.6
+travel_compensate_overlapping_walls_0_enabled = False
+wall_0_wipe_dist = =line_width * 2
+wall_line_width_x = =round(line_width * 0.8 / 0.8, 2)
+wall_thickness = 1.6
+
+default_material_bed_temperature = 95
diff --git a/resources/themes/cura-light/icons/favorites_star_empty.svg b/resources/themes/cura-light/icons/favorites_star_empty.svg
new file mode 100644
index 0000000000..bb1205e7a7
--- /dev/null
+++ b/resources/themes/cura-light/icons/favorites_star_empty.svg
@@ -0,0 +1,8 @@
+
+
+
diff --git a/resources/themes/cura-light/icons/favorites_star_full.svg b/resources/themes/cura-light/icons/favorites_star_full.svg
new file mode 100644
index 0000000000..aad45c5d02
--- /dev/null
+++ b/resources/themes/cura-light/icons/favorites_star_full.svg
@@ -0,0 +1,6 @@
+
+
+
diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json
index 7bcdafce98..c408146669 100644
--- a/resources/themes/cura-light/theme.json
+++ b/resources/themes/cura-light/theme.json
@@ -315,7 +315,13 @@
"tab_status_disconnected": [200, 200, 200, 255],
"printer_config_matched": [12, 169, 227, 255],
- "printer_config_mismatch": [127, 127, 127, 255]
+ "printer_config_mismatch": [127, 127, 127, 255],
+
+ "favorites_header_bar": [245, 245, 245, 255],
+ "favorites_header_hover": [245, 245, 245, 255],
+ "favorites_header_text": [31, 36, 39, 255],
+ "favorites_header_text_hover": [31, 36, 39, 255],
+ "favorites_row_selected": [196, 239, 255, 255]
},
"sizes": {
@@ -372,6 +378,10 @@
"small_button": [2, 2],
"small_button_icon": [1.5, 1.5],
+ "favorites_row": [2, 2],
+ "favorites_button": [2, 2],
+ "favorites_button_icon": [1.2, 1.2],
+
"printer_status_icon": [1.8, 1.8],
"printer_sync_icon": [1.2, 1.2],
diff --git a/tests/conftest.py b/tests/conftest.py
index f2c709d8d8..77d215815a 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -3,19 +3,21 @@
# The purpose of this class is to create fixtures or methods that can be shared among all tests.
+import unittest.mock
import pytest
+
from UM.Qt.QtApplication import QtApplication #QtApplication import is required, even though it isn't used.
from cura.CuraApplication import CuraApplication
from cura.MachineActionManager import MachineActionManager
+
+
# Create a CuraApplication object that will be shared among all tests. It needs to be initialized.
# Since we need to use it more that once, we create the application the first time and use its instance afterwards.
@pytest.fixture()
def application() -> CuraApplication:
- application = CuraApplication.getInstance()
- if application is None:
- application = CuraApplication()
- return application
+ app = unittest.mock.MagicMock()
+ return app
# Returns a MachineActionManager instance.
@pytest.fixture()