mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-08 14:34:01 -06:00
Merge branch 'master' of github.com:Ultimaker/Cura into CURA-7038
This commit is contained in:
commit
4b86400661
321 changed files with 5664 additions and 887 deletions
|
@ -790,7 +790,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
container_info = ContainerInfo(None, None, None)
|
||||
quality_changes_info.extruder_info_dict["0"] = container_info
|
||||
# If the global stack we're "targeting" has never been active, but was updated from Cura 3.4,
|
||||
# it might not have it's extruders set properly.
|
||||
# it might not have its extruders set properly.
|
||||
if not global_stack.extruders:
|
||||
ExtruderManager.getInstance().fixSingleExtrusionMachineExtruderDefinition(global_stack)
|
||||
extruder_stack = global_stack.extruders["0"]
|
||||
|
|
|
@ -97,7 +97,6 @@ Cura.MachineAction
|
|||
text: Cura.MachineManager.activeMachine.name
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font: UM.Theme.getFont("large_bold")
|
||||
color: UM.Theme.getColor("text")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
|
|
|
@ -40,11 +40,13 @@ Item
|
|||
// update active type label
|
||||
for (var button in meshTypeButtons.children)
|
||||
{
|
||||
if (meshTypeButtons.children[button].checked){
|
||||
if (meshTypeButtons.children[button].checked)
|
||||
{
|
||||
meshTypeLabel.text = catalog.i18nc("@label", "Mesh Type") + ": " + meshTypeButtons.children[button].text
|
||||
break
|
||||
}
|
||||
}
|
||||
visibility_handler.addSkipResetSetting(currentMeshType)
|
||||
}
|
||||
|
||||
function setOverhangsMeshType()
|
||||
|
@ -129,7 +131,7 @@ Item
|
|||
|
||||
}
|
||||
|
||||
Label
|
||||
Label
|
||||
{
|
||||
id: meshTypeLabel
|
||||
font: UM.Theme.getFont("default")
|
||||
|
@ -203,6 +205,7 @@ Item
|
|||
|
||||
visibilityHandler: Cura.PerObjectSettingVisibilityHandler
|
||||
{
|
||||
id: visibility_handler
|
||||
selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId")
|
||||
}
|
||||
|
||||
|
@ -319,10 +322,7 @@ Item
|
|||
Connections
|
||||
{
|
||||
target: inheritStackProvider
|
||||
onPropertiesChanged:
|
||||
{
|
||||
provider.forcePropertiesChanged()
|
||||
}
|
||||
onPropertiesChanged: provider.forcePropertiesChanged()
|
||||
}
|
||||
|
||||
Connections
|
||||
|
@ -458,5 +458,4 @@ Item
|
|||
|
||||
Cura.SettingUnknown { }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,133 +7,129 @@ import Cura 1.0 as Cura
|
|||
import ".."
|
||||
|
||||
UM.Dialog
|
||||
{
|
||||
id: settingPickDialog
|
||||
|
||||
title: catalog.i18nc("@title:window", "Select Settings to Customize for this model")
|
||||
width: screenScaleFactor * 360
|
||||
|
||||
property var additional_excluded_settings
|
||||
|
||||
onVisibilityChanged:
|
||||
{
|
||||
id: settingPickDialog
|
||||
|
||||
title: catalog.i18nc("@title:window", "Select Settings to Customize for this model")
|
||||
width: screenScaleFactor * 360
|
||||
|
||||
property var additional_excluded_settings
|
||||
|
||||
onVisibilityChanged:
|
||||
// force updating the model to sync it with addedSettingsModel
|
||||
if (visible)
|
||||
{
|
||||
// force updating the model to sync it with addedSettingsModel
|
||||
if (visible)
|
||||
{
|
||||
// Set skip setting, it will prevent from resetting selected mesh_type
|
||||
contents.model.visibilityHandler.addSkipResetSetting(currentMeshType)
|
||||
listview.model.forceUpdate()
|
||||
listview.model.forceUpdate()
|
||||
updateFilter()
|
||||
}
|
||||
}
|
||||
|
||||
updateFilter()
|
||||
}
|
||||
function updateFilter()
|
||||
{
|
||||
var new_filter = {}
|
||||
new_filter["settable_per_mesh"] = true
|
||||
// Don't filter on "settable_per_meshgroup" any more when `printSequencePropertyProvider.properties.value`
|
||||
// is set to "one_at_a_time", because the current backend architecture isn't ready for that.
|
||||
|
||||
if (filterInput.text != "")
|
||||
{
|
||||
new_filter["i18n_label"] = "*" + filterInput.text
|
||||
}
|
||||
|
||||
function updateFilter()
|
||||
listview.model.filter = new_filter
|
||||
}
|
||||
|
||||
TextField
|
||||
{
|
||||
id: filterInput
|
||||
|
||||
anchors
|
||||
{
|
||||
var new_filter = {}
|
||||
new_filter["settable_per_mesh"] = true
|
||||
// Don't filter on "settable_per_meshgroup" any more when `printSequencePropertyProvider.properties.value`
|
||||
// is set to "one_at_a_time", because the current backend architecture isn't ready for that.
|
||||
|
||||
if (filterInput.text != "")
|
||||
{
|
||||
new_filter["i18n_label"] = "*" + filterInput.text
|
||||
}
|
||||
|
||||
listview.model.filter = new_filter
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: toggleShowAll.left
|
||||
rightMargin: UM.Theme.getSize("default_margin").width
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: filterInput
|
||||
placeholderText: catalog.i18nc("@label:textbox", "Filter...")
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: toggleShowAll.left
|
||||
rightMargin: UM.Theme.getSize("default_margin").width
|
||||
}
|
||||
onTextChanged: settingPickDialog.updateFilter()
|
||||
}
|
||||
|
||||
placeholderText: catalog.i18nc("@label:textbox", "Filter...")
|
||||
CheckBox
|
||||
{
|
||||
id: toggleShowAll
|
||||
|
||||
onTextChanged: settingPickDialog.updateFilter()
|
||||
anchors
|
||||
{
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
CheckBox
|
||||
text: catalog.i18nc("@label:checkbox", "Show all")
|
||||
checked: listview.model.showAll
|
||||
onClicked: listview.model.showAll = checked
|
||||
}
|
||||
|
||||
ScrollView
|
||||
{
|
||||
id: scrollView
|
||||
|
||||
anchors
|
||||
{
|
||||
id: toggleShowAll
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
text: catalog.i18nc("@label:checkbox", "Show all")
|
||||
checked: listview.model.showAll
|
||||
onClicked:
|
||||
{
|
||||
listview.model.showAll = checked
|
||||
}
|
||||
top: filterInput.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
ScrollView
|
||||
ListView
|
||||
{
|
||||
id: scrollView
|
||||
|
||||
anchors
|
||||
id:listview
|
||||
model: UM.SettingDefinitionsModel
|
||||
{
|
||||
top: filterInput.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
ListView
|
||||
{
|
||||
id:listview
|
||||
model: UM.SettingDefinitionsModel
|
||||
id: definitionsModel
|
||||
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
|
||||
expanded: [ "*" ]
|
||||
exclude:
|
||||
{
|
||||
id: definitionsModel
|
||||
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
|
||||
expanded: [ "*" ]
|
||||
exclude:
|
||||
var excluded_settings = [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
|
||||
excluded_settings = excluded_settings.concat(settingPickDialog.additional_excluded_settings)
|
||||
return excluded_settings
|
||||
}
|
||||
}
|
||||
delegate:Loader
|
||||
{
|
||||
id: loader
|
||||
|
||||
width: parent.width
|
||||
height: model.type != undefined ? UM.Theme.getSize("section").height : 0
|
||||
|
||||
property var definition: model
|
||||
property var settingDefinitionsModel: definitionsModel
|
||||
|
||||
asynchronous: true
|
||||
source:
|
||||
{
|
||||
switch(model.type)
|
||||
{
|
||||
var excluded_settings = [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
|
||||
excluded_settings = excluded_settings.concat(settingPickDialog.additional_excluded_settings)
|
||||
return excluded_settings
|
||||
case "category":
|
||||
return "PerObjectCategory.qml"
|
||||
default:
|
||||
return "PerObjectItem.qml"
|
||||
}
|
||||
}
|
||||
delegate:Loader
|
||||
{
|
||||
id: loader
|
||||
|
||||
width: parent.width
|
||||
height: model.type != undefined ? UM.Theme.getSize("section").height : 0
|
||||
|
||||
property var definition: model
|
||||
property var settingDefinitionsModel: definitionsModel
|
||||
|
||||
asynchronous: true
|
||||
source:
|
||||
{
|
||||
switch(model.type)
|
||||
{
|
||||
case "category":
|
||||
return "PerObjectCategory.qml"
|
||||
default:
|
||||
return "PerObjectItem.qml"
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: settingPickDialog.updateFilter()
|
||||
}
|
||||
Component.onCompleted: settingPickDialog.updateFilter()
|
||||
}
|
||||
}
|
||||
|
||||
rightButtons: [
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Close")
|
||||
onClicked: {
|
||||
settingPickDialog.visible = false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
rightButtons: [
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Close")
|
||||
onClicked: settingPickDialog.visible = false
|
||||
}
|
||||
]
|
||||
}
|
55
plugins/SentryLogger/SentryLogger.py
Normal file
55
plugins/SentryLogger/SentryLogger.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from UM.Logger import LogOutput
|
||||
from typing import Set
|
||||
from sentry_sdk import add_breadcrumb
|
||||
from typing import Optional
|
||||
import os
|
||||
|
||||
home_dir = os.path.expanduser("~")
|
||||
|
||||
|
||||
class SentryLogger(LogOutput):
|
||||
# Sentry (https://sentry.io) is the service that Cura uses for logging crashes. This logger ensures that the
|
||||
# regular log entries that we create are added as breadcrumbs so when a crash actually happens, they are already
|
||||
# processed and ready for sending.
|
||||
# Note that this only prepares them for sending. It only sends them when the user actually agrees to sending the
|
||||
# information.
|
||||
|
||||
_levels = {
|
||||
"w": "warning",
|
||||
"i": "info",
|
||||
"c": "fatal",
|
||||
"e": "error",
|
||||
"d": "debug"
|
||||
}
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self._show_once = set() # type: Set[str]
|
||||
|
||||
## Log the message to the sentry hub as a breadcrumb
|
||||
# \param log_type "e" (error), "i"(info), "d"(debug), "w"(warning) or "c"(critical) (can postfix with "_once")
|
||||
# \param message String containing message to be logged
|
||||
def log(self, log_type: str, message: str) -> None:
|
||||
level = self._translateLogType(log_type)
|
||||
message = self._pruneSensitiveData(message)
|
||||
if level is None:
|
||||
if message not in self._show_once:
|
||||
level = self._translateLogType(log_type[0])
|
||||
if level is not None:
|
||||
self._show_once.add(message)
|
||||
add_breadcrumb(level = level, message = message)
|
||||
else:
|
||||
add_breadcrumb(level = level, message = message)
|
||||
|
||||
@staticmethod
|
||||
def _pruneSensitiveData(message):
|
||||
if home_dir in message:
|
||||
message = message.replace(home_dir, "<user_home>")
|
||||
return message
|
||||
|
||||
@staticmethod
|
||||
def _translateLogType(log_type: str) -> Optional[str]:
|
||||
return SentryLogger._levels.get(log_type)
|
16
plugins/SentryLogger/__init__.py
Normal file
16
plugins/SentryLogger/__init__.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import TYPE_CHECKING, Dict, Any
|
||||
|
||||
from . import SentryLogger
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from UM.Application import Application
|
||||
|
||||
|
||||
def getMetaData() -> Dict[str, Any]:
|
||||
return {}
|
||||
|
||||
|
||||
def register(app: "Application") -> Dict[str, Any]:
|
||||
return {"logger": SentryLogger.SentryLogger()}
|
8
plugins/SentryLogger/plugin.json
Normal file
8
plugins/SentryLogger/plugin.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "Sentry Logger",
|
||||
"author": "Ultimaker B.V.",
|
||||
"version": "1.0.0",
|
||||
"description": "Logs certain events so that they can be used by the crash reporter",
|
||||
"api": "7.0",
|
||||
"i18n-catalog": "cura"
|
||||
}
|
|
@ -65,10 +65,7 @@ class SolidView(View):
|
|||
else:
|
||||
self._support_angle = support_angle_stack.getProperty("support_angle", "value")
|
||||
|
||||
def beginRendering(self):
|
||||
scene = self.getController().getScene()
|
||||
renderer = self.getRenderer()
|
||||
|
||||
def _checkSetup(self):
|
||||
if not self._extruders_model:
|
||||
self._extruders_model = Application.getInstance().getExtrudersModel()
|
||||
|
||||
|
@ -95,6 +92,12 @@ class SolidView(View):
|
|||
self._support_mesh_shader.setUniformValue("u_vertical_stripes", True)
|
||||
self._support_mesh_shader.setUniformValue("u_width", 5.0)
|
||||
|
||||
def beginRendering(self):
|
||||
scene = self.getController().getScene()
|
||||
renderer = self.getRenderer()
|
||||
|
||||
self._checkSetup()
|
||||
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
if Application.getInstance().getPreferences().getValue("view/show_overhang"):
|
||||
|
|
|
@ -239,7 +239,7 @@ class VersionUpgrade41to42(VersionUpgrade):
|
|||
#
|
||||
# This renames the renamed settings in the containers.
|
||||
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
|
||||
parser = configparser.ConfigParser(interpolation = None, comment_prefixes=())
|
||||
parser = configparser.ConfigParser(interpolation = None, comment_prefixes = ())
|
||||
parser.read_string(serialized)
|
||||
|
||||
# Update version number.
|
||||
|
|
|
@ -104,7 +104,7 @@ class VersionUpgrade42to43(VersionUpgrade):
|
|||
#
|
||||
# This renames the renamed settings in the containers.
|
||||
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
|
||||
parser = configparser.ConfigParser(interpolation = None, comment_prefixes=())
|
||||
parser = configparser.ConfigParser(interpolation = None, comment_prefixes = ())
|
||||
parser.read_string(serialized)
|
||||
|
||||
# Update version number.
|
||||
|
|
|
@ -52,7 +52,7 @@ class VersionUpgrade43to44(VersionUpgrade):
|
|||
#
|
||||
# This renames the renamed settings in the containers.
|
||||
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
|
||||
parser = configparser.ConfigParser(interpolation = None, comment_prefixes=())
|
||||
parser = configparser.ConfigParser(interpolation = None, comment_prefixes = ())
|
||||
parser.read_string(serialized)
|
||||
|
||||
# Update version number.
|
||||
|
|
|
@ -3,10 +3,17 @@ from typing import Tuple, List
|
|||
import io
|
||||
from UM.VersionUpgrade import VersionUpgrade
|
||||
|
||||
# Merged preferences: machine_head_polygon and machine_head_with_fans_polygon -> machine_head_with_fans_polygon
|
||||
# When both are present, machine_head_polygon will be removed
|
||||
# When only one of the two is present, it's value will be used
|
||||
# Settings that were merged into one. Each one is a pair of settings. If both
|
||||
# are overwritten, the key wins. If only the key or the value is overwritten,
|
||||
# that value is used in the key.
|
||||
_merged_settings = {
|
||||
"machine_head_with_fans_polygon": "machine_head_polygon",
|
||||
"support_wall_count": "support_tree_wall_count"
|
||||
}
|
||||
|
||||
_removed_settings = {
|
||||
"support_tree_wall_thickness"
|
||||
}
|
||||
|
||||
class VersionUpgrade44to45(VersionUpgrade):
|
||||
def getCfgVersion(self, serialised: str) -> int:
|
||||
|
@ -35,20 +42,26 @@ class VersionUpgrade44to45(VersionUpgrade):
|
|||
#
|
||||
# This renames the renamed settings in the containers.
|
||||
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
|
||||
parser = configparser.ConfigParser(interpolation = None, comment_prefixes=())
|
||||
parser = configparser.ConfigParser(interpolation = None, comment_prefixes = ())
|
||||
parser.read_string(serialized)
|
||||
|
||||
# Update version number.
|
||||
parser["metadata"]["setting_version"] = "11"
|
||||
|
||||
if "values" in parser:
|
||||
# merge machine_head_with_fans_polygon (preferred) and machine_head_polygon
|
||||
if "machine_head_with_fans_polygon" in parser["values"]:
|
||||
if "machine_head_polygon" in parser["values"]:
|
||||
del parser["values"]["machine_head_polygon"]
|
||||
elif "machine_head_polygon" in parser["values"]:
|
||||
parser["values"]["machine_head_with_fans_polygon"] = parser["values"]["machine_head_polygon"]
|
||||
del parser["values"]["machine_head_polygon"]
|
||||
# Merged settings: When two settings are merged, one is preferred.
|
||||
# If the preferred one is available, that value is taken regardless
|
||||
# of the other one. If only the non-preferred one is available, that
|
||||
# value is moved to the preferred setting value.
|
||||
for preferred, removed in _merged_settings.items():
|
||||
if removed in parser["values"]:
|
||||
if preferred not in parser["values"]:
|
||||
parser["values"][preferred] = parser["values"][removed]
|
||||
del parser["values"][removed]
|
||||
|
||||
for removed in _removed_settings:
|
||||
if removed in parser["values"]:
|
||||
del parser["values"][removed]
|
||||
|
||||
result = io.StringIO()
|
||||
parser.write(result)
|
||||
|
|
|
@ -1106,6 +1106,12 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
"break preparation speed": "material_break_preparation_speed",
|
||||
"break preparation temperature": "material_break_preparation_temperature",
|
||||
"break position": "material_break_retracted_position",
|
||||
"flush purge speed": "material_flush_purge_speed",
|
||||
"flush purge length": "material_flush_purge_length",
|
||||
"end of filament purge speed": "material_end_of_filament_purge_speed",
|
||||
"end of filament purge length": "material_end_of_filament_purge_length",
|
||||
"maximum park duration": "material_maximum_park_duration",
|
||||
"no load move factor": "material_no_load_move_factor",
|
||||
"break speed": "material_break_speed",
|
||||
"break temperature": "material_break_temperature"
|
||||
} # type: Dict[str, str]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue