diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py
index 59c4f4fa5b..a01cc1194f 100644
--- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py
+++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py
@@ -6,10 +6,10 @@ from PyQt5.QtCore import Qt
from UM.Application import Application
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
+from UM.Settings.SettingFunction import SettingFunction
from cura.Machines.QualityManager import QualityGroup
-
#
# QML Model for all built-in quality profiles. This model is used for the drop-down quality menu.
#
@@ -106,4 +106,8 @@ class QualityProfilesDropDownMenuModel(ListModel):
container = global_stack.definition
if container and container.hasProperty("layer_height", "value"):
layer_height = container.getProperty("layer_height", "value")
+
+ if isinstance(layer_height, SettingFunction):
+ layer_height = layer_height(global_stack)
+
return float(layer_height)
diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py
index cb2776429f..6869d99bc7 100644
--- a/cura/Machines/QualityManager.py
+++ b/cura/Machines/QualityManager.py
@@ -363,8 +363,19 @@ class QualityManager(QObject):
@pyqtSlot(QObject)
def removeQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup"):
Logger.log("i", "Removing quality changes group [%s]", quality_changes_group.name)
+ removed_quality_changes_ids = set()
for node in quality_changes_group.getAllNodes():
- self._container_registry.removeContainer(node.getMetaDataEntry("id"))
+ container_id = node.getMetaDataEntry("id")
+ self._container_registry.removeContainer(container_id)
+ removed_quality_changes_ids.add(container_id)
+
+ # Reset all machines that have activated this quality changes to empty.
+ for global_stack in self._container_registry.findContainerStacks(type = "machine"):
+ if global_stack.qualityChanges.getId() in removed_quality_changes_ids:
+ global_stack.qualityChanges = self._empty_quality_changes_container
+ for extruder_stack in self._container_registry.findContainerStacks(type = "extruder_train"):
+ if extruder_stack.qualityChanges.getId() in removed_quality_changes_ids:
+ extruder_stack.qualityChanges = self._empty_quality_changes_container
#
# Rename a set of quality changes containers. Returns the new name.
diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml
index 04b055ed66..90b92bd832 100644
--- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml
+++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml
@@ -82,9 +82,16 @@ Item
}
spacing: Math.floor(UM.Theme.getSize("narrow_margin").height)
width: childrenRect.width
+
Label
{
- text: catalog.i18nc("@label", "Contact") + ":"
+ text: catalog.i18nc("@label", "Website") + ":"
+ font: UM.Theme.getFont("very_small")
+ color: UM.Theme.getColor("text_medium")
+ }
+ Label
+ {
+ text: catalog.i18nc("@label", "Email") + ":"
font: UM.Theme.getFont("very_small")
color: UM.Theme.getColor("text_medium")
}
@@ -100,18 +107,32 @@ Item
topMargin: UM.Theme.getSize("default_margin").height
}
spacing: Math.floor(UM.Theme.getSize("narrow_margin").height)
+
+ Label
+ {
+ text:
+ {
+ if (details.website)
+ {
+ return "" + details.website + ""
+ }
+ return ""
+ }
+ font: UM.Theme.getFont("very_small")
+ color: UM.Theme.getColor("text")
+ linkColor: UM.Theme.getColor("text_link")
+ onLinkActivated: Qt.openUrlExternally(link)
+ }
+
Label
{
text:
{
if (details.email)
{
- return ""+details.name+""
- }
- else
- {
- return ""+details.name+""
+ return "" + details.email + ""
}
+ return ""
}
font: UM.Theme.getFont("very_small")
color: UM.Theme.getColor("text")
diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml
index 1efcde2110..4a008f2a83 100644
--- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml
+++ b/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml
@@ -8,7 +8,18 @@ import UM 1.1 as UM
Item
{
+ id: base
+
property var packageData
+ property var technicalDataSheetUrl: {
+ var link = undefined
+ if ("Technical Data Sheet" in packageData.links)
+ {
+ link = packageData.links["Technical Data Sheet"]
+ }
+ return link
+ }
+
anchors.topMargin: UM.Theme.getSize("default_margin").height
height: visible ? childrenRect.height : 0
visible: packageData.type == "material" && packageData.has_configs
@@ -132,4 +143,25 @@ Item
width: Math.floor(table.width * 0.1)
}
}
+
+ Label
+ {
+ id: technical_data_sheet
+ anchors.top: table.bottom
+ anchors.topMargin: UM.Theme.getSize("default_margin").height / 2
+ visible: base.technicalDataSheetUrl !== undefined
+ text:
+ {
+ if (base.technicalDataSheetUrl !== undefined)
+ {
+ return "%2".arg(base.technicalDataSheetUrl).arg("Technical Data Sheet")
+ }
+ return ""
+ }
+ font: UM.Theme.getFont("very_small")
+ color: UM.Theme.getColor("text")
+ linkColor: UM.Theme.getColor("text_link")
+ onLinkActivated: Qt.openUrlExternally(link)
+ }
+
}
diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml
index ebd4c006f8..4366db041c 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml
+++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml
@@ -9,7 +9,7 @@ import UM 1.1 as UM
Item
{
- property int packageCount: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getTotalNumberOfPackagesByAuthor(model.id) : 1
+ property int packageCount: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getTotalNumberOfMaterialPackagesByAuthor(model.id) : 1
property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
height: childrenRect.height
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml
index 1089fcc51e..bcca02583d 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml
+++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml
@@ -30,7 +30,7 @@ ScrollView
id: allPlugins
width: parent.width
heading: toolbox.viewCategory == "material" ? catalog.i18nc("@label", "Community Contributions") : catalog.i18nc("@label", "Community Plugins")
- model: toolbox.viewCategory == "material" ? toolbox.authorsModel : toolbox.packagesModel
+ model: toolbox.viewCategory == "material" ? toolbox.materialsAvailableModel : toolbox.pluginsAvailableModel
}
ToolboxDownloadsGrid
diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml
index 15d1ae302c..845bbe8f91 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml
+++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml
@@ -9,7 +9,7 @@ import UM 1.1 as UM
Rectangle
{
- property int packageCount: toolbox.viewCategory == "material" ? toolbox.getTotalNumberOfPackagesByAuthor(model.id) : 1
+ property int packageCount: toolbox.viewCategory == "material" ? toolbox.getTotalNumberOfMaterialPackagesByAuthor(model.id) : 1
property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
id: tileBase
width: UM.Theme.getSize("toolbox_thumbnail_large").width + (2 * UM.Theme.getSize("default_lining").width)
diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py
index 8b9199b127..7892044d00 100644
--- a/plugins/Toolbox/src/PackagesModel.py
+++ b/plugins/Toolbox/src/PackagesModel.py
@@ -5,9 +5,13 @@ import re
from typing import Dict
from PyQt5.QtCore import Qt, pyqtProperty
+
+from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
+
from .ConfigsModel import ConfigsModel
+
## Model that holds cura packages. By setting the filter property the instances held by this model can be changed.
class PackagesModel(ListModel):
def __init__(self, parent = None):
@@ -34,6 +38,8 @@ class PackagesModel(ListModel):
self.addRoleName(Qt.UserRole + 17, "supported_configs")
self.addRoleName(Qt.UserRole + 18, "download_count")
self.addRoleName(Qt.UserRole + 19, "tags")
+ self.addRoleName(Qt.UserRole + 20, "links")
+ self.addRoleName(Qt.UserRole + 21, "website")
# List of filters for queries. The result is the union of the each list of results.
self._filter = {} # type: Dict[str, str]
@@ -45,10 +51,16 @@ class PackagesModel(ListModel):
def _update(self):
items = []
- for package in self._metadata:
+ if self._metadata is None:
+ Logger.logException("w", "Failed to load packages for Toolbox")
+ self.setItems(items)
+ return
+ for package in self._metadata:
has_configs = False
configs_model = None
+
+ links_dict = {}
if "data" in package:
if "supported_configs" in package["data"]:
if len(package["data"]["supported_configs"]) > 0:
@@ -56,41 +68,48 @@ class PackagesModel(ListModel):
configs_model = ConfigsModel()
configs_model.setConfigs(package["data"]["supported_configs"])
+ # Links is a list of dictionaries with "title" and "url". Convert this list into a dict so it's easier
+ # to process.
+ link_list = package['data']['links'] if 'links' in package['data'] else []
+ links_dict = {d["title"]: d["url"] for d in link_list}
+
if "author_id" not in package["author"] or "display_name" not in package["author"]:
package["author"]["author_id"] = ""
package["author"]["display_name"] = ""
# raise Exception("Detected a package with malformed author data.")
items.append({
- "id": package["package_id"],
- "type": package["package_type"],
- "name": package["display_name"],
- "version": package["package_version"],
- "author_id": package["author"]["author_id"],
- "author_name": package["author"]["display_name"],
- "author_email": package["author"]["email"] if "email" in package["author"] else None,
- "description": package["description"] if "description" in package else None,
- "icon_url": package["icon_url"] if "icon_url" in package else None,
- "image_urls": package["image_urls"] if "image_urls" in package else None,
- "download_url": package["download_url"] if "download_url" in package else None,
- "last_updated": package["last_updated"] if "last_updated" in package else None,
- "is_bundled": package["is_bundled"] if "is_bundled" in package else False,
- "is_active": package["is_active"] if "is_active" in package else False,
- "is_installed": package["is_installed"] if "is_installed" in package else False,
- "has_configs": has_configs,
- "supported_configs": configs_model,
- "download_count": package["download_count"] if "download_count" in package else 0,
- "tags": package["tags"] if "tags" in package else []
+ "id": package["package_id"],
+ "type": package["package_type"],
+ "name": package["display_name"],
+ "version": package["package_version"],
+ "author_id": package["author"]["author_id"],
+ "author_name": package["author"]["display_name"],
+ "author_email": package["author"]["email"] if "email" in package["author"] else None,
+ "description": package["description"] if "description" in package else None,
+ "icon_url": package["icon_url"] if "icon_url" in package else None,
+ "image_urls": package["image_urls"] if "image_urls" in package else None,
+ "download_url": package["download_url"] if "download_url" in package else None,
+ "last_updated": package["last_updated"] if "last_updated" in package else None,
+ "is_bundled": package["is_bundled"] if "is_bundled" in package else False,
+ "is_active": package["is_active"] if "is_active" in package else False,
+ "is_installed": package["is_installed"] if "is_installed" in package else False,
+ "has_configs": has_configs,
+ "supported_configs": configs_model,
+ "download_count": package["download_count"] if "download_count" in package else 0,
+ "tags": package["tags"] if "tags" in package else [],
+ "links": links_dict,
+ "website": package["website"] if "website" in package else None,
})
# Filter on all the key-word arguments.
for key, value in self._filter.items():
if key is "tags":
- key_filter = lambda item, value = value: value in item["tags"]
+ key_filter = lambda item, v = value: v in item["tags"]
elif "*" in value:
- key_filter = lambda candidate, key = key, value = value: self._matchRegExp(candidate, key, value)
+ key_filter = lambda candidate, k = key, v = value: self._matchRegExp(candidate, k, v)
else:
- key_filter = lambda candidate, key = key, value = value: self._matchString(candidate, key, value)
+ key_filter = lambda candidate, k = key, v = value: self._matchString(candidate, k, v)
items = filter(key_filter, items)
# Execute all filters.
diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py
index c4205b8ed5..00864c6b4e 100644
--- a/plugins/Toolbox/src/Toolbox.py
+++ b/plugins/Toolbox/src/Toolbox.py
@@ -83,7 +83,7 @@ class Toolbox(QObject, Extension):
"plugins_available": PackagesModel(self),
"plugins_installed": PackagesModel(self),
"materials_showcase": AuthorsModel(self),
- "materials_available": PackagesModel(self),
+ "materials_available": AuthorsModel(self),
"materials_installed": PackagesModel(self),
"materials_generic": PackagesModel(self)
} # type: Dict[str, ListModel]
@@ -514,12 +514,14 @@ class Toolbox(QObject, Extension):
count += 1
return count
+ # This slot is only used to get the number of material packages by author, not any other type of packages.
@pyqtSlot(str, result = int)
- def getTotalNumberOfPackagesByAuthor(self, author_id: str) -> int:
+ def getTotalNumberOfMaterialPackagesByAuthor(self, author_id: str) -> int:
count = 0
- for package in self._metadata["materials_available"]:
- if package["author"]["author_id"] == author_id:
- count += 1
+ for package in self._metadata["packages"]:
+ if package["package_type"] == "material":
+ if package["author"]["author_id"] == author_id:
+ count += 1
return count
@pyqtSlot(str, result = bool)
@@ -606,8 +608,21 @@ class Toolbox(QObject, Extension):
self.resetDownload()
return
+ # HACK: These request are not handled independently at this moment, but together from the "packages" call
+ do_not_handle = [
+ "materials_available",
+ "materials_showcase",
+ "plugins_available",
+ "plugins_showcase",
+ ]
+
if reply.operation() == QNetworkAccessManager.GetOperation:
for type, url in self._request_urls.items():
+
+ # HACK: Do nothing because we'll handle these from the "packages" call
+ if type in do_not_handle:
+ return
+
if reply.url() == url:
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200:
try:
@@ -623,25 +638,16 @@ class Toolbox(QObject, Extension):
if not self._models[type]:
Logger.log("e", "Could not find the %s model.", type)
break
-
- # HACK: Eventually get rid of the code from here...
- if type is "plugins_showcase" or type is "materials_showcase":
- self._metadata["plugins_showcase"] = json_data["data"]["plugin"]["packages"]
- self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"])
- self._metadata["materials_showcase"] = json_data["data"]["material"]["authors"]
- self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"])
- else:
- # ...until here.
- # This hack arises for multiple reasons but the main
- # one is because there are not separate API calls
- # for different kinds of showcases.
- self._metadata[type] = json_data["data"]
- self._models[type].setMetadata(self._metadata[type])
+
+ self._metadata[type] = json_data["data"]
+ self._models[type].setMetadata(self._metadata[type])
# Do some auto filtering
# TODO: Make multiple API calls in the future to handle this
if type is "packages":
self._models[type].setFilter({"type": "plugin"})
+ self.buildMaterialsModels()
+ self.buildPluginsModels()
if type is "authors":
self._models[type].setFilter({"package_types": "material"})
if type is "materials_generic":
@@ -755,6 +761,10 @@ class Toolbox(QObject, Extension):
def pluginsShowcaseModel(self) -> PackagesModel:
return cast(PackagesModel, self._models["plugins_showcase"])
+ @pyqtProperty(QObject, notify = metadataChanged)
+ def pluginsAvailableModel(self) -> PackagesModel:
+ return cast(PackagesModel, self._models["plugins_available"])
+
@pyqtProperty(QObject, notify = metadataChanged)
def pluginsInstalledModel(self) -> PackagesModel:
return cast(PackagesModel, self._models["plugins_installed"])
@@ -763,6 +773,10 @@ class Toolbox(QObject, Extension):
def materialsShowcaseModel(self) -> AuthorsModel:
return cast(AuthorsModel, self._models["materials_showcase"])
+ @pyqtProperty(QObject, notify = metadataChanged)
+ def materialsAvailableModel(self) -> AuthorsModel:
+ return cast(AuthorsModel, self._models["materials_available"])
+
@pyqtProperty(QObject, notify = metadataChanged)
def materialsInstalledModel(self) -> PackagesModel:
return cast(PackagesModel, self._models["materials_installed"])
@@ -798,3 +812,46 @@ class Toolbox(QObject, Extension):
return
self._models[model_type].setFilter({})
self.filterChanged.emit()
+
+
+ # HACK(S):
+ # --------------------------------------------------------------------------
+ def buildMaterialsModels(self) -> None:
+
+ self._metadata["materials_showcase"] = []
+ self._metadata["materials_available"] = []
+
+ processed_authors = [] # type: List[str]
+
+ for item in self._metadata["packages"]:
+ if item["package_type"] == "material":
+
+ author = item["author"]
+ if author["author_id"] in processed_authors:
+ continue
+
+ if "showcase" in item["tags"]:
+ self._metadata["materials_showcase"].append(author)
+ else:
+ self._metadata["materials_available"].append(author)
+
+ processed_authors.append(author["author_id"])
+
+ self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"])
+ self._models["materials_available"].setMetadata(self._metadata["materials_available"])
+
+ def buildPluginsModels(self) -> None:
+
+ self._metadata["plugins_showcase"] = []
+ self._metadata["plugins_available"] = []
+
+ for item in self._metadata["packages"]:
+ if item["package_type"] == "plugin":
+
+ if "showcase" in item["tags"]:
+ self._metadata["plugins_showcase"].append(item)
+ else:
+ self._metadata["plugins_available"].append(item)
+
+ self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"])
+ self._models["plugins_available"].setMetadata(self._metadata["plugins_available"])
diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py
index 45b566fcab..4ceda52875 100644
--- a/plugins/USBPrinting/USBPrinterOutputDevice.py
+++ b/plugins/USBPrinting/USBPrinterOutputDevice.py
@@ -326,7 +326,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
if self._firmware_name is None:
self.sendCommand("M115")
- if (b"ok " in line and b"T:" in line) or b"ok T:" in line or line.startswith(b"T:") or b"ok B:" in line or line.startswith(b"B:"): # Temperature message. 'T:' for extruder and 'B:' for bed
+ if (b"ok " in line and b"T:" in line) or line.startswith(b"T:") or b"ok B:" in line or line.startswith(b"B:"): # Temperature message. 'T:' for extruder and 'B:' for bed
extruder_temperature_matches = re.findall(b"T(\d*): ?([\d\.]+) ?\/?([\d\.]+)?", line)
# Update all temperature values
matched_extruder_nrs = []
diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json
index ca0e66ada2..90a86433fb 100644
--- a/resources/definitions/bq_hephestos_2.def.json
+++ b/resources/definitions/bq_hephestos_2.def.json
@@ -17,8 +17,8 @@
"overrides": {
"machine_name": { "default_value": "BQ Hephestos 2" },
- "machine_start_gcode": { "default_value": "; -- START GCODE --\nM104 S{material_print_temperature} ; Heat up extruder while leveling\nM800 ; Custom GCODE to fire start print procedure\nM109 S{material_print_temperature} ; Makes sure the temperature is correct before printing\n; -- end of START GCODE --" },
- "machine_end_gcode": { "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" },
+ "machine_start_gcode": { "default_value": "; -- START GCODE --\nM104 S{material_print_temperature}\nG28 ; Zero-ing position\nG29 ; Auto bed-leveling\nG0 X4 Y297 Z15 F4000 ; Fast move to BQ's start position\nG90 ; Set to Absolute Positioning\nG92 E0 ; Reset extruder 0\nG1 F1800 ; Set default feedrate\nM109 S{material_print_temperature} ; Makes sure the temperature is correct before printing\n; -- end of START GCODE --" },
+ "machine_end_gcode": { "default_value": "; -- END GCODE --\nM801 ; Marlin G-CODE to fire end print procedure\n; -- end of END GCODE --" },
"machine_width": { "default_value": 210 },
"machine_depth": { "default_value": 297 },
"machine_height": { "default_value": 220 },
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index 610ee1473e..a85a251ac2 100644
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -3875,6 +3875,19 @@
}
}
},
+ "support_infill_angle":
+ {
+ "label": "Support Infill Line Direction",
+ "description": "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane.",
+ "unit": "°",
+ "type": "float",
+ "minimum_value": "-180",
+ "maximum_value": "180",
+ "default_value": 0,
+ "enabled": "support_enable and support_pattern != 'concentric' and support_infill_rate > 0",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
"support_z_distance":
{
"label": "Support Z Distance",
diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml
index d5572298f7..db230ebca7 100644
--- a/resources/qml/Actions.qml
+++ b/resources/qml/Actions.qml
@@ -138,7 +138,7 @@ Item
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);
}
@@ -236,16 +236,6 @@ Item
onTriggered: CuraActions.deleteSelection();
}
- 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)
- enabled: UM.Controller.toolsEnabled && UM.Selection.hasSelection
- iconName: "edit-delete"
- shortcut: StandardKey.Backspace
- onTriggered: CuraActions.deleteSelection()
- }
-
Action
{
id: centerSelectionAction;
@@ -338,7 +328,7 @@ Item
Action
{
id: deleteAllAction;
- text: catalog.i18nc("@action:inmenu menubar:edit","&Clear Build Plate");
+ text: catalog.i18nc("@action:inmenu menubar:edit","Clear Build Plate");
enabled: UM.Controller.toolsEnabled;
iconName: "edit-delete";
shortcut: "Ctrl+D";
@@ -348,7 +338,7 @@ Item
Action
{
id: reloadAllAction;
- text: catalog.i18nc("@action:inmenu menubar:file","Re&load All Models");
+ text: catalog.i18nc("@action:inmenu menubar:file","Reload All Models");
iconName: "document-revert";
shortcut: "F5"
onTriggered: CuraApplication.reloadAll();
@@ -386,7 +376,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 616523fc45..97742de57a 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/vnd.ms-package.3dmanufacturing-3dmodel+xml" };
diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg
index 544728f8a4..d9d982ef11 100644
--- a/resources/variants/ultimaker2_plus_0.4.inst.cfg
+++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg
@@ -12,5 +12,5 @@ hardware_type = nozzle
machine_nozzle_size = 0.4
machine_nozzle_tip_outer_diameter = 1.05
speed_wall = =round(speed_print / 1.25, 1)
-speed_wall_0 = =1 if speed_wall < 10 else (speed_wall - 10)
+speed_wall_0 = =min(speed_wall - 10, 1)
speed_topbottom = =round(speed_print / 2.25, 1)