Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/cura
diff options
context:
space:
mode:
authorJaime van Kessel <nallath@gmail.com>2019-11-20 18:48:00 +0300
committerJaime van Kessel <nallath@gmail.com>2019-11-20 18:48:00 +0300
commit50d72692d8163d3e0cd5c577246a2eb024273dc6 (patch)
tree3e1e6ed85c8753f43a35e0fdc087f05c83b7df7a /cura
parent266f7d1f74c860eb80433ea248cc6da1d864c190 (diff)
parent9aeb9912c8d0d37db11bb11372c982d065b56c16 (diff)
Merge branch 'master' of github.com:Ultimaker/Cura into CURA-6522_one_at_a_time_overlapping_build_area
Diffstat (limited to 'cura')
-rw-r--r--cura/ApplicationMetadata.py17
-rwxr-xr-xcura/BuildVolume.py1
-rwxr-xr-xcura/CuraApplication.py31
-rw-r--r--cura/LayerPolygon.py4
-rw-r--r--cura/Machines/MachineNode.py2
-rw-r--r--cura/Machines/Models/BaseMaterialsModel.py8
-rw-r--r--cura/Machines/Models/BuildPlateModel.py7
-rw-r--r--cura/Machines/Models/DiscoveredPrintersModel.py1
-rw-r--r--cura/Machines/Models/IntentCategoryModel.py43
-rw-r--r--cura/Machines/Models/IntentTranslations.py24
-rw-r--r--cura/Machines/Models/QualityManagementModel.py6
-rw-r--r--cura/Machines/VariantNode.py17
-rw-r--r--cura/OAuth2/AuthorizationHelpers.py2
-rw-r--r--cura/OAuth2/AuthorizationService.py2
-rwxr-xr-xcura/PlatformPhysics.py1
-rw-r--r--cura/PrinterOutput/FirmwareUpdater.py4
-rw-r--r--cura/Scene/BuildPlateDecorator.py8
-rw-r--r--cura/Scene/ConvexHullNode.py7
-rw-r--r--cura/Settings/ContainerManager.py8
-rwxr-xr-xcura/Settings/ExtruderManager.py3
-rw-r--r--cura/Settings/IntentManager.py20
-rw-r--r--cura/Settings/SettingInheritanceManager.py13
-rw-r--r--cura/UI/CuraSplashScreen.py8
23 files changed, 152 insertions, 85 deletions
diff --git a/cura/ApplicationMetadata.py b/cura/ApplicationMetadata.py
index daa937197c..427cc77e65 100644
--- a/cura/ApplicationMetadata.py
+++ b/cura/ApplicationMetadata.py
@@ -9,7 +9,11 @@ DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura"
DEFAULT_CURA_VERSION = "master"
DEFAULT_CURA_BUILD_TYPE = ""
DEFAULT_CURA_DEBUG_MODE = False
-DEFAULT_CURA_SDK_VERSION = "7.0.0"
+
+# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
+# example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
+# CuraVersion.py.in template.
+CuraSDKVersion = "7.0.0"
try:
from cura.CuraVersion import CuraAppName # type: ignore
@@ -32,6 +36,9 @@ try:
except ImportError:
CuraVersion = DEFAULT_CURA_VERSION # [CodeStyle: Reflecting imported value]
+# CURA-6569
+# This string indicates what type of version it is. For example, "enterprise". By default it's empty which indicates
+# a default/normal Cura build.
try:
from cura.CuraVersion import CuraBuildType # type: ignore
except ImportError:
@@ -42,7 +49,7 @@ try:
except ImportError:
CuraDebugMode = DEFAULT_CURA_DEBUG_MODE
-# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
-# example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
-# CuraVersion.py.in template.
-CuraSDKVersion = "7.0.0"
+# CURA-6569
+# Various convenience flags indicating what kind of Cura build it is.
+__ENTERPRISE_VERSION_TYPE = "enterprise"
+IsEnterpriseVersion = CuraBuildType.lower() == __ENTERPRISE_VERSION_TYPE
diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py
index 7928b0243a..809d392c10 100755
--- a/cura/BuildVolume.py
+++ b/cura/BuildVolume.py
@@ -26,7 +26,6 @@ catalog = i18nCatalog("cura")
import numpy
import math
-import copy
from typing import List, Optional, TYPE_CHECKING, Any, Set, cast, Iterable, Dict
diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py
index 11784718ca..ef5f987b85 100755
--- a/cura/CuraApplication.py
+++ b/cura/CuraApplication.py
@@ -720,6 +720,8 @@ class CuraApplication(QtApplication):
## Handle loading of all plugin types (and the backend explicitly)
# \sa PluginRegistry
def _loadPlugins(self) -> None:
+ self._plugin_registry.setCheckIfTrusted(ApplicationMetadata.IsEnterpriseVersion)
+
self._plugin_registry.addType("profile_reader", self._addProfileReader)
self._plugin_registry.addType("profile_writer", self._addProfileWriter)
@@ -1368,16 +1370,19 @@ class CuraApplication(QtApplication):
for node in nodes:
mesh_data = node.getMeshData()
- if mesh_data and mesh_data.getFileName():
- job = ReadMeshJob(mesh_data.getFileName())
- job._node = node # type: ignore
- job.finished.connect(self._reloadMeshFinished)
- if has_merged_nodes:
- job.finished.connect(self.updateOriginOfMergedMeshes)
-
- job.start()
- else:
- Logger.log("w", "Unable to reload data because we don't have a filename.")
+
+ if mesh_data:
+ file_name = mesh_data.getFileName()
+ if file_name:
+ job = ReadMeshJob(file_name)
+ job._node = node # type: ignore
+ job.finished.connect(self._reloadMeshFinished)
+ if has_merged_nodes:
+ job.finished.connect(self.updateOriginOfMergedMeshes)
+
+ job.start()
+ else:
+ Logger.log("w", "Unable to reload data because we don't have a filename.")
@pyqtSlot("QStringList")
def setExpandedCategories(self, categories: List[str]) -> None:
@@ -1796,7 +1801,7 @@ class CuraApplication(QtApplication):
try:
result = workspace_reader.preRead(file_path, show_dialog=False)
return result == WorkspaceReader.PreReadResult.accepted
- except Exception as e:
+ except Exception:
Logger.logException("e", "Could not check file %s", file_url)
return False
@@ -1892,3 +1897,7 @@ class CuraApplication(QtApplication):
op.push()
from UM.Scene.Selection import Selection
Selection.clear()
+
+ @classmethod
+ def getInstance(cls, *args, **kwargs) -> "CuraApplication":
+ return cast(CuraApplication, super().getInstance(**kwargs))
diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py
index a62083945b..0d6489aaa2 100644
--- a/cura/LayerPolygon.py
+++ b/cura/LayerPolygon.py
@@ -1,7 +1,7 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from UM.Application import Application
+from UM.Qt.QtApplication import QtApplication
from typing import Any, Optional
import numpy
@@ -232,7 +232,7 @@ class LayerPolygon:
@classmethod
def getColorMap(cls):
if cls.__color_map is None:
- theme = Application.getInstance().getTheme()
+ theme = QtApplication.getInstance().getTheme()
cls.__color_map = numpy.array([
theme.getColor("layerview_none").getRgbF(), # NoneType
theme.getColor("layerview_inset_0").getRgbF(), # Inset0Type
diff --git a/cura/Machines/MachineNode.py b/cura/Machines/MachineNode.py
index 72652f2987..8d69ffdc8d 100644
--- a/cura/Machines/MachineNode.py
+++ b/cura/Machines/MachineNode.py
@@ -140,7 +140,7 @@ class MachineNode(ContainerNode):
elif groups_by_name[name].intent_category == "default": # Intent category should be stored as "default" if everything is default or as the intent if any of the extruder have an actual intent.
groups_by_name[name].intent_category = quality_changes.get("intent_category", "default")
- if "position" in quality_changes: # An extruder profile.
+ if quality_changes.get("position") is not None: # An extruder profile.
groups_by_name[name].metadata_per_extruder[int(quality_changes["position"])] = quality_changes
else: # Global profile.
groups_by_name[name].metadata_for_global = quality_changes
diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py
index 73d9d48b22..db660704b5 100644
--- a/cura/Machines/Models/BaseMaterialsModel.py
+++ b/cura/Machines/Models/BaseMaterialsModel.py
@@ -6,6 +6,7 @@ from typing import Dict, Set
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, pyqtProperty
from UM.Qt.ListModel import ListModel
+from UM.Logger import Logger
import cura.CuraApplication # Imported like this to prevent a circular reference.
from cura.Machines.ContainerTree import ContainerTree
@@ -153,7 +154,12 @@ class BaseMaterialsModel(ListModel):
if not extruder_stack:
return
nozzle_name = extruder_stack.variant.getName()
- materials = ContainerTree.getInstance().machines[global_stack.definition.getId()].variants[nozzle_name].materials
+ machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
+ if nozzle_name not in machine_node.variants:
+ Logger.log("w", "Unable to find variant %s in container tree", nozzle_name)
+ self._available_materials = {}
+ return
+ materials = machine_node.variants[nozzle_name].materials
approximate_material_diameter = extruder_stack.getApproximateMaterialDiameter()
self._available_materials = {key: material for key, material in materials.items() if float(material.getMetaDataEntry("approximate_diameter", -1)) == approximate_material_diameter}
diff --git a/cura/Machines/Models/BuildPlateModel.py b/cura/Machines/Models/BuildPlateModel.py
index c52228cf76..3697dd2762 100644
--- a/cura/Machines/Models/BuildPlateModel.py
+++ b/cura/Machines/Models/BuildPlateModel.py
@@ -2,13 +2,8 @@
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt
-
-from UM.Application import Application
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
-from UM.Util import parseBool
-
-from cura.Machines.VariantType import VariantType
class BuildPlateModel(ListModel):
@@ -26,4 +21,4 @@ class BuildPlateModel(ListModel):
def _update(self):
Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
self.setItems([])
- return \ No newline at end of file
+ return
diff --git a/cura/Machines/Models/DiscoveredPrintersModel.py b/cura/Machines/Models/DiscoveredPrintersModel.py
index a1b68ee1ae..c662334470 100644
--- a/cura/Machines/Models/DiscoveredPrintersModel.py
+++ b/cura/Machines/Models/DiscoveredPrintersModel.py
@@ -11,7 +11,6 @@ from UM.Util import parseBool
from UM.OutputDevice.OutputDeviceManager import ManualDeviceAdditionAttempt
if TYPE_CHECKING:
- from PyQt5.QtCore import QObject
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
from cura.CuraApplication import CuraApplication
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice
diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py
index 0ff52b325a..202d79bb15 100644
--- a/cura/Machines/Models/IntentCategoryModel.py
+++ b/cura/Machines/Models/IntentCategoryModel.py
@@ -1,9 +1,10 @@
#Copyright (c) 2019 Ultimaker B.V.
#Cura is released under the terms of the LGPLv3 or higher.
-from PyQt5.QtCore import Qt, QTimer
import collections
+from PyQt5.QtCore import Qt, QTimer
from typing import TYPE_CHECKING, Optional, Dict
+from cura.Machines.Models.IntentTranslations import intent_translations
from cura.Machines.Models.IntentModel import IntentModel
from cura.Settings.IntentManager import IntentManager
@@ -29,21 +30,29 @@ class IntentCategoryModel(ListModel):
modelUpdated = pyqtSignal()
+ _translations = collections.OrderedDict() # type: "collections.OrderedDict[str,Dict[str,Optional[str]]]"
+
# Translations to user-visible string. Ordered by weight.
# TODO: Create a solution for this name and weight to be used dynamically.
- _translations = collections.OrderedDict() # type: "collections.OrderedDict[str,Dict[str,Optional[str]]]"
- _translations["default"] = {
- "name": catalog.i18nc("@label", "Default")
- }
- _translations["engineering"] = {
- "name": catalog.i18nc("@label", "Engineering"),
- "description": catalog.i18nc("@text", "Suitable for engineering work")
-
- }
- _translations["smooth"] = {
- "name": catalog.i18nc("@label", "Smooth"),
- "description": catalog.i18nc("@text", "Optimized for a smooth surfaces")
- }
+ @classmethod
+ def _get_translations(cls):
+ if len(cls._translations) == 0:
+ cls._translations["default"] = {
+ "name": catalog.i18nc("@label", "Default")
+ }
+ cls._translations["visual"] = {
+ "name": catalog.i18nc("@label", "Visual"),
+ "description": catalog.i18nc("@text", "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality.")
+ }
+ cls._translations["engineering"] = {
+ "name": catalog.i18nc("@label", "Engineering"),
+ "description": catalog.i18nc("@text", "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances.")
+ }
+ cls._translations["quick"] = {
+ "name": catalog.i18nc("@label", "Draft"),
+ "description": catalog.i18nc("@text", "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction.")
+ }
+ return cls._translations
## Creates a new model for a certain intent category.
# \param The category to list the intent profiles for.
@@ -95,15 +104,15 @@ class IntentCategoryModel(ListModel):
"name": IntentCategoryModel.translation(category, "name", catalog.i18nc("@label", "Unknown")),
"description": IntentCategoryModel.translation(category, "description", None),
"intent_category": category,
- "weight": list(self._translations.keys()).index(category),
+ "weight": list(IntentCategoryModel._get_translations().keys()).index(category),
"qualities": qualities
})
result.sort(key = lambda k: k["weight"])
self.setItems(result)
- ## Get a display value for a category. See IntenCategoryModel._translations
+ ## Get a display value for a category.
## for categories and keys
@staticmethod
def translation(category: str, key: str, default: Optional[str] = None):
- display_strings = IntentCategoryModel._translations.get(category, {})
+ display_strings = IntentCategoryModel._get_translations().get(category, {})
return display_strings.get(key, default)
diff --git a/cura/Machines/Models/IntentTranslations.py b/cura/Machines/Models/IntentTranslations.py
new file mode 100644
index 0000000000..050fb1de56
--- /dev/null
+++ b/cura/Machines/Models/IntentTranslations.py
@@ -0,0 +1,24 @@
+import collections
+from typing import Dict, Optional
+
+from UM.i18n import i18nCatalog
+from typing import Dict, Optional
+catalog = i18nCatalog("cura")
+
+
+intent_translations = collections.OrderedDict() # type: collections.OrderedDict[str, Dict[str, Optional[str]]]
+intent_translations["default"] = {
+ "name": catalog.i18nc("@label", "Default")
+}
+intent_translations["visual"] = {
+ "name": catalog.i18nc("@label", "Visual"),
+ "description": catalog.i18nc("@text", "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality.")
+}
+intent_translations["engineering"] = {
+ "name": catalog.i18nc("@label", "Engineering"),
+ "description": catalog.i18nc("@text", "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances.")
+}
+intent_translations["quick"] = {
+ "name": catalog.i18nc("@label", "Draft"),
+ "description": catalog.i18nc("@text", "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction.")
+}
diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py
index d8b0785778..74dc8649d0 100644
--- a/cura/Machines/Models/QualityManagementModel.py
+++ b/cura/Machines/Models/QualityManagementModel.py
@@ -14,6 +14,7 @@ from cura.Machines.ContainerTree import ContainerTree
from cura.Settings.cura_empty_instance_containers import empty_quality_changes_container
from cura.Settings.IntentManager import IntentManager
from cura.Machines.Models.MachineModelUtils import fetchLayerHeight
+from cura.Machines.Models.IntentTranslations import intent_translations
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
@@ -336,10 +337,11 @@ class QualityManagementModel(ListModel):
"quality_type": quality_type,
"quality_changes_group": None,
"intent_category": intent_category,
- "section_name": catalog.i18nc("@label", intent_category.capitalize()),
+ "section_name": catalog.i18nc("@label", intent_translations.get(intent_category, {}).get("name", catalog.i18nc("@label", "Unknown"))),
})
# Sort by quality_type for each intent category
- result = sorted(result, key = lambda x: (x["intent_category"], x["quality_type"]))
+
+ result = sorted(result, key = lambda x: (list(intent_translations).index(x["intent_category"]), x["quality_type"]))
item_list += result
# Create quality_changes group items
diff --git a/cura/Machines/VariantNode.py b/cura/Machines/VariantNode.py
index 334a01158b..c9e3ec4913 100644
--- a/cura/Machines/VariantNode.py
+++ b/cura/Machines/VariantNode.py
@@ -1,13 +1,12 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import Optional, TYPE_CHECKING
+from typing import TYPE_CHECKING
from UM.Logger import Logger
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.Interfaces import ContainerInterface
from UM.Signal import Signal
-from cura.Settings.cura_empty_instance_containers import empty_variant_container
from cura.Machines.ContainerNode import ContainerNode
from cura.Machines.MaterialNode import MaterialNode
@@ -83,12 +82,22 @@ class VariantNode(ContainerNode):
# if there is no match.
def preferredMaterial(self, approximate_diameter: int) -> MaterialNode:
for base_material, material_node in self.materials.items():
- if self.machine.preferred_material in base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
+ if self.machine.preferred_material == base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
return material_node
- # First fallback: Choose any material with matching diameter.
+
+ # First fallback: Check if we should be checking for the 175 variant.
+ if approximate_diameter == 2:
+ preferred_material = self.machine.preferred_material + "_175"
+ for base_material, material_node in self.materials.items():
+ if preferred_material == base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
+ return material_node
+
+ # Second fallback: Choose any material with matching diameter.
for material_node in self.materials.values():
if material_node.getMetaDataEntry("approximate_diameter") and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
+ Logger.log("w", "Could not find preferred material %s, falling back to whatever works", self.machine.preferred_material)
return material_node
+
fallback = next(iter(self.materials.values())) # Should only happen with empty material node.
Logger.log("w", "Could not find preferred material {preferred_material} with diameter {diameter} for variant {variant_id}, falling back to {fallback}.".format(
preferred_material = self.machine.preferred_material,
diff --git a/cura/OAuth2/AuthorizationHelpers.py b/cura/OAuth2/AuthorizationHelpers.py
index 08309fa30e..9fc01ba50b 100644
--- a/cura/OAuth2/AuthorizationHelpers.py
+++ b/cura/OAuth2/AuthorizationHelpers.py
@@ -99,7 +99,7 @@ class AuthorizationHelpers:
})
except requests.exceptions.ConnectionError:
# Connection was suddenly dropped. Nothing we can do about that.
- Logger.log("w", "Something failed while attempting to parse the JWT token")
+ Logger.logException("w", "Something failed while attempting to parse the JWT token")
return None
if token_request.status_code not in (200, 201):
Logger.log("w", "Could not retrieve token data from auth server: %s", token_request.text)
diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py
index 68756f8df6..0848623410 100644
--- a/cura/OAuth2/AuthorizationService.py
+++ b/cura/OAuth2/AuthorizationService.py
@@ -3,7 +3,6 @@
import json
from datetime import datetime, timedelta
-import os
from typing import Optional, TYPE_CHECKING
from urllib.parse import urlencode
@@ -14,7 +13,6 @@ from PyQt5.QtGui import QDesktopServices
from UM.Logger import Logger
from UM.Message import Message
-from UM.Platform import Platform
from UM.Signal import Signal
from cura.OAuth2.LocalAuthorizationServer import LocalAuthorizationServer
diff --git a/cura/PlatformPhysics.py b/cura/PlatformPhysics.py
index d084c0dbf4..a411478b16 100755
--- a/cura/PlatformPhysics.py
+++ b/cura/PlatformPhysics.py
@@ -17,6 +17,7 @@ from cura.Scene import ZOffsetDecorator
import random # used for list shuffling
+
class PlatformPhysics:
def __init__(self, controller, volume):
super().__init__()
diff --git a/cura/PrinterOutput/FirmwareUpdater.py b/cura/PrinterOutput/FirmwareUpdater.py
index 3f20e0f3c4..56e260a7f0 100644
--- a/cura/PrinterOutput/FirmwareUpdater.py
+++ b/cura/PrinterOutput/FirmwareUpdater.py
@@ -20,7 +20,7 @@ class FirmwareUpdater(QObject):
self._output_device = output_device
- self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True)
+ self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True, name = "FirmwareUpdateThread")
self._firmware_file = ""
self._firmware_progress = 0
@@ -43,7 +43,7 @@ class FirmwareUpdater(QObject):
## Cleanup after a succesful update
def _cleanupAfterUpdate(self) -> None:
# Clean up for next attempt.
- self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True)
+ self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True, name = "FirmwareUpdateThread")
self._firmware_file = ""
self._onFirmwareProgress(100)
self._setFirmwareUpdateState(FirmwareUpdateState.completed)
diff --git a/cura/Scene/BuildPlateDecorator.py b/cura/Scene/BuildPlateDecorator.py
index dfb465b7ad..cff9f88f62 100644
--- a/cura/Scene/BuildPlateDecorator.py
+++ b/cura/Scene/BuildPlateDecorator.py
@@ -4,12 +4,12 @@ from cura.Scene.CuraSceneNode import CuraSceneNode
## Make a SceneNode build plate aware CuraSceneNode objects all have this decorator.
class BuildPlateDecorator(SceneNodeDecorator):
- def __init__(self, build_plate_number = -1):
+ def __init__(self, build_plate_number: int = -1) -> None:
super().__init__()
- self._build_plate_number = None
+ self._build_plate_number = build_plate_number
self.setBuildPlateNumber(build_plate_number)
- def setBuildPlateNumber(self, nr):
+ def setBuildPlateNumber(self, nr: int) -> None:
# Make sure that groups are set correctly
# setBuildPlateForSelection in CuraActions makes sure that no single childs are set.
self._build_plate_number = nr
@@ -19,7 +19,7 @@ class BuildPlateDecorator(SceneNodeDecorator):
for child in self._node.getChildren():
child.callDecoration("setBuildPlateNumber", nr)
- def getBuildPlateNumber(self):
+ def getBuildPlateNumber(self) -> int:
return self._build_plate_number
def __deepcopy__(self, memo):
diff --git a/cura/Scene/ConvexHullNode.py b/cura/Scene/ConvexHullNode.py
index 6aa71223e5..da2713a522 100644
--- a/cura/Scene/ConvexHullNode.py
+++ b/cura/Scene/ConvexHullNode.py
@@ -1,6 +1,6 @@
# Copyright (c) 2015 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import Optional
+from typing import Optional, TYPE_CHECKING
from UM.Application import Application
from UM.Math.Polygon import Polygon
@@ -11,6 +11,9 @@ from UM.Math.Color import Color
from UM.Mesh.MeshBuilder import MeshBuilder # To create a mesh to display the convex hull with.
from UM.View.GL.OpenGL import OpenGL
+if TYPE_CHECKING:
+ from UM.Mesh.MeshData import MeshData
+
class ConvexHullNode(SceneNode):
shader = None # To prevent the shader from being re-built over and over again, only load it once.
@@ -44,7 +47,7 @@ class ConvexHullNode(SceneNode):
# The node this mesh is "watching"
self._node = node
# Area of the head + fans for display as a shadow on the buildplate
- self._convex_hull_head_mesh = None
+ self._convex_hull_head_mesh = None # type: Optional[MeshData]
self._node.decoratorsChanged.connect(self._onNodeDecoratorsChanged)
self._onNodeDecoratorsChanged(self._node)
diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py
index 4a4a7b64dd..92f06929d2 100644
--- a/cura/Settings/ContainerManager.py
+++ b/cura/Settings/ContainerManager.py
@@ -247,7 +247,7 @@ class ContainerManager(QObject):
try:
with open(file_url, "rt", encoding = "utf-8") as f:
- container.deserialize(f.read())
+ container.deserialize(f.read(), file_url)
except PermissionError:
return {"status": "error", "message": "Permission denied when trying to read the file."}
except ContainerFormatError:
@@ -339,11 +339,11 @@ class ContainerManager(QObject):
# \return A list of names of materials with the same GUID.
@pyqtSlot("QVariant", bool, result = "QStringList")
def getLinkedMaterials(self, material_node: "MaterialNode", exclude_self: bool = False) -> List[str]:
- same_guid = ContainerRegistry.getInstance().findInstanceContainersMetadata(guid = material_node.guid)
+ same_guid = ContainerRegistry.getInstance().findInstanceContainersMetadata(GUID = material_node.guid)
if exclude_self:
- return [metadata["name"] for metadata in same_guid if metadata["base_file"] != material_node.base_file]
+ return list({meta["name"] for meta in same_guid if meta["base_file"] != material_node.base_file})
else:
- return [metadata["name"] for metadata in same_guid]
+ return list({meta["name"] for meta in same_guid})
## Unlink a material from all other materials by creating a new GUID
# \param material_id \type{str} the id of the material to create a new GUID for.
diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py
index b3d108e1aa..62bf396878 100755
--- a/cura/Settings/ExtruderManager.py
+++ b/cura/Settings/ExtruderManager.py
@@ -12,7 +12,6 @@ from UM.Scene.SceneNode import SceneNode
from UM.Scene.Selection import Selection
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
from UM.Settings.ContainerRegistry import ContainerRegistry # Finding containers by ID.
-from UM.Decorators import deprecated
from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING, Union
@@ -369,7 +368,7 @@ class ExtruderManager(QObject):
printer = global_stack.getId(), expected = expected_extruder_definition_0_id, got = extruder_stack_0.definition.getId()))
try:
extruder_definition = container_registry.findDefinitionContainers(id = expected_extruder_definition_0_id)[0]
- except IndexError as e:
+ except IndexError:
# It still needs to break, but we want to know what extruder ID made it break.
msg = "Unable to find extruder definition with the id [%s]" % expected_extruder_definition_0_id
Logger.logException("e", msg)
diff --git a/cura/Settings/IntentManager.py b/cura/Settings/IntentManager.py
index c1d59fb84a..732e22d1bd 100644
--- a/cura/Settings/IntentManager.py
+++ b/cura/Settings/IntentManager.py
@@ -1,13 +1,15 @@
-#Copyright (c) 2019 Ultimaker B.V.
-#Cura is released under the terms of the LGPLv3 or higher.
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
from typing import Any, Dict, List, Optional, Set, Tuple, TYPE_CHECKING
-import cura.CuraApplication
+
from UM.Logger import Logger
+from UM.Settings.InstanceContainer import InstanceContainer
+
+import cura.CuraApplication
from cura.Machines.ContainerTree import ContainerTree
from cura.Settings.cura_empty_instance_containers import empty_intent_container
-from UM.Settings.InstanceContainer import InstanceContainer
if TYPE_CHECKING:
from UM.Settings.InstanceContainer import InstanceContainer
@@ -36,8 +38,12 @@ class IntentManager(QObject):
# \return A list of metadata dictionaries matching the search criteria, or
# an empty list if nothing was found.
def intentMetadatas(self, definition_id: str, nozzle_name: str, material_base_file: str) -> List[Dict[str, Any]]:
- material_node = ContainerTree.getInstance().machines[definition_id].variants[nozzle_name].materials[material_base_file]
- intent_metadatas = []
+ intent_metadatas = [] # type: List[Dict[str, Any]]
+ materials = ContainerTree.getInstance().machines[definition_id].variants[nozzle_name].materials
+ if material_base_file not in materials:
+ return intent_metadatas
+
+ material_node = materials[material_base_file]
for quality_node in material_node.qualities.values():
for intent_node in quality_node.intents.values():
intent_metadatas.append(intent_node.getMetadata())
@@ -116,7 +122,7 @@ class IntentManager(QObject):
## The intent that gets selected by default when no intent is available for
# the configuration, an extruder can't match the intent that the user
# selects, or just when creating a new printer.
- def getDefaultIntent(self) -> InstanceContainer:
+ def getDefaultIntent(self) -> "InstanceContainer":
return empty_intent_container
@pyqtProperty(str, notify = intentCategoryChanged)
diff --git a/cura/Settings/SettingInheritanceManager.py b/cura/Settings/SettingInheritanceManager.py
index 8be0813d0a..7db579bf3f 100644
--- a/cura/Settings/SettingInheritanceManager.py
+++ b/cura/Settings/SettingInheritanceManager.py
@@ -28,20 +28,21 @@ if TYPE_CHECKING:
class SettingInheritanceManager(QObject):
def __init__(self, parent = None) -> None:
super().__init__(parent)
- Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
+
self._global_container_stack = None # type: Optional[ContainerStack]
self._settings_with_inheritance_warning = [] # type: List[str]
self._active_container_stack = None # type: Optional[ExtruderStack]
- self._onGlobalContainerChanged()
-
- ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged)
- self._onActiveExtruderChanged()
self._update_timer = QTimer()
self._update_timer.setInterval(500)
self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._update)
+ Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
+ ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged)
+ self._onGlobalContainerChanged()
+ self._onActiveExtruderChanged()
+
settingsWithIntheritanceChanged = pyqtSignal()
## Get the keys of all children settings with an override.
@@ -106,7 +107,7 @@ class SettingInheritanceManager(QObject):
if self._active_container_stack is not None:
self._active_container_stack.propertyChanged.connect(self._onPropertyChanged)
self._active_container_stack.containersChanged.connect(self._onContainersChanged)
- self._update() # Ensure that the settings_with_inheritance_warning list is populated.
+ self._update_timer.start() # Ensure that the settings_with_inheritance_warning list is populated.
def _onPropertyChanged(self, key: str, property_name: str) -> None:
if (property_name == "value" or property_name == "enabled") and self._global_container_stack:
diff --git a/cura/UI/CuraSplashScreen.py b/cura/UI/CuraSplashScreen.py
index 77c9ad1427..05231c106d 100644
--- a/cura/UI/CuraSplashScreen.py
+++ b/cura/UI/CuraSplashScreen.py
@@ -56,11 +56,11 @@ class CuraSplashScreen(QSplashScreen):
if buildtype:
version[0] += " (%s)" % buildtype
- # draw version text
+ # Draw version text
font = QFont() # Using system-default font here
font.setPixelSize(37)
painter.setFont(font)
- painter.drawText(215, 66, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[0])
+ painter.drawText(60, 66, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[0])
if len(version) > 1:
font.setPixelSize(16)
painter.setFont(font)
@@ -68,14 +68,14 @@ class CuraSplashScreen(QSplashScreen):
painter.drawText(247, 105, 330 * self._scale, 255 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[1])
painter.setPen(QColor(255, 255, 255, 255))
- # draw the loading image
+ # Draw the loading image
pen = QPen()
pen.setWidth(6 * self._scale)
pen.setColor(QColor(32, 166, 219, 255))
painter.setPen(pen)
painter.drawArc(60, 150, 32 * self._scale, 32 * self._scale, self._loading_image_rotation_angle * 16, 300 * 16)
- # draw message text
+ # Draw message text
if self._current_message:
font = QFont() # Using system-default font here
font.setPixelSize(13)