diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 2f880a9e32..6934354a70 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,33 +1,49 @@
+---
+name: Bug report
+about: Create a report to help us fix issues.
+title: ''
+labels: 'Type: Bug'
+assignees: ''
+
+---
+
-**Application Version**
-
+**Application version**
+(The version of the application this issue occurs with.)
**Platform**
-
+(Information about the operating system the issue occurs on. Include at least the operating system and maybe GPU.)
**Printer**
-
+(Which printer was selected in Cura?)
-**Steps to Reproduce**
-
+**Reproduction steps**
+1. (Something you did.)
+2. (Something you did next.)
-**Actual Results**
-
+**Screenshot(s)**
+(Image showing the problem, perhaps before/after images.)
+
+**Actual results**
+(What happens after the above steps have been followed.)
**Expected results**
-
+(What should happen after the above steps have been followed.)
-**Additional Information**
-
+**Project file**
+(For slicing bugs, provide a project which clearly shows the bug, by going to File->Save. For big files you may need to use WeTransfer or similar file sharing sites.)
+
+**Log file**
+(See https://github.com/Ultimaker/Cura#logging-issues to find the log file to upload, or copy a relevant snippet from it.)
+
+**Additional information**
+(Extra information relevant to the issue.)
diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md
new file mode 100644
index 0000000000..6934354a70
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -0,0 +1,49 @@
+---
+name: Bug report
+about: Create a report to help us fix issues.
+title: ''
+labels: 'Type: Bug'
+assignees: ''
+
+---
+
+
+
+**Application version**
+(The version of the application this issue occurs with.)
+
+**Platform**
+(Information about the operating system the issue occurs on. Include at least the operating system and maybe GPU.)
+
+**Printer**
+(Which printer was selected in Cura?)
+
+**Reproduction steps**
+1. (Something you did.)
+2. (Something you did next.)
+
+**Screenshot(s)**
+(Image showing the problem, perhaps before/after images.)
+
+**Actual results**
+(What happens after the above steps have been followed.)
+
+**Expected results**
+(What should happen after the above steps have been followed.)
+
+**Project file**
+(For slicing bugs, provide a project which clearly shows the bug, by going to File->Save. For big files you may need to use WeTransfer or similar file sharing sites.)
+
+**Log file**
+(See https://github.com/Ultimaker/Cura#logging-issues to find the log file to upload, or copy a relevant snippet from it.)
+
+**Additional information**
+(Extra information relevant to the issue.)
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000000..a10d664a04
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,23 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: 'Type: New Feature'
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+(A clear and concise description of what the problem is. Ex. I'm always frustrated when [...])
+
+**Describe the solution you'd like**
+(A clear and concise description of what you want to happen. If possible, describe why you think this is a good solution.)
+
+**Describe alternatives you've considered**
+(A clear and concise description of any alternative solutions or features you've considered. Again, if possible, think about why these alternatives are not working out.)
+
+**Affected users and/or printers**
+(Who do you think will benefit from this? Is everyone going to benefit from these changes? Or specific kinds of users?)
+
+**Additional context**
+(Add any other context or screenshots about the feature request here.)
diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml
new file mode 100644
index 0000000000..3a0b57d714
--- /dev/null
+++ b/.github/workflows/cicd.yml
@@ -0,0 +1,13 @@
+---
+name: CI/CD
+on: [push, pull_request]
+jobs:
+ build:
+ name: Build and test
+ runs-on: ubuntu-latest
+ container: ultimaker/cura-build-environment
+ steps:
+ - name: Checkout master
+ uses: actions/checkout@v1.2.0
+ - name: Build and test
+ run: docker/build.sh
diff --git a/.gitignore b/.gitignore
index 60b59e6829..eed686fda7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,7 +35,7 @@ cura.desktop
.pydevproject
.settings
-#Externally located plug-ins.
+#Externally located plug-ins commonly installed by our devs.
plugins/cura-big-flame-graph
plugins/cura-god-mode-plugin
plugins/cura-siemensnx-plugin
@@ -52,6 +52,7 @@ plugins/FlatProfileExporter
plugins/GodMode
plugins/OctoPrintPlugin
plugins/ProfileFlattener
+plugins/SettingsGuide
plugins/X3GWriter
#Build stuff
@@ -71,3 +72,7 @@ run.sh
.scannerwork/
CuraEngine
+/.coverage
+
+#Prevents import failures when plugin running tests
+plugins/__init__.py
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000..6c5bc61cbe
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,16 @@
+image: registry.gitlab.com/ultimaker/cura/cura-build-environment:centos7
+
+stages:
+ - build
+
+build and test linux:
+ stage: build
+ tags:
+ - cura
+ - docker
+ - linux
+ script:
+ - docker/build.sh
+ artifacts:
+ paths:
+ - build
diff --git a/CMakeLists.txt b/CMakeLists.txt
index be6c9d938e..4954ac46dc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,11 +1,10 @@
-project(cura NONE)
-cmake_minimum_required(VERSION 2.8.12)
-
-set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/
- ${CMAKE_MODULE_PATH})
+project(cura)
+cmake_minimum_required(VERSION 3.6)
include(GNUInstallDirs)
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
+
set(URANIUM_DIR "${CMAKE_SOURCE_DIR}/../Uranium" CACHE DIRECTORY "The location of the Uranium repository")
set(URANIUM_SCRIPTS_DIR "${URANIUM_DIR}/scripts" CACHE DIRECTORY "The location of the scripts directory of the Uranium repository")
@@ -21,15 +20,36 @@ set(CURA_APP_NAME "cura" CACHE STRING "Short name of Cura, used for configuratio
set(CURA_APP_DISPLAY_NAME "Ultimaker Cura" CACHE STRING "Display name of Cura")
set(CURA_VERSION "master" CACHE STRING "Version name of Cura")
set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'")
-set(CURA_SDK_VERSION "" CACHE STRING "SDK version of Cura")
set(CURA_CLOUD_API_ROOT "" CACHE STRING "Alternative Cura cloud API root")
set(CURA_CLOUD_API_VERSION "" CACHE STRING "Alternative Cura cloud API version")
+set(CURA_CLOUD_ACCOUNT_API_ROOT "" CACHE STRING "Alternative Cura cloud account API version")
configure_file(${CMAKE_SOURCE_DIR}/cura.desktop.in ${CMAKE_BINARY_DIR}/cura.desktop @ONLY)
+
configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY)
+
+# FIXME: Remove the code for CMake <3.12 once we have switched over completely.
+# FindPython3 is a new module since CMake 3.12. It deprecates FindPythonInterp and FindPythonLibs. The FindPython3
+# module is copied from the CMake repository here so in CMake <3.12 we can still use it.
+if(${CMAKE_VERSION} VERSION_LESS 3.12)
+ # Use FindPythonInterp and FindPythonLibs for CMake <3.12
+ find_package(PythonInterp 3 REQUIRED)
+
+ set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
+
+ set(Python3_VERSION ${PYTHON_VERSION_STRING})
+ set(Python3_VERSION_MAJOR ${PYTHON_VERSION_MAJOR})
+ set(Python3_VERSION_MINOR ${PYTHON_VERSION_MINOR})
+ set(Python3_VERSION_PATCH ${PYTHON_VERSION_PATCH})
+else()
+ # Use FindPython3 for CMake >=3.12
+ find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
+endif()
+
+
if(NOT ${URANIUM_DIR} STREQUAL "")
- set(CMAKE_MODULE_PATH "${URANIUM_DIR}/cmake")
+ set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${URANIUM_DIR}/cmake")
endif()
if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "")
list(APPEND CMAKE_MODULE_PATH ${URANIUM_DIR}/cmake)
@@ -40,12 +60,12 @@ if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "")
CREATE_TRANSLATION_TARGETS()
endif()
-find_package(PythonInterp 3.5.0 REQUIRED)
install(DIRECTORY resources
DESTINATION ${CMAKE_INSTALL_DATADIR}/cura)
-install(DIRECTORY plugins
- DESTINATION lib${LIB_SUFFIX}/cura)
+
+include(CuraPluginInstall)
+
if(NOT APPLE AND NOT WIN32)
install(FILES cura_app.py
DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -53,16 +73,16 @@ if(NOT APPLE AND NOT WIN32)
RENAME cura)
if(EXISTS /etc/debian_version)
install(DIRECTORY cura
- DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}/dist-packages
+ DESTINATION lib${LIB_SUFFIX}/python${Python3_VERSION_MAJOR}/dist-packages
FILES_MATCHING PATTERN *.py)
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
- DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}/dist-packages/cura)
+ DESTINATION lib${LIB_SUFFIX}/python${Python3_VERSION_MAJOR}/dist-packages/cura)
else()
install(DIRECTORY cura
- DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
+ DESTINATION lib${LIB_SUFFIX}/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages
FILES_MATCHING PATTERN *.py)
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
- DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/cura)
+ DESTINATION lib${LIB_SUFFIX}/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages/cura)
endif()
install(FILES ${CMAKE_BINARY_DIR}/cura.desktop
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
@@ -78,8 +98,8 @@ else()
DESTINATION ${CMAKE_INSTALL_BINDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(DIRECTORY cura
- DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
+ DESTINATION lib${LIB_SUFFIX}/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages
FILES_MATCHING PATTERN *.py)
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
- DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/cura)
+ DESTINATION lib${LIB_SUFFIX}/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages/cura)
endif()
diff --git a/cmake/CuraPluginInstall.cmake b/cmake/CuraPluginInstall.cmake
new file mode 100644
index 0000000000..d35e74acb8
--- /dev/null
+++ b/cmake/CuraPluginInstall.cmake
@@ -0,0 +1,99 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# CuraPluginInstall.cmake is released under the terms of the LGPLv3 or higher.
+
+#
+# This module detects all plugins that need to be installed and adds them using the CMake install() command.
+# It detects all plugin folder in the path "plugins/*" where there's a "plugin.json" in it.
+#
+# Plugins can be configured to NOT BE INSTALLED via the variable "CURA_NO_INSTALL_PLUGINS" as a list of string in the
+# form of "a;b;c" or "a,b,c". By default all plugins will be installed.
+#
+
+# FIXME: Remove the code for CMake <3.12 once we have switched over completely.
+# FindPython3 is a new module since CMake 3.12. It deprecates FindPythonInterp and FindPythonLibs. The FindPython3
+# module is copied from the CMake repository here so in CMake <3.12 we can still use it.
+if(${CMAKE_VERSION} VERSION_LESS 3.12)
+ # Use FindPythonInterp and FindPythonLibs for CMake <3.12
+ find_package(PythonInterp 3 REQUIRED)
+
+ set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
+else()
+ # Use FindPython3 for CMake >=3.12
+ find_package(Python3 REQUIRED COMPONENTS Interpreter)
+endif()
+
+# Options or configuration variables
+set(CURA_NO_INSTALL_PLUGINS "" CACHE STRING "A list of plugins that should not be installed, separated with ';' or ','.")
+
+file(GLOB_RECURSE _plugin_json_list ${CMAKE_SOURCE_DIR}/plugins/*/plugin.json)
+list(LENGTH _plugin_json_list _plugin_json_list_len)
+
+# Sort the lists alphabetically so we can handle cases like this:
+# - plugins/my_plugin/plugin.json
+# - plugins/my_plugin/my_module/plugin.json
+# In this case, only "plugins/my_plugin" should be added via install().
+set(_no_install_plugin_list ${CURA_NO_INSTALL_PLUGINS})
+# Sanitize the string so the comparison will be case-insensitive.
+string(STRIP "${_no_install_plugin_list}" _no_install_plugin_list)
+string(TOLOWER "${_no_install_plugin_list}" _no_install_plugin_list)
+
+# WORKAROUND counterpart of what's in cura-build.
+string(REPLACE "," ";" _no_install_plugin_list "${_no_install_plugin_list}")
+
+list(LENGTH _no_install_plugin_list _no_install_plugin_list_len)
+
+if(_no_install_plugin_list_len GREATER 0)
+ list(SORT _no_install_plugin_list)
+endif()
+if(_plugin_json_list_len GREATER 0)
+ list(SORT _plugin_json_list)
+endif()
+
+# Check all plugin directories and add them via install() if needed.
+set(_install_plugin_list "")
+foreach(_plugin_json_path ${_plugin_json_list})
+ get_filename_component(_plugin_dir ${_plugin_json_path} DIRECTORY)
+ file(RELATIVE_PATH _rel_plugin_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_plugin_dir})
+ get_filename_component(_plugin_dir_name ${_plugin_dir} NAME)
+
+ # Make plugin name comparison case-insensitive
+ string(TOLOWER "${_plugin_dir_name}" _plugin_dir_name_lowercase)
+
+ # Check if this plugin needs to be skipped for installation
+ set(_add_plugin ON) # Indicates if this plugin should be added to the build or not.
+ set(_is_no_install_plugin OFF) # If this plugin will not be added, this indicates if it's because the plugin is
+ # specified in the NO_INSTALL_PLUGINS list.
+ if(_no_install_plugin_list)
+ if("${_plugin_dir_name_lowercase}" IN_LIST _no_install_plugin_list)
+ set(_add_plugin OFF)
+ set(_is_no_install_plugin ON)
+ endif()
+ endif()
+
+ # Make sure this is not a subdirectory in a plugin that's already in the install list
+ if(_add_plugin)
+ foreach(_known_install_plugin_dir ${_install_plugin_list})
+ if(_plugin_dir MATCHES "${_known_install_plugin_dir}.+")
+ set(_add_plugin OFF)
+ break()
+ endif()
+ endforeach()
+ endif()
+
+ if(_add_plugin)
+ message(STATUS "[+] PLUGIN TO INSTALL: ${_rel_plugin_dir}")
+ get_filename_component(_rel_plugin_parent_dir ${_rel_plugin_dir} DIRECTORY)
+ install(DIRECTORY ${_rel_plugin_dir}
+ DESTINATION lib${LIB_SUFFIX}/cura/${_rel_plugin_parent_dir}
+ PATTERN "__pycache__" EXCLUDE
+ PATTERN "*.qmlc" EXCLUDE
+ )
+ list(APPEND _install_plugin_list ${_plugin_dir})
+ elseif(_is_no_install_plugin)
+ message(STATUS "[-] PLUGIN TO REMOVE : ${_rel_plugin_dir}")
+ execute_process(COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_bundled_packages_json.py
+ -d ${CMAKE_CURRENT_SOURCE_DIR}/resources/bundled_packages
+ ${_plugin_dir_name}
+ RESULT_VARIABLE _mod_json_result)
+ endif()
+endforeach()
diff --git a/cmake/CuraTests.cmake b/cmake/CuraTests.cmake
index b6d04de036..b1d3e0ddc4 100644
--- a/cmake/CuraTests.cmake
+++ b/cmake/CuraTests.cmake
@@ -1,10 +1,21 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-enable_testing()
+include(CTest)
include(CMakeParseArguments)
-find_package(PythonInterp 3.5.0 REQUIRED)
+# FIXME: Remove the code for CMake <3.12 once we have switched over completely.
+# FindPython3 is a new module since CMake 3.12. It deprecates FindPythonInterp and FindPythonLibs. The FindPython3
+# module is copied from the CMake repository here so in CMake <3.12 we can still use it.
+if(${CMAKE_VERSION} VERSION_LESS 3.12)
+ # Use FindPythonInterp and FindPythonLibs for CMake <3.12
+ find_package(PythonInterp 3 REQUIRED)
+
+ set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
+else()
+ # Use FindPython3 for CMake >=3.12
+ find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
+endif()
add_custom_target(test-verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose)
@@ -36,7 +47,7 @@ function(cura_add_test)
if (NOT ${test_exists})
add_test(
NAME ${_NAME}
- COMMAND ${PYTHON_EXECUTABLE} -m pytest --verbose --full-trace --capture=no --no-print-log --junitxml=${CMAKE_BINARY_DIR}/junit-${_NAME}.xml ${_DIRECTORY}
+ COMMAND ${Python3_EXECUTABLE} -m pytest --junitxml=${CMAKE_BINARY_DIR}/junit-${_NAME}.xml ${_DIRECTORY}
)
set_tests_properties(${_NAME} PROPERTIES ENVIRONMENT LANG=C)
set_tests_properties(${_NAME} PROPERTIES ENVIRONMENT "PYTHONPATH=${_PYTHONPATH}")
@@ -59,13 +70,13 @@ endforeach()
#Add code style test.
add_test(
NAME "code-style"
- COMMAND ${PYTHON_EXECUTABLE} run_mypy.py
+ COMMAND ${Python3_EXECUTABLE} run_mypy.py
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
#Add test for whether the shortcut alt-keys are unique in every translation.
add_test(
NAME "shortcut-keys"
- COMMAND ${PYTHON_EXECUTABLE} scripts/check_shortcut_keys.py
+ COMMAND ${Python3_EXECUTABLE} scripts/check_shortcut_keys.py
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-)
\ No newline at end of file
+)
diff --git a/cmake/mod_bundled_packages_json.py b/cmake/mod_bundled_packages_json.py
new file mode 100755
index 0000000000..6423591f57
--- /dev/null
+++ b/cmake/mod_bundled_packages_json.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+#
+# This script removes the given package entries in the bundled_packages JSON files. This is used by the PluginInstall
+# CMake module.
+#
+
+import argparse
+import collections
+import json
+import os
+import sys
+
+
+## Finds all JSON files in the given directory recursively and returns a list of those files in absolute paths.
+#
+# \param work_dir The directory to look for JSON files recursively.
+# \return A list of JSON files in absolute paths that are found in the given directory.
+def find_json_files(work_dir: str) -> list:
+ json_file_list = []
+ for root, dir_names, file_names in os.walk(work_dir):
+ for file_name in file_names:
+ abs_path = os.path.abspath(os.path.join(root, file_name))
+ json_file_list.append(abs_path)
+ return json_file_list
+
+
+## Removes the given entries from the given JSON file. The file will modified in-place.
+#
+# \param file_path The JSON file to modify.
+# \param entries A list of strings as entries to remove.
+# \return None
+def remove_entries_from_json_file(file_path: str, entries: list) -> None:
+ try:
+ with open(file_path, "r", encoding = "utf-8") as f:
+ package_dict = json.load(f, object_hook = collections.OrderedDict)
+ except Exception as e:
+ msg = "Failed to load '{file_path}' as a JSON file. This file will be ignored Exception: {e}"\
+ .format(file_path = file_path, e = e)
+ sys.stderr.write(msg + os.linesep)
+ return
+
+ for entry in entries:
+ if entry in package_dict:
+ del package_dict[entry]
+ print("[INFO] Remove entry [{entry}] from [{file_path}]".format(file_path = file_path, entry = entry))
+
+ try:
+ with open(file_path, "w", encoding = "utf-8", newline = "\n") as f:
+ json.dump(package_dict, f, indent = 4)
+ except Exception as e:
+ msg = "Failed to write '{file_path}' as a JSON file. Exception: {e}".format(file_path = file_path, e = e)
+ raise IOError(msg)
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser("mod_bundled_packages_json")
+ parser.add_argument("-d", "--dir", dest = "work_dir",
+ help = "The directory to look for bundled packages JSON files, recursively.")
+ parser.add_argument("entries", metavar = "ENTRIES", type = str, nargs = "+")
+
+ args = parser.parse_args()
+
+ json_file_list = find_json_files(args.work_dir)
+ for json_file_path in json_file_list:
+ remove_entries_from_json_file(json_file_path, args.entries)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/contributing.md b/contributing.md
new file mode 100644
index 0000000000..06f9dd472b
--- /dev/null
+++ b/contributing.md
@@ -0,0 +1,19 @@
+Submitting bug reports
+----------------------
+Please submit bug reports for all of Cura and CuraEngine to the [Cura repository](https://github.com/Ultimaker/Cura/issues). There will be a template there to fill in. Depending on the type of issue, we will usually ask for the [Cura log](Logging Issues) or a project file.
+
+If a bug report would contain private information, such as a proprietary 3D model, you may also e-mail us. Ask for contact information in the issue.
+
+Bugs related to supporting certain types of printers can usually not be solved by the Cura maintainers, since we don't have access to every 3D printer model in the world either. We have to rely on external contributors to fix this. If it's something simple and obvious, such as a mistake in the start g-code, then we can directly fix it for you, but e.g. issues with USB cable connectivity are impossible for us to debug.
+
+Requesting features
+-------------------
+The issue template in the Cura repository does not apply to feature requests. You can ignore it.
+
+When requesting a feature, please describe clearly what you need and why you think this is valuable to users or what problem it solves.
+
+Making pull requests
+--------------------
+If you want to propose a change to Cura's source code, please create a pull request in the appropriate repository (being [Cura](https://github.com/Ultimaker/Cura), [Uranium](https://github.com/Ultimaker/Uranium), [CuraEngine](https://github.com/Ultimaker/CuraEngine), [fdm_materials](https://github.com/Ultimaker/fdm_materials), [libArcus](https://github.com/Ultimaker/libArcus), [cura-build](https://github.com/Ultimaker/cura-build), [cura-build-environment](https://github.com/Ultimaker/cura-build-environment), [libSavitar](https://github.com/Ultimaker/libSavitar), [libCharon](https://github.com/Ultimaker/libCharon) or [cura-binary-data](https://github.com/Ultimaker/cura-binary-data)) and if your change requires changes on multiple of these repositories, please link them together so that we know to merge them together.
+
+Some of these repositories will have automated tests running when you create a pull request, indicated by green check marks or red crosses in the Github web page. If you see a red cross, that means that a test has failed. If the test doesn't fail on the Master branch but does fail on your branch, that indicates that you've probably made a mistake and you need to do that. Click on the cross for more details, or run the test locally by running `cmake . && ctest --verbose`.
\ No newline at end of file
diff --git a/cura.desktop.in b/cura.desktop.in
index b0195015a5..1e17e30f4e 100644
--- a/cura.desktop.in
+++ b/cura.desktop.in
@@ -13,6 +13,7 @@ TryExec=@CMAKE_INSTALL_FULL_BINDIR@/cura
Icon=cura-icon
Terminal=false
Type=Application
-MimeType=model/stl;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;image/bmp;image/gif;image/jpeg;image/png;model/x3d+xml;text/x-gcode;
+MimeType=model/stl;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;image/bmp;image/gif;image/jpeg;image/png;text/x-gcode;application/x-amf;application/x-ply;application/x-ctm;model/vnd.collada+xml;model/gltf-binary;model/gltf+json;model/vnd.collada+xml+zip;
Categories=Graphics;
Keywords=3D;Printing;Slicer;
+StartupWMClass=cura.real
diff --git a/cura/API/Account.py b/cura/API/Account.py
index 8a8b708cfa..0e3af0e6c1 100644
--- a/cura/API/Account.py
+++ b/cura/API/Account.py
@@ -29,6 +29,7 @@ i18n_catalog = i18nCatalog("cura")
class Account(QObject):
# Signal emitted when user logged in or out.
loginStateChanged = pyqtSignal(bool)
+ accessTokenChanged = pyqtSignal()
def __init__(self, application: "CuraApplication", parent = None) -> None:
super().__init__(parent)
@@ -59,8 +60,12 @@ class Account(QObject):
self._authorization_service.initialize(self._application.getPreferences())
self._authorization_service.onAuthStateChanged.connect(self._onLoginStateChanged)
self._authorization_service.onAuthenticationError.connect(self._onLoginStateChanged)
+ self._authorization_service.accessTokenChanged.connect(self._onAccessTokenChanged)
self._authorization_service.loadAuthDataFromPreferences()
+ def _onAccessTokenChanged(self):
+ self.accessTokenChanged.emit()
+
## Returns a boolean indicating whether the given authentication is applied against staging or not.
@property
def is_staging(self) -> bool:
@@ -76,6 +81,9 @@ class Account(QObject):
self._error_message.hide()
self._error_message = Message(error_message, title = i18n_catalog.i18nc("@info:title", "Login failed"))
self._error_message.show()
+ self._logged_in = False
+ self.loginStateChanged.emit(False)
+ return
if self._logged_in != logged_in:
self._logged_in = logged_in
@@ -102,7 +110,7 @@ class Account(QObject):
return None
return user_profile.profile_image_url
- @pyqtProperty(str, notify=loginStateChanged)
+ @pyqtProperty(str, notify=accessTokenChanged)
def accessToken(self) -> Optional[str]:
return self._authorization_service.getAccessToken()
diff --git a/cura/ApplicationMetadata.py b/cura/ApplicationMetadata.py
index faa3364e08..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 = "6.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,9 +49,7 @@ try:
except ImportError:
CuraDebugMode = DEFAULT_CURA_DEBUG_MODE
-try:
- from cura.CuraVersion import CuraSDKVersion # type: ignore
- if CuraSDKVersion == "":
- CuraSDKVersion = DEFAULT_CURA_SDK_VERSION
-except ImportError:
- CuraSDKVersion = DEFAULT_CURA_SDK_VERSION
+# 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/Arranging/Arrange.py b/cura/Arranging/Arrange.py
index 32796005c8..caa7aae910 100644
--- a/cura/Arranging/Arrange.py
+++ b/cura/Arranging/Arrange.py
@@ -217,11 +217,6 @@ class Arrange:
prio_slice = self._priority[min_y:max_y, min_x:max_x]
prio_slice[new_occupied] = 999
- # If you want to see how the rasterized arranger build plate looks like, uncomment this code
- # numpy.set_printoptions(linewidth=500, edgeitems=200)
- # print(self._occupied.shape)
- # print(self._occupied)
-
@property
def isEmpty(self):
return self._is_empty
diff --git a/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py b/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py
index 8bbc2bf132..89f613e180 100644
--- a/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py
+++ b/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from UM.Application import Application
@@ -48,7 +48,6 @@ class ArrangeArray:
return self._count
def get(self, index):
- print(self._arrange)
return self._arrange[index]
def getFirstEmpty(self):
diff --git a/cura/Arranging/ShapeArray.py b/cura/Arranging/ShapeArray.py
index 64b78d6f17..403db5e706 100644
--- a/cura/Arranging/ShapeArray.py
+++ b/cura/Arranging/ShapeArray.py
@@ -1,12 +1,19 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
import numpy
import copy
+from typing import Optional, Tuple, TYPE_CHECKING
from UM.Math.Polygon import Polygon
+if TYPE_CHECKING:
+ from UM.Scene.SceneNode import SceneNode
+
## Polygon representation as an array for use with Arrange
class ShapeArray:
- def __init__(self, arr, offset_x, offset_y, scale = 1):
+ def __init__(self, arr: numpy.array, offset_x: float, offset_y: float, scale: float = 1) -> None:
self.arr = arr
self.offset_x = offset_x
self.offset_y = offset_y
@@ -16,7 +23,7 @@ class ShapeArray:
# \param vertices
# \param scale scale the coordinates
@classmethod
- def fromPolygon(cls, vertices, scale = 1):
+ def fromPolygon(cls, vertices: numpy.array, scale: float = 1) -> "ShapeArray":
# scale
vertices = vertices * scale
# flip y, x -> x, y
@@ -42,7 +49,7 @@ class ShapeArray:
# \param min_offset offset for the offset ShapeArray
# \param scale scale the coordinates
@classmethod
- def fromNode(cls, node, min_offset, scale = 0.5, include_children = False):
+ def fromNode(cls, node: "SceneNode", min_offset: float, scale: float = 0.5, include_children: bool = False) -> Tuple[Optional["ShapeArray"], Optional["ShapeArray"]]:
transform = node._transformation
transform_x = transform._data[0][3]
transform_y = transform._data[2][3]
@@ -88,14 +95,16 @@ class ShapeArray:
# \param shape numpy format shape, [x-size, y-size]
# \param vertices
@classmethod
- def arrayFromPolygon(cls, shape, vertices):
+ def arrayFromPolygon(cls, shape: Tuple[int, int], vertices: numpy.array) -> numpy.array:
base_array = numpy.zeros(shape, dtype = numpy.int32) # Initialize your array of zeros
fill = numpy.ones(base_array.shape) * True # Initialize boolean array defining shape fill
# Create check array for each edge segment, combine into fill array
for k in range(vertices.shape[0]):
- fill = numpy.all([fill, cls._check(vertices[k - 1], vertices[k], base_array)], axis=0)
+ check_array = cls._check(vertices[k - 1], vertices[k], base_array)
+ if check_array is not None:
+ fill = numpy.all([fill, check_array], axis=0)
# Set all values inside polygon to one
base_array[fill] = 1
@@ -111,9 +120,9 @@ class ShapeArray:
# \param p2 2-tuple with x, y for point 2
# \param base_array boolean array to project the line on
@classmethod
- def _check(cls, p1, p2, base_array):
+ def _check(cls, p1: numpy.array, p2: numpy.array, base_array: numpy.array) -> Optional[numpy.array]:
if p1[0] == p2[0] and p1[1] == p2[1]:
- return
+ return None
idxs = numpy.indices(base_array.shape) # Create 3D array of indices
p1 = p1.astype(float)
@@ -131,5 +140,4 @@ class ShapeArray:
max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1] - p1[1]) + p1[1]
sign = numpy.sign(p2[0] - p1[0])
- return idxs[1] * sign <= max_col_idx * sign
-
+ return idxs[1] * sign <= max_col_idx * sign
\ No newline at end of file
diff --git a/cura/AutoSave.py b/cura/AutoSave.py
index 1639868d6a..3b42fdafdf 100644
--- a/cura/AutoSave.py
+++ b/cura/AutoSave.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QTimer
@@ -16,9 +16,10 @@ class AutoSave:
self._application.getPreferences().addPreference("cura/autosave_delay", 1000 * 10)
self._change_timer = QTimer()
- self._change_timer.setInterval(self._application.getPreferences().getValue("cura/autosave_delay"))
+ self._change_timer.setInterval(int(self._application.getPreferences().getValue("cura/autosave_delay")))
self._change_timer.setSingleShot(True)
+ self._enabled = True
self._saving = False
def initialize(self):
@@ -32,6 +33,13 @@ class AutoSave:
if not self._saving:
self._change_timer.start()
+ def setEnabled(self, enabled: bool) -> None:
+ self._enabled = enabled
+ if self._enabled:
+ self._change_timer.start()
+ else:
+ self._change_timer.stop()
+
def _onGlobalStackChanged(self):
if self._global_stack:
self._global_stack.propertyChanged.disconnect(self._triggerTimer)
diff --git a/cura/Backups/Backup.py b/cura/Backups/Backup.py
index 714d6527fe..9ccdcaf64d 100644
--- a/cura/Backups/Backup.py
+++ b/cura/Backups/Backup.py
@@ -116,12 +116,13 @@ class Backup:
current_version = self._application.getVersion()
version_to_restore = self.meta_data.get("cura_release", "master")
- if current_version != version_to_restore:
- # Cannot restore version older or newer than current because settings might have changed.
- # Restoring this will cause a lot of issues so we don't allow this for now.
+
+ if current_version < version_to_restore:
+ # Cannot restore version newer than current because settings might have changed.
+ Logger.log("d", "Tried to restore a Cura backup of version {version_to_restore} with cura version {current_version}".format(version_to_restore = version_to_restore, current_version = current_version))
self._showMessage(
self.catalog.i18nc("@info:backup_failed",
- "Tried to restore a Cura backup that does not match your current version."))
+ "Tried to restore a Cura backup that is higher than the current version."))
return False
version_data_dir = Resources.getDataStoragePath()
@@ -147,5 +148,9 @@ class Backup:
Logger.log("d", "Removing current data in location: %s", target_path)
Resources.factoryReset()
Logger.log("d", "Extracting backup to location: %s", target_path)
- archive.extractall(target_path)
+ try:
+ archive.extractall(target_path)
+ except PermissionError:
+ Logger.logException("e", "Unable to extract the backup due to permission errors")
+ return False
return True
diff --git a/cura/Backups/BackupsManager.py b/cura/Backups/BackupsManager.py
index a0d3881209..ba6fcab8d7 100644
--- a/cura/Backups/BackupsManager.py
+++ b/cura/Backups/BackupsManager.py
@@ -51,8 +51,18 @@ class BackupsManager:
## Here we try to disable the auto-save plug-in as it might interfere with
# restoring a back-up.
def _disableAutoSave(self) -> None:
- self._application.setSaveDataEnabled(False)
+ auto_save = self._application.getAutoSave()
+ # The auto save is only not created if the application has not yet started.
+ if auto_save:
+ auto_save.setEnabled(False)
+ else:
+ Logger.log("e", "Unable to disable the autosave as application init has not been completed")
## Re-enable auto-save after we're done.
def _enableAutoSave(self) -> None:
- self._application.setSaveDataEnabled(True)
+ auto_save = self._application.getAutoSave()
+ # The auto save is only not created if the application has not yet started.
+ if auto_save:
+ auto_save.setEnabled(True)
+ else:
+ Logger.log("e", "Unable to enable the autosave as application init has not been completed")
diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py
index 42ef3d942f..aba94e8c60 100755
--- a/cura/BuildVolume.py
+++ b/cura/BuildVolume.py
@@ -1,6 +1,6 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-
+from UM.Mesh.MeshData import MeshData
from cura.Scene.CuraSceneNode import CuraSceneNode
from cura.Settings.ExtruderManager import ExtruderManager
from UM.Application import Application #To modify the maximum zoom level.
@@ -20,13 +20,19 @@ from UM.Signal import Signal
from PyQt5.QtCore import QTimer
from UM.View.RenderBatch import RenderBatch
from UM.View.GL.OpenGL import OpenGL
+from cura.Settings.GlobalStack import GlobalStack
+
catalog = i18nCatalog("cura")
import numpy
import math
-import copy
-from typing import List, Optional
+from typing import List, Optional, TYPE_CHECKING, Any, Set, cast, Iterable, Dict
+
+if TYPE_CHECKING:
+ from cura.CuraApplication import CuraApplication
+ from cura.Settings.ExtruderStack import ExtruderStack
+ from UM.Settings.ContainerStack import ContainerStack
# Radius of disallowed area in mm around prime. I.e. how much distance to keep from prime position.
PRIME_CLEARANCE = 6.5
@@ -36,45 +42,47 @@ PRIME_CLEARANCE = 6.5
class BuildVolume(SceneNode):
raftThicknessChanged = Signal()
- def __init__(self, application, parent = None):
+ def __init__(self, application: "CuraApplication", parent: Optional[SceneNode] = None) -> None:
super().__init__(parent)
self._application = application
self._machine_manager = self._application.getMachineManager()
- self._volume_outline_color = None
- self._x_axis_color = None
- self._y_axis_color = None
- self._z_axis_color = None
- self._disallowed_area_color = None
- self._error_area_color = None
+ self._volume_outline_color = None # type: Optional[Color]
+ self._x_axis_color = None # type: Optional[Color]
+ self._y_axis_color = None # type: Optional[Color]
+ self._z_axis_color = None # type: Optional[Color]
+ self._disallowed_area_color = None # type: Optional[Color]
+ self._error_area_color = None # type: Optional[Color]
- self._width = 0 #type: float
- self._height = 0 #type: float
- self._depth = 0 #type: float
- self._shape = "" #type: str
+ self._width = 0 # type: float
+ self._height = 0 # type: float
+ self._depth = 0 # type: float
+ self._shape = "" # type: str
self._shader = None
- self._origin_mesh = None
+ self._origin_mesh = None # type: Optional[MeshData]
self._origin_line_length = 20
- self._origin_line_width = 0.5
+ self._origin_line_width = 1.5
+ self._enabled = False
- self._grid_mesh = None
+ self._grid_mesh = None # type: Optional[MeshData]
self._grid_shader = None
- self._disallowed_areas = []
- self._disallowed_areas_no_brim = []
- self._disallowed_area_mesh = None
+ self._disallowed_areas = [] # type: List[Polygon]
+ self._disallowed_areas_no_brim = [] # type: List[Polygon]
+ self._disallowed_area_mesh = None # type: Optional[MeshData]
+ self._disallowed_area_size = 0.
- self._error_areas = []
- self._error_mesh = None
+ self._error_areas = [] # type: List[Polygon]
+ self._error_mesh = None # type: Optional[MeshData]
self.setCalculateBoundingBox(False)
- self._volume_aabb = None
+ self._volume_aabb = None # type: Optional[AxisAlignedBox]
self._raft_thickness = 0.0
self._extra_z_clearance = 0.0
- self._adhesion_type = None
+ self._adhesion_type = None # type: Any
self._platform = Platform(self)
self._build_volume_message = Message(catalog.i18nc("@info:status",
@@ -82,7 +90,7 @@ class BuildVolume(SceneNode):
" \"Print Sequence\" setting to prevent the gantry from colliding"
" with printed models."), title = catalog.i18nc("@info:title", "Build Volume"))
- self._global_container_stack = None
+ self._global_container_stack = None # type: Optional[GlobalStack]
self._stack_change_timer = QTimer()
self._stack_change_timer.setInterval(100)
@@ -100,7 +108,7 @@ class BuildVolume(SceneNode):
self._application.getController().getScene().sceneChanged.connect(self._onSceneChanged)
#Objects loaded at the moment. We are connected to the property changed events of these objects.
- self._scene_objects = set()
+ self._scene_objects = set() # type: Set[SceneNode]
self._scene_change_timer = QTimer()
self._scene_change_timer.setInterval(100)
@@ -112,26 +120,22 @@ class BuildVolume(SceneNode):
self._setting_change_timer.setSingleShot(True)
self._setting_change_timer.timeout.connect(self._onSettingChangeTimerFinished)
-
-
# Must be after setting _build_volume_message, apparently that is used in getMachineManager.
# activeQualityChanged is always emitted after setActiveVariant, setActiveMaterial and setActiveQuality.
# Therefore this works.
self._machine_manager.activeQualityChanged.connect(self._onStackChanged)
- # This should also ways work, and it is semantically more correct,
- # but it does not update the disallowed areas after material change
- self._machine_manager.activeStackChanged.connect(self._onStackChanged)
-
# Enable and disable extruder
self._machine_manager.extruderChanged.connect(self.updateNodeBoundaryCheck)
- # list of settings which were updated
- self._changed_settings_since_last_rebuild = []
+ # List of settings which were updated
+ self._changed_settings_since_last_rebuild = [] # type: List[str]
def _onSceneChanged(self, source):
if self._global_container_stack:
- self._scene_change_timer.start()
+ # Ignore anything that is not something we can slice in the first place!
+ if source.callDecoration("isSliceable"):
+ self._scene_change_timer.start()
def _onSceneChangeTimerFinished(self):
root = self._application.getController().getScene().getRoot()
@@ -148,7 +152,7 @@ class BuildVolume(SceneNode):
if active_extruder_changed is not None:
node.callDecoration("getActiveExtruderChangedSignal").disconnect(self._updateDisallowedAreasAndRebuild)
node.decoratorsChanged.disconnect(self._updateNodeListeners)
- self._updateDisallowedAreasAndRebuild() # make sure we didn't miss anything before we updated the node listeners
+ self.rebuild()
self._scene_objects = new_scene_objects
self._onSettingPropertyChanged("print_sequence", "value") # Create fake event, so right settings are triggered.
@@ -165,16 +169,13 @@ class BuildVolume(SceneNode):
active_extruder_changed.connect(self._updateDisallowedAreasAndRebuild)
def setWidth(self, width: float) -> None:
- if width is not None:
- self._width = width
+ self._width = width
def setHeight(self, height: float) -> None:
- if height is not None:
- self._height = height
+ self._height = height
def setDepth(self, depth: float) -> None:
- if depth is not None:
- self._depth = depth
+ self._depth = depth
def setShape(self, shape: str) -> None:
if shape:
@@ -196,7 +197,7 @@ class BuildVolume(SceneNode):
self._disallowed_areas = areas
def render(self, renderer):
- if not self.getMeshData():
+ if not self.getMeshData() or not self.isVisible():
return True
if not self._shader:
@@ -222,13 +223,18 @@ class BuildVolume(SceneNode):
## For every sliceable node, update node._outside_buildarea
#
def updateNodeBoundaryCheck(self):
+ if not self._global_container_stack:
+ return
+
root = self._application.getController().getScene().getRoot()
- nodes = list(BreadthFirstIterator(root))
- group_nodes = []
+ nodes = cast(List[SceneNode], list(cast(Iterable, BreadthFirstIterator(root))))
+ group_nodes = [] # type: List[SceneNode]
build_volume_bounding_box = self.getBoundingBox()
if build_volume_bounding_box:
# It's over 9000!
+ # We set this to a very low number, as we do allow models to intersect the build plate.
+ # This means the model gets cut off at the build plate.
build_volume_bounding_box = build_volume_bounding_box.set(bottom=-9001)
else:
# No bounding box. This is triggered when running Cura from command line with a model for the first time
@@ -241,20 +247,28 @@ class BuildVolume(SceneNode):
group_nodes.append(node) # Keep list of affected group_nodes
if node.callDecoration("isSliceable") or node.callDecoration("isGroup"):
+ if not isinstance(node, CuraSceneNode):
+ continue
+
if node.collidesWithBbox(build_volume_bounding_box):
node.setOutsideBuildArea(True)
continue
- if node.collidesWithArea(self.getDisallowedAreas()):
+ if node.collidesWithAreas(self.getDisallowedAreas()):
+ node.setOutsideBuildArea(True)
+ continue
+ # If the entire node is below the build plate, still mark it as outside.
+ node_bounding_box = node.getBoundingBox()
+ if node_bounding_box and node_bounding_box.top < 0:
node.setOutsideBuildArea(True)
continue
-
# Mark the node as outside build volume if the set extruder is disabled
extruder_position = node.callDecoration("getActiveExtruderPosition")
- if extruder_position not in self._global_container_stack.extruders:
- continue
- if not self._global_container_stack.extruders[extruder_position].isEnabled:
- node.setOutsideBuildArea(True)
+ try:
+ if not self._global_container_stack.extruderList[int(extruder_position)].isEnabled:
+ node.setOutsideBuildArea(True)
+ continue
+ except IndexError:
continue
node.setOutsideBuildArea(False)
@@ -274,8 +288,8 @@ class BuildVolume(SceneNode):
child_node.setOutsideBuildArea(group_node.isOutsideBuildArea())
## Update the outsideBuildArea of a single node, given bounds or current build volume
- def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None):
- if not isinstance(node, CuraSceneNode):
+ def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None) -> None:
+ if not isinstance(node, CuraSceneNode) or self._global_container_stack is None:
return
if bounds is None:
@@ -295,44 +309,55 @@ class BuildVolume(SceneNode):
node.setOutsideBuildArea(True)
return
- if node.collidesWithArea(self.getDisallowedAreas()):
+ if node.collidesWithAreas(self.getDisallowedAreas()):
node.setOutsideBuildArea(True)
return
# Mark the node as outside build volume if the set extruder is disabled
extruder_position = node.callDecoration("getActiveExtruderPosition")
- if not self._global_container_stack.extruders[extruder_position].isEnabled:
+ if not self._global_container_stack.extruderList[int(extruder_position)].isEnabled:
node.setOutsideBuildArea(True)
return
node.setOutsideBuildArea(False)
- ## Recalculates the build volume & disallowed areas.
- def rebuild(self):
- if not self._width or not self._height or not self._depth:
- return
+ def _buildGridMesh(self, min_w: float, max_w: float, min_h: float, max_h: float, min_d: float, max_d:float, z_fight_distance: float) -> MeshData:
+ mb = MeshBuilder()
+ if self._shape != "elliptic":
+ # Build plate grid mesh
+ mb.addQuad(
+ Vector(min_w, min_h - z_fight_distance, min_d),
+ Vector(max_w, min_h - z_fight_distance, min_d),
+ Vector(max_w, min_h - z_fight_distance, max_d),
+ Vector(min_w, min_h - z_fight_distance, max_d)
+ )
- if not self._engine_ready:
- return
+ for n in range(0, 6):
+ v = mb.getVertex(n)
+ mb.setVertexUVCoordinates(n, v[0], v[2])
+ return mb.build()
+ else:
+ aspect = 1.0
+ scale_matrix = Matrix()
+ if self._width != 0:
+ # Scale circular meshes by aspect ratio if width != height
+ aspect = self._depth / self._width
+ scale_matrix.compose(scale=Vector(1, 1, aspect))
+ mb.addVertex(0, min_h - z_fight_distance, 0)
+ mb.addArc(max_w, Vector.Unit_Y, center=Vector(0, min_h - z_fight_distance, 0))
+ sections = mb.getVertexCount() - 1 # Center point is not an arc section
+ indices = []
+ for n in range(0, sections - 1):
+ indices.append([0, n + 2, n + 1])
+ mb.addIndices(numpy.asarray(indices, dtype=numpy.int32))
+ mb.calculateNormals()
- if not self._volume_outline_color:
- theme = self._application.getTheme()
- self._volume_outline_color = Color(*theme.getColor("volume_outline").getRgb())
- self._x_axis_color = Color(*theme.getColor("x_axis").getRgb())
- self._y_axis_color = Color(*theme.getColor("y_axis").getRgb())
- self._z_axis_color = Color(*theme.getColor("z_axis").getRgb())
- self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb())
- self._error_area_color = Color(*theme.getColor("error_area").getRgb())
-
- min_w = -self._width / 2
- max_w = self._width / 2
- min_h = 0.0
- max_h = self._height
- min_d = -self._depth / 2
- max_d = self._depth / 2
-
- z_fight_distance = 0.2 # Distance between buildplate and disallowed area meshes to prevent z-fighting
+ for n in range(0, mb.getVertexCount()):
+ v = mb.getVertex(n)
+ mb.setVertexUVCoordinates(n, v[0], v[2] * aspect)
+ return mb.build().getTransformed(scale_matrix)
+ def _buildMesh(self, min_w: float, max_w: float, min_h: float, max_h: float, min_d: float, max_d:float, z_fight_distance: float) -> MeshData:
if self._shape != "elliptic":
# Outline 'cube' of the build volume
mb = MeshBuilder()
@@ -351,25 +376,10 @@ class BuildVolume(SceneNode):
mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color = self._volume_outline_color)
mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color = self._volume_outline_color)
- self.setMeshData(mb.build())
-
- # Build plate grid mesh
- mb = MeshBuilder()
- mb.addQuad(
- Vector(min_w, min_h - z_fight_distance, min_d),
- Vector(max_w, min_h - z_fight_distance, min_d),
- Vector(max_w, min_h - z_fight_distance, max_d),
- Vector(min_w, min_h - z_fight_distance, max_d)
- )
-
- for n in range(0, 6):
- v = mb.getVertex(n)
- mb.setVertexUVCoordinates(n, v[0], v[2])
- self._grid_mesh = mb.build()
+ return mb.build()
else:
# Bottom and top 'ellipse' of the build volume
- aspect = 1.0
scale_matrix = Matrix()
if self._width != 0:
# Scale circular meshes by aspect ratio if width != height
@@ -378,23 +388,119 @@ class BuildVolume(SceneNode):
mb = MeshBuilder()
mb.addArc(max_w, Vector.Unit_Y, center = (0, min_h - z_fight_distance, 0), color = self._volume_outline_color)
mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0), color = self._volume_outline_color)
- self.setMeshData(mb.build().getTransformed(scale_matrix))
+ return mb.build().getTransformed(scale_matrix)
- # Build plate grid mesh
- mb = MeshBuilder()
- mb.addVertex(0, min_h - z_fight_distance, 0)
- mb.addArc(max_w, Vector.Unit_Y, center = Vector(0, min_h - z_fight_distance, 0))
- sections = mb.getVertexCount() - 1 # Center point is not an arc section
- indices = []
- for n in range(0, sections - 1):
- indices.append([0, n + 2, n + 1])
- mb.addIndices(numpy.asarray(indices, dtype = numpy.int32))
- mb.calculateNormals()
+ def _buildOriginMesh(self, origin: Vector) -> MeshData:
+ mb = MeshBuilder()
+ mb.addCube(
+ width=self._origin_line_length,
+ height=self._origin_line_width,
+ depth=self._origin_line_width,
+ center=origin + Vector(self._origin_line_length / 2, 0, 0),
+ color=self._x_axis_color
+ )
+ mb.addCube(
+ width=self._origin_line_width,
+ height=self._origin_line_length,
+ depth=self._origin_line_width,
+ center=origin + Vector(0, self._origin_line_length / 2, 0),
+ color=self._y_axis_color
+ )
+ mb.addCube(
+ width=self._origin_line_width,
+ height=self._origin_line_width,
+ depth=self._origin_line_length,
+ center=origin - Vector(0, 0, self._origin_line_length / 2),
+ color=self._z_axis_color
+ )
+ return mb.build()
- for n in range(0, mb.getVertexCount()):
- v = mb.getVertex(n)
- mb.setVertexUVCoordinates(n, v[0], v[2] * aspect)
- self._grid_mesh = mb.build().getTransformed(scale_matrix)
+ def _updateColors(self):
+ theme = self._application.getTheme()
+ if theme is None:
+ return
+ self._volume_outline_color = Color(*theme.getColor("volume_outline").getRgb())
+ self._x_axis_color = Color(*theme.getColor("x_axis").getRgb())
+ self._y_axis_color = Color(*theme.getColor("y_axis").getRgb())
+ self._z_axis_color = Color(*theme.getColor("z_axis").getRgb())
+ self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb())
+ self._error_area_color = Color(*theme.getColor("error_area").getRgb())
+
+ def _buildErrorMesh(self, min_w: float, max_w: float, min_h: float, max_h: float, min_d: float, max_d: float, disallowed_area_height: float) -> Optional[MeshData]:
+ if not self._error_areas:
+ return None
+ mb = MeshBuilder()
+ for error_area in self._error_areas:
+ color = self._error_area_color
+ points = error_area.getPoints()
+ first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
+ self._clamp(points[0][1], min_d, max_d))
+ previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
+ self._clamp(points[0][1], min_d, max_d))
+ for point in points:
+ new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height,
+ self._clamp(point[1], min_d, max_d))
+ mb.addFace(first, previous_point, new_point, color=color)
+ previous_point = new_point
+ return mb.build()
+
+ def _buildDisallowedAreaMesh(self, min_w: float, max_w: float, min_h: float, max_h: float, min_d: float, max_d: float, disallowed_area_height: float) -> Optional[MeshData]:
+ if not self._disallowed_areas:
+ return None
+
+ mb = MeshBuilder()
+ color = self._disallowed_area_color
+ for polygon in self._disallowed_areas:
+ points = polygon.getPoints()
+ if len(points) == 0:
+ continue
+
+ first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
+ self._clamp(points[0][1], min_d, max_d))
+ previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
+ self._clamp(points[0][1], min_d, max_d))
+ for point in points:
+ new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height,
+ self._clamp(point[1], min_d, max_d))
+ mb.addFace(first, previous_point, new_point, color=color)
+ previous_point = new_point
+
+ # Find the largest disallowed area to exclude it from the maximum scale bounds.
+ # This is a very nasty hack. This pretty much only works for UM machines.
+ # This disallowed area_size needs a -lot- of rework at some point in the future: TODO
+ if numpy.min(points[:,
+ 1]) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area.
+ size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1]))
+ else:
+ size = 0
+ self._disallowed_area_size = max(size, self._disallowed_area_size)
+ return mb.build()
+
+ ## Recalculates the build volume & disallowed areas.
+ def rebuild(self) -> None:
+ if not self._width or not self._height or not self._depth:
+ return
+
+ if not self._engine_ready:
+ return
+
+ if not self._global_container_stack:
+ return
+
+ if not self._volume_outline_color:
+ self._updateColors()
+
+ min_w = -self._width / 2
+ max_w = self._width / 2
+ min_h = 0.0
+ max_h = self._height
+ min_d = -self._depth / 2
+ max_d = self._depth / 2
+
+ z_fight_distance = 0.2 # Distance between buildplate and disallowed area meshes to prevent z-fighting
+
+ self._grid_mesh = self._buildGridMesh(min_w, max_w, min_h, max_h, min_d, max_d, z_fight_distance)
+ self.setMeshData(self._buildMesh(min_w, max_w, min_h, max_h, min_d, max_d, z_fight_distance))
# Indication of the machine origin
if self._global_container_stack.getProperty("machine_center_is_zero", "value"):
@@ -402,77 +508,13 @@ class BuildVolume(SceneNode):
else:
origin = Vector(min_w, min_h, max_d)
- mb = MeshBuilder()
- mb.addCube(
- width = self._origin_line_length,
- height = self._origin_line_width,
- depth = self._origin_line_width,
- center = origin + Vector(self._origin_line_length / 2, 0, 0),
- color = self._x_axis_color
- )
- mb.addCube(
- width = self._origin_line_width,
- height = self._origin_line_length,
- depth = self._origin_line_width,
- center = origin + Vector(0, self._origin_line_length / 2, 0),
- color = self._y_axis_color
- )
- mb.addCube(
- width = self._origin_line_width,
- height = self._origin_line_width,
- depth = self._origin_line_length,
- center = origin - Vector(0, 0, self._origin_line_length / 2),
- color = self._z_axis_color
- )
- self._origin_mesh = mb.build()
+ self._origin_mesh = self._buildOriginMesh(origin)
disallowed_area_height = 0.1
- disallowed_area_size = 0
- if self._disallowed_areas:
- mb = MeshBuilder()
- color = self._disallowed_area_color
- for polygon in self._disallowed_areas:
- points = polygon.getPoints()
- if len(points) == 0:
- continue
+ self._disallowed_area_size = 0.
+ self._disallowed_area_mesh = self._buildDisallowedAreaMesh(min_w, max_w, min_h, max_h, min_d, max_d, disallowed_area_height)
- first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d))
- previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d))
- for point in points:
- new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d))
- mb.addFace(first, previous_point, new_point, color = color)
- previous_point = new_point
-
- # Find the largest disallowed area to exclude it from the maximum scale bounds.
- # This is a very nasty hack. This pretty much only works for UM machines.
- # This disallowed area_size needs a -lot- of rework at some point in the future: TODO
- if numpy.min(points[:, 1]) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area.
- size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1]))
- else:
- size = 0
- disallowed_area_size = max(size, disallowed_area_size)
-
- self._disallowed_area_mesh = mb.build()
- else:
- self._disallowed_area_mesh = None
-
- if self._error_areas:
- mb = MeshBuilder()
- for error_area in self._error_areas:
- color = self._error_area_color
- points = error_area.getPoints()
- first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
- self._clamp(points[0][1], min_d, max_d))
- previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
- self._clamp(points[0][1], min_d, max_d))
- for point in points:
- new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height,
- self._clamp(point[1], min_d, max_d))
- mb.addFace(first, previous_point, new_point, color=color)
- previous_point = new_point
- self._error_mesh = mb.build()
- else:
- self._error_mesh = None
+ self._error_mesh = self._buildErrorMesh(min_w, max_w, min_h, max_h, min_d, max_d, disallowed_area_height)
self._volume_aabb = AxisAlignedBox(
minimum = Vector(min_w, min_h - 1.0, min_d),
@@ -484,23 +526,26 @@ class BuildVolume(SceneNode):
# This is probably wrong in all other cases. TODO!
# The +1 and -1 is added as there is always a bit of extra room required to work properly.
scale_to_max_bounds = AxisAlignedBox(
- minimum = Vector(min_w + bed_adhesion_size + 1, min_h, min_d + disallowed_area_size - bed_adhesion_size + 1),
- maximum = Vector(max_w - bed_adhesion_size - 1, max_h - self._raft_thickness - self._extra_z_clearance, max_d - disallowed_area_size + bed_adhesion_size - 1)
+ minimum = Vector(min_w + bed_adhesion_size + 1, min_h, min_d + self._disallowed_area_size - bed_adhesion_size + 1),
+ maximum = Vector(max_w - bed_adhesion_size - 1, max_h - self._raft_thickness - self._extra_z_clearance, max_d - self._disallowed_area_size + bed_adhesion_size - 1)
)
- self._application.getController().getScene()._maximum_bounds = scale_to_max_bounds
+ self._application.getController().getScene()._maximum_bounds = scale_to_max_bounds # type: ignore
self.updateNodeBoundaryCheck()
- def getBoundingBox(self) -> AxisAlignedBox:
+ def getBoundingBox(self):
return self._volume_aabb
def getRaftThickness(self) -> float:
return self._raft_thickness
- def _updateRaftThickness(self):
+ def _updateRaftThickness(self) -> None:
+ if not self._global_container_stack:
+ return
+
old_raft_thickness = self._raft_thickness
- if self._global_container_stack.extruders:
+ if self._global_container_stack.extruderList:
# This might be called before the extruder stacks have initialised, in which case getting the adhesion_type fails
self._adhesion_type = self._global_container_stack.getProperty("adhesion_type", "value")
self._raft_thickness = 0.0
@@ -509,7 +554,7 @@ class BuildVolume(SceneNode):
self._global_container_stack.getProperty("raft_base_thickness", "value") +
self._global_container_stack.getProperty("raft_interface_thickness", "value") +
self._global_container_stack.getProperty("raft_surface_layers", "value") *
- self._global_container_stack.getProperty("raft_surface_thickness", "value") +
+ self._global_container_stack.getProperty("raft_surface_thickness", "value") +
self._global_container_stack.getProperty("raft_airgap", "value") -
self._global_container_stack.getProperty("layer_0_z_overlap", "value"))
@@ -518,28 +563,23 @@ class BuildVolume(SceneNode):
self.setPosition(Vector(0, -self._raft_thickness, 0), SceneNode.TransformSpace.World)
self.raftThicknessChanged.emit()
- def _updateExtraZClearance(self) -> None:
+ def _calculateExtraZClearance(self, extruders: List["ContainerStack"]) -> float:
+ if not self._global_container_stack:
+ return 0
+
extra_z = 0.0
- extruders = ExtruderManager.getInstance().getUsedExtruderStacks()
- use_extruders = False
for extruder in extruders:
if extruder.getProperty("retraction_hop_enabled", "value"):
retraction_hop = extruder.getProperty("retraction_hop", "value")
if extra_z is None or retraction_hop > extra_z:
extra_z = retraction_hop
- use_extruders = True
- if not use_extruders:
- # If no extruders, take global value.
- if self._global_container_stack.getProperty("retraction_hop_enabled", "value"):
- extra_z = self._global_container_stack.getProperty("retraction_hop", "value")
- if extra_z != self._extra_z_clearance:
- self._extra_z_clearance = extra_z
+ return extra_z
def _onStackChanged(self):
self._stack_change_timer.start()
## Update the build volume visualization
- def _onStackChangeTimerFinished(self):
+ def _onStackChangeTimerFinished(self) -> None:
if self._global_container_stack:
self._global_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged)
extruders = ExtruderManager.getInstance().getActiveExtruderStacks()
@@ -570,7 +610,7 @@ class BuildVolume(SceneNode):
self._updateDisallowedAreas()
self._updateRaftThickness()
- self._updateExtraZClearance()
+ self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
if self._engine_ready:
self.rebuild()
@@ -579,20 +619,23 @@ class BuildVolume(SceneNode):
if camera:
diagonal = self.getDiagonalSize()
if diagonal > 1:
- camera.setZoomRange(min = 0.1, max = diagonal * 5) #You can zoom out up to 5 times the diagonal. This gives some space around the volume.
+ # You can zoom out up to 5 times the diagonal. This gives some space around the volume.
+ camera.setZoomRange(min = 0.1, max = diagonal * 5) # type: ignore
- def _onEngineCreated(self):
+ def _onEngineCreated(self) -> None:
self._engine_ready = True
self.rebuild()
- def _onSettingChangeTimerFinished(self):
+ def _onSettingChangeTimerFinished(self) -> None:
+ if not self._global_container_stack:
+ return
+
rebuild_me = False
update_disallowed_areas = False
update_raft_thickness = False
update_extra_z_clearance = True
for setting_key in self._changed_settings_since_last_rebuild:
-
if setting_key == "print_sequence":
machine_height = self._global_container_stack.getProperty("machine_height", "value")
if self._application.getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time" and len(self._scene_objects) > 1:
@@ -605,33 +648,26 @@ class BuildVolume(SceneNode):
self._height = self._global_container_stack.getProperty("machine_height", "value")
self._build_volume_message.hide()
update_disallowed_areas = True
- rebuild_me = True
# sometimes the machine size or shape settings are adjusted on the active machine, we should reflect this
if setting_key in self._machine_settings:
- self._height = self._global_container_stack.getProperty("machine_height", "value")
- self._width = self._global_container_stack.getProperty("machine_width", "value")
- self._depth = self._global_container_stack.getProperty("machine_depth", "value")
- self._shape = self._global_container_stack.getProperty("machine_shape", "value")
+ self._updateMachineSizeProperties()
update_extra_z_clearance = True
update_disallowed_areas = True
- rebuild_me = True
- if setting_key in self._skirt_settings + self._prime_settings + self._tower_settings + self._ooze_shield_settings + self._distance_settings + self._extruder_settings:
+ if setting_key in self._disallowed_area_settings:
update_disallowed_areas = True
- rebuild_me = True
if setting_key in self._raft_settings:
update_raft_thickness = True
- rebuild_me = True
if setting_key in self._extra_z_settings:
update_extra_z_clearance = True
- rebuild_me = True
if setting_key in self._limit_to_extruder_settings:
update_disallowed_areas = True
- rebuild_me = True
+
+ rebuild_me = update_extra_z_clearance or update_disallowed_areas or update_raft_thickness
# We only want to update all of them once.
if update_disallowed_areas:
@@ -641,7 +677,7 @@ class BuildVolume(SceneNode):
self._updateRaftThickness()
if update_extra_z_clearance:
- self._updateExtraZClearance()
+ self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
if rebuild_me:
self.rebuild()
@@ -649,7 +685,7 @@ class BuildVolume(SceneNode):
# We just did a rebuild, reset the list.
self._changed_settings_since_last_rebuild = []
- def _onSettingPropertyChanged(self, setting_key: str, property_name: str):
+ def _onSettingPropertyChanged(self, setting_key: str, property_name: str) -> None:
if property_name != "value":
return
@@ -660,6 +696,14 @@ class BuildVolume(SceneNode):
def hasErrors(self) -> bool:
return self._has_errors
+ def _updateMachineSizeProperties(self) -> None:
+ if not self._global_container_stack:
+ return
+ self._height = self._global_container_stack.getProperty("machine_height", "value")
+ self._width = self._global_container_stack.getProperty("machine_width", "value")
+ self._depth = self._global_container_stack.getProperty("machine_depth", "value")
+ self._shape = self._global_container_stack.getProperty("machine_shape", "value")
+
## Calls _updateDisallowedAreas and makes sure the changes appear in the
# scene.
#
@@ -667,60 +711,30 @@ class BuildVolume(SceneNode):
# ``_updateDisallowedAreas`` method itself shouldn't call ``rebuild``,
# since there may be other changes before it needs to be rebuilt, which
# would hit performance.
+
def _updateDisallowedAreasAndRebuild(self):
self._updateDisallowedAreas()
self._updateRaftThickness()
- self._updateExtraZClearance()
+ self._extra_z_clearance = self._calculateExtraZClearance(ExtruderManager.getInstance().getUsedExtruderStacks())
self.rebuild()
- def _updateDisallowedAreas(self):
+ def _updateDisallowedAreas(self) -> None:
if not self._global_container_stack:
return
self._error_areas = []
- extruder_manager = ExtruderManager.getInstance()
- used_extruders = extruder_manager.getUsedExtruderStacks()
+ used_extruders = ExtruderManager.getInstance().getUsedExtruderStacks()
disallowed_border_size = self.getEdgeDisallowedSize()
- if not used_extruders:
- # If no extruder is used, assume that the active extruder is used (else nothing is drawn)
- if extruder_manager.getActiveExtruderStack():
- used_extruders = [extruder_manager.getActiveExtruderStack()]
- else:
- used_extruders = [self._global_container_stack]
-
- result_areas = self._computeDisallowedAreasStatic(disallowed_border_size, used_extruders) #Normal machine disallowed areas can always be added.
+ result_areas = self._computeDisallowedAreasStatic(disallowed_border_size, used_extruders) # Normal machine disallowed areas can always be added.
prime_areas = self._computeDisallowedAreasPrimeBlob(disallowed_border_size, used_extruders)
- result_areas_no_brim = self._computeDisallowedAreasStatic(0, used_extruders) #Where the priming is not allowed to happen. This is not added to the result, just for collision checking.
- prime_disallowed_areas = copy.deepcopy(result_areas_no_brim)
+ result_areas_no_brim = self._computeDisallowedAreasStatic(0, used_extruders) # Where the priming is not allowed to happen. This is not added to the result, just for collision checking.
- #Check if prime positions intersect with disallowed areas.
+ # Check if prime positions intersect with disallowed areas.
for extruder in used_extruders:
extruder_id = extruder.getId()
- collision = False
- for prime_polygon in prime_areas[extruder_id]:
- for disallowed_polygon in prime_disallowed_areas[extruder_id]:
- if prime_polygon.intersectsPolygon(disallowed_polygon) is not None:
- collision = True
- break
- if collision:
- break
-
- #Also check other prime positions (without additional offset).
- for other_extruder_id in prime_areas:
- if extruder_id == other_extruder_id: #It is allowed to collide with itself.
- continue
- for other_prime_polygon in prime_areas[other_extruder_id]:
- if prime_polygon.intersectsPolygon(other_prime_polygon):
- collision = True
- break
- if collision:
- break
- if collision:
- break
-
result_areas[extruder_id].extend(prime_areas[extruder_id])
result_areas_no_brim[extruder_id].extend(prime_areas[extruder_id])
@@ -728,33 +742,28 @@ class BuildVolume(SceneNode):
for area in nozzle_disallowed_areas:
polygon = Polygon(numpy.array(area, numpy.float32))
polygon_disallowed_border = polygon.getMinkowskiHull(Polygon.approximatedCircle(disallowed_border_size))
- result_areas[extruder_id].append(polygon_disallowed_border) #Don't perform the offset on these.
- #polygon_minimal_border = polygon.getMinkowskiHull(5)
- result_areas_no_brim[extruder_id].append(polygon) # no brim
+ result_areas[extruder_id].append(polygon_disallowed_border) # Don't perform the offset on these.
+ result_areas_no_brim[extruder_id].append(polygon) # No brim
# Add prime tower location as disallowed area.
- if len(used_extruders) > 1: #No prime tower in single-extrusion.
-
- if len([x for x in used_extruders if x.isEnabled == True]) > 1: #No prime tower if only one extruder is enabled
- prime_tower_collision = False
- prime_tower_areas = self._computeDisallowedAreasPrinted(used_extruders)
- for extruder_id in prime_tower_areas:
- for i_area, prime_tower_area in enumerate(prime_tower_areas[extruder_id]):
- for area in result_areas[extruder_id]:
- if prime_tower_area.intersectsPolygon(area) is not None:
- prime_tower_collision = True
- break
- if prime_tower_collision: #Already found a collision.
+ if len([x for x in used_extruders if x.isEnabled]) > 1: # No prime tower if only one extruder is enabled
+ prime_tower_collision = False
+ prime_tower_areas = self._computeDisallowedAreasPrinted(used_extruders)
+ for extruder_id in prime_tower_areas:
+ for area_index, prime_tower_area in enumerate(prime_tower_areas[extruder_id]):
+ for area in result_areas[extruder_id]:
+ if prime_tower_area.intersectsPolygon(area) is not None:
+ prime_tower_collision = True
break
- if (ExtruderManager.getInstance().getResolveOrValue("prime_tower_brim_enable") and
- ExtruderManager.getInstance().getResolveOrValue("adhesion_type") != "raft"):
- prime_tower_areas[extruder_id][i_area] = prime_tower_area.getMinkowskiHull(
- Polygon.approximatedCircle(disallowed_border_size))
- if not prime_tower_collision:
- result_areas[extruder_id].extend(prime_tower_areas[extruder_id])
- result_areas_no_brim[extruder_id].extend(prime_tower_areas[extruder_id])
- else:
- self._error_areas.extend(prime_tower_areas[extruder_id])
+ if prime_tower_collision: # Already found a collision.
+ break
+ if self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and self._global_container_stack.getProperty("adhesion_type", "value") != "raft":
+ prime_tower_areas[extruder_id][area_index] = prime_tower_area.getMinkowskiHull(Polygon.approximatedCircle(disallowed_border_size))
+ if not prime_tower_collision:
+ result_areas[extruder_id].extend(prime_tower_areas[extruder_id])
+ result_areas_no_brim[extruder_id].extend(prime_tower_areas[extruder_id])
+ else:
+ self._error_areas.extend(prime_tower_areas[extruder_id])
self._has_errors = len(self._error_areas) > 0
@@ -775,11 +784,14 @@ class BuildVolume(SceneNode):
# where that extruder may not print.
def _computeDisallowedAreasPrinted(self, used_extruders):
result = {}
+ adhesion_extruder = None #type: ExtruderStack
for extruder in used_extruders:
+ if int(extruder.getProperty("extruder_nr", "value")) == int(self._global_container_stack.getProperty("adhesion_extruder_nr", "value")):
+ adhesion_extruder = extruder
result[extruder.getId()] = []
- #Currently, the only normally printed object is the prime tower.
- if ExtruderManager.getInstance().getResolveOrValue("prime_tower_enable"):
+ # Currently, the only normally printed object is the prime tower.
+ if self._global_container_stack.getProperty("prime_tower_enable", "value"):
prime_tower_size = self._global_container_stack.getProperty("prime_tower_size", "value")
machine_width = self._global_container_stack.getProperty("machine_width", "value")
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
@@ -789,27 +801,19 @@ class BuildVolume(SceneNode):
prime_tower_x = prime_tower_x - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left.
prime_tower_y = prime_tower_y + machine_depth / 2
- if (ExtruderManager.getInstance().getResolveOrValue("prime_tower_brim_enable") and
- ExtruderManager.getInstance().getResolveOrValue("adhesion_type") != "raft"):
+ if adhesion_extruder is not None and self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and self._global_container_stack.getProperty("adhesion_type", "value") != "raft":
brim_size = (
- extruder.getProperty("brim_line_count", "value") *
- extruder.getProperty("skirt_brim_line_width", "value") / 100.0 *
- extruder.getProperty("initial_layer_line_width_factor", "value")
+ adhesion_extruder.getProperty("brim_line_count", "value") *
+ adhesion_extruder.getProperty("skirt_brim_line_width", "value") / 100.0 *
+ adhesion_extruder.getProperty("initial_layer_line_width_factor", "value")
)
prime_tower_x -= brim_size
prime_tower_y += brim_size
- if self._global_container_stack.getProperty("prime_tower_circular", "value"):
- radius = prime_tower_size / 2
- prime_tower_area = Polygon.approximatedCircle(radius)
- prime_tower_area = prime_tower_area.translate(prime_tower_x - radius, prime_tower_y - radius)
- else:
- prime_tower_area = Polygon([
- [prime_tower_x - prime_tower_size, prime_tower_y - prime_tower_size],
- [prime_tower_x, prime_tower_y - prime_tower_size],
- [prime_tower_x, prime_tower_y],
- [prime_tower_x - prime_tower_size, prime_tower_y],
- ])
+ radius = prime_tower_size / 2
+ prime_tower_area = Polygon.approximatedCircle(radius)
+ prime_tower_area = prime_tower_area.translate(prime_tower_x - radius, prime_tower_y - radius)
+
prime_tower_area = prime_tower_area.getMinkowskiHull(Polygon.approximatedCircle(0))
for extruder in used_extruders:
result[extruder.getId()].append(prime_tower_area) #The prime tower location is the same for each extruder, regardless of offset.
@@ -827,9 +831,10 @@ class BuildVolume(SceneNode):
# \param used_extruders The extruder stacks to generate disallowed areas
# for.
# \return A dictionary with for each used extruder ID the prime areas.
- def _computeDisallowedAreasPrimeBlob(self, border_size, used_extruders):
- result = {}
-
+ def _computeDisallowedAreasPrimeBlob(self, border_size: float, used_extruders: List["ExtruderStack"]) -> Dict[str, List[Polygon]]:
+ result = {} # type: Dict[str, List[Polygon]]
+ if not self._global_container_stack:
+ return result
machine_width = self._global_container_stack.getProperty("machine_width", "value")
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
for extruder in used_extruders:
@@ -837,13 +842,13 @@ class BuildVolume(SceneNode):
prime_x = extruder.getProperty("extruder_prime_pos_x", "value")
prime_y = -extruder.getProperty("extruder_prime_pos_y", "value")
- #Ignore extruder prime position if it is not set or if blob is disabled
+ # Ignore extruder prime position if it is not set or if blob is disabled
if (prime_x == 0 and prime_y == 0) or not prime_blob_enabled:
result[extruder.getId()] = []
continue
if not self._global_container_stack.getProperty("machine_center_is_zero", "value"):
- prime_x = prime_x - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left.
+ prime_x = prime_x - machine_width / 2 # Offset by half machine_width and _depth to put the origin in the front-left.
prime_y = prime_y + machine_depth / 2
prime_polygon = Polygon.approximatedCircle(PRIME_CLEARANCE)
@@ -866,9 +871,12 @@ class BuildVolume(SceneNode):
# for.
# \return A dictionary with for each used extruder ID the disallowed areas
# where that extruder may not print.
- def _computeDisallowedAreasStatic(self, border_size, used_extruders):
- #Convert disallowed areas to polygons and dilate them.
+ def _computeDisallowedAreasStatic(self, border_size:float, used_extruders: List["ExtruderStack"]) -> Dict[str, List[Polygon]]:
+ # Convert disallowed areas to polygons and dilate them.
machine_disallowed_polygons = []
+ if self._global_container_stack is None:
+ return {}
+
for area in self._global_container_stack.getProperty("machine_disallowed_areas", "value"):
polygon = Polygon(numpy.array(area, numpy.float32))
polygon = polygon.getMinkowskiHull(Polygon.approximatedCircle(border_size))
@@ -879,7 +887,7 @@ class BuildVolume(SceneNode):
nozzle_offsetting_for_disallowed_areas = self._global_container_stack.getMetaDataEntry(
"nozzle_offsetting_for_disallowed_areas", True)
- result = {}
+ result = {} # type: Dict[str, List[Polygon]]
for extruder in used_extruders:
extruder_id = extruder.getId()
offset_x = extruder.getProperty("machine_nozzle_offset_x", "value")
@@ -888,13 +896,13 @@ class BuildVolume(SceneNode):
offset_y = extruder.getProperty("machine_nozzle_offset_y", "value")
if offset_y is None:
offset_y = 0
- offset_y = -offset_y #Y direction of g-code is the inverse of Y direction of Cura's scene space.
+ offset_y = -offset_y # Y direction of g-code is the inverse of Y direction of Cura's scene space.
result[extruder_id] = []
for polygon in machine_disallowed_polygons:
- result[extruder_id].append(polygon.translate(offset_x, offset_y)) #Compensate for the nozzle offset of this extruder.
+ result[extruder_id].append(polygon.translate(offset_x, offset_y)) # Compensate for the nozzle offset of this extruder.
- #Add the border around the edge of the build volume.
+ # Add the border around the edge of the build volume.
left_unreachable_border = 0
right_unreachable_border = 0
top_unreachable_border = 0
@@ -902,7 +910,8 @@ class BuildVolume(SceneNode):
# Only do nozzle offsetting if needed
if nozzle_offsetting_for_disallowed_areas:
- #The build volume is defined as the union of the area that all extruders can reach, so we need to know the relative offset to all extruders.
+ # The build volume is defined as the union of the area that all extruders can reach, so we need to know
+ # the relative offset to all extruders.
for other_extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
other_offset_x = other_extruder.getProperty("machine_nozzle_offset_x", "value")
if other_offset_x is None:
@@ -986,8 +995,8 @@ class BuildVolume(SceneNode):
[ half_machine_width - border_size, 0]
], numpy.float32)))
result[extruder_id].append(Polygon(numpy.array([
- [ half_machine_width,-half_machine_depth],
- [-half_machine_width,-half_machine_depth],
+ [ half_machine_width, -half_machine_depth],
+ [-half_machine_width, -half_machine_depth],
[ 0, -half_machine_depth + border_size]
], numpy.float32)))
@@ -999,48 +1008,24 @@ class BuildVolume(SceneNode):
# stack.
#
# \return A sequence of setting values, one for each extruder.
- def _getSettingFromAllExtruders(self, setting_key):
+ def _getSettingFromAllExtruders(self, setting_key: str) -> List[Any]:
all_values = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "value")
all_types = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "type")
- for i in range(len(all_values)):
- if not all_values[i] and (all_types[i] == "int" or all_types[i] == "float"):
+ for i, (setting_value, setting_type) in enumerate(zip(all_values, all_types)):
+ if not setting_value and (setting_type == "int" or setting_type == "float"):
all_values[i] = 0
return all_values
- ## Calculate the disallowed radius around the edge.
- #
- # This disallowed radius is to allow for space around the models that is
- # not part of the collision radius, such as bed adhesion (skirt/brim/raft)
- # and travel avoid distance.
- def getEdgeDisallowedSize(self):
- if not self._global_container_stack or not self._global_container_stack.extruders:
- return 0
+ def _calculateBedAdhesionSize(self, used_extruders):
+ if self._global_container_stack is None:
+ return
container_stack = self._global_container_stack
- used_extruders = ExtruderManager.getInstance().getUsedExtruderStacks()
-
- # If we are printing one at a time, we need to add the bed adhesion size to the disallowed areas of the objects
- if container_stack.getProperty("print_sequence", "value") == "one_at_a_time":
- return 0.1 # Return a very small value, so we do draw disallowed area's near the edges.
-
adhesion_type = container_stack.getProperty("adhesion_type", "value")
skirt_brim_line_width = self._global_container_stack.getProperty("skirt_brim_line_width", "value")
initial_layer_line_width_factor = self._global_container_stack.getProperty("initial_layer_line_width_factor", "value")
- if adhesion_type == "skirt":
- skirt_distance = self._global_container_stack.getProperty("skirt_gap", "value")
- skirt_line_count = self._global_container_stack.getProperty("skirt_line_count", "value")
-
- bed_adhesion_size = skirt_distance + (skirt_brim_line_width * skirt_line_count) * initial_layer_line_width_factor / 100.0
-
- for extruder_stack in used_extruders:
- bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
-
- # We don't create an additional line for the extruder we're printing the skirt with.
- bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0
-
- elif (adhesion_type == "brim" or
- (self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and
- self._global_container_stack.getProperty("adhesion_type", "value") != "raft")):
+ # Use brim width if brim is enabled OR the prime tower has a brim.
+ if adhesion_type == "brim" or (self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and adhesion_type != "raft"):
brim_line_count = self._global_container_stack.getProperty("brim_line_count", "value")
bed_adhesion_size = skirt_brim_line_width * brim_line_count * initial_layer_line_width_factor / 100.0
@@ -1049,13 +1034,22 @@ class BuildVolume(SceneNode):
# We don't create an additional line for the extruder we're printing the brim with.
bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0
+ elif adhesion_type == "skirt": # No brim? Also not on prime tower? Then use whatever the adhesion type is saying: Skirt, raft or none.
+ skirt_distance = self._global_container_stack.getProperty("skirt_gap", "value")
+ skirt_line_count = self._global_container_stack.getProperty("skirt_line_count", "value")
+ bed_adhesion_size = skirt_distance + (
+ skirt_brim_line_width * skirt_line_count) * initial_layer_line_width_factor / 100.0
+
+ for extruder_stack in used_extruders:
+ bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
+
+ # We don't create an additional line for the extruder we're printing the skirt with.
+ bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0
elif adhesion_type == "raft":
bed_adhesion_size = self._global_container_stack.getProperty("raft_margin", "value")
-
elif adhesion_type == "none":
bed_adhesion_size = 0
-
else:
raise Exception("Unknown bed adhesion type. Did you forget to update the build volume calculations for your new bed adhesion type?")
@@ -1064,26 +1058,56 @@ class BuildVolume(SceneNode):
self._global_container_stack.getProperty("machine_depth", "value")
)
bed_adhesion_size = min(bed_adhesion_size, max_length_available)
+ return bed_adhesion_size
+ def _calculateFarthestShieldDistance(self, container_stack):
+ farthest_shield_distance = 0
+ if container_stack.getProperty("draft_shield_enabled", "value"):
+ farthest_shield_distance = max(farthest_shield_distance, container_stack.getProperty("draft_shield_dist", "value"))
+ if container_stack.getProperty("ooze_shield_enabled", "value"):
+ farthest_shield_distance = max(farthest_shield_distance,container_stack.getProperty("ooze_shield_dist", "value"))
+ return farthest_shield_distance
+
+ def _calculateSupportExpansion(self, container_stack):
support_expansion = 0
support_enabled = self._global_container_stack.getProperty("support_enable", "value")
support_offset = self._global_container_stack.getProperty("support_offset", "value")
if support_enabled and support_offset:
support_expansion += support_offset
+ return support_expansion
- farthest_shield_distance = 0
- if container_stack.getProperty("draft_shield_enabled", "value"):
- farthest_shield_distance = max(farthest_shield_distance, container_stack.getProperty("draft_shield_dist", "value"))
- if container_stack.getProperty("ooze_shield_enabled", "value"):
- farthest_shield_distance = max(farthest_shield_distance, container_stack.getProperty("ooze_shield_dist", "value"))
-
+ def _calculateMoveFromWallRadius(self, used_extruders):
move_from_wall_radius = 0 # Moves that start from outer wall.
- move_from_wall_radius = max(move_from_wall_radius, max(self._getSettingFromAllExtruders("infill_wipe_dist")))
- avoid_enabled_per_extruder = [stack.getProperty("travel_avoid_other_parts","value") for stack in used_extruders]
+ all_values = [move_from_wall_radius]
+ all_values.extend(self._getSettingFromAllExtruders("infill_wipe_dist"))
+ move_from_wall_radius = max(all_values)
+ avoid_enabled_per_extruder = [stack.getProperty("travel_avoid_other_parts", "value") for stack in used_extruders]
travel_avoid_distance_per_extruder = [stack.getProperty("travel_avoid_distance", "value") for stack in used_extruders]
- for avoid_other_parts_enabled, avoid_distance in zip(avoid_enabled_per_extruder, travel_avoid_distance_per_extruder): #For each extruder (or just global).
+ for avoid_other_parts_enabled, avoid_distance in zip(avoid_enabled_per_extruder, travel_avoid_distance_per_extruder): # For each extruder (or just global).
if avoid_other_parts_enabled:
move_from_wall_radius = max(move_from_wall_radius, avoid_distance)
+ return move_from_wall_radius
+
+ ## Calculate the disallowed radius around the edge.
+ #
+ # This disallowed radius is to allow for space around the models that is
+ # not part of the collision radius, such as bed adhesion (skirt/brim/raft)
+ # and travel avoid distance.
+ def getEdgeDisallowedSize(self):
+ if not self._global_container_stack or not self._global_container_stack.extruderList:
+ return 0
+
+ container_stack = self._global_container_stack
+ used_extruders = ExtruderManager.getInstance().getUsedExtruderStacks()
+
+ # If we are printing one at a time, we need to add the bed adhesion size to the disallowed areas of the objects
+ if container_stack.getProperty("print_sequence", "value") == "one_at_a_time":
+ return 0.1
+
+ bed_adhesion_size = self._calculateBedAdhesionSize(used_extruders)
+ support_expansion = self._calculateSupportExpansion(self._global_container_stack)
+ farthest_shield_distance = self._calculateFarthestShieldDistance(self._global_container_stack)
+ move_from_wall_radius = self._calculateMoveFromWallRadius(used_extruders)
# Now combine our different pieces of data to get the final border size.
# Support expansion is added to the bed adhesion, since the bed adhesion goes around support.
@@ -1099,8 +1123,9 @@ class BuildVolume(SceneNode):
_raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap", "layer_0_z_overlap"]
_extra_z_settings = ["retraction_hop_enabled", "retraction_hop"]
_prime_settings = ["extruder_prime_pos_x", "extruder_prime_pos_y", "extruder_prime_pos_z", "prime_blob_enable"]
- _tower_settings = ["prime_tower_enable", "prime_tower_circular", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y", "prime_tower_brim_enable"]
+ _tower_settings = ["prime_tower_enable", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y", "prime_tower_brim_enable"]
_ooze_shield_settings = ["ooze_shield_enabled", "ooze_shield_dist"]
_distance_settings = ["infill_wipe_dist", "travel_avoid_distance", "support_offset", "support_enable", "travel_avoid_other_parts", "travel_avoid_supports"]
_extruder_settings = ["support_enable", "support_bottom_enable", "support_roof_enable", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "brim_line_count", "adhesion_extruder_nr", "adhesion_type"] #Settings that can affect which extruders are used.
_limit_to_extruder_settings = ["wall_extruder_nr", "wall_0_extruder_nr", "wall_x_extruder_nr", "top_bottom_extruder_nr", "infill_extruder_nr", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "adhesion_extruder_nr"]
+ _disallowed_area_settings = _skirt_settings + _prime_settings + _tower_settings + _ooze_shield_settings + _distance_settings + _extruder_settings
diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py
index d43743bc37..1ec00787d7 100644
--- a/cura/CrashHandler.py
+++ b/cura/CrashHandler.py
@@ -12,9 +12,10 @@ import json
import ssl
import urllib.request
import urllib.error
-import shutil
-from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, Qt, QUrl
+import certifi
+
+from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QUrl
from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit, QGroupBox, QCheckBox, QPushButton
from PyQt5.QtGui import QDesktopServices
@@ -22,9 +23,10 @@ from UM.Application import Application
from UM.Logger import Logger
from UM.View.GL.OpenGL import OpenGL
from UM.i18n import i18nCatalog
-from UM.Platform import Platform
from UM.Resources import Resources
+from cura import ApplicationMetadata
+
catalog = i18nCatalog("cura")
MYPY = False
@@ -181,6 +183,7 @@ class CrashHandler:
self.cura_version = catalog.i18nc("@label unknown version of Cura", "Unknown")
crash_info = "" + catalog.i18nc("@label Cura version number", "Cura version") + ": " + str(self.cura_version) + " "
+ crash_info += "" + catalog.i18nc("@label Cura build type", "Cura build type") + ": " + str(ApplicationMetadata.CuraBuildType) + " "
crash_info += "" + catalog.i18nc("@label Type of platform", "Platform") + ": " + str(platform.platform()) + " "
crash_info += "" + catalog.i18nc("@label", "Qt version") + ": " + str(QT_VERSION_STR) + " "
crash_info += "" + catalog.i18nc("@label", "PyQt version") + ": " + str(PYQT_VERSION_STR) + " "
@@ -191,6 +194,7 @@ class CrashHandler:
group.setLayout(layout)
self.data["cura_version"] = self.cura_version
+ self.data["cura_build_type"] = ApplicationMetadata.CuraBuildType
self.data["os"] = {"type": platform.system(), "version": platform.version()}
self.data["qt_version"] = QT_VERSION_STR
self.data["pyqt_version"] = PYQT_VERSION_STR
@@ -319,7 +323,8 @@ class CrashHandler:
def _userDescriptionWidget(self):
group = QGroupBox()
- group.setTitle(catalog.i18nc("@title:groupbox", "User description"))
+ group.setTitle(catalog.i18nc("@title:groupbox", "User description" +
+ " (Note: Developers may not speak your language, please use English if possible)"))
layout = QVBoxLayout()
# When sending the report, the user comments will be collected
@@ -351,11 +356,13 @@ class CrashHandler:
# Convert data to bytes
binary_data = json.dumps(self.data).encode("utf-8")
+ # CURA-6698 Create an SSL context and use certifi CA certificates for verification.
+ context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLSv1_2)
+ context.load_verify_locations(cafile = certifi.where())
# Submit data
- kwoptions = {"data": binary_data, "timeout": 5}
-
- if Platform.isOSX():
- kwoptions["context"] = ssl._create_unverified_context()
+ kwoptions = {"data": binary_data,
+ "timeout": 5,
+ "context": context}
Logger.log("i", "Sending crash report info to [%s]...", self.crash_url)
if not self.has_started:
diff --git a/cura/CuraActions.py b/cura/CuraActions.py
index 91e0966fed..b92abbe706 100644
--- a/cura/CuraActions.py
+++ b/cura/CuraActions.py
@@ -3,15 +3,17 @@
from PyQt5.QtCore import QObject, QUrl
from PyQt5.QtGui import QDesktopServices
-from typing import List, TYPE_CHECKING, cast
+from typing import List, Optional, cast
from UM.Event import CallFunctionEvent
from UM.FlameProfiler import pyqtSlot
+from UM.Math.Quaternion import Quaternion
from UM.Math.Vector import Vector
from UM.Scene.Selection import Selection
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
+from UM.Operations.RotateOperation import RotateOperation
from UM.Operations.TranslateOperation import TranslateOperation
import cura.CuraApplication
@@ -23,9 +25,8 @@ from cura.Settings.ExtruderManager import ExtruderManager
from cura.Operations.SetBuildPlateNumberOperation import SetBuildPlateNumberOperation
from UM.Logger import Logger
+from UM.Scene.SceneNode import SceneNode
-if TYPE_CHECKING:
- from UM.Scene.SceneNode import SceneNode
class CuraActions(QObject):
def __init__(self, parent: QObject = None) -> None:
diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py
index 4d3d2434ff..ef5f987b85 100755
--- a/cura/CuraApplication.py
+++ b/cura/CuraApplication.py
@@ -13,119 +13,130 @@ from PyQt5.QtGui import QColor, QIcon
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType
+from UM.i18n import i18nCatalog
from UM.Application import Application
+from UM.Decorators import override, deprecated
+from UM.FlameProfiler import pyqtSlot
+from UM.Logger import Logger
+from UM.Message import Message
+from UM.Platform import Platform
from UM.PluginError import PluginNotFoundError
-from UM.Scene.SceneNode import SceneNode
-from UM.Scene.Camera import Camera
-from UM.Math.Vector import Vector
-from UM.Math.Quaternion import Quaternion
+from UM.Resources import Resources
+from UM.Preferences import Preferences
+from UM.Qt.QtApplication import QtApplication # The class we're inheriting from.
+import UM.Util
+from UM.View.SelectionPass import SelectionPass # For typing.
+
from UM.Math.AxisAlignedBox import AxisAlignedBox
from UM.Math.Matrix import Matrix
-from UM.Platform import Platform
-from UM.Resources import Resources
-from UM.Scene.ToolHandle import ToolHandle
-from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
+from UM.Math.Quaternion import Quaternion
+from UM.Math.Vector import Vector
+
from UM.Mesh.ReadMeshJob import ReadMeshJob
-from UM.Logger import Logger
-from UM.Preferences import Preferences
-from UM.Qt.QtApplication import QtApplication #The class we're inheriting from.
-from UM.View.SelectionPass import SelectionPass #For typing.
-from UM.Scene.Selection import Selection
-from UM.Scene.GroupDecorator import GroupDecorator
-from UM.Settings.ContainerStack import ContainerStack
-from UM.Settings.InstanceContainer import InstanceContainer
-from UM.Settings.Validator import Validator
-from UM.Message import Message
-from UM.i18n import i18nCatalog
-from UM.Workspace.WorkspaceReader import WorkspaceReader
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Operations.SetTransformOperation import SetTransformOperation
+from UM.Scene.Camera import Camera
+from UM.Scene.GroupDecorator import GroupDecorator
+from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
+from UM.Scene.SceneNode import SceneNode
+from UM.Scene.Selection import Selection
+from UM.Scene.ToolHandle import ToolHandle
+
+from UM.Settings.ContainerRegistry import ContainerRegistry
+from UM.Settings.InstanceContainer import InstanceContainer
+from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
+from UM.Settings.SettingFunction import SettingFunction
+from UM.Settings.Validator import Validator
+
+from UM.Workspace.WorkspaceReader import WorkspaceReader
+
from cura.API import CuraAPI
+
from cura.Arranging.Arrange import Arrange
from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob
from cura.Arranging.ShapeArray import ShapeArray
-from cura.MultiplyObjectsJob import MultiplyObjectsJob
-from cura.GlobalStacksModel import GlobalStacksModel
-from cura.Scene.ConvexHullDecorator import ConvexHullDecorator
+
from cura.Operations.SetParentOperation import SetParentOperation
-from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
+
from cura.Scene.BlockSlicingDecorator import BlockSlicingDecorator
from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
-from cura.Scene.CuraSceneNode import CuraSceneNode
-
+from cura.Scene.ConvexHullDecorator import ConvexHullDecorator
from cura.Scene.CuraSceneController import CuraSceneController
+from cura.Scene.CuraSceneNode import CuraSceneNode
+from cura.Scene.GCodeListDecorator import GCodeListDecorator
+from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
+from cura.Scene import ZOffsetDecorator
-from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from UM.Settings.SettingFunction import SettingFunction
-from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
-from cura.Settings.MachineNameValidator import MachineNameValidator
-
-from cura.Machines.Models.BuildPlateModel import BuildPlateModel
-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.FavoriteMaterialsModel import FavoriteMaterialsModel
-from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel
-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
-
-from cura.Machines.Models.SettingVisibilityPresetsModel import SettingVisibilityPresetsModel
-
+from cura.Machines.ContainerTree import ContainerTree
from cura.Machines.MachineErrorChecker import MachineErrorChecker
+from cura.Machines.Models.BuildPlateModel import BuildPlateModel
+from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel
+from cura.Machines.Models.DiscoveredPrintersModel import DiscoveredPrintersModel
+from cura.Machines.Models.ExtrudersModel import ExtrudersModel
+from cura.Machines.Models.FavoriteMaterialsModel import FavoriteMaterialsModel
+from cura.Machines.Models.FirstStartMachineActionsModel import FirstStartMachineActionsModel
+from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel
+from cura.Machines.Models.GlobalStacksModel import GlobalStacksModel
+from cura.Machines.Models.MaterialBrandsModel import MaterialBrandsModel
+from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel
+from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
+from cura.Machines.Models.NozzleModel import NozzleModel
+from cura.Machines.Models.QualityManagementModel import QualityManagementModel
+from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel
+from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel
+from cura.Machines.Models.SettingVisibilityPresetsModel import SettingVisibilityPresetsModel
+from cura.Machines.Models.UserChangesModel import UserChangesModel
+from cura.Machines.Models.IntentModel import IntentModel
+from cura.Machines.Models.IntentCategoryModel import IntentCategoryModel
+
+from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
+from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage
+
+import cura.Settings.cura_empty_instance_containers
+from cura.Settings.ContainerManager import ContainerManager
+from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
+from cura.Settings.CuraFormulaFunctions import CuraFormulaFunctions
+from cura.Settings.ExtruderManager import ExtruderManager
+from cura.Settings.ExtruderStack import ExtruderStack
+from cura.Settings.MachineManager import MachineManager
+from cura.Settings.MachineNameValidator import MachineNameValidator
+from cura.Settings.IntentManager import IntentManager
+from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
+from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager
-from cura.Machines.VariantManager import VariantManager
+from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
+
+from cura.UI import CuraSplashScreen, MachineActionManager, PrintInformation
+from cura.UI.MachineSettingsManager import MachineSettingsManager
+from cura.UI.ObjectsModel import ObjectsModel
+from cura.UI.TextManager import TextManager
+from cura.UI.AddPrinterPagesModel import AddPrinterPagesModel
+from cura.UI.RecommendedMode import RecommendedMode
+from cura.UI.WelcomePagesModel import WelcomePagesModel
+from cura.UI.WhatsNewPagesModel import WhatsNewPagesModel
+
+from cura.Utils.NetworkingUtil import NetworkingUtil
from .SingleInstance import SingleInstance
from .AutoSave import AutoSave
from . import PlatformPhysics
from . import BuildVolume
from . import CameraAnimation
-from . import PrintInformation
from . import CuraActions
-from cura.Scene import ZOffsetDecorator
-from . import CuraSplashScreen
from . import PrintJobPreviewImageProvider
-from . import MachineActionManager
-
-from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
-
-from cura.Settings.MachineManager import MachineManager
-from cura.Settings.ExtruderManager import ExtruderManager
-from cura.Settings.UserChangesModel import UserChangesModel
-from cura.Settings.ExtrudersModel import ExtrudersModel
-from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
-from cura.Settings.ContainerManager import ContainerManager
-from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
-import cura.Settings.cura_empty_instance_containers
-from cura.Settings.CuraFormulaFunctions import CuraFormulaFunctions
-
-from cura.ObjectsModel import ObjectsModel
-
-from cura.PrinterOutputDevice import PrinterOutputDevice
-from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage
from cura import ApplicationMetadata, UltimakerCloudAuthentication
-
-from UM.FlameProfiler import pyqtSlot
-from UM.Decorators import override
+from cura.Settings.GlobalStack import GlobalStack
if TYPE_CHECKING:
- from cura.Machines.MaterialManager import MaterialManager
- from cura.Machines.QualityManager import QualityManager
from UM.Settings.EmptyInstanceContainer import EmptyInstanceContainer
- from cura.Settings.GlobalStack import GlobalStack
-
numpy.seterr(all = "ignore")
@@ -134,7 +145,7 @@ class CuraApplication(QtApplication):
# SettingVersion represents the set of settings available in the machine/extruder definitions.
# You need to make sure that this version number needs to be increased if there is any non-backwards-compatible
# changes of the settings.
- SettingVersion = 7
+ SettingVersion = 11
Created = False
@@ -150,6 +161,7 @@ class CuraApplication(QtApplication):
ExtruderStack = Resources.UserType + 9
DefinitionChangesContainer = Resources.UserType + 10
SettingVisibilityPreset = Resources.UserType + 11
+ IntentInstanceContainer = Resources.UserType + 12
Q_ENUMS(ResourceTypes)
@@ -186,13 +198,12 @@ class CuraApplication(QtApplication):
self.empty_container = None # type: EmptyInstanceContainer
self.empty_definition_changes_container = None # type: EmptyInstanceContainer
self.empty_variant_container = None # type: EmptyInstanceContainer
+ self.empty_intent_container = None # type: EmptyInstanceContainer
self.empty_material_container = None # type: EmptyInstanceContainer
self.empty_quality_container = None # type: EmptyInstanceContainer
self.empty_quality_changes_container = None # type: EmptyInstanceContainer
- self._variant_manager = None
self._material_manager = None
- self._quality_manager = None
self._machine_manager = None
self._extruder_manager = None
self._container_manager = None
@@ -208,6 +219,17 @@ class CuraApplication(QtApplication):
self._cura_scene_controller = None
self._machine_error_checker = None
+ self._machine_settings_manager = MachineSettingsManager(self, parent = self)
+ self._material_management_model = None
+ self._quality_management_model = None
+
+ self._discovered_printer_model = DiscoveredPrintersModel(self, parent = self)
+ self._first_start_machine_actions_model = None
+ self._welcome_pages_model = WelcomePagesModel(self, parent = self)
+ self._add_printer_pages_model = AddPrinterPagesModel(self, parent = self)
+ self._whats_new_pages_model = WhatsNewPagesModel(self, parent = self)
+ self._text_manager = TextManager(parent = self)
+
self._quality_profile_drop_down_menu_model = None
self._custom_quality_profile_drop_down_menu_model = None
self._cura_API = CuraAPI(self)
@@ -237,15 +259,12 @@ class CuraApplication(QtApplication):
self._update_platform_activity_timer = None
- self._need_to_show_user_agreement = True
-
self._sidebar_custom_menu_items = [] # type: list # Keeps list of custom menu items for the side bar
self._plugins_loaded = False
# Backups
- self._auto_save = None
- self._save_data_enabled = True
+ self._auto_save = None # type: Optional[AutoSave]
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
self._container_registry_class = CuraContainerRegistry
@@ -329,7 +348,7 @@ class CuraApplication(QtApplication):
# Adds expected directory names and search paths for Resources.
def __addExpectedResourceDirsAndSearchPaths(self):
# this list of dir names will be used by UM to detect an old cura directory
- for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "quality_changes", "user", "variants"]:
+ for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "quality_changes", "user", "variants", "intent"]:
Resources.addExpectedDirNameInData(dir_name)
Resources.addSearchPath(os.path.join(self._app_install_dir, "share", "cura", "resources"))
@@ -387,6 +406,7 @@ class CuraApplication(QtApplication):
Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances")
Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
Resources.addStorageType(self.ResourceTypes.SettingVisibilityPreset, "setting_visibility")
+ Resources.addStorageType(self.ResourceTypes.IntentInstanceContainer, "intent")
self._container_registry.addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality")
self._container_registry.addResourceType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes")
@@ -396,6 +416,7 @@ class CuraApplication(QtApplication):
self._container_registry.addResourceType(self.ResourceTypes.ExtruderStack, "extruder_train")
self._container_registry.addResourceType(self.ResourceTypes.MachineStack, "machine")
self._container_registry.addResourceType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
+ self._container_registry.addResourceType(self.ResourceTypes.IntentInstanceContainer, "intent")
Resources.addType(self.ResourceTypes.QmlFiles, "qml")
Resources.addType(self.ResourceTypes.Firmware, "firmware")
@@ -405,7 +426,7 @@ class CuraApplication(QtApplication):
# Add empty variant, material and quality containers.
# Since they are empty, they should never be serialized and instead just programmatically created.
# We need them to simplify the switching between materials.
- self.empty_container = cura.Settings.cura_empty_instance_containers.empty_container # type: EmptyInstanceContainer
+ self.empty_container = cura.Settings.cura_empty_instance_containers.empty_container
self._container_registry.addContainer(
cura.Settings.cura_empty_instance_containers.empty_definition_changes_container)
@@ -414,6 +435,9 @@ class CuraApplication(QtApplication):
self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_variant_container)
self.empty_variant_container = cura.Settings.cura_empty_instance_containers.empty_variant_container
+ self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_intent_container)
+ self.empty_intent_container = cura.Settings.cura_empty_instance_containers.empty_intent_container
+
self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_material_container)
self.empty_material_container = cura.Settings.cura_empty_instance_containers.empty_material_container
@@ -428,14 +452,15 @@ class CuraApplication(QtApplication):
def __setLatestResouceVersionsForVersionUpgrade(self):
self._version_upgrade_manager.setCurrentVersions(
{
- ("quality", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
- ("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityChangesInstanceContainer, "application/x-uranium-instancecontainer"),
- ("machine_stack", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.MachineStack, "application/x-cura-globalstack"),
- ("extruder_train", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"),
- ("preferences", Preferences.Version * 1000000 + self.SettingVersion): (Resources.Preferences, "application/x-uranium-preferences"),
- ("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer"),
- ("definition_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.DefinitionChangesContainer, "application/x-uranium-instancecontainer"),
- ("variant", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.VariantInstanceContainer, "application/x-uranium-instancecontainer"),
+ ("quality", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
+ ("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityChangesInstanceContainer, "application/x-uranium-instancecontainer"),
+ ("intent", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.IntentInstanceContainer, "application/x-uranium-instancecontainer"),
+ ("machine_stack", GlobalStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.MachineStack, "application/x-cura-globalstack"),
+ ("extruder_train", ExtruderStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"),
+ ("preferences", Preferences.Version * 1000000 + self.SettingVersion): (Resources.Preferences, "application/x-uranium-preferences"),
+ ("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer"),
+ ("definition_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.DefinitionChangesContainer, "application/x-uranium-instancecontainer"),
+ ("variant", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.VariantInstanceContainer, "application/x-uranium-instancecontainer"),
}
)
@@ -450,7 +475,6 @@ class CuraApplication(QtApplication):
# Misc.:
"ConsoleLogger", #You want to be able to read the log if something goes wrong.
"CuraEngineBackend", #Cura is useless without this one since you can't slice.
- "UserAgreement", #Our lawyers want every user to see this at least once.
"FileLogger", #You want to be able to read the log if something goes wrong.
"XmlMaterialProfile", #Cura crashes without this one.
"Toolbox", #This contains the interface to enable/disable plug-ins, so if you disable it you can't enable it back.
@@ -488,10 +512,13 @@ class CuraApplication(QtApplication):
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading machines..."))
+ self._container_registry.allMetadataLoaded.connect(ContainerRegistry.getInstance)
+
with self._container_registry.lockFile():
self._container_registry.loadAllMetadata()
- # set the setting version for Preferences
+ self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up preferences..."))
+ # Set the setting version for Preferences
preferences = self.getPreferences()
preferences.addPreference("metadata/setting_version", 0)
preferences.setValue("metadata/setting_version", self.SettingVersion) #Don't make it equal to the default so that the setting version always gets written to the file.
@@ -509,8 +536,13 @@ class CuraApplication(QtApplication):
preferences.addPreference("cura/choice_on_profile_override", "always_ask")
preferences.addPreference("cura/choice_on_open_project", "always_ask")
preferences.addPreference("cura/use_multi_build_plate", False)
+ preferences.addPreference("cura/show_list_of_objects", False)
preferences.addPreference("view/settings_list_height", 400)
preferences.addPreference("view/settings_visible", False)
+ preferences.addPreference("view/settings_xpos", 0)
+ preferences.addPreference("view/settings_ypos", 56)
+ preferences.addPreference("view/colorscheme_xpos", 0)
+ preferences.addPreference("view/colorscheme_ypos", 56)
preferences.addPreference("cura/currency", "€")
preferences.addPreference("cura/material_settings", "{}")
@@ -522,7 +554,7 @@ class CuraApplication(QtApplication):
preferences.addPreference("cura/expanded_brands", "")
preferences.addPreference("cura/expanded_types", "")
- self._need_to_show_user_agreement = not preferences.getValue("general/accepted_user_agreement")
+ preferences.addPreference("general/accepted_user_agreement", False)
for key in [
"dialog_load_path", # dialog_save_path is in LocalFileOutputDevicePlugin
@@ -545,13 +577,20 @@ class CuraApplication(QtApplication):
@pyqtProperty(bool)
def needToShowUserAgreement(self) -> bool:
- return self._need_to_show_user_agreement
+ return not UM.Util.parseBool(self.getPreferences().getValue("general/accepted_user_agreement"))
- def setNeedToShowUserAgreement(self, set_value = True) -> None:
- self._need_to_show_user_agreement = set_value
+ @pyqtSlot(bool)
+ def setNeedToShowUserAgreement(self, set_value: bool = True) -> None:
+ self.getPreferences().setValue("general/accepted_user_agreement", str(not set_value))
+
+ @pyqtSlot(str, str)
+ def writeToLog(self, severity: str, message: str) -> None:
+ Logger.log(severity, message)
# DO NOT call this function to close the application, use checkAndExitApplication() instead which will perform
# pre-exit checks such as checking for in-progress USB printing, etc.
+ # Except for the 'Decline and close' in the 'User Agreement'-step in the Welcome-pages, that should be a hard exit.
+ @pyqtSlot()
def closeApplication(self) -> None:
Logger.log("i", "Close application")
main_window = self.getMainWindow()
@@ -604,9 +643,17 @@ class CuraApplication(QtApplication):
## A reusable dialogbox
#
- showMessageBox = pyqtSignal(str, str, str, str, int, int, arguments = ["title", "text", "informativeText", "detailedText", "buttons", "icon"])
+ showMessageBox = pyqtSignal(str,str, str, str, int, int,
+ arguments = ["title", "text", "informativeText", "detailedText","buttons", "icon"])
- def messageBox(self, title, text, informativeText = "", detailedText = "", buttons = QMessageBox.Ok, icon = QMessageBox.NoIcon, callback = None, callback_arguments = []):
+ def messageBox(self, title, text,
+ informativeText = "",
+ detailedText = "",
+ buttons = QMessageBox.Ok,
+ icon = QMessageBox.NoIcon,
+ callback = None,
+ callback_arguments = []
+ ):
self._message_box_callback = callback
self._message_box_callback_arguments = callback_arguments
self.showMessageBox.emit(title, text, informativeText, detailedText, buttons, icon)
@@ -632,14 +679,14 @@ class CuraApplication(QtApplication):
def discardOrKeepProfileChangesClosed(self, option: str) -> None:
global_stack = self.getGlobalContainerStack()
if option == "discard":
- for extruder in global_stack.extruders.values():
+ for extruder in global_stack.extruderList:
extruder.userChanges.clear()
global_stack.userChanges.clear()
# if the user decided to keep settings then the user settings should be re-calculated and validated for errors
# before slicing. To ensure that slicer uses right settings values
elif option == "keep":
- for extruder in global_stack.extruders.values():
+ for extruder in global_stack.extruderList:
extruder.userChanges.update()
global_stack.userChanges.update()
@@ -649,13 +696,10 @@ class CuraApplication(QtApplication):
self._message_box_callback(button, *self._message_box_callback_arguments)
self._message_box_callback = None
self._message_box_callback_arguments = []
-
- def setSaveDataEnabled(self, enabled: bool) -> None:
- self._save_data_enabled = enabled
# Cura has multiple locations where instance containers need to be saved, so we need to handle this differently.
def saveSettings(self):
- if not self.started or not self._save_data_enabled:
+ if not self.started:
# Do not do saving during application start or when data should not be saved on quit.
return
ContainerRegistry.getInstance().saveDirtyContainers()
@@ -676,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)
@@ -699,21 +745,6 @@ class CuraApplication(QtApplication):
def run(self):
super().run()
- container_registry = self._container_registry
-
- Logger.log("i", "Initializing variant manager")
- self._variant_manager = VariantManager(container_registry)
- self._variant_manager.initialize()
-
- Logger.log("i", "Initializing material manager")
- from cura.Machines.MaterialManager import MaterialManager
- self._material_manager = MaterialManager(container_registry, parent = self)
- self._material_manager.initialize()
-
- Logger.log("i", "Initializing quality manager")
- from cura.Machines.QualityManager import QualityManager
- self._quality_manager = QualityManager(self, parent = self)
- self._quality_manager.initialize()
Logger.log("i", "Initializing machine manager")
self._machine_manager = MachineManager(self, parent = self)
@@ -745,6 +776,11 @@ class CuraApplication(QtApplication):
# Initialize Cura API
self._cura_API.initialize()
+ self._output_device_manager.start()
+ self._welcome_pages_model.initialize()
+ self._add_printer_pages_model.initialize()
+ self._whats_new_pages_model.initialize()
+
# Detect in which mode to run and execute that mode
if self._is_headless:
self.runWithoutGUI()
@@ -810,7 +846,6 @@ class CuraApplication(QtApplication):
if diagonal < 1: #No printer added yet. Set a default camera distance for normal-sized printers.
diagonal = 375
camera.setPosition(Vector(-80, 250, 700) * diagonal / 375)
- camera.setPerspective(True)
camera.lookAt(Vector(0, 0, 0))
controller.getScene().setActiveCamera("3d")
@@ -839,10 +874,42 @@ class CuraApplication(QtApplication):
# Hide the splash screen
self.closeSplash()
+ @pyqtSlot(result = QObject)
+ def getDiscoveredPrintersModel(self, *args) -> "DiscoveredPrintersModel":
+ return self._discovered_printer_model
+
+ @pyqtSlot(result = QObject)
+ def getFirstStartMachineActionsModel(self, *args) -> "FirstStartMachineActionsModel":
+ if self._first_start_machine_actions_model is None:
+ self._first_start_machine_actions_model = FirstStartMachineActionsModel(self, parent = self)
+ if self.started:
+ self._first_start_machine_actions_model.initialize()
+ return self._first_start_machine_actions_model
+
@pyqtSlot(result = QObject)
def getSettingVisibilityPresetsModel(self, *args) -> SettingVisibilityPresetsModel:
return self._setting_visibility_presets_model
+ @pyqtSlot(result = QObject)
+ def getWelcomePagesModel(self, *args) -> "WelcomePagesModel":
+ return self._welcome_pages_model
+
+ @pyqtSlot(result = QObject)
+ def getAddPrinterPagesModel(self, *args) -> "AddPrinterPagesModel":
+ return self._add_printer_pages_model
+
+ @pyqtSlot(result = QObject)
+ def getWhatsNewPagesModel(self, *args) -> "WhatsNewPagesModel":
+ return self._whats_new_pages_model
+
+ @pyqtSlot(result = QObject)
+ def getMachineSettingsManager(self, *args) -> "MachineSettingsManager":
+ return self._machine_settings_manager
+
+ @pyqtSlot(result = QObject)
+ def getTextManager(self, *args) -> "TextManager":
+ return self._text_manager
+
def getCuraFormulaFunctions(self, *args) -> "CuraFormulaFunctions":
if self._cura_formula_functions is None:
self._cura_formula_functions = CuraFormulaFunctions(self)
@@ -861,20 +928,12 @@ class CuraApplication(QtApplication):
self._extruder_manager = ExtruderManager()
return self._extruder_manager
- def getVariantManager(self, *args) -> VariantManager:
- return self._variant_manager
-
- @pyqtSlot(result = QObject)
- def getMaterialManager(self, *args) -> "MaterialManager":
- return self._material_manager
-
- @pyqtSlot(result = QObject)
- def getQualityManager(self, *args) -> "QualityManager":
- return self._quality_manager
+ def getIntentManager(self, *args) -> IntentManager:
+ return IntentManager.getInstance()
def getObjectsModel(self, *args):
if self._object_manager is None:
- self._object_manager = ObjectsModel.createObjectsModel()
+ self._object_manager = ObjectsModel(self)
return self._object_manager
@pyqtSlot(result = QObject)
@@ -918,6 +977,18 @@ class CuraApplication(QtApplication):
def getMachineActionManager(self, *args):
return self._machine_action_manager
+ @pyqtSlot(result = QObject)
+ def getMaterialManagementModel(self) -> MaterialManagementModel:
+ if not self._material_management_model:
+ self._material_management_model = MaterialManagementModel(parent = self)
+ return self._material_management_model
+
+ @pyqtSlot(result = QObject)
+ def getQualityManagementModel(self) -> QualityManagementModel:
+ if not self._quality_management_model:
+ self._quality_management_model = QualityManagementModel(parent = self)
+ return self._quality_management_model
+
def getSimpleModeSettingsManager(self, *args):
if self._simple_mode_settings_manager is None:
self._simple_mode_settings_manager = SimpleModeSettingsManager()
@@ -933,7 +1004,7 @@ class CuraApplication(QtApplication):
return super().event(event)
- def getAutoSave(self):
+ def getAutoSave(self) -> Optional[AutoSave]:
return self._auto_save
## Get print information (duration / material used)
@@ -971,13 +1042,22 @@ class CuraApplication(QtApplication):
qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 0, "SceneController", self.getCuraSceneController)
qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, "ExtruderManager", self.getExtruderManager)
qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager)
+ qmlRegisterSingletonType(IntentManager, "Cura", 1, 6, "IntentManager", self.getIntentManager)
qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager", self.getSettingInheritanceManager)
qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager)
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
+ qmlRegisterType(NetworkingUtil, "Cura", 1, 5, "NetworkingUtil")
+
+ qmlRegisterType(WelcomePagesModel, "Cura", 1, 0, "WelcomePagesModel")
+ qmlRegisterType(WhatsNewPagesModel, "Cura", 1, 0, "WhatsNewPagesModel")
+ qmlRegisterType(AddPrinterPagesModel, "Cura", 1, 0, "AddPrinterPagesModel")
+ qmlRegisterType(TextManager, "Cura", 1, 0, "TextManager")
+ qmlRegisterType(RecommendedMode, "Cura", 1, 0, "RecommendedMode")
+
qmlRegisterType(NetworkMJPGImage, "Cura", 1, 0, "NetworkMJPGImage")
- qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 0, "ObjectsModel", self.getObjectsModel)
+ qmlRegisterType(ObjectsModel, "Cura", 1, 0, "ObjectsModel")
qmlRegisterType(BuildPlateModel, "Cura", 1, 0, "BuildPlateModel")
qmlRegisterType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel")
qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer")
@@ -987,18 +1067,23 @@ class CuraApplication(QtApplication):
qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel")
qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel")
qmlRegisterType(MaterialBrandsModel, "Cura", 1, 0, "MaterialBrandsModel")
- qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel")
- qmlRegisterType(MachineManagementModel, "Cura", 1, 0, "MachineManagementModel")
+ qmlRegisterSingletonType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel", self.getQualityManagementModel)
+ qmlRegisterSingletonType(MaterialManagementModel, "Cura", 1, 5, "MaterialManagementModel", self.getMaterialManagementModel)
+
+ qmlRegisterType(DiscoveredPrintersModel, "Cura", 1, 0, "DiscoveredPrintersModel")
qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0,
"QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel)
qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0,
"CustomQualityProfilesDropDownMenuModel", self.getCustomQualityProfilesDropDownMenuModel)
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
+ qmlRegisterType(IntentModel, "Cura", 1, 6, "IntentModel")
+ qmlRegisterType(IntentCategoryModel, "Cura", 1, 6, "IntentCategoryModel")
qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
qmlRegisterType(SettingVisibilityPresetsModel, "Cura", 1, 0, "SettingVisibilityPresetsModel")
qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel")
+ qmlRegisterType(FirstStartMachineActionsModel, "Cura", 1, 0, "FirstStartMachineActionsModel")
qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel")
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.getInstance)
@@ -1055,7 +1140,6 @@ class CuraApplication(QtApplication):
self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition())
self._camera_animation.start()
- requestAddPrinter = pyqtSignal()
activityChanged = pyqtSignal()
sceneBoundingBoxChanged = pyqtSignal()
@@ -1197,7 +1281,7 @@ class CuraApplication(QtApplication):
@pyqtSlot()
def arrangeObjectsToAllBuildPlates(self) -> None:
nodes_to_arrange = []
- for node in DepthFirstIterator(self.getController().getScene().getRoot()): # type: ignore
+ for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if not isinstance(node, SceneNode):
continue
@@ -1224,7 +1308,7 @@ class CuraApplication(QtApplication):
def arrangeAll(self) -> None:
nodes_to_arrange = []
active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate
- for node in DepthFirstIterator(self.getController().getScene().getRoot()): # type: ignore
+ for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if not isinstance(node, SceneNode):
continue
@@ -1262,7 +1346,13 @@ class CuraApplication(QtApplication):
Logger.log("i", "Reloading all loaded mesh data.")
nodes = []
has_merged_nodes = False
- for node in DepthFirstIterator(self.getController().getScene().getRoot()): # type: ignore
+ gcode_filename = None # type: Optional[str]
+ for node in DepthFirstIterator(self.getController().getScene().getRoot()):
+ # Objects loaded from Gcode should also be included.
+ gcode_filename = node.callDecoration("getGcodeFileName")
+ if gcode_filename is not None:
+ break
+
if not isinstance(node, CuraSceneNode) or not node.getMeshData():
if node.getName() == "MergedMesh":
has_merged_nodes = True
@@ -1270,21 +1360,29 @@ class CuraApplication(QtApplication):
nodes.append(node)
+ # We can open only one gcode file at the same time. If the current view has a gcode file open, just reopen it
+ # for reloading.
+ if gcode_filename:
+ self._openFile(gcode_filename)
+
if not nodes:
return
for node in nodes:
- file_name = node.getMeshData().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)
+ mesh_data = node.getMeshData()
- 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:
@@ -1515,8 +1613,12 @@ class CuraApplication(QtApplication):
openProjectFile = pyqtSignal(QUrl, arguments = ["project_file"]) # Emitted when a project file is about to open.
- @pyqtSlot(QUrl, bool)
- def readLocalFile(self, file, skip_project_file_check = False):
+ @pyqtSlot(QUrl, str)
+ @pyqtSlot(QUrl)
+ ## Open a local file
+ # \param project_mode How to handle project files. Either None(default): Follow user preference, "open_as_model" or
+ # "open_as_project". This parameter is only considered if the file is a project file.
+ def readLocalFile(self, file: QUrl, project_mode: Optional[str] = None):
if not file.isValid():
return
@@ -1527,10 +1629,24 @@ class CuraApplication(QtApplication):
self.deleteAll()
break
- if not skip_project_file_check and self.checkIsValidProjectFile(file):
+ is_project_file = self.checkIsValidProjectFile(file)
+
+ if project_mode is None:
+ project_mode = self.getPreferences().getValue("cura/choice_on_open_project")
+
+ if is_project_file and project_mode == "open_as_project":
+ # open as project immediately without presenting a dialog
+ workspace_handler = self.getWorkspaceFileHandler()
+ workspace_handler.readLocalFile(file)
+ return
+
+ if is_project_file and project_mode == "always_ask":
+ # present a dialog asking to open as project or import models
self.callLater(self.openProjectFile.emit, file)
return
+ # Either the file is a model file or we want to load only models from project. Continue to load models.
+
if self.getPreferences().getValue("cura/select_models_on_load"):
Selection.clear()
@@ -1591,7 +1707,7 @@ class CuraApplication(QtApplication):
arranger = Arrange.create(x = machine_width, y = machine_depth, fixed_nodes = fixed_nodes)
min_offset = 8
default_extruder_position = self.getMachineManager().defaultExtruderPosition
- default_extruder_id = self._global_container_stack.extruders[default_extruder_position].getId()
+ default_extruder_id = self._global_container_stack.extruderList[int(default_extruder_position)].getId()
select_models_on_load = self.getPreferences().getValue("cura/select_models_on_load")
@@ -1685,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
@@ -1715,3 +1831,73 @@ class CuraApplication(QtApplication):
def getSidebarCustomMenuItems(self) -> list:
return self._sidebar_custom_menu_items
+ @pyqtSlot(result = bool)
+ def shouldShowWelcomeDialog(self) -> bool:
+ # Only show the complete flow if there is no printer yet.
+ return self._machine_manager.activeMachine is None
+
+ @pyqtSlot(result = bool)
+ def shouldShowWhatsNewDialog(self) -> bool:
+ has_active_machine = self._machine_manager.activeMachine is not None
+ has_app_just_upgraded = self.hasJustUpdatedFromOldVersion()
+
+ # Only show the what's new dialog if there's no machine and we have just upgraded
+ show_whatsnew_only = has_active_machine and has_app_just_upgraded
+ return show_whatsnew_only
+
+ @pyqtSlot(result = int)
+ def appWidth(self) -> int:
+ main_window = QtApplication.getInstance().getMainWindow()
+ if main_window:
+ return main_window.width()
+ else:
+ return 0
+
+ @pyqtSlot(result = int)
+ def appHeight(self) -> int:
+ main_window = QtApplication.getInstance().getMainWindow()
+ if main_window:
+ return main_window.height()
+ else:
+ return 0
+
+ @pyqtSlot()
+ def deleteAll(self, only_selectable: bool = True) -> None:
+ super().deleteAll(only_selectable = only_selectable)
+
+ # Also remove nodes with LayerData
+ self._removeNodesWithLayerData(only_selectable = only_selectable)
+
+ def _removeNodesWithLayerData(self, only_selectable: bool = True) -> None:
+ Logger.log("i", "Clearing scene")
+ nodes = []
+ for node in DepthFirstIterator(self.getController().getScene().getRoot()):
+ if not isinstance(node, SceneNode):
+ continue
+ if not node.isEnabled():
+ continue
+ if (not node.getMeshData() and not node.callDecoration("getLayerData")) and not node.callDecoration("isGroup"):
+ continue # Node that doesnt have a mesh and is not a group.
+ if only_selectable and not node.isSelectable():
+ continue # Only remove nodes that are selectable.
+ if not node.callDecoration("isSliceable") and not node.callDecoration("getLayerData") and not node.callDecoration("isGroup"):
+ continue # Grouped nodes don't need resetting as their parent (the group) is resetted)
+ nodes.append(node)
+ if nodes:
+ from UM.Operations.GroupedOperation import GroupedOperation
+ op = GroupedOperation()
+
+ for node in nodes:
+ from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
+ op.addOperation(RemoveSceneNodeOperation(node))
+
+ # Reset the print information
+ self.getController().getScene().sceneChanged.emit(node)
+
+ 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/CuraVersion.py.in b/cura/CuraVersion.py.in
index 1a500df248..4583e76f67 100644
--- a/cura/CuraVersion.py.in
+++ b/cura/CuraVersion.py.in
@@ -6,7 +6,6 @@ CuraAppDisplayName = "@CURA_APP_DISPLAY_NAME@"
CuraVersion = "@CURA_VERSION@"
CuraBuildType = "@CURA_BUILDTYPE@"
CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False
-CuraSDKVersion = "@CURA_SDK_VERSION@"
CuraCloudAPIRoot = "@CURA_CLOUD_API_ROOT@"
CuraCloudAPIVersion = "@CURA_CLOUD_API_VERSION@"
CuraCloudAccountAPIRoot = "@CURA_CLOUD_ACCOUNT_API_ROOT@"
diff --git a/cura/CuraView.py b/cura/CuraView.py
index 978c651b43..b358558dff 100644
--- a/cura/CuraView.py
+++ b/cura/CuraView.py
@@ -3,8 +3,11 @@
from PyQt5.QtCore import pyqtProperty, QUrl
+from UM.Resources import Resources
from UM.View.View import View
+from cura.CuraApplication import CuraApplication
+
# Since Cura has a few pre-defined "space claims" for the locations of certain components, we've provided some structure
# to indicate this.
@@ -12,13 +15,20 @@ from UM.View.View import View
# the stageMenuComponent returns an item that should be used somehwere in the stage menu. It's up to the active stage
# to actually do something with this.
class CuraView(View):
- def __init__(self, parent = None) -> None:
+ def __init__(self, parent = None, use_empty_menu_placeholder: bool = False) -> None:
super().__init__(parent)
+ self._empty_menu_placeholder_url = QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles,
+ "EmptyViewMenuComponent.qml"))
+ self._use_empty_menu_placeholder = use_empty_menu_placeholder
+
@pyqtProperty(QUrl, constant = True)
def mainComponent(self) -> QUrl:
return self.getDisplayComponent("main")
@pyqtProperty(QUrl, constant = True)
def stageMenuComponent(self) -> QUrl:
- return self.getDisplayComponent("menu")
\ No newline at end of file
+ url = self.getDisplayComponent("menu")
+ if not url.toString() and self._use_empty_menu_placeholder:
+ url = self._empty_menu_placeholder_url
+ return url
diff --git a/cura/Layer.py b/cura/Layer.py
index 9cd45380fc..73fda64a45 100644
--- a/cura/Layer.py
+++ b/cura/Layer.py
@@ -1,14 +1,20 @@
-from UM.Mesh.MeshBuilder import MeshBuilder
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import List
import numpy
+from UM.Mesh.MeshBuilder import MeshBuilder
+from UM.Mesh.MeshData import MeshData
+from cura.LayerPolygon import LayerPolygon
+
class Layer:
- def __init__(self, layer_id):
+ def __init__(self, layer_id: int) -> None:
self._id = layer_id
self._height = 0.0
self._thickness = 0.0
- self._polygons = []
+ self._polygons = [] # type: List[LayerPolygon]
self._element_count = 0
@property
@@ -20,7 +26,7 @@ class Layer:
return self._thickness
@property
- def polygons(self):
+ def polygons(self) -> List[LayerPolygon]:
return self._polygons
@property
@@ -33,14 +39,14 @@ class Layer:
def setThickness(self, thickness):
self._thickness = thickness
- def lineMeshVertexCount(self):
+ def lineMeshVertexCount(self) -> int:
result = 0
for polygon in self._polygons:
result += polygon.lineMeshVertexCount()
return result
- def lineMeshElementCount(self):
+ def lineMeshElementCount(self) -> int:
result = 0
for polygon in self._polygons:
result += polygon.lineMeshElementCount()
@@ -57,18 +63,18 @@ class Layer:
result_index_offset += polygon.lineMeshElementCount()
self._element_count += polygon.elementCount
- return (result_vertex_offset, result_index_offset)
+ return result_vertex_offset, result_index_offset
- def createMesh(self):
+ def createMesh(self) -> MeshData:
return self.createMeshOrJumps(True)
- def createJumps(self):
+ def createJumps(self) -> MeshData:
return self.createMeshOrJumps(False)
# Defines the two triplets of local point indices to use to draw the two faces for each line segment in createMeshOrJump
__index_pattern = numpy.array([[0, 3, 2, 0, 1, 3]], dtype = numpy.int32 )
- def createMeshOrJumps(self, make_mesh):
+ def createMeshOrJumps(self, make_mesh: bool) -> MeshData:
builder = MeshBuilder()
line_count = 0
@@ -79,14 +85,14 @@ class Layer:
for polygon in self._polygons:
line_count += polygon.jumpCount
- # Reserve the neccesary space for the data upfront
+ # Reserve the necessary space for the data upfront
builder.reserveFaceAndVertexCount(2 * line_count, 4 * line_count)
for polygon in self._polygons:
- # Filter out the types of lines we are not interesed in depending on whether we are drawing the mesh or the jumps.
+ # Filter out the types of lines we are not interested in depending on whether we are drawing the mesh or the jumps.
index_mask = numpy.logical_not(polygon.jumpMask) if make_mesh else polygon.jumpMask
- # Create an array with rows [p p+1] and only keep those we whant to draw based on make_mesh
+ # Create an array with rows [p p+1] and only keep those we want to draw based on make_mesh
points = numpy.concatenate((polygon.data[:-1], polygon.data[1:]), 1)[index_mask.ravel()]
# Line types of the points we want to draw
line_types = polygon.types[index_mask]
diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py
index 072d5f94f5..0d6489aaa2 100644
--- a/cura/LayerPolygon.py
+++ b/cura/LayerPolygon.py
@@ -1,7 +1,7 @@
-# Copyright (c) 2017 Ultimaker B.V.
+# 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
@@ -20,7 +20,7 @@ class LayerPolygon:
MoveCombingType = 8
MoveRetractionType = 9
SupportInterfaceType = 10
- PrimeTower = 11
+ PrimeTowerType = 11
__number_of_types = 12
__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)
@@ -61,19 +61,19 @@ class LayerPolygon:
# When type is used as index returns true if type == LayerPolygon.InfillType or type == LayerPolygon.SkinType or type == LayerPolygon.SupportInfillType
# Should be generated in better way, not hardcoded.
- self._isInfillOrSkinTypeMap = numpy.array([0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1], dtype=numpy.bool)
+ self._isInfillOrSkinTypeMap = numpy.array([0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0], dtype = numpy.bool)
self._build_cache_line_mesh_mask = None # type: Optional[numpy.ndarray]
self._build_cache_needed_points = None # type: Optional[numpy.ndarray]
def buildCache(self) -> None:
# For the line mesh we do not draw Infill or Jumps. Therefore those lines are filtered out.
- self._build_cache_line_mesh_mask = numpy.ones(self._jump_mask.shape, dtype=bool)
+ self._build_cache_line_mesh_mask = numpy.ones(self._jump_mask.shape, dtype = bool)
mesh_line_count = numpy.sum(self._build_cache_line_mesh_mask)
self._index_begin = 0
self._index_end = mesh_line_count
- self._build_cache_needed_points = numpy.ones((len(self._types), 2), dtype=numpy.bool)
+ self._build_cache_needed_points = numpy.ones((len(self._types), 2), dtype = numpy.bool)
# Only if the type of line segment changes do we need to add an extra vertex to change colors
self._build_cache_needed_points[1:, 0][:, numpy.newaxis] = self._types[1:] != self._types[:-1]
# Mark points as unneeded if they are of types we don't want in the line mesh according to the calculated mask
@@ -136,9 +136,9 @@ class LayerPolygon:
self._index_begin += index_offset
self._index_end += index_offset
- indices[self._index_begin:self._index_end, :] = numpy.arange(self._index_end-self._index_begin, dtype=numpy.int32).reshape((-1, 1))
+ indices[self._index_begin:self._index_end, :] = numpy.arange(self._index_end-self._index_begin, dtype = numpy.int32).reshape((-1, 1))
# When the line type changes the index needs to be increased by 2.
- indices[self._index_begin:self._index_end, :] += numpy.cumsum(needed_points_list[line_mesh_mask.ravel(), 0], dtype=numpy.int32).reshape((-1, 1))
+ indices[self._index_begin:self._index_end, :] += numpy.cumsum(needed_points_list[line_mesh_mask.ravel(), 0], dtype = numpy.int32).reshape((-1, 1))
# Each line segment goes from it's starting point p to p+1, offset by the vertex index.
# The -1 is to compensate for the neccecarily True value of needed_points_list[0,0] which causes an unwanted +1 in cumsum above.
indices[self._index_begin:self._index_end, :] += numpy.array([self._vertex_begin - 1, self._vertex_begin])
@@ -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
@@ -245,7 +245,7 @@ class LayerPolygon:
theme.getColor("layerview_move_combing").getRgbF(), # MoveCombingType
theme.getColor("layerview_move_retraction").getRgbF(), # MoveRetractionType
theme.getColor("layerview_support_interface").getRgbF(), # SupportInterfaceType
- theme.getColor("layerview_prime_tower").getRgbF()
+ theme.getColor("layerview_prime_tower").getRgbF() # PrimeTowerType
])
return cls.__color_map
diff --git a/cura/MachineAction.py b/cura/MachineAction.py
index 94b096f9c1..0f05401c89 100644
--- a/cura/MachineAction.py
+++ b/cura/MachineAction.py
@@ -2,8 +2,9 @@
# Cura is released under the terms of the LGPLv3 or higher.
import os
+from typing import Optional
-from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
+from PyQt5.QtCore import QObject, QUrl, pyqtSlot, pyqtProperty, pyqtSignal
from UM.Logger import Logger
from UM.PluginObject import PluginObject
@@ -33,6 +34,12 @@ class MachineAction(QObject, PluginObject):
def getKey(self) -> str:
return self._key
+ ## Whether this action needs to ask the user anything.
+ # If not, we shouldn't present the user with certain screens which otherwise show up.
+ # Defaults to true to be in line with the old behaviour.
+ def needsUserInteraction(self) -> bool:
+ return True
+
@pyqtProperty(str, notify = labelChanged)
def label(self) -> str:
return self._label
@@ -66,18 +73,26 @@ class MachineAction(QObject, PluginObject):
return self._finished
## Protected helper to create a view object based on provided QML.
- def _createViewFromQML(self) -> None:
+ def _createViewFromQML(self) -> Optional["QObject"]:
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
if plugin_path is None:
Logger.log("e", "Cannot create QML view: cannot find plugin path for plugin [%s]", self.getPluginId())
- return
+ return None
path = os.path.join(plugin_path, self._qml_url)
from cura.CuraApplication import CuraApplication
- self._view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
+ view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
+ return view
- @pyqtProperty(QObject, constant = True)
- def displayItem(self):
- if not self._view:
- self._createViewFromQML()
- return self._view
+ @pyqtProperty(QUrl, constant = True)
+ def qmlPath(self) -> "QUrl":
+ plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
+ if plugin_path is None:
+ Logger.log("e", "Cannot create QML view: cannot find plugin path for plugin [%s]", self.getPluginId())
+ return QUrl("")
+ path = os.path.join(plugin_path, self._qml_url)
+ return QUrl.fromLocalFile(path)
+
+ @pyqtSlot(result = QObject)
+ def getDisplayItem(self) -> Optional["QObject"]:
+ return self._createViewFromQML()
diff --git a/cura/Machines/ContainerNode.py b/cura/Machines/ContainerNode.py
index eef1c63127..a8bbf0a537 100644
--- a/cura/Machines/ContainerNode.py
+++ b/cura/Machines/ContainerNode.py
@@ -1,64 +1,64 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import Optional, Any, Dict, Union, TYPE_CHECKING
-
-from collections import OrderedDict
+from typing import Any, Dict, Optional
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
+from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Logger import Logger
from UM.Settings.InstanceContainer import InstanceContainer
-##
-# A metadata / container combination. Use getContainer() to get the container corresponding to the metadata.
-#
-# ContainerNode is a multi-purpose class. It has two main purposes:
-# 1. It encapsulates an InstanceContainer. It contains that InstanceContainer's
-# - metadata (Always)
-# - container (lazy-loaded when needed)
-# 2. It also serves as a node in a hierarchical InstanceContainer lookup table/tree.
-# This is used in Variant, Material, and Quality Managers.
+## A node in the container tree. It represents one container.
#
+# The container it represents is referenced by its container_id. During normal
+# use of the tree, this container is not constructed. Only when parts of the
+# tree need to get loaded in the container stack should it get constructed.
class ContainerNode:
- __slots__ = ("_metadata", "_container", "children_map")
+ ## Creates a new node for the container tree.
+ # \param container_id The ID of the container that this node should
+ # represent.
+ def __init__(self, container_id: str) -> None:
+ self.container_id = container_id
+ self._container = None # type: Optional[InstanceContainer]
+ self.children_map = {} # type: Dict[str, ContainerNode] # Mapping from container ID to container node.
- def __init__(self, metadata: Optional[Dict[str, Any]] = None) -> None:
- self._metadata = metadata
- self._container = None # type: Optional[InstanceContainer]
- self.children_map = OrderedDict() # type: ignore # This is because it's children are supposed to override it.
+ ## Gets the metadata of the container that this node represents.
+ # Getting the metadata from the container directly is about 10x as fast.
+ # \return The metadata of the container in this node.
+ def getMetadata(self):
+ return ContainerRegistry.getInstance().findContainersMetadata(id = self.container_id)[0]
- ## Get an entry value from the metadata
+ ## Get an entry from the metadata of the container that this node contains.
+ #
+ # This is just a convenience function.
+ # \param entry The metadata entry key to return.
+ # \param default If the metadata is not present or the container is not
+ # found, the value of this default is returned.
+ # \return The value of the metadata entry, or the default if it was not
+ # present.
def getMetaDataEntry(self, entry: str, default: Any = None) -> Any:
- if self._metadata is None:
+ container_metadata = ContainerRegistry.getInstance().findContainersMetadata(id = self.container_id)
+ if len(container_metadata) == 0:
return default
- return self._metadata.get(entry, default)
+ return container_metadata[0].get(entry, default)
- def getMetadata(self) -> Dict[str, Any]:
- if self._metadata is None:
- return {}
- return self._metadata
-
- def getChildNode(self, child_key: str) -> Optional["ContainerNode"]:
- return self.children_map.get(child_key)
-
- def getContainer(self) -> Optional["InstanceContainer"]:
- if self._metadata is None:
- Logger.log("e", "Cannot get container for a ContainerNode without metadata.")
- return None
-
- if self._container is None:
- container_id = self._metadata["id"]
- from UM.Settings.ContainerRegistry import ContainerRegistry
- container_list = ContainerRegistry.getInstance().findInstanceContainers(id = container_id)
- if not container_list:
- Logger.log("e", "Failed to lazy-load container [{container_id}]. Cannot find it.".format(container_id = container_id))
+ ## The container that this node's container ID refers to.
+ #
+ # This can be used to finally instantiate the container in order to put it
+ # in the container stack.
+ # \return A container.
+ @property
+ def container(self) -> Optional[InstanceContainer]:
+ if not self._container:
+ container_list = ContainerRegistry.getInstance().findInstanceContainers(id = self.container_id)
+ if len(container_list) == 0:
+ Logger.log("e", "Failed to lazy-load container [{container_id}]. Cannot find it.".format(container_id = self.container_id))
error_message = ConfigurationErrorMessage.getInstance()
- error_message.addFaultyContainers(container_id)
+ error_message.addFaultyContainers(self.container_id)
return None
self._container = container_list[0]
-
return self._container
def __str__(self) -> str:
- return "%s[%s]" % (self.__class__.__name__, self.getMetaDataEntry("id"))
+ return "%s[%s]" % (self.__class__.__name__, self.container_id)
\ No newline at end of file
diff --git a/cura/Machines/ContainerTree.py b/cura/Machines/ContainerTree.py
new file mode 100644
index 0000000000..c2bfabea2c
--- /dev/null
+++ b/cura/Machines/ContainerTree.py
@@ -0,0 +1,158 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from UM.Job import Job # For our background task of loading MachineNodes lazily.
+from UM.JobQueue import JobQueue # For our background task of loading MachineNodes lazily.
+from UM.Logger import Logger
+from UM.Settings.ContainerRegistry import ContainerRegistry # To listen to containers being added.
+from UM.Signal import Signal
+import cura.CuraApplication # Imported like this to prevent circular dependencies.
+from cura.Machines.MachineNode import MachineNode
+from cura.Settings.GlobalStack import GlobalStack # To listen only to global stacks being added.
+
+from typing import Dict, List, Optional, TYPE_CHECKING
+import time
+
+if TYPE_CHECKING:
+ from cura.Machines.QualityGroup import QualityGroup
+ from cura.Machines.QualityChangesGroup import QualityChangesGroup
+ from UM.Settings.ContainerStack import ContainerStack
+
+
+## This class contains a look-up tree for which containers are available at
+# which stages of configuration.
+#
+# The tree starts at the machine definitions. For every distinct definition
+# there will be one machine node here.
+#
+# All of the fallbacks for material choices, quality choices, etc. should be
+# encoded in this tree. There must always be at least one child node (for
+# nodes that have children) but that child node may be a node representing the
+# empty instance container.
+class ContainerTree:
+ __instance = None
+
+ @classmethod
+ def getInstance(cls):
+ if cls.__instance is None:
+ cls.__instance = ContainerTree()
+ return cls.__instance
+
+ def __init__(self) -> None:
+ self.machines = self._MachineNodeMap() # Mapping from definition ID to machine nodes with lazy loading.
+ self.materialsChanged = Signal() # Emitted when any of the material nodes in the tree got changed.
+ cura.CuraApplication.CuraApplication.getInstance().initializationFinished.connect(self._onStartupFinished) # Start the background task to load more machine nodes after start-up is completed.
+
+ ## Get the quality groups available for the currently activated printer.
+ #
+ # This contains all quality groups, enabled or disabled. To check whether
+ # the quality group can be activated, test for the
+ # ``QualityGroup.is_available`` property.
+ # \return For every quality type, one quality group.
+ def getCurrentQualityGroups(self) -> Dict[str, "QualityGroup"]:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return {}
+ variant_names = [extruder.variant.getName() for extruder in global_stack.extruderList]
+ material_bases = [extruder.material.getMetaDataEntry("base_file") for extruder in global_stack.extruderList]
+ extruder_enabled = [extruder.isEnabled for extruder in global_stack.extruderList]
+ return self.machines[global_stack.definition.getId()].getQualityGroups(variant_names, material_bases, extruder_enabled)
+
+ ## Get the quality changes groups available for the currently activated
+ # printer.
+ #
+ # This contains all quality changes groups, enabled or disabled. To check
+ # whether the quality changes group can be activated, test for the
+ # ``QualityChangesGroup.is_available`` property.
+ # \return A list of all quality changes groups.
+ def getCurrentQualityChangesGroups(self) -> List["QualityChangesGroup"]:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return []
+ variant_names = [extruder.variant.getName() for extruder in global_stack.extruderList]
+ material_bases = [extruder.material.getMetaDataEntry("base_file") for extruder in global_stack.extruderList]
+ extruder_enabled = [extruder.isEnabled for extruder in global_stack.extruderList]
+ return self.machines[global_stack.definition.getId()].getQualityChangesGroups(variant_names, material_bases, extruder_enabled)
+
+ ## Ran after completely starting up the application.
+ def _onStartupFinished(self):
+ currently_added = ContainerRegistry.getInstance().findContainerStacks() # Find all currently added global stacks.
+ JobQueue.getInstance().add(self._MachineNodeLoadJob(self, currently_added))
+
+ ## Dictionary-like object that contains the machines.
+ #
+ # This handles the lazy loading of MachineNodes.
+ class _MachineNodeMap:
+ def __init__(self) -> None:
+ self._machines = {} # type: Dict[str, MachineNode]
+
+ ## Returns whether a printer with a certain definition ID exists. This
+ # is regardless of whether or not the printer is loaded yet.
+ # \param definition_id The definition to look for.
+ # \return Whether or not a printer definition exists with that name.
+ def __contains__(self, definition_id: str) -> bool:
+ return len(ContainerRegistry.getInstance().findContainersMetadata(id = definition_id)) > 0
+
+ ## Returns a machine node for the specified definition ID.
+ #
+ # If the machine node wasn't loaded yet, this will load it lazily.
+ # \param definition_id The definition to look for.
+ # \return A machine node for that definition.
+ def __getitem__(self, definition_id: str) -> MachineNode:
+ if definition_id not in self._machines:
+ start_time = time.time()
+ self._machines[definition_id] = MachineNode(definition_id)
+ self._machines[definition_id].materialsChanged.connect(ContainerTree.getInstance().materialsChanged)
+ Logger.log("d", "Adding container tree for {definition_id} took {duration} seconds.".format(definition_id = definition_id, duration = time.time() - start_time))
+ return self._machines[definition_id]
+
+ ## Gets a machine node for the specified definition ID, with default.
+ #
+ # The default is returned if there is no definition with the specified
+ # ID. If the machine node wasn't loaded yet, this will load it lazily.
+ # \param definition_id The definition to look for.
+ # \param default The machine node to return if there is no machine
+ # with that definition (can be ``None`` optionally or if not
+ # provided).
+ # \return A machine node for that definition, or the default if there
+ # is no definition with the provided definition_id.
+ def get(self, definition_id: str, default: Optional[MachineNode] = None) -> Optional[MachineNode]:
+ if definition_id not in self:
+ return default
+ return self[definition_id]
+
+ ## Returns whether we've already cached this definition's node.
+ # \param definition_id The definition that we may have cached.
+ # \return ``True`` if it's cached.
+ def is_loaded(self, definition_id: str) -> bool:
+ return definition_id in self._machines
+
+ ## Pre-loads all currently added printers as a background task so that
+ # switching printers in the interface is faster.
+ class _MachineNodeLoadJob(Job):
+ ## Creates a new background task.
+ # \param tree_root The container tree instance. This cannot be
+ # obtained through the singleton static function since the instance
+ # may not yet be constructed completely.
+ # \param container_stacks All of the stacks to pre-load the container
+ # trees for. This needs to be provided from here because the stacks
+ # need to be constructed on the main thread because they are QObject.
+ def __init__(self, tree_root: "ContainerTree", container_stacks: List["ContainerStack"]):
+ self.tree_root = tree_root
+ self.container_stacks = container_stacks
+ super().__init__()
+
+ ## Starts the background task.
+ #
+ # The ``JobQueue`` will schedule this on a different thread.
+ def run(self) -> None:
+ for stack in self.container_stacks: # Load all currently-added containers.
+ if not isinstance(stack, GlobalStack):
+ continue
+ # Allow a thread switch after every container.
+ # Experimentally, sleep(0) didn't allow switching. sleep(0.1) or sleep(0.2) neither.
+ # We're in no hurry though. Half a second is fine.
+ time.sleep(0.5)
+ definition_id = stack.definition.getId()
+ if not self.tree_root.machines.is_loaded(definition_id):
+ _ = self.tree_root.machines[definition_id]
diff --git a/cura/Machines/IntentNode.py b/cura/Machines/IntentNode.py
new file mode 100644
index 0000000000..2b3a596f81
--- /dev/null
+++ b/cura/Machines/IntentNode.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import TYPE_CHECKING
+
+from UM.Settings.ContainerRegistry import ContainerRegistry
+
+from cura.Machines.ContainerNode import ContainerNode
+
+if TYPE_CHECKING:
+ from cura.Machines.QualityNode import QualityNode
+
+
+## This class represents an intent profile in the container tree.
+#
+# This class has no more subnodes.
+class IntentNode(ContainerNode):
+ def __init__(self, container_id: str, quality: "QualityNode") -> None:
+ super().__init__(container_id)
+ self.quality = quality
+ self.intent_category = ContainerRegistry.getInstance().findContainersMetadata(id = container_id)[0].get("intent_category", "default")
diff --git a/cura/Machines/MachineErrorChecker.py b/cura/Machines/MachineErrorChecker.py
index fb11123af6..4c6ed891b1 100644
--- a/cura/Machines/MachineErrorChecker.py
+++ b/cura/Machines/MachineErrorChecker.py
@@ -58,7 +58,6 @@ class MachineErrorChecker(QObject):
# Whenever the machine settings get changed, we schedule an error check.
self._machine_manager.globalContainerChanged.connect(self.startErrorCheck)
- self._machine_manager.globalValueChanged.connect(self.startErrorCheck)
self._onMachineChanged()
@@ -67,7 +66,7 @@ class MachineErrorChecker(QObject):
self._global_stack.propertyChanged.disconnect(self.startErrorCheckPropertyChanged)
self._global_stack.containersChanged.disconnect(self.startErrorCheck)
- for extruder in self._global_stack.extruders.values():
+ for extruder in self._global_stack.extruderList:
extruder.propertyChanged.disconnect(self.startErrorCheckPropertyChanged)
extruder.containersChanged.disconnect(self.startErrorCheck)
@@ -77,7 +76,7 @@ class MachineErrorChecker(QObject):
self._global_stack.propertyChanged.connect(self.startErrorCheckPropertyChanged)
self._global_stack.containersChanged.connect(self.startErrorCheck)
- for extruder in self._global_stack.extruders.values():
+ for extruder in self._global_stack.extruderList:
extruder.propertyChanged.connect(self.startErrorCheckPropertyChanged)
extruder.containersChanged.connect(self.startErrorCheck)
@@ -127,7 +126,7 @@ class MachineErrorChecker(QObject):
# Populate the (stack, key) tuples to check
self._stacks_and_keys_to_check = deque()
- for stack in [global_stack] + list(global_stack.extruders.values()):
+ for stack in global_stack.extruderList:
for key in stack.getAllKeys():
self._stacks_and_keys_to_check.append((stack, key))
@@ -168,7 +167,7 @@ class MachineErrorChecker(QObject):
if validator_type:
validator = validator_type(key)
validation_state = validator(stack)
- if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
+ if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError, ValidatorState.Invalid):
# Finish
self._setResult(True)
return
diff --git a/cura/Machines/MachineNode.py b/cura/Machines/MachineNode.py
new file mode 100644
index 0000000000..92f71b409b
--- /dev/null
+++ b/cura/Machines/MachineNode.py
@@ -0,0 +1,183 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Dict, List
+
+from UM.Logger import Logger
+from UM.Signal import Signal
+from UM.Util import parseBool
+from UM.Settings.ContainerRegistry import ContainerRegistry # To find all the variants for this machine.
+
+import cura.CuraApplication # Imported like this to prevent circular dependencies.
+from cura.Machines.ContainerNode import ContainerNode
+from cura.Machines.QualityChangesGroup import QualityChangesGroup # To construct groups of quality changes profiles that belong together.
+from cura.Machines.QualityGroup import QualityGroup # To construct groups of quality profiles that belong together.
+from cura.Machines.QualityNode import QualityNode
+from cura.Machines.VariantNode import VariantNode
+import UM.FlameProfiler
+
+
+## This class represents a machine in the container tree.
+#
+# The subnodes of these nodes are variants.
+class MachineNode(ContainerNode):
+ def __init__(self, container_id: str) -> None:
+ super().__init__(container_id)
+ self.variants = {} # type: Dict[str, VariantNode] # Mapping variant names to their nodes.
+ self.global_qualities = {} # type: Dict[str, QualityNode] # Mapping quality types to the global quality for those types.
+ self.materialsChanged = Signal() # Emitted when one of the materials underneath this machine has been changed.
+
+ container_registry = ContainerRegistry.getInstance()
+ try:
+ my_metadata = container_registry.findContainersMetadata(id = container_id)[0]
+ except IndexError:
+ Logger.log("Unable to find metadata for container %s", container_id)
+ my_metadata = {}
+ # Some of the metadata is cached upon construction here.
+ # ONLY DO THAT FOR METADATA THAT DOESN'T CHANGE DURING RUNTIME!
+ # Otherwise you need to keep it up-to-date during runtime.
+ self.has_materials = parseBool(my_metadata.get("has_materials", "true"))
+ self.has_variants = parseBool(my_metadata.get("has_variants", "false"))
+ self.has_machine_quality = parseBool(my_metadata.get("has_machine_quality", "false"))
+ self.quality_definition = my_metadata.get("quality_definition", container_id) if self.has_machine_quality else "fdmprinter"
+ self.exclude_materials = my_metadata.get("exclude_materials", [])
+ self.preferred_variant_name = my_metadata.get("preferred_variant_name", "")
+ self.preferred_material = my_metadata.get("preferred_material", "")
+ self.preferred_quality_type = my_metadata.get("preferred_quality_type", "")
+
+ self._loadAll()
+
+ ## Get the available quality groups for this machine.
+ #
+ # This returns all quality groups, regardless of whether they are
+ # available to the combination of extruders or not. On the resulting
+ # quality groups, the is_available property is set to indicate whether the
+ # quality group can be selected according to the combination of extruders
+ # in the parameters.
+ # \param variant_names The names of the variants loaded in each extruder.
+ # \param material_bases The base file names of the materials loaded in
+ # each extruder.
+ # \param extruder_enabled Whether or not the extruders are enabled. This
+ # allows the function to set the is_available properly.
+ # \return For each available quality type, a QualityGroup instance.
+ def getQualityGroups(self, variant_names: List[str], material_bases: List[str], extruder_enabled: List[bool]) -> Dict[str, QualityGroup]:
+ if len(variant_names) != len(material_bases) or len(variant_names) != len(extruder_enabled):
+ Logger.log("e", "The number of extruders in the list of variants (" + str(len(variant_names)) + ") is not equal to the number of extruders in the list of materials (" + str(len(material_bases)) + ") or the list of enabled extruders (" + str(len(extruder_enabled)) + ").")
+ return {}
+ # For each extruder, find which quality profiles are available. Later we'll intersect the quality types.
+ qualities_per_type_per_extruder = [{}] * len(variant_names) # type: List[Dict[str, QualityNode]]
+ for extruder_nr, variant_name in enumerate(variant_names):
+ if not extruder_enabled[extruder_nr]:
+ continue # No qualities are available in this extruder. It'll get skipped when calculating the available quality types.
+ material_base = material_bases[extruder_nr]
+ if variant_name not in self.variants or material_base not in self.variants[variant_name].materials:
+ # The printer has no variant/material-specific quality profiles. Use the global quality profiles.
+ qualities_per_type_per_extruder[extruder_nr] = self.global_qualities
+ else:
+ # Use the actually specialised quality profiles.
+ qualities_per_type_per_extruder[extruder_nr] = {node.quality_type: node for node in self.variants[variant_name].materials[material_base].qualities.values()}
+
+ # Create the quality group for each available type.
+ quality_groups = {}
+ for quality_type, global_quality_node in self.global_qualities.items():
+ if not global_quality_node.container:
+ Logger.log("w", "Node {0} doesn't have a container.".format(global_quality_node.container_id))
+ continue
+ quality_groups[quality_type] = QualityGroup(name = global_quality_node.getMetaDataEntry("name", "Unnamed profile"), quality_type = quality_type)
+ quality_groups[quality_type].node_for_global = global_quality_node
+ for extruder_position, qualities_per_type in enumerate(qualities_per_type_per_extruder):
+ if quality_type in qualities_per_type:
+ quality_groups[quality_type].setExtruderNode(extruder_position, qualities_per_type[quality_type])
+
+ available_quality_types = set(quality_groups.keys())
+ for extruder_nr, qualities_per_type in enumerate(qualities_per_type_per_extruder):
+ if not extruder_enabled[extruder_nr]:
+ continue
+ available_quality_types.intersection_update(qualities_per_type.keys())
+ for quality_type in available_quality_types:
+ quality_groups[quality_type].is_available = True
+ return quality_groups
+
+ ## Returns all of the quality changes groups available to this printer.
+ #
+ # The quality changes groups store which quality type and intent category
+ # they were made for, but not which material and nozzle. Instead for the
+ # quality type and intent category, the quality changes will always be
+ # available but change the quality type and intent category when
+ # activated.
+ #
+ # The quality changes group does depend on the printer: Which quality
+ # definition is used.
+ #
+ # The quality changes groups that are available do depend on the quality
+ # types that are available, so it must still be known which extruders are
+ # enabled and which materials and variants are loaded in them. This allows
+ # setting the correct is_available flag.
+ # \param variant_names The names of the variants loaded in each extruder.
+ # \param material_bases The base file names of the materials loaded in
+ # each extruder.
+ # \param extruder_enabled For each extruder whether or not they are
+ # enabled.
+ # \return List of all quality changes groups for the printer.
+ def getQualityChangesGroups(self, variant_names: List[str], material_bases: List[str], extruder_enabled: List[bool]) -> List[QualityChangesGroup]:
+ machine_quality_changes = ContainerRegistry.getInstance().findContainersMetadata(type = "quality_changes", definition = self.quality_definition) # All quality changes for each extruder.
+
+ groups_by_name = {} #type: Dict[str, QualityChangesGroup] # Group quality changes profiles by their display name. The display name must be unique for quality changes. This finds profiles that belong together in a group.
+ for quality_changes in machine_quality_changes:
+ name = quality_changes["name"]
+ if name not in groups_by_name:
+ # CURA-6599
+ # For some reason, QML will get null or fail to convert type for MachineManager.activeQualityChangesGroup() to
+ # a QObject. Setting the object ownership to QQmlEngine.CppOwnership doesn't work, but setting the object
+ # parent to application seems to work.
+ from cura.CuraApplication import CuraApplication
+ groups_by_name[name] = QualityChangesGroup(name, quality_type = quality_changes["quality_type"],
+ intent_category = quality_changes.get("intent_category", "default"),
+ parent = CuraApplication.getInstance())
+ # CURA-6882
+ # Custom qualities are always available, even if they are based on the "not supported" profile.
+ groups_by_name[name].is_available = True
+ 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 quality_changes.get("position") is not None and quality_changes.get("position") != "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
+
+ return list(groups_by_name.values())
+
+ ## Gets the preferred global quality node, going by the preferred quality
+ # type.
+ #
+ # If the preferred global quality is not in there, an arbitrary global
+ # quality is taken.
+ # If there are no global qualities, an empty quality is returned.
+ def preferredGlobalQuality(self) -> "QualityNode":
+ return self.global_qualities.get(self.preferred_quality_type, next(iter(self.global_qualities.values())))
+
+ ## (Re)loads all variants under this printer.
+ @UM.FlameProfiler.profile
+ def _loadAll(self) -> None:
+ container_registry = ContainerRegistry.getInstance()
+ if not self.has_variants:
+ self.variants["empty"] = VariantNode("empty_variant", machine = self)
+ else:
+ # Find all the variants for this definition ID.
+ variants = container_registry.findInstanceContainersMetadata(type = "variant", definition = self.container_id, hardware_type = "nozzle")
+ for variant in variants:
+ variant_name = variant["name"]
+ if variant_name not in self.variants:
+ self.variants[variant_name] = VariantNode(variant["id"], machine = self)
+ self.variants[variant_name].materialsChanged.connect(self.materialsChanged)
+ if not self.variants:
+ self.variants["empty"] = VariantNode("empty_variant", machine = self)
+
+ # Find the global qualities for this printer.
+ global_qualities = container_registry.findInstanceContainersMetadata(type = "quality", definition = self.quality_definition, global_quality = "True") # First try specific to this printer.
+ if len(global_qualities) == 0: # This printer doesn't override the global qualities.
+ global_qualities = container_registry.findInstanceContainersMetadata(type = "quality", definition = "fdmprinter", global_quality = "True") # Otherwise pick the global global qualities.
+ if len(global_qualities) == 0: # There are no global qualities either?! Something went very wrong, but we'll not crash and properly fill the tree.
+ global_qualities = [cura.CuraApplication.CuraApplication.getInstance().empty_quality_container.getMetaData()]
+ for global_quality in global_qualities:
+ self.global_qualities[global_quality["quality_type"]] = QualityNode(global_quality["id"], parent = self)
diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py
deleted file mode 100644
index 68e894642d..0000000000
--- a/cura/Machines/MaterialManager.py
+++ /dev/null
@@ -1,698 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from collections import defaultdict, OrderedDict
-import copy
-import uuid
-from typing import Dict, Optional, TYPE_CHECKING, Any, Set, List, cast, Tuple
-
-from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot
-
-from UM.Application import Application
-from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
-from UM.Logger import Logger
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from UM.Settings.SettingFunction import SettingFunction
-from UM.Util import parseBool
-
-from .MaterialNode import MaterialNode
-from .MaterialGroup import MaterialGroup
-from .VariantType import VariantType
-
-if TYPE_CHECKING:
- from UM.Settings.DefinitionContainer import DefinitionContainer
- from UM.Settings.InstanceContainer import InstanceContainer
- from cura.Settings.GlobalStack import GlobalStack
- from cura.Settings.ExtruderStack import ExtruderStack
-
-
-#
-# MaterialManager maintains a number of maps and trees for material lookup.
-# The models GUI and QML use are now only dependent on the MaterialManager. That means as long as the data in
-# MaterialManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI.
-#
-# For now, updating the lookup maps and trees here is very simple: we discard the old data completely and recreate them
-# again. This means the update is exactly the same as initialization. There are performance concerns about this approach
-# but so far the creation of the tables and maps is very fast and there is no noticeable slowness, we keep it like this
-# because it's simple.
-#
-class MaterialManager(QObject):
-
- 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)
- self._application = Application.getInstance()
- self._container_registry = container_registry # type: ContainerRegistry
-
- # Material_type -> generic material metadata
- self._fallback_materials_map = dict() # type: Dict[str, Dict[str, Any]]
-
- # Root_material_id -> MaterialGroup
- self._material_group_map = dict() # type: Dict[str, MaterialGroup]
-
- # Approximate diameter str
- self._diameter_machine_nozzle_buildplate_material_map = dict() # type: Dict[str, Dict[str, MaterialNode]]
-
- # We're using these two maps to convert between the specific diameter material id and the generic material id
- # because the generic material ids are used in qualities and definitions, while the specific diameter material is meant
- # i.e. generic_pla -> generic_pla_175
- # root_material_id -> approximate diameter str -> root_material_id for that diameter
- self._material_diameter_map = defaultdict(dict) # type: Dict[str, Dict[str, str]]
-
- # Material id including diameter (generic_pla_175) -> material root id (generic_pla)
- self._diameter_material_map = dict() # type: Dict[str, str]
-
- # This is used in Legacy UM3 send material function and the material management page.
- # GUID -> a list of material_groups
- self._guid_material_groups_map = defaultdict(list) # type: Dict[str, List[MaterialGroup]]
-
- # The machine definition ID for the non-machine-specific materials.
- # This is used as the last fallback option if the given machine-specific material(s) cannot be found.
- self._default_machine_definition_id = "fdmprinter"
- self._default_approximate_diameter_for_quality_search = "3"
-
- # When a material gets added/imported, there can be more than one InstanceContainers. In those cases, we don't
- # want to react on every container/metadata changed signal. The timer here is to buffer it a bit so we don't
- # react too many time.
- self._update_timer = QTimer(self)
- self._update_timer.setInterval(300)
- self._update_timer.setSingleShot(True)
- self._update_timer.timeout.connect(self._updateMaps)
-
- self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged)
- self._container_registry.containerAdded.connect(self._onContainerMetadataChanged)
- self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged)
-
- self._favorites = set() # type: Set[str]
-
- def initialize(self) -> None:
- # Find all materials and put them in a matrix for quick search.
- material_metadatas = {metadata["id"]: metadata for metadata in
- self._container_registry.findContainersMetadata(type = "material") if
- metadata.get("GUID")} # type: Dict[str, Dict[str, Any]]
-
- self._material_group_map = dict() # type: Dict[str, MaterialGroup]
-
- # Map #1
- # root_material_id -> MaterialGroup
- for material_id, material_metadata in material_metadatas.items():
- # We don't store empty material in the lookup tables
- if material_id == "empty_material":
- continue
-
- root_material_id = material_metadata.get("base_file", "")
- if root_material_id not in self._material_group_map:
- self._material_group_map[root_material_id] = MaterialGroup(root_material_id, MaterialNode(material_metadatas[root_material_id]))
- self._material_group_map[root_material_id].is_read_only = self._container_registry.isReadOnly(root_material_id)
- group = self._material_group_map[root_material_id]
-
- # Store this material in the group of the appropriate root material.
- if material_id != root_material_id:
- new_node = MaterialNode(material_metadata)
- group.derived_material_node_list.append(new_node)
-
- # Order this map alphabetically so it's easier to navigate in a debugger
- self._material_group_map = OrderedDict(sorted(self._material_group_map.items(), key = lambda x: x[0]))
-
- # Map #1.5
- # GUID -> material group list
- self._guid_material_groups_map = defaultdict(list) # type: Dict[str, List[MaterialGroup]]
- for root_material_id, material_group in self._material_group_map.items():
- guid = material_group.root_material_node.getMetaDataEntry("GUID", "")
- self._guid_material_groups_map[guid].append(material_group)
-
- # Map #2
- # Lookup table for material type -> fallback material metadata, only for read-only materials
- grouped_by_type_dict = dict() # type: Dict[str, Any]
- material_types_without_fallback = set()
- for root_material_id, material_node in self._material_group_map.items():
- material_type = material_node.root_material_node.getMetaDataEntry("material", "")
- if material_type not in grouped_by_type_dict:
- grouped_by_type_dict[material_type] = {"generic": None,
- "others": []}
- material_types_without_fallback.add(material_type)
- brand = material_node.root_material_node.getMetaDataEntry("brand", "")
- if brand.lower() == "generic":
- to_add = True
- if material_type in grouped_by_type_dict:
- diameter = material_node.root_material_node.getMetaDataEntry("approximate_diameter", "")
- if diameter != self._default_approximate_diameter_for_quality_search:
- to_add = False # don't add if it's not the default diameter
-
- if to_add:
- # Checking this first allow us to differentiate between not read only materials:
- # - if it's in the list, it means that is a new material without fallback
- # - if it is not, then it is a custom material with a fallback material (parent)
- if material_type in material_types_without_fallback:
- grouped_by_type_dict[material_type] = material_node.root_material_node._metadata
- material_types_without_fallback.remove(material_type)
-
- # Remove the materials that have no fallback materials
- for material_type in material_types_without_fallback:
- del grouped_by_type_dict[material_type]
- self._fallback_materials_map = grouped_by_type_dict
-
- # Map #3
- # There can be multiple material profiles for the same material with different diameters, such as "generic_pla"
- # and "generic_pla_175". This is inconvenient when we do material-specific quality lookup because a quality can
- # be for either "generic_pla" or "generic_pla_175", but not both. This map helps to get the correct material ID
- # for quality search.
- self._material_diameter_map = defaultdict(dict)
- self._diameter_material_map = dict()
-
- # Group the material IDs by the same name, material, brand, and color but with different diameters.
- material_group_dict = dict() # type: Dict[Tuple[Any], Dict[str, str]]
- keys_to_fetch = ("name", "material", "brand", "color")
- for root_material_id, machine_node in self._material_group_map.items():
- root_material_metadata = machine_node.root_material_node._metadata
-
- key_data_list = [] # type: List[Any]
- for key in keys_to_fetch:
- key_data_list.append(machine_node.root_material_node.getMetaDataEntry(key))
- key_data = cast(Tuple[Any], tuple(key_data_list)) # type: Tuple[Any]
-
- # If the key_data doesn't exist, it doesn't matter if the material is read only...
- if key_data not in material_group_dict:
- material_group_dict[key_data] = dict()
- else:
- # ...but if key_data exists, we just overwrite it if the material is read only, otherwise we skip it
- if not machine_node.is_read_only:
- continue
- approximate_diameter = machine_node.root_material_node.getMetaDataEntry("approximate_diameter", "")
- material_group_dict[key_data][approximate_diameter] = machine_node.root_material_node.getMetaDataEntry("id", "")
-
- # Map [root_material_id][diameter] -> root_material_id for this diameter
- for data_dict in material_group_dict.values():
- for root_material_id1 in data_dict.values():
- if root_material_id1 in self._material_diameter_map:
- continue
- diameter_map = data_dict
- for root_material_id2 in data_dict.values():
- self._material_diameter_map[root_material_id2] = diameter_map
-
- default_root_material_id = data_dict.get(self._default_approximate_diameter_for_quality_search)
- if default_root_material_id is None:
- default_root_material_id = list(data_dict.values())[0] # no default diameter present, just take "the" only one
- for root_material_id in data_dict.values():
- self._diameter_material_map[root_material_id] = default_root_material_id
-
- # Map #4
- # "machine" -> "nozzle name" -> "buildplate name" -> "root material ID" -> specific material InstanceContainer
- self._diameter_machine_nozzle_buildplate_material_map = dict() # type: Dict[str, Dict[str, MaterialNode]]
- for material_metadata in material_metadatas.values():
- self.__addMaterialMetadataIntoLookupTree(material_metadata)
-
- favorites = self._application.getPreferences().getValue("cura/favorite_materials")
- for item in favorites.split(";"):
- self._favorites.add(item)
-
- self.materialsUpdated.emit()
-
- def __addMaterialMetadataIntoLookupTree(self, material_metadata: Dict[str, Any]) -> None:
- material_id = material_metadata["id"]
-
- # We don't store empty material in the lookup tables
- if material_id == "empty_material":
- return
-
- root_material_id = material_metadata["base_file"]
- definition = material_metadata["definition"]
- approximate_diameter = material_metadata["approximate_diameter"]
-
- if approximate_diameter not in self._diameter_machine_nozzle_buildplate_material_map:
- self._diameter_machine_nozzle_buildplate_material_map[approximate_diameter] = {}
-
- machine_nozzle_buildplate_material_map = self._diameter_machine_nozzle_buildplate_material_map[
- approximate_diameter]
- if definition not in machine_nozzle_buildplate_material_map:
- machine_nozzle_buildplate_material_map[definition] = MaterialNode()
-
- # This is a list of information regarding the intermediate nodes:
- # nozzle -> buildplate
- nozzle_name = material_metadata.get("variant_name")
- buildplate_name = material_metadata.get("buildplate_name")
- intermediate_node_info_list = [(nozzle_name, VariantType.NOZZLE),
- (buildplate_name, VariantType.BUILD_PLATE),
- ]
-
- variant_manager = self._application.getVariantManager()
-
- machine_node = machine_nozzle_buildplate_material_map[definition]
- current_node = machine_node
- current_intermediate_node_info_idx = 0
- error_message = None # type: Optional[str]
- while current_intermediate_node_info_idx < len(intermediate_node_info_list):
- variant_name, variant_type = intermediate_node_info_list[current_intermediate_node_info_idx]
- if variant_name is not None:
- # The new material has a specific variant, so it needs to be added to that specific branch in the tree.
- variant = variant_manager.getVariantNode(definition, variant_name, variant_type)
- if variant is None:
- error_message = "Material {id} contains a variant {name} that does not exist.".format(
- id = material_metadata["id"], name = variant_name)
- break
-
- # Update the current node to advance to a more specific branch
- if variant_name not in current_node.children_map:
- current_node.children_map[variant_name] = MaterialNode()
- current_node = current_node.children_map[variant_name]
-
- current_intermediate_node_info_idx += 1
-
- if error_message is not None:
- Logger.log("e", "%s It will not be added into the material lookup tree.", error_message)
- self._container_registry.addWrongContainerId(material_metadata["id"])
- return
-
- # Add the material to the current tree node, which is the deepest (the most specific) branch we can find.
- # Sanity check: Make sure that there is no duplicated materials.
- if root_material_id in current_node.material_map:
- Logger.log("e", "Duplicated material [%s] with root ID [%s]. It has already been added.",
- material_id, root_material_id)
- ConfigurationErrorMessage.getInstance().addFaultyContainers(root_material_id)
- return
-
- current_node.material_map[root_material_id] = MaterialNode(material_metadata)
-
- def _updateMaps(self):
- Logger.log("i", "Updating material lookup data ...")
- self.initialize()
-
- def _onContainerMetadataChanged(self, container):
- self._onContainerChanged(container)
-
- def _onContainerChanged(self, container):
- container_type = container.getMetaDataEntry("type")
- if container_type != "material":
- return
-
- # update the maps
- self._update_timer.start()
-
- def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]:
- return self._material_group_map.get(root_material_id)
-
- def getRootMaterialIDForDiameter(self, root_material_id: str, approximate_diameter: str) -> str:
- return self._material_diameter_map.get(root_material_id, {}).get(approximate_diameter, root_material_id)
-
- def getRootMaterialIDWithoutDiameter(self, root_material_id: str) -> str:
- return self._diameter_material_map.get(root_material_id, "")
-
- def getMaterialGroupListByGUID(self, guid: str) -> Optional[List[MaterialGroup]]:
- return self._guid_material_groups_map.get(guid)
-
- # Returns a dict of all material groups organized by root_material_id.
- def getAllMaterialGroups(self) -> Dict[str, "MaterialGroup"]:
- return self._material_group_map
-
- #
- # Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup.
- #
- def getAvailableMaterials(self, machine_definition: "DefinitionContainer", nozzle_name: Optional[str],
- buildplate_name: Optional[str], diameter: float) -> Dict[str, MaterialNode]:
- # round the diameter to get the approximate diameter
- rounded_diameter = str(round(diameter))
- if rounded_diameter not in self._diameter_machine_nozzle_buildplate_material_map:
- Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s])", diameter, rounded_diameter)
- return dict()
-
- machine_definition_id = machine_definition.getId()
-
- # If there are nozzle-and-or-buildplate materials, get the nozzle-and-or-buildplate material
- machine_nozzle_buildplate_material_map = self._diameter_machine_nozzle_buildplate_material_map[rounded_diameter]
- machine_node = machine_nozzle_buildplate_material_map.get(machine_definition_id)
- default_machine_node = machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id)
- nozzle_node = None
- buildplate_node = None
- if nozzle_name is not None and machine_node is not None:
- nozzle_node = machine_node.getChildNode(nozzle_name)
- # Get buildplate node if possible
- if nozzle_node is not None and buildplate_name is not None:
- buildplate_node = nozzle_node.getChildNode(buildplate_name)
-
- nodes_to_check = [buildplate_node, nozzle_node, machine_node, default_machine_node]
-
- # Fallback mechanism of finding materials:
- # 1. buildplate-specific material
- # 2. nozzle-specific material
- # 3. machine-specific material
- # 4. generic material (for fdmprinter)
- machine_exclude_materials = machine_definition.getMetaDataEntry("exclude_materials", [])
-
- material_id_metadata_dict = dict() # type: Dict[str, MaterialNode]
- excluded_materials = set()
- for current_node in nodes_to_check:
- if current_node is None:
- continue
-
- # Only exclude the materials that are explicitly specified in the "exclude_materials" field.
- # Do not exclude other materials that are of the same type.
- for material_id, node in current_node.material_map.items():
- if material_id in machine_exclude_materials:
- excluded_materials.add(material_id)
- continue
-
- if material_id not in material_id_metadata_dict:
- material_id_metadata_dict[material_id] = node
-
- if excluded_materials:
- Logger.log("d", "Exclude materials {excluded_materials} for machine {machine_definition_id}".format(excluded_materials = ", ".join(excluded_materials), machine_definition_id = machine_definition_id))
-
- return material_id_metadata_dict
-
- #
- # A convenience function to get available materials for the given machine with the extruder position.
- #
- def getAvailableMaterialsForMachineExtruder(self, machine: "GlobalStack",
- extruder_stack: "ExtruderStack") -> Optional[Dict[str, MaterialNode]]:
- buildplate_name = machine.getBuildplateName()
- nozzle_name = None
- if extruder_stack.variant.getId() != "empty_variant":
- nozzle_name = extruder_stack.variant.getName()
- diameter = extruder_stack.getApproximateMaterialDiameter()
-
- # Fetch the available materials (ContainerNode) for the current active machine and extruder setup.
- return self.getAvailableMaterials(machine.definition, nozzle_name, buildplate_name, diameter)
-
- #
- # Gets MaterialNode for the given extruder and machine with the given material name.
- # Returns None if:
- # 1. the given machine doesn't have materials;
- # 2. cannot find any material InstanceContainers with the given settings.
- #
- def getMaterialNode(self, machine_definition_id: str, nozzle_name: Optional[str],
- buildplate_name: Optional[str], diameter: float, root_material_id: str) -> Optional["MaterialNode"]:
- # round the diameter to get the approximate diameter
- rounded_diameter = str(round(diameter))
- if rounded_diameter not in self._diameter_machine_nozzle_buildplate_material_map:
- Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s]) for root material id [%s]",
- diameter, rounded_diameter, root_material_id)
- return None
-
- # If there are nozzle materials, get the nozzle-specific material
- machine_nozzle_buildplate_material_map = self._diameter_machine_nozzle_buildplate_material_map[rounded_diameter] # type: Dict[str, MaterialNode]
- machine_node = machine_nozzle_buildplate_material_map.get(machine_definition_id)
- nozzle_node = None
- buildplate_node = None
-
- # Fallback for "fdmprinter" if the machine-specific materials cannot be found
- if machine_node is None:
- machine_node = machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id)
- if machine_node is not None and nozzle_name is not None:
- nozzle_node = machine_node.getChildNode(nozzle_name)
- if nozzle_node is not None and buildplate_name is not None:
- buildplate_node = nozzle_node.getChildNode(buildplate_name)
-
- # Fallback mechanism of finding materials:
- # 1. buildplate-specific material
- # 2. nozzle-specific material
- # 3. machine-specific material
- # 4. generic material (for fdmprinter)
- nodes_to_check = [buildplate_node, nozzle_node, machine_node,
- machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id)]
-
- material_node = None
- for node in nodes_to_check:
- if node is not None:
- material_node = node.material_map.get(root_material_id)
- if material_node:
- break
-
- return material_node
-
- #
- # Gets MaterialNode for the given extruder and machine with the given material type.
- # Returns None if:
- # 1. the given machine doesn't have materials;
- # 2. cannot find any material InstanceContainers with the given settings.
- #
- def getMaterialNodeByType(self, global_stack: "GlobalStack", position: str, nozzle_name: str,
- buildplate_name: Optional[str], material_guid: str) -> Optional["MaterialNode"]:
- node = None
- machine_definition = global_stack.definition
- extruder_definition = global_stack.extruders[position].definition
- if parseBool(machine_definition.getMetaDataEntry("has_materials", False)):
- material_diameter = extruder_definition.getProperty("material_diameter", "value")
- if isinstance(material_diameter, SettingFunction):
- material_diameter = material_diameter(global_stack)
-
- # Look at the guid to material dictionary
- root_material_id = None
- for material_group in self._guid_material_groups_map[material_guid]:
- root_material_id = cast(str, material_group.root_material_node.getMetaDataEntry("id", ""))
- break
-
- if not root_material_id:
- Logger.log("i", "Cannot find materials with guid [%s] ", material_guid)
- return None
-
- node = self.getMaterialNode(machine_definition.getId(), nozzle_name, buildplate_name,
- material_diameter, root_material_id)
- return node
-
- # There are 2 ways to get fallback materials;
- # - A fallback by type (@sa getFallbackMaterialIdByMaterialType), which adds the generic version of this material
- # - A fallback by GUID; If a material has been duplicated, it should also check if the original materials do have
- # a GUID. This should only be done if the material itself does not have a quality just yet.
- def getFallBackMaterialIdsByMaterial(self, material: "InstanceContainer") -> List[str]:
- results = [] # type: List[str]
-
- material_groups = self.getMaterialGroupListByGUID(material.getMetaDataEntry("GUID"))
- for material_group in material_groups: # type: ignore
- if material_group.name != material.getId():
- # If the material in the group is read only, put it at the front of the list (since that is the most
- # likely one to get a result)
- if material_group.is_read_only:
- results.insert(0, material_group.name)
- else:
- results.append(material_group.name)
-
- fallback = self.getFallbackMaterialIdByMaterialType(material.getMetaDataEntry("material"))
- if fallback is not None:
- results.append(fallback)
- return results
-
- #
- # Used by QualityManager. Built-in quality profiles may be based on generic material IDs such as "generic_pla".
- # For materials such as ultimaker_pla_orange, no quality profiles may be found, so we should fall back to use
- # the generic material IDs to search for qualities.
- #
- # An example would be, suppose we have machine with preferred material set to "filo3d_pla" (1.75mm), but its
- # extruders only use 2.85mm materials, then we won't be able to find the preferred material for this machine.
- # A fallback would be to fetch a generic material of the same type "PLA" as "filo3d_pla", and in this case it will
- # be "generic_pla". This function is intended to get a generic fallback material for the given material type.
- #
- # This function returns the generic root material ID for the given material type, where material types are "PLA",
- # "ABS", etc.
- #
- def getFallbackMaterialIdByMaterialType(self, material_type: str) -> Optional[str]:
- # For safety
- if material_type not in self._fallback_materials_map:
- Logger.log("w", "The material type [%s] does not have a fallback material" % material_type)
- return None
- fallback_material = self._fallback_materials_map[material_type]
- if fallback_material:
- return self.getRootMaterialIDWithoutDiameter(fallback_material["id"])
- else:
- return None
-
- ## Get default material for given global stack, extruder position and extruder nozzle name
- # you can provide the extruder_definition and then the position is ignored (useful when building up global stack in CuraStackBuilder)
- def getDefaultMaterial(self, global_stack: "GlobalStack", position: str, nozzle_name: Optional[str],
- extruder_definition: Optional["DefinitionContainer"] = None) -> Optional["MaterialNode"]:
- node = None
-
- buildplate_name = global_stack.getBuildplateName()
- machine_definition = global_stack.definition
-
- # The extruder-compatible material diameter in the extruder definition may not be the correct value because
- # the user can change it in the definition_changes container.
- if extruder_definition is None:
- extruder_stack_or_definition = global_stack.extruders[position]
- is_extruder_stack = True
- else:
- extruder_stack_or_definition = extruder_definition
- is_extruder_stack = False
-
- if extruder_stack_or_definition and parseBool(global_stack.getMetaDataEntry("has_materials", False)):
- if is_extruder_stack:
- material_diameter = extruder_stack_or_definition.getCompatibleMaterialDiameter()
- else:
- material_diameter = extruder_stack_or_definition.getProperty("material_diameter", "value")
-
- if isinstance(material_diameter, SettingFunction):
- material_diameter = material_diameter(global_stack)
- approximate_material_diameter = str(round(material_diameter))
- root_material_id = machine_definition.getMetaDataEntry("preferred_material")
- root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter)
- node = self.getMaterialNode(machine_definition.getId(), nozzle_name, buildplate_name,
- material_diameter, root_material_id)
- return node
-
- def removeMaterialByRootId(self, root_material_id: str):
- material_group = self.getMaterialGroup(root_material_id)
- if not material_group:
- Logger.log("i", "Unable to remove the material with id %s, because it doesn't exist.", root_material_id)
- return
-
- nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list
- for node in nodes_to_remove:
- self._container_registry.removeContainer(node.getMetaDataEntry("id", ""))
-
- #
- # Methods for GUI
- #
-
- #
- # Sets the new name for the given material.
- #
- @pyqtSlot("QVariant", str)
- def setMaterialName(self, material_node: "MaterialNode", name: str) -> None:
- root_material_id = material_node.getMetaDataEntry("base_file")
- if root_material_id is None:
- return
- if self._container_registry.isReadOnly(root_material_id):
- Logger.log("w", "Cannot set name of read-only container %s.", root_material_id)
- return
-
- material_group = self.getMaterialGroup(root_material_id)
- if material_group:
- container = material_group.root_material_node.getContainer()
- if container:
- container.setName(name)
-
- #
- # Removes the given material.
- #
- @pyqtSlot("QVariant")
- def removeMaterial(self, material_node: "MaterialNode") -> None:
- root_material_id = material_node.getMetaDataEntry("base_file")
- if root_material_id is not None:
- self.removeMaterialByRootId(root_material_id)
-
- #
- # Creates a duplicate of a material, which has the same GUID and base_file metadata.
- # Returns the root material ID of the duplicated material if successful.
- #
- @pyqtSlot("QVariant", result = str)
- def duplicateMaterial(self, material_node: MaterialNode, new_base_id: Optional[str] = None, new_metadata: Dict[str, Any] = None) -> Optional[str]:
- root_material_id = cast(str, material_node.getMetaDataEntry("base_file", ""))
-
- material_group = self.getMaterialGroup(root_material_id)
- if not material_group:
- Logger.log("i", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id)
- return None
-
- base_container = material_group.root_material_node.getContainer()
- if not base_container:
- return None
-
- # Ensure all settings are saved.
- self._application.saveSettings()
-
- # Create a new ID & container to hold the data.
- new_containers = []
- if new_base_id is None:
- new_base_id = self._container_registry.uniqueName(base_container.getId())
- new_base_container = copy.deepcopy(base_container)
- new_base_container.getMetaData()["id"] = new_base_id
- new_base_container.getMetaData()["base_file"] = new_base_id
- if new_metadata is not None:
- for key, value in new_metadata.items():
- new_base_container.getMetaData()[key] = value
- new_containers.append(new_base_container)
-
- # Clone all of them.
- for node in material_group.derived_material_node_list:
- container_to_copy = node.getContainer()
- if not container_to_copy:
- continue
- # Create unique IDs for every clone.
- new_id = new_base_id
- if container_to_copy.getMetaDataEntry("definition") != "fdmprinter":
- new_id += "_" + container_to_copy.getMetaDataEntry("definition")
- if container_to_copy.getMetaDataEntry("variant_name"):
- nozzle_name = container_to_copy.getMetaDataEntry("variant_name")
- new_id += "_" + nozzle_name.replace(" ", "_")
-
- new_container = copy.deepcopy(container_to_copy)
- new_container.getMetaData()["id"] = new_id
- new_container.getMetaData()["base_file"] = new_base_id
- if new_metadata is not None:
- for key, value in new_metadata.items():
- new_container.getMetaData()[key] = value
-
- new_containers.append(new_container)
-
- for container_to_add in new_containers:
- container_to_add.setDirty(True)
- self._container_registry.addContainer(container_to_add)
-
- # if the duplicated material was favorite then the new material should also be added to favorite.
- if root_material_id in self.getFavorites():
- self.addFavorite(new_base_id)
-
- return new_base_id
-
- #
- # Create a new material by cloning Generic PLA for the current material diameter and generate a new GUID.
- # Returns the ID of the newly created material.
- @pyqtSlot(result = str)
- def createMaterial(self) -> str:
- from UM.i18n import i18nCatalog
- catalog = i18nCatalog("cura")
- # Ensure all settings are saved.
- self._application.saveSettings()
-
- machine_manager = self._application.getMachineManager()
- extruder_stack = machine_manager.activeStack
-
- machine_definition = self._application.getGlobalContainerStack().definition
- root_material_id = machine_definition.getMetaDataEntry("preferred_material", default = "generic_pla")
-
- approximate_diameter = str(extruder_stack.approximateMaterialDiameter)
- root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_diameter)
- material_group = self.getMaterialGroup(root_material_id)
-
- if not material_group: # This should never happen
- Logger.log("w", "Cannot get the material group of %s.", root_material_id)
- return ""
-
- # Create a new ID & container to hold the data.
- new_id = self._container_registry.uniqueName("custom_material")
- new_metadata = {"name": catalog.i18nc("@label", "Custom Material"),
- "brand": catalog.i18nc("@label", "Custom"),
- "GUID": str(uuid.uuid4()),
- }
-
- self.duplicateMaterial(material_group.root_material_node,
- new_base_id = new_id,
- new_metadata = new_metadata)
- return new_id
-
- @pyqtSlot(str)
- def addFavorite(self, root_material_id: str) -> None:
- self._favorites.add(root_material_id)
- self.materialsUpdated.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) -> None:
- try:
- self._favorites.remove(root_material_id)
- except KeyError:
- Logger.log("w", "Could not delete material %s from favorites as it was already deleted", root_material_id)
- return
- self.materialsUpdated.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
diff --git a/cura/Machines/MaterialNode.py b/cura/Machines/MaterialNode.py
index a4dcb0564f..fe20af2cd5 100644
--- a/cura/Machines/MaterialNode.py
+++ b/cura/Machines/MaterialNode.py
@@ -1,25 +1,136 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import Optional, Dict, Any
-from collections import OrderedDict
-from .ContainerNode import ContainerNode
+from typing import Any, Optional, 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.Machines.ContainerNode import ContainerNode
+from cura.Machines.QualityNode import QualityNode
+import UM.FlameProfiler
+if TYPE_CHECKING:
+ from typing import Dict
+ from cura.Machines.VariantNode import VariantNode
+
+## Represents a material in the container tree.
#
-# A MaterialNode is a node in the material lookup tree/map/table. It contains 2 (extra) fields:
-# - material_map: a one-to-one map of "material_root_id" to material_node.
-# - children_map: the key-value map for child nodes of this node. This is used in a lookup tree.
-#
-#
+# Its subcontainers are quality profiles.
class MaterialNode(ContainerNode):
- __slots__ = ("material_map", "children_map")
+ def __init__(self, container_id: str, variant: "VariantNode") -> None:
+ super().__init__(container_id)
+ self.variant = variant
+ self.qualities = {} # type: Dict[str, QualityNode] # Mapping container IDs to quality profiles.
+ self.materialChanged = Signal() # Triggered when the material is removed or its metadata is updated.
- def __init__(self, metadata: Optional[Dict[str, Any]] = None) -> None:
- super().__init__(metadata = metadata)
- self.material_map = {} # type: Dict[str, MaterialNode] # material_root_id -> material_node
+ container_registry = ContainerRegistry.getInstance()
+ my_metadata = container_registry.findContainersMetadata(id = container_id)[0]
+ self.base_file = my_metadata["base_file"]
+ self.material_type = my_metadata["material"]
+ self.guid = my_metadata["GUID"]
+ self._loadAll()
+ container_registry.containerRemoved.connect(self._onRemoved)
+ container_registry.containerMetaDataChanged.connect(self._onMetadataChanged)
- # We overide this as we want to indicate that MaterialNodes can only contain other material nodes.
- self.children_map = OrderedDict() # type: OrderedDict[str, "MaterialNode"]
+ ## Finds the preferred quality for this printer with this material and this
+ # variant loaded.
+ #
+ # If the preferred quality is not available, an arbitrary quality is
+ # returned. If there is a configuration mistake (like a typo in the
+ # preferred quality) this returns a random available quality. If there are
+ # no available qualities, this will return the empty quality node.
+ # \return The node for the preferred quality, or any arbitrary quality if
+ # there is no match.
+ def preferredQuality(self) -> QualityNode:
+ for quality_id, quality_node in self.qualities.items():
+ if self.variant.machine.preferred_quality_type == quality_node.quality_type:
+ return quality_node
+ fallback = next(iter(self.qualities.values())) # Should only happen with empty quality node.
+ Logger.log("w", "Could not find preferred quality type {preferred_quality_type} for material {material_id} and variant {variant_id}, falling back to {fallback}.".format(
+ preferred_quality_type = self.variant.machine.preferred_quality_type,
+ material_id = self.container_id,
+ variant_id = self.variant.container_id,
+ fallback = fallback.container_id
+ ))
+ return fallback
- def getChildNode(self, child_key: str) -> Optional["MaterialNode"]:
- return self.children_map.get(child_key)
\ No newline at end of file
+ @UM.FlameProfiler.profile
+ def _loadAll(self) -> None:
+ container_registry = ContainerRegistry.getInstance()
+ # Find all quality profiles that fit on this material.
+ if not self.variant.machine.has_machine_quality: # Need to find the global qualities.
+ qualities = container_registry.findInstanceContainersMetadata(type = "quality", definition = "fdmprinter")
+ elif not self.variant.machine.has_materials:
+ qualities = container_registry.findInstanceContainersMetadata(type="quality", definition=self.variant.machine.quality_definition)
+ else:
+ if self.variant.machine.has_variants:
+ # Need to find the qualities that specify a material profile with the same material type.
+ qualities = container_registry.findInstanceContainersMetadata(type = "quality", definition = self.variant.machine.quality_definition, variant = self.variant.variant_name, material = self.container_id) # First try by exact material ID.
+ else:
+ qualities = container_registry.findInstanceContainersMetadata(type="quality", definition=self.variant.machine.quality_definition, material=self.container_id)
+ if not qualities:
+ my_material_type = self.material_type
+ if self.variant.machine.has_variants:
+ qualities_any_material = container_registry.findInstanceContainersMetadata(type = "quality", definition = self.variant.machine.quality_definition, variant = self.variant.variant_name)
+ else:
+ qualities_any_material = container_registry.findInstanceContainersMetadata(type="quality", definition = self.variant.machine.quality_definition)
+ for material_metadata in container_registry.findInstanceContainersMetadata(type = "material", material = my_material_type):
+ qualities.extend((quality for quality in qualities_any_material if quality.get("material") == material_metadata["id"]))
+
+ if not qualities: # No quality profiles found. Go by GUID then.
+ my_guid = self.guid
+ for material_metadata in container_registry.findInstanceContainersMetadata(type = "material", guid = my_guid):
+ qualities.extend((quality for quality in qualities_any_material if quality["material"] == material_metadata["id"]))
+
+ if not qualities:
+ # There are still some machines that should use global profiles in the extruder, so do that now.
+ # These are mostly older machines that haven't received updates (so single extruder machines without specific qualities
+ # but that do have materials and profiles specific to that machine)
+ qualities.extend([quality for quality in qualities_any_material if quality.get("global_quality", "False") != "False"])
+
+ for quality in qualities:
+ quality_id = quality["id"]
+ if quality_id not in self.qualities:
+ self.qualities[quality_id] = QualityNode(quality_id, parent = self)
+ if not self.qualities:
+ self.qualities["empty_quality"] = QualityNode("empty_quality", parent = self)
+
+ ## Triggered when any container is removed, but only handles it when the
+ # container is removed that this node represents.
+ # \param container The container that was allegedly removed.
+ def _onRemoved(self, container: ContainerInterface) -> None:
+ if container.getId() == self.container_id:
+ # Remove myself from my parent.
+ if self.base_file in self.variant.materials:
+ del self.variant.materials[self.base_file]
+ if not self.variant.materials:
+ self.variant.materials["empty_material"] = MaterialNode("empty_material", variant = self.variant)
+ self.materialChanged.emit(self)
+
+ ## Triggered when any metadata changed in any container, but only handles
+ # it when the metadata of this node is changed.
+ # \param container The container whose metadata changed.
+ # \param kwargs Key-word arguments provided when changing the metadata.
+ # These are ignored. As far as I know they are never provided to this
+ # call.
+ def _onMetadataChanged(self, container: ContainerInterface, **kwargs: Any) -> None:
+ if container.getId() != self.container_id:
+ return
+
+ new_metadata = container.getMetaData()
+ old_base_file = self.base_file
+ if new_metadata["base_file"] != old_base_file:
+ self.base_file = new_metadata["base_file"]
+ if old_base_file in self.variant.materials: # Move in parent node.
+ del self.variant.materials[old_base_file]
+ self.variant.materials[self.base_file] = self
+
+ old_material_type = self.material_type
+ self.material_type = new_metadata["material"]
+ old_guid = self.guid
+ self.guid = new_metadata["GUID"]
+ if self.base_file != old_base_file or self.material_type != old_material_type or self.guid != old_guid: # List of quality profiles could've changed.
+ self.qualities = {}
+ self._loadAll() # Re-load the quality profiles for this node.
+ self.materialChanged.emit(self)
diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py
index 212e4fcf1e..db660704b5 100644
--- a/cura/Machines/Models/BaseMaterialsModel.py
+++ b/cura/Machines/Models/BaseMaterialsModel.py
@@ -1,42 +1,63 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import Optional, Dict, Set
-from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
+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
+from cura.Machines.MaterialNode import MaterialNode
+from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
## 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
-from cura.Machines.MaterialNode import MaterialNode
-
-
class BaseMaterialsModel(ListModel):
extruderPositionChanged = pyqtSignal()
+ enabledChanged = pyqtSignal()
def __init__(self, parent = None):
super().__init__(parent)
-
from cura.CuraApplication import CuraApplication
self._application = CuraApplication.getInstance()
+ self._available_materials = {} # type: Dict[str, MaterialNode]
+ self._favorite_ids = set() # type: Set[str]
+
# 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()
+
+ self._extruder_position = 0
+ self._extruder_stack = None
+ self._enabled = True
+
+ # CURA-6904
+ # Updating the material model requires information from material nodes and containers. We use a timer here to
+ # make sure that an update function call will not be directly invoked by an event. Because the triggered event
+ # can be caused in the middle of a XMLMaterial loading, and the material container we try to find may not be
+ # in the system yet. This will cause an infinite recursion of (1) trying to load a material, (2) trying to
+ # update the material model, (3) cannot find the material container, load it, (4) repeat #1.
+ self._update_timer = QTimer()
+ self._update_timer.setInterval(100)
+ self._update_timer.setSingleShot(True)
+ self._update_timer.timeout.connect(self._update)
# Update the stack and the model data when the machine changes
self._machine_manager.globalContainerChanged.connect(self._updateExtruderStack)
+ 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 switching machines or tabs, when adding materials or changing their metadata.
+ self._machine_manager.activeStackChanged.connect(self._onChanged)
+ ContainerTree.getInstance().materialsChanged.connect(self._materialsListChanged)
+ self._application.getMaterialManagementModel().favoritesChanged.connect(self._onChanged)
self.addRoleName(Qt.UserRole + 1, "root_material_id")
self.addRoleName(Qt.UserRole + 2, "id")
@@ -55,11 +76,8 @@ class BaseMaterialsModel(ListModel):
self.addRoleName(Qt.UserRole + 15, "container_node")
self.addRoleName(Qt.UserRole + 16, "is_favorite")
- self._extruder_position = 0
- self._extruder_stack = None
-
- self._available_materials = None # type: Optional[Dict[str, MaterialNode]]
- self._favorite_ids = set() # type: Set[str]
+ def _onChanged(self) -> None:
+ self._update_timer.start()
def _updateExtruderStack(self):
global_stack = self._machine_manager.activeMachine
@@ -67,14 +85,19 @@ class BaseMaterialsModel(ListModel):
return
if self._extruder_stack is not None:
- self._extruder_stack.pyqtContainersChanged.disconnect(self._update)
- self._extruder_stack.approximateMaterialDiameterChanged.disconnect(self._update)
- self._extruder_stack = global_stack.extruders.get(str(self._extruder_position))
+ self._extruder_stack.pyqtContainersChanged.disconnect(self._onChanged)
+ self._extruder_stack.approximateMaterialDiameterChanged.disconnect(self._onChanged)
+
+ try:
+ self._extruder_stack = global_stack.extruderList[self._extruder_position]
+ except IndexError:
+ self._extruder_stack = None
+
if self._extruder_stack is not None:
- self._extruder_stack.pyqtContainersChanged.connect(self._update)
- self._extruder_stack.approximateMaterialDiameterChanged.connect(self._update)
+ self._extruder_stack.pyqtContainersChanged.connect(self._onChanged)
+ self._extruder_stack.approximateMaterialDiameterChanged.connect(self._onChanged)
# Force update the model when the extruder stack changes
- self._update()
+ self._onChanged()
def setExtruderPosition(self, position: int):
if self._extruder_stack is None or self._extruder_position != position:
@@ -86,36 +109,81 @@ class BaseMaterialsModel(ListModel):
def extruderPosition(self) -> int:
return self._extruder_position
- ## This is an abstract method that needs to be implemented by the specific
- # models themselves.
+ def setEnabled(self, enabled):
+ if self._enabled != enabled:
+ self._enabled = enabled
+ if self._enabled:
+ # ensure the data is there again.
+ self._onChanged()
+ self.enabledChanged.emit()
+
+ @pyqtProperty(bool, fset = setEnabled, notify = enabledChanged)
+ def enabled(self):
+ return self._enabled
+
+ ## Triggered when a list of materials changed somewhere in the container
+ # tree. This change may trigger an _update() call when the materials
+ # changed for the configuration that this model is looking for.
+ def _materialsListChanged(self, material: MaterialNode) -> None:
+ if self._extruder_stack is None:
+ return
+ if material.variant.container_id != self._extruder_stack.variant.getId():
+ return
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_stack:
+ return
+ if material.variant.machine.container_id != global_stack.definition.getId():
+ return
+ self._onChanged()
+
+ ## Triggered when the list of favorite materials is changed.
+ def _favoritesChanged(self, material_base_file: str) -> None:
+ if material_base_file in self._available_materials:
+ self._onChanged()
+
+ ## This is an abstract method that needs to be implemented by the specific
+ # models themselves.
def _update(self):
- pass
+ self._favorite_ids = set(cura.CuraApplication.CuraApplication.getInstance().getPreferences().getValue("cura/favorite_materials").split(";"))
+
+ # Update the available materials (ContainerNode) for the current active machine and extruder setup.
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_stack.hasMaterials:
+ return # There are no materials for this machine, so nothing to do.
+ extruder_stack = global_stack.extruders.get(str(self._extruder_position))
+ if not extruder_stack:
+ return
+ nozzle_name = extruder_stack.variant.getName()
+ 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}
## 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:
+ if global_stack is None or not self._enabled:
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.getMetadata()
+ metadata_list = CuraContainerRegistry.getInstance().findContainersMetadata(id = container_node.container_id)
+ if not metadata_list:
+ return None
+ metadata = metadata_list[0]
item = {
"root_material_id": root_material_id,
"id": metadata["id"],
@@ -136,4 +204,3 @@ class BaseMaterialsModel(ListModel):
"is_favorite": root_material_id in self._favorite_ids
}
return item
-
diff --git a/cura/Machines/Models/BuildPlateModel.py b/cura/Machines/Models/BuildPlateModel.py
index 82b9db4d64..3697dd2762 100644
--- a/cura/Machines/Models/BuildPlateModel.py
+++ b/cura/Machines/Models/BuildPlateModel.py
@@ -1,14 +1,9 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# 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):
@@ -21,31 +16,9 @@ class BuildPlateModel(ListModel):
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.ContainerNodeRole, "container_node")
- self._application = Application.getInstance()
- self._variant_manager = self._application._variant_manager
- self._machine_manager = self._application.getMachineManager()
-
- self._machine_manager.globalContainerChanged.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._global_container_stack
- if not global_stack:
- self.setItems([])
- return
-
- has_variants = parseBool(global_stack.getMetaDataEntry("has_variant_buildplates", False))
- if not has_variants:
- self.setItems([])
- return
-
- variant_dict = self._variant_manager.getVariantNodes(global_stack, variant_type = VariantType.BUILD_PLATE)
-
- item_list = []
- for name, variant_node in variant_dict.items():
- item = {"name": name,
- "container_node": variant_node}
- item_list.append(item)
- self.setItems(item_list)
+ self.setItems([])
+ return
diff --git a/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py
index dcade8cb0d..1ab7e21700 100644
--- a/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py
+++ b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py
@@ -1,31 +1,48 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+from typing import Optional, TYPE_CHECKING
+
from UM.Logger import Logger
+import cura.CuraApplication # Imported this way to prevent circular references.
+from cura.Machines.ContainerTree import ContainerTree
from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel
+if TYPE_CHECKING:
+ from PyQt5.QtCore import QObject
+ from UM.Settings.Interfaces import ContainerInterface
-#
-# This model is used for the custom profile items in the profile drop down menu.
-#
+
+## This model is used for the custom profile items in the profile drop down
+# menu.
class CustomQualityProfilesDropDownMenuModel(QualityProfilesDropDownMenuModel):
- def _update(self):
+ def __init__(self, parent: Optional["QObject"] = None) -> None:
+ super().__init__(parent)
+
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ container_registry.containerAdded.connect(self._qualityChangesListChanged)
+ container_registry.containerRemoved.connect(self._qualityChangesListChanged)
+ container_registry.containerMetaDataChanged.connect(self._qualityChangesListChanged)
+
+ def _qualityChangesListChanged(self, container: "ContainerInterface") -> None:
+ if container.getMetaDataEntry("type") == "quality_changes":
+ self._update()
+
+ def _update(self) -> None:
Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
- active_global_stack = self._machine_manager.activeMachine
+ active_global_stack = cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeMachine
if active_global_stack is None:
self.setItems([])
Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__)
return
- quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(active_global_stack)
+ quality_changes_list = ContainerTree.getInstance().getCurrentQualityChangesGroups()
item_list = []
- for key in sorted(quality_changes_group_dict, key = lambda name: name.upper()):
- quality_changes_group = quality_changes_group_dict[key]
-
+ for quality_changes_group in sorted(quality_changes_list, key = lambda qgc: qgc.name.lower()):
item = {"name": quality_changes_group.name,
"layer_height": "",
"layer_height_without_unit": "",
diff --git a/cura/Machines/Models/DiscoveredPrintersModel.py b/cura/Machines/Models/DiscoveredPrintersModel.py
new file mode 100644
index 0000000000..c662334470
--- /dev/null
+++ b/cura/Machines/Models/DiscoveredPrintersModel.py
@@ -0,0 +1,263 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Callable, Dict, List, Optional, TYPE_CHECKING
+
+from PyQt5.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject, QTimer
+
+from UM.i18n import i18nCatalog
+from UM.Logger import Logger
+from UM.Util import parseBool
+from UM.OutputDevice.OutputDeviceManager import ManualDeviceAdditionAttempt
+
+if TYPE_CHECKING:
+ from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
+ from cura.CuraApplication import CuraApplication
+ from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice
+
+
+catalog = i18nCatalog("cura")
+
+
+class DiscoveredPrinter(QObject):
+
+ def __init__(self, ip_address: str, key: str, name: str, create_callback: Callable[[str], None], machine_type: str,
+ device: "NetworkedPrinterOutputDevice", parent: Optional["QObject"] = None) -> None:
+ super().__init__(parent)
+
+ self._ip_address = ip_address
+ self._key = key
+ self._name = name
+ self.create_callback = create_callback
+ self._machine_type = machine_type
+ self._device = device
+
+ nameChanged = pyqtSignal()
+
+ def getKey(self) -> str:
+ return self._key
+
+ @pyqtProperty(str, notify = nameChanged)
+ def name(self) -> str:
+ return self._name
+
+ def setName(self, name: str) -> None:
+ if self._name != name:
+ self._name = name
+ self.nameChanged.emit()
+
+ @pyqtProperty(str, constant = True)
+ def address(self) -> str:
+ return self._ip_address
+
+ machineTypeChanged = pyqtSignal()
+
+ @pyqtProperty(str, notify = machineTypeChanged)
+ def machineType(self) -> str:
+ return self._machine_type
+
+ def setMachineType(self, machine_type: str) -> None:
+ if self._machine_type != machine_type:
+ self._machine_type = machine_type
+ self.machineTypeChanged.emit()
+
+ # Checks if the given machine type name in the available machine list.
+ # The machine type is a code name such as "ultimaker_3", while the machine type name is the human-readable name of
+ # the machine type, which is "Ultimaker 3" for "ultimaker_3".
+ def _hasHumanReadableMachineTypeName(self, machine_type_name: str) -> bool:
+ from cura.CuraApplication import CuraApplication
+ results = CuraApplication.getInstance().getContainerRegistry().findDefinitionContainersMetadata(name = machine_type_name)
+ return len(results) > 0
+
+ # Human readable machine type string
+ @pyqtProperty(str, notify = machineTypeChanged)
+ def readableMachineType(self) -> str:
+ from cura.CuraApplication import CuraApplication
+ machine_manager = CuraApplication.getInstance().getMachineManager()
+ # In NetworkOutputDevice, when it updates a printer information, it updates the machine type using the field
+ # "machine_variant", and for some reason, it's not the machine type ID/codename/... but a human-readable string
+ # like "Ultimaker 3". The code below handles this case.
+ if self._hasHumanReadableMachineTypeName(self._machine_type):
+ readable_type = self._machine_type
+ else:
+ readable_type = self._getMachineTypeNameFromId(self._machine_type)
+ if not readable_type:
+ readable_type = catalog.i18nc("@label", "Unknown")
+ return readable_type
+
+ @pyqtProperty(bool, notify = machineTypeChanged)
+ def isUnknownMachineType(self) -> bool:
+ if self._hasHumanReadableMachineTypeName(self._machine_type):
+ readable_type = self._machine_type
+ else:
+ readable_type = self._getMachineTypeNameFromId(self._machine_type)
+ return not readable_type
+
+ def _getMachineTypeNameFromId(self, machine_type_id: str) -> str:
+ machine_type_name = ""
+ from cura.CuraApplication import CuraApplication
+ results = CuraApplication.getInstance().getContainerRegistry().findDefinitionContainersMetadata(id = machine_type_id)
+ if results:
+ machine_type_name = results[0]["name"]
+ return machine_type_name
+
+ @pyqtProperty(QObject, constant = True)
+ def device(self) -> "NetworkedPrinterOutputDevice":
+ return self._device
+
+ @pyqtProperty(bool, constant = True)
+ def isHostOfGroup(self) -> bool:
+ return getattr(self._device, "clusterSize", 1) > 0
+
+ @pyqtProperty(str, constant = True)
+ def sectionName(self) -> str:
+ if self.isUnknownMachineType or not self.isHostOfGroup:
+ return catalog.i18nc("@label", "The printer(s) below cannot be connected because they are part of a group")
+ else:
+ return catalog.i18nc("@label", "Available networked printers")
+
+
+#
+# Discovered printers are all the printers that were found on the network, which provide a more convenient way
+# to add networked printers (Plugin finds a bunch of printers, user can select one from the list, plugin can then
+# add that printer to Cura as the active one).
+#
+class DiscoveredPrintersModel(QObject):
+
+ def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
+ super().__init__(parent)
+
+ self._application = application
+ self._discovered_printer_by_ip_dict = dict() # type: Dict[str, DiscoveredPrinter]
+
+ self._plugin_for_manual_device = None # type: Optional[OutputDevicePlugin]
+ self._manual_device_address = ""
+
+ self._manual_device_request_timeout_in_seconds = 5 # timeout for adding a manual device in seconds
+ self._manual_device_request_timer = QTimer()
+ self._manual_device_request_timer.setInterval(self._manual_device_request_timeout_in_seconds * 1000)
+ self._manual_device_request_timer.setSingleShot(True)
+ self._manual_device_request_timer.timeout.connect(self._onManualRequestTimeout)
+
+ discoveredPrintersChanged = pyqtSignal()
+
+ @pyqtSlot(str)
+ def checkManualDevice(self, address: str) -> None:
+ if self.hasManualDeviceRequestInProgress:
+ Logger.log("i", "A manual device request for address [%s] is still in progress, do nothing",
+ self._manual_device_address)
+ return
+
+ priority_order = [
+ ManualDeviceAdditionAttempt.PRIORITY,
+ ManualDeviceAdditionAttempt.POSSIBLE,
+ ] # type: List[ManualDeviceAdditionAttempt]
+
+ all_plugins_dict = self._application.getOutputDeviceManager().getAllOutputDevicePlugins()
+
+ can_add_manual_plugins = [item for item in filter(
+ lambda plugin_item: plugin_item.canAddManualDevice(address) in priority_order,
+ all_plugins_dict.values())]
+
+ if not can_add_manual_plugins:
+ Logger.log("d", "Could not find a plugin to accept adding %s manually via address.", address)
+ return
+
+ plugin = max(can_add_manual_plugins, key = lambda p: priority_order.index(p.canAddManualDevice(address)))
+ self._plugin_for_manual_device = plugin
+ self._plugin_for_manual_device.addManualDevice(address, callback = self._onManualDeviceRequestFinished)
+ self._manual_device_address = address
+ self._manual_device_request_timer.start()
+ self.hasManualDeviceRequestInProgressChanged.emit()
+
+ @pyqtSlot()
+ def cancelCurrentManualDeviceRequest(self) -> None:
+ self._manual_device_request_timer.stop()
+
+ if self._manual_device_address:
+ if self._plugin_for_manual_device is not None:
+ self._plugin_for_manual_device.removeManualDevice(self._manual_device_address, address = self._manual_device_address)
+ self._manual_device_address = ""
+ self._plugin_for_manual_device = None
+ self.hasManualDeviceRequestInProgressChanged.emit()
+ self.manualDeviceRequestFinished.emit(False)
+
+ def _onManualRequestTimeout(self) -> None:
+ Logger.log("w", "Manual printer [%s] request timed out. Cancel the current request.", self._manual_device_address)
+ self.cancelCurrentManualDeviceRequest()
+
+ hasManualDeviceRequestInProgressChanged = pyqtSignal()
+
+ @pyqtProperty(bool, notify = hasManualDeviceRequestInProgressChanged)
+ def hasManualDeviceRequestInProgress(self) -> bool:
+ return self._manual_device_address != ""
+
+ manualDeviceRequestFinished = pyqtSignal(bool, arguments = ["success"])
+
+ def _onManualDeviceRequestFinished(self, success: bool, address: str) -> None:
+ self._manual_device_request_timer.stop()
+ if address == self._manual_device_address:
+ self._manual_device_address = ""
+ self.hasManualDeviceRequestInProgressChanged.emit()
+ self.manualDeviceRequestFinished.emit(success)
+
+ @pyqtProperty("QVariantMap", notify = discoveredPrintersChanged)
+ def discoveredPrintersByAddress(self) -> Dict[str, DiscoveredPrinter]:
+ return self._discovered_printer_by_ip_dict
+
+ @pyqtProperty("QVariantList", notify = discoveredPrintersChanged)
+ def discoveredPrinters(self) -> List["DiscoveredPrinter"]:
+ item_list = list(
+ x for x in self._discovered_printer_by_ip_dict.values() if not parseBool(x.device.getProperty("temporary")))
+
+ # Split the printers into 2 lists and sort them ascending based on names.
+ available_list = []
+ not_available_list = []
+ for item in item_list:
+ if item.isUnknownMachineType or getattr(item.device, "clusterSize", 1) < 1:
+ not_available_list.append(item)
+ else:
+ available_list.append(item)
+
+ available_list.sort(key = lambda x: x.device.name)
+ not_available_list.sort(key = lambda x: x.device.name)
+
+ return available_list + not_available_list
+
+ def addDiscoveredPrinter(self, ip_address: str, key: str, name: str, create_callback: Callable[[str], None],
+ machine_type: str, device: "NetworkedPrinterOutputDevice") -> None:
+ if ip_address in self._discovered_printer_by_ip_dict:
+ Logger.log("e", "Printer with ip [%s] has already been added", ip_address)
+ return
+
+ discovered_printer = DiscoveredPrinter(ip_address, key, name, create_callback, machine_type, device, parent = self)
+ self._discovered_printer_by_ip_dict[ip_address] = discovered_printer
+ self.discoveredPrintersChanged.emit()
+
+ def updateDiscoveredPrinter(self, ip_address: str,
+ name: Optional[str] = None,
+ machine_type: Optional[str] = None) -> None:
+ if ip_address not in self._discovered_printer_by_ip_dict:
+ Logger.log("w", "Printer with ip [%s] is not known", ip_address)
+ return
+
+ item = self._discovered_printer_by_ip_dict[ip_address]
+
+ if name is not None:
+ item.setName(name)
+ if machine_type is not None:
+ item.setMachineType(machine_type)
+
+ def removeDiscoveredPrinter(self, ip_address: str) -> None:
+ if ip_address not in self._discovered_printer_by_ip_dict:
+ Logger.log("w", "Key [%s] does not exist in the discovered printers list.", ip_address)
+ return
+
+ del self._discovered_printer_by_ip_dict[ip_address]
+ self.discoveredPrintersChanged.emit()
+
+ # A convenience function for QML to create a machine (GlobalStack) out of the given discovered printer.
+ # This function invokes the given discovered printer's "create_callback" to do this.
+ @pyqtSlot("QVariant")
+ def createMachineFromDiscoveredPrinter(self, discovered_printer: "DiscoveredPrinter") -> None:
+ discovered_printer.create_callback(discovered_printer.getKey())
diff --git a/cura/Settings/ExtrudersModel.py b/cura/Machines/Models/ExtrudersModel.py
similarity index 96%
rename from cura/Settings/ExtrudersModel.py
rename to cura/Machines/Models/ExtrudersModel.py
index afc2af94b3..9eee7f5f9e 100644
--- a/cura/Settings/ExtrudersModel.py
+++ b/cura/Machines/Models/ExtrudersModel.py
@@ -2,23 +2,25 @@
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer
-from typing import Iterable
+from typing import Iterable, TYPE_CHECKING
from UM.i18n import i18nCatalog
-import UM.Qt.ListModel
+from UM.Qt.ListModel import ListModel
from UM.Application import Application
import UM.FlameProfiler
-from cura.Settings.ExtruderStack import ExtruderStack # To listen to changes on the extruders.
+if TYPE_CHECKING:
+ from cura.Settings.ExtruderStack import ExtruderStack # To listen to changes on the extruders.
catalog = i18nCatalog("cura")
+
## Model that holds extruders.
#
# This model is designed for use by any list of extruders, but specifically
# intended for drop-down lists of the current machine's extruders in place of
# settings.
-class ExtrudersModel(UM.Qt.ListModel.ListModel):
+class ExtrudersModel(ListModel):
# The ID of the container stack for the extruder.
IdRole = Qt.UserRole + 1
@@ -134,8 +136,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
self._updateExtruders() # Since the new extruders may have different properties, update our own model.
def _onExtruderStackContainersChanged(self, container):
- # Update when there is an empty container or material change
- if container.getMetaDataEntry("type") == "material" or container.getMetaDataEntry("type") is None:
+ # Update when there is an empty container or material or variant change
+ if container.getMetaDataEntry("type") in ["material", "variant", None]:
# The ExtrudersModel needs to be updated when the material-name or -color changes, because the user identifies extruders by material-name
self._updateExtruders()
diff --git a/cura/Machines/Models/FavoriteMaterialsModel.py b/cura/Machines/Models/FavoriteMaterialsModel.py
index 98a2a01597..6b8f0e8e56 100644
--- a/cura/Machines/Models/FavoriteMaterialsModel.py
+++ b/cura/Machines/Models/FavoriteMaterialsModel.py
@@ -1,28 +1,33 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
+import cura.CuraApplication # To listen to changes to the preferences.
## Model that shows the list of favorite materials.
class FavoriteMaterialsModel(BaseMaterialsModel):
def __init__(self, parent = None):
super().__init__(parent)
- self._update()
+ cura.CuraApplication.CuraApplication.getInstance().getPreferences().preferenceChanged.connect(self._onFavoritesChanged)
+ self._onChanged()
+
+ ## Triggered when any preference changes, but only handles it when the list
+ # of favourites is changed.
+ def _onFavoritesChanged(self, preference_key: str) -> None:
+ if preference_key != "cura/favorite_materials":
+ return
+ self._onChanged()
def _update(self):
if not self._canUpdate():
return
-
- # Get updated list of favorites
- self._favorite_ids = self._material_manager.getFavorites()
+ super()._update()
item_list = []
for root_material_id, container_node in self._available_materials.items():
- metadata = container_node.getMetadata()
-
# Do not include the materials from a to-be-removed package
- if bool(metadata.get("removed", False)):
+ if bool(container_node.getMetaDataEntry("removed", False)):
continue
# Only add results for favorite materials
@@ -30,7 +35,8 @@ class FavoriteMaterialsModel(BaseMaterialsModel):
continue
item = self._createMaterialItem(root_material_id, container_node)
- item_list.append(item)
+ if item:
+ item_list.append(item)
# Sort the item list alphabetically by name
item_list = sorted(item_list, key = lambda d: d["brand"].upper())
diff --git a/cura/Machines/Models/FirstStartMachineActionsModel.py b/cura/Machines/Models/FirstStartMachineActionsModel.py
new file mode 100644
index 0000000000..92caed7b12
--- /dev/null
+++ b/cura/Machines/Models/FirstStartMachineActionsModel.py
@@ -0,0 +1,112 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Optional, Dict, Any, TYPE_CHECKING
+
+from PyQt5.QtCore import QObject, Qt, pyqtProperty, pyqtSignal, pyqtSlot
+
+from UM.Qt.ListModel import ListModel
+
+if TYPE_CHECKING:
+ from cura.CuraApplication import CuraApplication
+
+
+#
+# This model holds all first-start machine actions for the currently active machine. It has 2 roles:
+# - title : the title/name of the action
+# - content : the QObject of the QML content of the action
+# - action : the MachineAction object itself
+#
+class FirstStartMachineActionsModel(ListModel):
+
+ TitleRole = Qt.UserRole + 1
+ ContentRole = Qt.UserRole + 2
+ ActionRole = Qt.UserRole + 3
+
+ def __init__(self, application: "CuraApplication", parent: Optional[QObject] = None) -> None:
+ super().__init__(parent)
+
+ self.addRoleName(self.TitleRole, "title")
+ self.addRoleName(self.ContentRole, "content")
+ self.addRoleName(self.ActionRole, "action")
+
+ self._current_action_index = 0
+
+ self._application = application
+ self._application.initializationFinished.connect(self.initialize)
+
+ self._previous_global_stack = None
+
+ def initialize(self) -> None:
+ self._application.getMachineManager().globalContainerChanged.connect(self._update)
+ self._update()
+
+ currentActionIndexChanged = pyqtSignal()
+ allFinished = pyqtSignal() # Emitted when all actions have been finished.
+
+ @pyqtProperty(int, notify = currentActionIndexChanged)
+ def currentActionIndex(self) -> int:
+ return self._current_action_index
+
+ @pyqtProperty("QVariantMap", notify = currentActionIndexChanged)
+ def currentItem(self) -> Optional[Dict[str, Any]]:
+ if self._current_action_index >= self.count:
+ return dict()
+ else:
+ return self.getItem(self._current_action_index)
+
+ @pyqtProperty(bool, notify = currentActionIndexChanged)
+ def hasMoreActions(self) -> bool:
+ return self._current_action_index < self.count - 1
+
+ @pyqtSlot()
+ def goToNextAction(self) -> None:
+ # finish the current item
+ if "action" in self.currentItem:
+ self.currentItem["action"].setFinished()
+
+ if not self.hasMoreActions:
+ self.allFinished.emit()
+ self.reset()
+ return
+
+ self._current_action_index += 1
+ self.currentActionIndexChanged.emit()
+
+ # Resets the current action index to 0 so the wizard panel can show actions from the beginning.
+ @pyqtSlot()
+ def reset(self) -> None:
+ self._current_action_index = 0
+ self.currentActionIndexChanged.emit()
+
+ if self.count == 0:
+ self.allFinished.emit()
+
+ def _update(self) -> None:
+ global_stack = self._application.getMachineManager().activeMachine
+ if global_stack is None:
+ self.setItems([])
+ return
+
+ # Do not update if the machine has not been switched. This can cause the SettingProviders on the Machine
+ # Setting page to do a force update, but they can use potential outdated cached values.
+ if self._previous_global_stack is not None and global_stack.getId() == self._previous_global_stack.getId():
+ return
+ self._previous_global_stack = global_stack
+
+ definition_id = global_stack.definition.getId()
+ first_start_actions = self._application.getMachineActionManager().getFirstStartActions(definition_id)
+
+ item_list = []
+ for item in first_start_actions:
+ item_list.append({"title": item.label,
+ "content": item.getDisplayItem(),
+ "action": item,
+ })
+ item.reset()
+
+ self.setItems(item_list)
+ self.reset()
+
+
+__all__ = ["FirstStartMachineActionsModel"]
diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py
index 8f41dd6a70..9ed1632b87 100644
--- a/cura/Machines/Models/GenericMaterialsModel.py
+++ b/cura/Machines/Models/GenericMaterialsModel.py
@@ -1,37 +1,33 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 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 GenericMaterialsModel(BaseMaterialsModel):
def __init__(self, parent = None):
super().__init__(parent)
- self._update()
+ self._onChanged()
def _update(self):
if not self._canUpdate():
return
-
- # Get updated list of favorites
- self._favorite_ids = self._material_manager.getFavorites()
+ super()._update()
item_list = []
for root_material_id, container_node in self._available_materials.items():
- metadata = container_node.getMetadata()
-
# Do not include the materials from a to-be-removed package
- if bool(metadata.get("removed", False)):
+ if bool(container_node.getMetaDataEntry("removed", False)):
continue
# Only add results for generic materials
- if metadata["brand"].lower() != "generic":
+ if container_node.getMetaDataEntry("brand", "unknown").lower() != "generic":
continue
item = self._createMaterialItem(root_material_id, container_node)
- item_list.append(item)
+ if item:
+ item_list.append(item)
# Sort the item list alphabetically by name
item_list = sorted(item_list, key = lambda d: d["name"].upper())
diff --git a/cura/GlobalStacksModel.py b/cura/Machines/Models/GlobalStacksModel.py
similarity index 57%
rename from cura/GlobalStacksModel.py
rename to cura/Machines/Models/GlobalStacksModel.py
index 32b0d9cead..9db4ffe6db 100644
--- a/cura/GlobalStacksModel.py
+++ b/cura/Machines/Models/GlobalStacksModel.py
@@ -1,11 +1,15 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from PyQt5.QtCore import Qt
+from PyQt5.QtCore import Qt, QTimer
from UM.Qt.ListModel import ListModel
-from cura.PrinterOutputDevice import ConnectionType
+from UM.i18n import i18nCatalog
+from UM.Util import parseBool
+
+from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
+from cura.Settings.GlobalStack import GlobalStack
class GlobalStacksModel(ListModel):
@@ -14,47 +18,60 @@ class GlobalStacksModel(ListModel):
HasRemoteConnectionRole = Qt.UserRole + 3
ConnectionTypeRole = Qt.UserRole + 4
MetaDataRole = Qt.UserRole + 5
+ DiscoverySourceRole = Qt.UserRole + 6 # For separating local and remote printers in the machine management page
- def __init__(self, parent = None):
+ def __init__(self, parent = None) -> None:
super().__init__(parent)
+
+ self._catalog = i18nCatalog("cura")
+
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.IdRole, "id")
self.addRoleName(self.HasRemoteConnectionRole, "hasRemoteConnection")
self.addRoleName(self.MetaDataRole, "metadata")
- self._container_stacks = []
+ self.addRoleName(self.DiscoverySourceRole, "discoverySource")
+
+ self._change_timer = QTimer()
+ self._change_timer.setInterval(200)
+ self._change_timer.setSingleShot(True)
+ self._change_timer.timeout.connect(self._update)
# Listen to changes
CuraContainerRegistry.getInstance().containerAdded.connect(self._onContainerChanged)
CuraContainerRegistry.getInstance().containerMetaDataChanged.connect(self._onContainerChanged)
CuraContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChanged)
- self._filter_dict = {}
- self._update()
+ self._updateDelayed()
## Handler for container added/removed events from registry
- def _onContainerChanged(self, container):
- from cura.Settings.GlobalStack import GlobalStack # otherwise circular imports
-
+ def _onContainerChanged(self, container) -> None:
# We only need to update when the added / removed container GlobalStack
if isinstance(container, GlobalStack):
- self._update()
+ self._updateDelayed()
+
+ def _updateDelayed(self) -> None:
+ self._change_timer.start()
def _update(self) -> None:
items = []
container_stacks = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine")
-
for container_stack in container_stacks:
has_remote_connection = False
for connection_type in container_stack.configuredConnectionTypes:
- has_remote_connection |= connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value]
+ has_remote_connection |= connection_type in [ConnectionType.NetworkConnection.value,
+ ConnectionType.CloudConnection.value]
- if container_stack.getMetaDataEntry("hidden", False) in ["True", True]:
+ if parseBool(container_stack.getMetaDataEntry("hidden", False)):
continue
+ section_name = "Network enabled printers" if has_remote_connection else "Local printers"
+ section_name = self._catalog.i18nc("@info:title", section_name)
+
items.append({"name": container_stack.getMetaDataEntry("group_name", container_stack.getName()),
"id": container_stack.getId(),
"hasRemoteConnection": has_remote_connection,
- "metadata": container_stack.getMetaData().copy()})
- items.sort(key=lambda i: not i["hasRemoteConnection"])
+ "metadata": container_stack.getMetaData().copy(),
+ "discoverySource": section_name})
+ items.sort(key = lambda i: (not i["hasRemoteConnection"], i["name"]))
self.setItems(items)
diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py
new file mode 100644
index 0000000000..202d79bb15
--- /dev/null
+++ b/cura/Machines/Models/IntentCategoryModel.py
@@ -0,0 +1,118 @@
+#Copyright (c) 2019 Ultimaker B.V.
+#Cura is released under the terms of the LGPLv3 or higher.
+
+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
+from UM.Qt.ListModel import ListModel
+from UM.Settings.ContainerRegistry import ContainerRegistry #To update the list if anything changes.
+from PyQt5.QtCore import pyqtProperty, pyqtSignal
+import cura.CuraApplication
+if TYPE_CHECKING:
+ from UM.Settings.ContainerRegistry import ContainerInterface
+
+from UM.i18n import i18nCatalog
+catalog = i18nCatalog("cura")
+
+
+## Lists the intent categories that are available for the current printer
+# configuration.
+class IntentCategoryModel(ListModel):
+ NameRole = Qt.UserRole + 1
+ IntentCategoryRole = Qt.UserRole + 2
+ WeightRole = Qt.UserRole + 3
+ QualitiesRole = Qt.UserRole + 4
+ DescriptionRole = Qt.UserRole + 5
+
+ 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.
+ @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.
+ def __init__(self, intent_category: str) -> None:
+ super().__init__()
+ self._intent_category = intent_category
+
+ self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.IntentCategoryRole, "intent_category")
+ self.addRoleName(self.WeightRole, "weight")
+ self.addRoleName(self.QualitiesRole, "qualities")
+ self.addRoleName(self.DescriptionRole, "description")
+
+ application = cura.CuraApplication.CuraApplication.getInstance()
+
+ ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChange)
+ ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChange)
+ machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
+ machine_manager.activeMaterialChanged.connect(self.update)
+ machine_manager.activeVariantChanged.connect(self.update)
+ machine_manager.extruderChanged.connect(self.update)
+
+ extruder_manager = application.getExtruderManager()
+ extruder_manager.extrudersChanged.connect(self.update)
+
+ self._update_timer = QTimer()
+ self._update_timer.setInterval(500)
+ self._update_timer.setSingleShot(True)
+ self._update_timer.timeout.connect(self._update)
+
+ self.update()
+
+ ## Updates the list of intents if an intent profile was added or removed.
+ def _onContainerChange(self, container: "ContainerInterface") -> None:
+ if container.getMetaDataEntry("type") == "intent":
+ self.update()
+
+ def update(self):
+ self._update_timer.start()
+
+ ## Updates the list of intents.
+ def _update(self) -> None:
+ available_categories = IntentManager.getInstance().currentAvailableIntentCategories()
+ result = []
+ for category in available_categories:
+ qualities = IntentModel()
+ qualities.setIntentCategory(category)
+ result.append({
+ "name": IntentCategoryModel.translation(category, "name", catalog.i18nc("@label", "Unknown")),
+ "description": IntentCategoryModel.translation(category, "description", None),
+ "intent_category": 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.
+ ## for categories and keys
+ @staticmethod
+ def translation(category: str, key: str, default: Optional[str] = None):
+ display_strings = IntentCategoryModel._get_translations().get(category, {})
+ return display_strings.get(key, default)
diff --git a/cura/Machines/Models/IntentModel.py b/cura/Machines/Models/IntentModel.py
new file mode 100644
index 0000000000..986f28a826
--- /dev/null
+++ b/cura/Machines/Models/IntentModel.py
@@ -0,0 +1,135 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import Optional, Dict, Any, Set, List
+
+from PyQt5.QtCore import Qt, QObject, pyqtProperty, pyqtSignal
+
+import cura.CuraApplication
+from UM.Qt.ListModel import ListModel
+from UM.Settings.ContainerRegistry import ContainerRegistry
+from UM.Logger import Logger
+from cura.Machines.ContainerTree import ContainerTree
+from cura.Machines.MaterialNode import MaterialNode
+from cura.Machines.Models.MachineModelUtils import fetchLayerHeight
+from cura.Machines.QualityGroup import QualityGroup
+
+
+class IntentModel(ListModel):
+ NameRole = Qt.UserRole + 1
+ QualityTypeRole = Qt.UserRole + 2
+ LayerHeightRole = Qt.UserRole + 3
+ AvailableRole = Qt.UserRole + 4
+ IntentRole = Qt.UserRole + 5
+
+ def __init__(self, parent: Optional[QObject] = None) -> None:
+ super().__init__(parent)
+
+ self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.QualityTypeRole, "quality_type")
+ self.addRoleName(self.LayerHeightRole, "layer_height")
+ self.addRoleName(self.AvailableRole, "available")
+ self.addRoleName(self.IntentRole, "intent_category")
+
+ self._intent_category = "engineering"
+
+ machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
+ machine_manager.globalContainerChanged.connect(self._update)
+ machine_manager.extruderChanged.connect(self._update) # We also need to update if an extruder gets disabled
+ ContainerRegistry.getInstance().containerAdded.connect(self._onChanged)
+ ContainerRegistry.getInstance().containerRemoved.connect(self._onChanged)
+ self._layer_height_unit = "" # This is cached
+ self._update()
+
+ intentCategoryChanged = pyqtSignal()
+
+ def setIntentCategory(self, new_category: str) -> None:
+ if self._intent_category != new_category:
+ self._intent_category = new_category
+ self.intentCategoryChanged.emit()
+ self._update()
+
+ @pyqtProperty(str, fset = setIntentCategory, notify = intentCategoryChanged)
+ def intentCategory(self) -> str:
+ return self._intent_category
+
+ def _onChanged(self, container):
+ if container.getMetaDataEntry("type") == "intent":
+ self._update()
+
+ def _update(self) -> None:
+ new_items = [] # type: List[Dict[str, Any]]
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_stack:
+ self.setItems(new_items)
+ return
+ quality_groups = ContainerTree.getInstance().getCurrentQualityGroups()
+
+ material_nodes = self._getActiveMaterials()
+
+ added_quality_type_set = set() # type: Set[str]
+ for material_node in material_nodes:
+ intents = self._getIntentsForMaterial(material_node, quality_groups)
+ for intent in intents:
+ if intent["quality_type"] not in added_quality_type_set:
+ new_items.append(intent)
+ added_quality_type_set.add(intent["quality_type"])
+
+ # Now that we added all intents that we found something for, ensure that we set add ticks (and layer_heights)
+ # for all groups that we don't have anything for (and set it to not available)
+ for quality_type, quality_group in quality_groups.items():
+ # Add the intents that are of the correct category
+ if quality_type not in added_quality_type_set:
+ layer_height = fetchLayerHeight(quality_group)
+ new_items.append({"name": "Unavailable",
+ "quality_type": quality_type,
+ "layer_height": layer_height,
+ "intent_category": self._intent_category,
+ "available": False})
+ added_quality_type_set.add(quality_type)
+
+ new_items = sorted(new_items, key = lambda x: x["layer_height"])
+ self.setItems(new_items)
+
+ ## Get the active materials for all extruders. No duplicates will be returned
+ def _getActiveMaterials(self) -> Set["MaterialNode"]:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return set()
+
+ container_tree = ContainerTree.getInstance()
+ machine_node = container_tree.machines[global_stack.definition.getId()]
+ nodes = set() # type: Set[MaterialNode]
+
+ for extruder in global_stack.extruderList:
+ active_variant_name = extruder.variant.getMetaDataEntry("name")
+ if active_variant_name not in machine_node.variants:
+ Logger.log("w", "Could not find the variant %s", active_variant_name)
+ continue
+ active_variant_node = machine_node.variants[active_variant_name]
+ active_material_node = active_variant_node.materials[extruder.material.getMetaDataEntry("base_file")]
+ nodes.add(active_material_node)
+
+ return nodes
+
+ def _getIntentsForMaterial(self, active_material_node: "MaterialNode", quality_groups: Dict[str, "QualityGroup"]) -> List[Dict[str, Any]]:
+ extruder_intents = [] # type: List[Dict[str, Any]]
+
+ for quality_id, quality_node in active_material_node.qualities.items():
+ if quality_node.quality_type not in quality_groups: # Don't add the empty quality type (or anything else that would crash, defensively).
+ continue
+ quality_group = quality_groups[quality_node.quality_type]
+ layer_height = fetchLayerHeight(quality_group)
+
+ for intent_id, intent_node in quality_node.intents.items():
+ if intent_node.intent_category != self._intent_category:
+ continue
+ extruder_intents.append({"name": quality_group.name,
+ "quality_type": quality_group.quality_type,
+ "layer_height": layer_height,
+ "available": quality_group.is_available,
+ "intent_category": self._intent_category
+ })
+ return extruder_intents
+
+ def __repr__(self):
+ return str(self.items)
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/MachineManagementModel.py b/cura/Machines/Models/MachineManagementModel.py
deleted file mode 100644
index 3297b8a467..0000000000
--- a/cura/Machines/Models/MachineManagementModel.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from UM.Qt.ListModel import ListModel
-
-from PyQt5.QtCore import Qt
-
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from UM.Settings.ContainerStack import ContainerStack
-
-from UM.i18n import i18nCatalog
-catalog = i18nCatalog("cura")
-
-
-#
-# This the QML model for the quality management page.
-#
-class MachineManagementModel(ListModel):
- NameRole = Qt.UserRole + 1
- IdRole = Qt.UserRole + 2
- MetaDataRole = Qt.UserRole + 3
- GroupRole = Qt.UserRole + 4
-
- def __init__(self, parent = None):
- super().__init__(parent)
- self.addRoleName(self.NameRole, "name")
- self.addRoleName(self.IdRole, "id")
- self.addRoleName(self.MetaDataRole, "metadata")
- self.addRoleName(self.GroupRole, "group")
- self._local_container_stacks = []
- self._network_container_stacks = []
-
- # Listen to changes
- ContainerRegistry.getInstance().containerAdded.connect(self._onContainerChanged)
- ContainerRegistry.getInstance().containerMetaDataChanged.connect(self._onContainerChanged)
- ContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChanged)
- self._filter_dict = {}
- self._update()
-
- ## Handler for container added/removed events from registry
- def _onContainerChanged(self, container):
- # We only need to update when the added / removed container is a stack.
- if isinstance(container, ContainerStack) and container.getMetaDataEntry("type") == "machine":
- self._update()
-
- ## Private convenience function to reset & repopulate the model.
- def _update(self):
- items = []
-
- # Get first the network enabled printers
- network_filter_printers = {"type": "machine",
- "um_network_key": "*",
- "hidden": "False"}
- self._network_container_stacks = ContainerRegistry.getInstance().findContainerStacks(**network_filter_printers)
- self._network_container_stacks.sort(key = lambda i: i.getMetaDataEntry("group_name", ""))
-
- for container in self._network_container_stacks:
- metadata = container.getMetaData().copy()
- if container.getBottom():
- metadata["definition_name"] = container.getBottom().getName()
-
- items.append({"name": metadata.get("group_name", ""),
- "id": container.getId(),
- "metadata": metadata,
- "group": catalog.i18nc("@info:title", "Network enabled printers")})
-
- # Get now the local printers
- local_filter_printers = {"type": "machine", "um_network_key": None}
- self._local_container_stacks = ContainerRegistry.getInstance().findContainerStacks(**local_filter_printers)
- self._local_container_stacks.sort(key = lambda i: i.getName())
-
- for container in self._local_container_stacks:
- metadata = container.getMetaData().copy()
- if container.getBottom():
- metadata["definition_name"] = container.getBottom().getName()
-
- items.append({"name": container.getName(),
- "id": container.getId(),
- "metadata": metadata,
- "group": catalog.i18nc("@info:title", "Local printers")})
-
- self.setItems(items)
diff --git a/cura/Machines/Models/MachineModelUtils.py b/cura/Machines/Models/MachineModelUtils.py
new file mode 100644
index 0000000000..a23b1ff3a5
--- /dev/null
+++ b/cura/Machines/Models/MachineModelUtils.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import TYPE_CHECKING
+
+from UM.Settings.SettingFunction import SettingFunction
+
+if TYPE_CHECKING:
+ from cura.Machines.QualityGroup import QualityGroup
+
+layer_height_unit = ""
+
+
+def fetchLayerHeight(quality_group: "QualityGroup") -> float:
+ from cura.CuraApplication import CuraApplication
+ global_stack = CuraApplication.getInstance().getMachineManager().activeMachine
+
+ default_layer_height = global_stack.definition.getProperty("layer_height", "value")
+
+ # Get layer_height from the quality profile for the GlobalStack
+ if quality_group.node_for_global is None:
+ return float(default_layer_height)
+ container = quality_group.node_for_global.container
+
+ layer_height = default_layer_height
+ if container and container.hasProperty("layer_height", "value"):
+ layer_height = container.getProperty("layer_height", "value")
+ else:
+ # Look for layer_height in the GlobalStack from material -> definition
+ 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/Models/MaterialBrandsModel.py b/cura/Machines/Models/MaterialBrandsModel.py
index ac82cf6670..184d27f390 100644
--- a/cura/Machines/Models/MaterialBrandsModel.py
+++ b/cura/Machines/Models/MaterialBrandsModel.py
@@ -1,9 +1,8 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
+from PyQt5.QtCore import Qt, pyqtSignal
from UM.Qt.ListModel import ListModel
-from UM.Logger import Logger
from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
class MaterialTypesModel(ListModel):
@@ -30,8 +29,7 @@ class MaterialBrandsModel(BaseMaterialsModel):
def _update(self):
if not self._canUpdate():
return
- # Get updated list of favorites
- self._favorite_ids = self._material_manager.getFavorites()
+ super()._update()
brand_item_list = []
brand_group_dict = {}
@@ -56,7 +54,8 @@ class MaterialBrandsModel(BaseMaterialsModel):
# Now handle the individual materials
item = self._createMaterialItem(root_material_id, container_node)
- brand_group_dict[brand][material_type].append(item)
+ if item:
+ brand_group_dict[brand][material_type].append(item)
# Part 2: Organize the tree into models
#
diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py
new file mode 100644
index 0000000000..f00b81e987
--- /dev/null
+++ b/cura/Machines/Models/MaterialManagementModel.py
@@ -0,0 +1,246 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+import copy # To duplicate materials.
+from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot # To allow the preference page proxy to be used from the actual preferences page.
+from typing import Any, Dict, Optional, TYPE_CHECKING
+import uuid # To generate new GUIDs for new materials.
+
+from UM.i18n import i18nCatalog
+from UM.Logger import Logger
+from UM.Signal import postponeSignals, CompressTechnique
+
+import cura.CuraApplication # Imported like this to prevent circular imports.
+from cura.Machines.ContainerTree import ContainerTree
+from cura.Settings.CuraContainerRegistry import CuraContainerRegistry # To find the sets of materials belonging to each other, and currently loaded extruder stacks.
+
+if TYPE_CHECKING:
+ from cura.Machines.MaterialNode import MaterialNode
+
+catalog = i18nCatalog("cura")
+
+## Proxy class to the materials page in the preferences.
+#
+# This class handles the actions in that page, such as creating new materials,
+# renaming them, etc.
+class MaterialManagementModel(QObject):
+ ## Triggered when a favorite is added or removed.
+ # \param The base file of the material is provided as parameter when this
+ # emits.
+ favoritesChanged = pyqtSignal(str)
+
+ ## Can a certain material be deleted, or is it still in use in one of the
+ # container stacks anywhere?
+ #
+ # We forbid the user from deleting a material if it's in use in any stack.
+ # Deleting it while it's in use can lead to corrupted stacks. In the
+ # future we might enable this functionality again (deleting the material
+ # from those stacks) but for now it is easier to prevent the user from
+ # doing this.
+ # \param material_node The ContainerTree node of the material to check.
+ # \return Whether or not the material can be removed.
+ @pyqtSlot("QVariant", result = bool)
+ def canMaterialBeRemoved(self, material_node: "MaterialNode") -> bool:
+ container_registry = CuraContainerRegistry.getInstance()
+ ids_to_remove = {metadata.get("id", "") for metadata in container_registry.findInstanceContainersMetadata(base_file = material_node.base_file)}
+ for extruder_stack in container_registry.findContainerStacks(type = "extruder_train"):
+ if extruder_stack.material.getId() in ids_to_remove:
+ return False
+ return True
+
+ ## Change the user-visible name of a material.
+ # \param material_node The ContainerTree node of the material to rename.
+ # \param name The new name for the material.
+ @pyqtSlot("QVariant", str)
+ def setMaterialName(self, material_node: "MaterialNode", name: str) -> None:
+ container_registry = CuraContainerRegistry.getInstance()
+ root_material_id = material_node.base_file
+ if container_registry.isReadOnly(root_material_id):
+ Logger.log("w", "Cannot set name of read-only container %s.", root_material_id)
+ return
+ return container_registry.findContainers(id = root_material_id)[0].setName(name)
+
+ ## Deletes a material from Cura.
+ #
+ # This function does not do any safety checking any more. Please call this
+ # function only if:
+ # - The material is not read-only.
+ # - The material is not used in any stacks.
+ # If the material was not lazy-loaded yet, this will fully load the
+ # container. When removing this material node, all other materials with
+ # the same base fill will also be removed.
+ # \param material_node The material to remove.
+ @pyqtSlot("QVariant")
+ def removeMaterial(self, material_node: "MaterialNode") -> None:
+ container_registry = CuraContainerRegistry.getInstance()
+ materials_this_base_file = container_registry.findContainersMetadata(base_file = material_node.base_file)
+
+ # The material containers belonging to the same material file are supposed to work together. This postponeSignals()
+ # does two things:
+ # - optimizing the signal emitting.
+ # - making sure that the signals will only be emitted after all the material containers have been removed.
+ with postponeSignals(container_registry.containerRemoved, compress = CompressTechnique.CompressPerParameterValue):
+ # CURA-6886: Some containers may not have been loaded. If remove one material container, its material file
+ # will be removed. If later we remove a sub-material container which hasn't been loaded previously, it will
+ # crash because removeContainer() requires to load the container first, but the material file was already
+ # gone.
+ for material_metadata in materials_this_base_file:
+ container_registry.findInstanceContainers(id = material_metadata["id"])
+ for material_metadata in materials_this_base_file:
+ container_registry.removeContainer(material_metadata["id"])
+
+ ## Creates a duplicate of a material with the same GUID and base_file
+ # metadata.
+ # \param base_file: The base file of the material to duplicate.
+ # \param new_base_id A new material ID for the base material. The IDs of
+ # the submaterials will be based off this one. If not provided, a material
+ # ID will be generated automatically.
+ # \param new_metadata Metadata for the new material. If not provided, this
+ # will be duplicated from the original material.
+ # \return The root material ID of the duplicate material.
+ def duplicateMaterialByBaseFile(self, base_file: str, new_base_id: Optional[str] = None,
+ new_metadata: Optional[Dict[str, Any]] = None) -> Optional[str]:
+ container_registry = CuraContainerRegistry.getInstance()
+
+ root_materials = container_registry.findContainers(id = base_file)
+ if not root_materials:
+ Logger.log("i", "Unable to duplicate the root material with ID {root_id}, because it doesn't exist.".format(root_id = base_file))
+ return None
+ root_material = root_materials[0]
+
+ # Ensure that all settings are saved.
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ application.saveSettings()
+
+ # Create a new ID and container to hold the data.
+ if new_base_id is None:
+ new_base_id = container_registry.uniqueName(root_material.getId())
+ new_root_material = copy.deepcopy(root_material)
+ new_root_material.getMetaData()["id"] = new_base_id
+ new_root_material.getMetaData()["base_file"] = new_base_id
+ if new_metadata is not None:
+ new_root_material.getMetaData().update(new_metadata)
+ new_containers = [new_root_material]
+
+ # Clone all submaterials.
+ for container_to_copy in container_registry.findInstanceContainers(base_file = base_file):
+ if container_to_copy.getId() == base_file:
+ continue # We already have that one. Skip it.
+ new_id = new_base_id
+ definition = container_to_copy.getMetaDataEntry("definition")
+ if definition != "fdmprinter":
+ new_id += "_" + definition
+ variant_name = container_to_copy.getMetaDataEntry("variant_name")
+ if variant_name:
+ new_id += "_" + variant_name.replace(" ", "_")
+
+ new_container = copy.deepcopy(container_to_copy)
+ new_container.getMetaData()["id"] = new_id
+ new_container.getMetaData()["base_file"] = new_base_id
+ if new_metadata is not None:
+ new_container.getMetaData().update(new_metadata)
+ new_containers.append(new_container)
+
+ # CURA-6863: Nodes in ContainerTree will be updated upon ContainerAdded signals, one at a time. It will use the
+ # best fit material container at the time it sees one. For example, if you duplicate and get generic_pva #2,
+ # if the node update function sees the containers in the following order:
+ #
+ # - generic_pva #2
+ # - generic_pva #2_um3_aa04
+ #
+ # It will first use "generic_pva #2" because that's the best fit it has ever seen, and later "generic_pva #2_um3_aa04"
+ # once it sees that. Because things run in the Qt event loop, they don't happen at the same time. This means if
+ # between those two events, the ContainerTree will have nodes that contain invalid data.
+ #
+ # This sort fixes the problem by emitting the most specific containers first.
+ new_containers = sorted(new_containers, key = lambda x: x.getId(), reverse = True)
+
+ # Optimization. Serving the same purpose as the postponeSignals() in removeMaterial()
+ # postpone the signals emitted when duplicating materials. This is easier on the event loop; changes the
+ # behavior to be like a transaction. Prevents concurrency issues.
+ with postponeSignals(container_registry.containerAdded, compress=CompressTechnique.CompressPerParameterValue):
+ for container_to_add in new_containers:
+ container_to_add.setDirty(True)
+ container_registry.addContainer(container_to_add)
+
+ # If the duplicated material was favorite then the new material should also be added to the favorites.
+ favorites_set = set(application.getPreferences().getValue("cura/favorite_materials").split(";"))
+ if base_file in favorites_set:
+ favorites_set.add(new_base_id)
+ application.getPreferences().setValue("cura/favorite_materials", ";".join(favorites_set))
+
+ return new_base_id
+
+ ## Creates a duplicate of a material with the same GUID and base_file
+ # metadata.
+ # \param material_node The node representing the material to duplicate.
+ # \param new_base_id A new material ID for the base material. The IDs of
+ # the submaterials will be based off this one. If not provided, a material
+ # ID will be generated automatically.
+ # \param new_metadata Metadata for the new material. If not provided, this
+ # will be duplicated from the original material.
+ # \return The root material ID of the duplicate material.
+ @pyqtSlot("QVariant", result = str)
+ def duplicateMaterial(self, material_node: "MaterialNode", new_base_id: Optional[str] = None,
+ new_metadata: Optional[Dict[str, Any]] = None) -> Optional[str]:
+ return self.duplicateMaterialByBaseFile(material_node.base_file, new_base_id, new_metadata)
+
+ ## Create a new material by cloning the preferred material for the current
+ # material diameter and generate a new GUID.
+ #
+ # The material type is explicitly left to be the one from the preferred
+ # material, since this allows the user to still have SOME profiles to work
+ # with.
+ # \return The ID of the newly created material.
+ @pyqtSlot(result = str)
+ def createMaterial(self) -> str:
+ # Ensure all settings are saved.
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ application.saveSettings()
+
+ # Find the preferred material.
+ extruder_stack = application.getMachineManager().activeStack
+ active_variant_name = extruder_stack.variant.getName()
+ approximate_diameter = int(extruder_stack.approximateMaterialDiameter)
+ global_container_stack = application.getGlobalContainerStack()
+ if not global_container_stack:
+ return ""
+ machine_node = ContainerTree.getInstance().machines[global_container_stack.definition.getId()]
+ preferred_material_node = machine_node.variants[active_variant_name].preferredMaterial(approximate_diameter)
+
+ # Create a new ID & new metadata for the new material.
+ new_id = CuraContainerRegistry.getInstance().uniqueName("custom_material")
+ new_metadata = {"name": catalog.i18nc("@label", "Custom Material"),
+ "brand": catalog.i18nc("@label", "Custom"),
+ "GUID": str(uuid.uuid4()),
+ }
+
+ self.duplicateMaterial(preferred_material_node, new_base_id = new_id, new_metadata = new_metadata)
+ return new_id
+
+ ## Adds a certain material to the favorite materials.
+ # \param material_base_file The base file of the material to add.
+ @pyqtSlot(str)
+ def addFavorite(self, material_base_file: str) -> None:
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ favorites = application.getPreferences().getValue("cura/favorite_materials").split(";")
+ if material_base_file not in favorites:
+ favorites.append(material_base_file)
+ application.getPreferences().setValue("cura/favorite_materials", ";".join(favorites))
+ application.saveSettings()
+ self.favoritesChanged.emit(material_base_file)
+
+ ## Removes a certain material from the favorite materials.
+ #
+ # If the material was not in the favorite materials, nothing happens.
+ @pyqtSlot(str)
+ def removeFavorite(self, material_base_file: str) -> None:
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ favorites = application.getPreferences().getValue("cura/favorite_materials").split(";")
+ try:
+ favorites.remove(material_base_file)
+ application.getPreferences().setValue("cura/favorite_materials", ";".join(favorites))
+ application.saveSettings()
+ self.favoritesChanged.emit(material_base_file)
+ except ValueError: # Material was not in the favorites list.
+ Logger.log("w", "Material {material_base_file} was already not a favorite material.".format(material_base_file = material_base_file))
diff --git a/cura/Machines/Models/MultiBuildPlateModel.py b/cura/Machines/Models/MultiBuildPlateModel.py
index 958e93837a..add960a545 100644
--- a/cura/Machines/Models/MultiBuildPlateModel.py
+++ b/cura/Machines/Models/MultiBuildPlateModel.py
@@ -4,6 +4,7 @@
from PyQt5.QtCore import QTimer, pyqtSignal, pyqtProperty
from UM.Application import Application
+from UM.Scene.Camera import Camera
from UM.Scene.Selection import Selection
from UM.Qt.ListModel import ListModel
@@ -34,8 +35,9 @@ class MultiBuildPlateModel(ListModel):
self._active_build_plate = -1
def setMaxBuildPlate(self, max_build_plate):
- self._max_build_plate = max_build_plate
- self.maxBuildPlateChanged.emit()
+ if self._max_build_plate != max_build_plate:
+ self._max_build_plate = max_build_plate
+ self.maxBuildPlateChanged.emit()
## Return the highest build plate number
@pyqtProperty(int, notify = maxBuildPlateChanged)
@@ -43,15 +45,17 @@ class MultiBuildPlateModel(ListModel):
return self._max_build_plate
def setActiveBuildPlate(self, nr):
- self._active_build_plate = nr
- self.activeBuildPlateChanged.emit()
+ if self._active_build_plate != nr:
+ self._active_build_plate = nr
+ self.activeBuildPlateChanged.emit()
@pyqtProperty(int, notify = activeBuildPlateChanged)
def activeBuildPlate(self):
return self._active_build_plate
def _updateSelectedObjectBuildPlateNumbersDelayed(self, *args):
- self._update_timer.start()
+ if not isinstance(args[0], Camera):
+ self._update_timer.start()
def _updateSelectedObjectBuildPlateNumbers(self, *args):
result = set()
diff --git a/cura/Machines/Models/NozzleModel.py b/cura/Machines/Models/NozzleModel.py
index 785ff5b9b9..5f7f8b02f5 100644
--- a/cura/Machines/Models/NozzleModel.py
+++ b/cura/Machines/Models/NozzleModel.py
@@ -1,14 +1,12 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# 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
+import cura.CuraApplication # Imported like this to prevent circular dependencies.
+from cura.Machines.ContainerTree import ContainerTree
class NozzleModel(ListModel):
@@ -23,33 +21,24 @@ class NozzleModel(ListModel):
self.addRoleName(self.HotendNameRole, "hotend_name")
self.addRoleName(self.ContainerNodeRole, "container_node")
- self._application = Application.getInstance()
- self._machine_manager = self._application.getMachineManager()
- self._variant_manager = self._application.getVariantManager()
-
- self._machine_manager.globalContainerChanged.connect(self._update)
+ cura.CuraApplication.CuraApplication.getInstance().getMachineManager().globalContainerChanged.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
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
if global_stack is None:
self.setItems([])
return
+ machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
- has_variants = parseBool(global_stack.getMetaDataEntry("has_variants", False))
- if not has_variants:
- self.setItems([])
- return
-
- variant_node_dict = self._variant_manager.getVariantNodes(global_stack, VariantType.NOZZLE)
- if not variant_node_dict:
+ if not machine_node.has_variants:
self.setItems([])
return
item_list = []
- for hotend_name, container_node in sorted(variant_node_dict.items(), key = lambda i: i[0].upper()):
+ for hotend_name, container_node in sorted(machine_node.variants.items(), key = lambda i: i[0].upper()):
item = {"id": hotend_name,
"hotend_name": hotend_name,
"container_node": container_node
@@ -57,4 +46,4 @@ class NozzleModel(ListModel):
item_list.append(item)
- self.setItems(item_list)
+ self.setItems(item_list)
\ No newline at end of file
diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py
index 315ab010bb..74dc8649d0 100644
--- a/cura/Machines/Models/QualityManagementModel.py
+++ b/cura/Machines/Models/QualityManagementModel.py
@@ -1,10 +1,30 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from PyQt5.QtCore import Qt, pyqtSlot
+from typing import Any, cast, Dict, Optional, TYPE_CHECKING
+from PyQt5.QtCore import pyqtSlot, QObject, Qt, QTimer
-from UM.Qt.ListModel import ListModel
from UM.Logger import Logger
+from UM.Qt.ListModel import ListModel
+from UM.Settings.InstanceContainer import InstanceContainer # To create new profiles.
+
+import cura.CuraApplication # Imported this way to prevent circular imports.
+from cura.Settings.ContainerManager import ContainerManager
+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")
+
+if TYPE_CHECKING:
+ from UM.Settings.Interfaces import ContainerInterface
+ from cura.Machines.QualityChangesGroup import QualityChangesGroup
+ from cura.Settings.ExtruderStack import ExtruderStack
+ from cura.Settings.GlobalStack import GlobalStack
+
#
# This the QML model for the quality management page.
@@ -13,26 +33,257 @@ class QualityManagementModel(ListModel):
NameRole = Qt.UserRole + 1
IsReadOnlyRole = Qt.UserRole + 2
QualityGroupRole = Qt.UserRole + 3
- QualityChangesGroupRole = Qt.UserRole + 4
+ QualityTypeRole = Qt.UserRole + 4
+ QualityChangesGroupRole = Qt.UserRole + 5
+ IntentCategoryRole = Qt.UserRole + 6
+ SectionNameRole = Qt.UserRole + 7
- def __init__(self, parent = None):
+ def __init__(self, parent: Optional["QObject"] = None) -> None:
super().__init__(parent)
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.IsReadOnlyRole, "is_read_only")
self.addRoleName(self.QualityGroupRole, "quality_group")
+ self.addRoleName(self.QualityTypeRole, "quality_type")
self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
+ self.addRoleName(self.IntentCategoryRole, "intent_category")
+ self.addRoleName(self.SectionNameRole, "section_name")
- from cura.CuraApplication import CuraApplication
- self._container_registry = CuraApplication.getInstance().getContainerRegistry()
- self._machine_manager = CuraApplication.getInstance().getMachineManager()
- self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
- self._quality_manager = CuraApplication.getInstance().getQualityManager()
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ container_registry = application.getContainerRegistry()
+ self._machine_manager = application.getMachineManager()
+ self._machine_manager.activeQualityGroupChanged.connect(self._onChange)
+ self._machine_manager.activeStackChanged.connect(self._onChange)
+ self._machine_manager.extruderChanged.connect(self._onChange)
+ self._machine_manager.globalContainerChanged.connect(self._onChange)
- self._machine_manager.globalContainerChanged.connect(self._update)
- self._quality_manager.qualitiesUpdated.connect(self._update)
+ self._extruder_manager = application.getExtruderManager()
+ self._extruder_manager.extrudersChanged.connect(self._onChange)
- self._update()
+ container_registry.containerAdded.connect(self._qualityChangesListChanged)
+ container_registry.containerRemoved.connect(self._qualityChangesListChanged)
+ container_registry.containerMetaDataChanged.connect(self._qualityChangesListChanged)
+
+ self._update_timer = QTimer()
+ self._update_timer.setInterval(100)
+ self._update_timer.setSingleShot(True)
+ self._update_timer.timeout.connect(self._update)
+
+ self._onChange()
+
+ def _onChange(self) -> None:
+ self._update_timer.start()
+
+ ## Deletes a custom profile. It will be gone forever.
+ # \param quality_changes_group The quality changes group representing the
+ # profile to delete.
+ @pyqtSlot(QObject)
+ def removeQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup") -> None:
+ Logger.log("i", "Removing quality changes group {group_name}".format(group_name = quality_changes_group.name))
+ removed_quality_changes_ids = set()
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ for metadata in [quality_changes_group.metadata_for_global] + list(quality_changes_group.metadata_per_extruder.values()):
+ container_id = metadata["id"]
+ container_registry.removeContainer(container_id)
+ removed_quality_changes_ids.add(container_id)
+
+ # Reset all machines that have activated this custom profile.
+ for global_stack in container_registry.findContainerStacks(type = "machine"):
+ if global_stack.qualityChanges.getId() in removed_quality_changes_ids:
+ global_stack.qualityChanges = empty_quality_changes_container
+ for extruder_stack in container_registry.findContainerStacks(type = "extruder_train"):
+ if extruder_stack.qualityChanges.getId() in removed_quality_changes_ids:
+ extruder_stack.qualityChanges = empty_quality_changes_container
+
+ ## Rename a custom profile.
+ #
+ # Because the names must be unique, the new name may not actually become
+ # the name that was given. The actual name is returned by this function.
+ # \param quality_changes_group The custom profile that must be renamed.
+ # \param new_name The desired name for the profile.
+ # \return The actual new name of the profile, after making the name
+ # unique.
+ @pyqtSlot(QObject, str, result = str)
+ def renameQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", new_name: str) -> str:
+ Logger.log("i", "Renaming QualityChangesGroup {old_name} to {new_name}.".format(old_name = quality_changes_group.name, new_name = new_name))
+ if new_name == quality_changes_group.name:
+ Logger.log("i", "QualityChangesGroup name {name} unchanged.".format(name = quality_changes_group.name))
+ return new_name
+
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ container_registry = application.getContainerRegistry()
+ new_name = container_registry.uniqueName(new_name)
+ # CURA-6842
+ # FIXME: setName() will trigger metaDataChanged signal that are connected with type Qt.AutoConnection. In this
+ # case, setName() will trigger direct connections which in turn causes the quality changes group and the models
+ # to update. Because multiple containers need to be renamed, and every time a container gets renamed, updates
+ # gets triggered and this results in partial updates. For example, if we rename the global quality changes
+ # container first, the rest of the system still thinks that I have selected "my_profile" instead of
+ # "my_new_profile", but an update already gets triggered, and the quality changes group that's selected will
+ # have no container for the global stack, because "my_profile" just got renamed to "my_new_profile". This results
+ # in crashes because the rest of the system assumes that all data in a QualityChangesGroup will be correct.
+ #
+ # Renaming the container for the global stack in the end seems to be ok, because the assumption is mostly based
+ # on the quality changes container for the global stack.
+ for metadata in quality_changes_group.metadata_per_extruder.values():
+ extruder_container = cast(InstanceContainer, container_registry.findContainers(id = metadata["id"])[0])
+ extruder_container.setName(new_name)
+ global_container = cast(InstanceContainer, container_registry.findContainers(id=quality_changes_group.metadata_for_global["id"])[0])
+ global_container.setName(new_name)
+
+ quality_changes_group.name = new_name
+
+ application.getMachineManager().activeQualityChanged.emit()
+ application.getMachineManager().activeQualityGroupChanged.emit()
+
+ return new_name
+
+ ## Duplicates a given quality profile OR quality changes profile.
+ # \param new_name The desired name of the new profile. This will be made
+ # unique, so it might end up with a different name.
+ # \param quality_model_item The item of this model to duplicate, as
+ # dictionary. See the descriptions of the roles of this list model.
+ @pyqtSlot(str, "QVariantMap")
+ def duplicateQualityChanges(self, new_name: str, quality_model_item: Dict[str, Any]) -> None:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_stack:
+ Logger.log("i", "No active global stack, cannot duplicate quality (changes) profile.")
+ return
+
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ new_name = container_registry.uniqueName(new_name)
+
+ intent_category = quality_model_item["intent_category"]
+ quality_group = quality_model_item["quality_group"]
+ quality_changes_group = quality_model_item["quality_changes_group"]
+ if quality_changes_group is None:
+ # Create global quality changes only.
+ new_quality_changes = self._createQualityChanges(quality_group.quality_type, intent_category, new_name,
+ global_stack, extruder_stack = None)
+ container_registry.addContainer(new_quality_changes)
+ else:
+ for metadata in [quality_changes_group.metadata_for_global] + list(quality_changes_group.metadata_per_extruder.values()):
+ containers = container_registry.findContainers(id = metadata["id"])
+ if not containers:
+ continue
+ container = containers[0]
+ new_id = container_registry.uniqueName(container.getId())
+ container_registry.addContainer(container.duplicate(new_id, new_name))
+
+ ## Create quality changes containers from the user containers in the active
+ # stacks.
+ #
+ # This will go through the global and extruder stacks and create
+ # quality_changes containers from the user containers in each stack. These
+ # then replace the quality_changes containers in the stack and clear the
+ # user settings.
+ # \param base_name The new name for the quality changes profile. The final
+ # name of the profile might be different from this, because it needs to be
+ # made unique.
+ @pyqtSlot(str)
+ def createQualityChanges(self, base_name: str) -> None:
+ machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
+
+ global_stack = machine_manager.activeMachine
+ if not global_stack:
+ return
+
+ active_quality_name = machine_manager.activeQualityOrQualityChangesName
+ if active_quality_name == "":
+ Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
+ return
+
+ machine_manager.blurSettings.emit()
+ if base_name is None or base_name == "":
+ base_name = active_quality_name
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ unique_name = container_registry.uniqueName(base_name)
+
+ # Go through the active stacks and create quality_changes containers from the user containers.
+ container_manager = ContainerManager.getInstance()
+ stack_list = [global_stack] + list(global_stack.extruders.values())
+ for stack in stack_list:
+ quality_container = stack.quality
+ quality_changes_container = stack.qualityChanges
+ if not quality_container or not quality_changes_container:
+ Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
+ continue
+
+ extruder_stack = None
+ intent_category = None
+ if stack.getMetaDataEntry("position") is not None:
+ extruder_stack = stack
+ intent_category = stack.intent.getMetaDataEntry("intent_category")
+ new_changes = self._createQualityChanges(quality_container.getMetaDataEntry("quality_type"), intent_category, unique_name, global_stack, extruder_stack)
+ container_manager._performMerge(new_changes, quality_changes_container, clear_settings = False)
+ container_manager._performMerge(new_changes, stack.userChanges)
+
+ container_registry.addContainer(new_changes)
+
+ ## Create a quality changes container with the given set-up.
+ # \param quality_type The quality type of the new container.
+ # \param intent_category The intent category of the new container.
+ # \param new_name The name of the container. This name must be unique.
+ # \param machine The global stack to create the profile for.
+ # \param extruder_stack The extruder stack to create the profile for. If
+ # not provided, only a global container will be created.
+ def _createQualityChanges(self, quality_type: str, intent_category: Optional[str], new_name: str, machine: "GlobalStack", extruder_stack: Optional["ExtruderStack"]) -> "InstanceContainer":
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ base_id = machine.definition.getId() if extruder_stack is None else extruder_stack.getId()
+ new_id = base_id + "_" + new_name
+ new_id = new_id.lower().replace(" ", "_")
+ new_id = container_registry.uniqueName(new_id)
+
+ # Create a new quality_changes container for the quality.
+ quality_changes = InstanceContainer(new_id)
+ quality_changes.setName(new_name)
+ quality_changes.setMetaDataEntry("type", "quality_changes")
+ quality_changes.setMetaDataEntry("quality_type", quality_type)
+ if intent_category is not None:
+ quality_changes.setMetaDataEntry("intent_category", intent_category)
+
+ # If we are creating a container for an extruder, ensure we add that to the container.
+ if extruder_stack is not None:
+ quality_changes.setMetaDataEntry("position", extruder_stack.getMetaDataEntry("position"))
+
+ # If the machine specifies qualities should be filtered, ensure we match the current criteria.
+ machine_definition_id = ContainerTree.getInstance().machines[machine.definition.getId()].quality_definition
+ quality_changes.setDefinition(machine_definition_id)
+
+ quality_changes.setMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.getInstance().SettingVersion)
+ return quality_changes
+
+ ## Triggered when any container changed.
+ #
+ # This filters the updates to the container manager: When it applies to
+ # the list of quality changes, we need to update our list.
+ def _qualityChangesListChanged(self, container: "ContainerInterface") -> None:
+ if container.getMetaDataEntry("type") == "quality_changes":
+ self._update()
+
+ @pyqtSlot("QVariantMap", result = str)
+ def getQualityItemDisplayName(self, quality_model_item: Dict[str, Any]) -> str:
+ quality_group = quality_model_item["quality_group"]
+ is_read_only = quality_model_item["is_read_only"]
+ intent_category = quality_model_item["intent_category"]
+
+ quality_level_name = "Not Supported"
+ if quality_group is not None:
+ quality_level_name = quality_group.name
+
+ display_name = quality_level_name
+
+ if intent_category != "default":
+ intent_display_name = catalog.i18nc("@label", intent_category.capitalize())
+ display_name = "{intent_name} - {the_rest}".format(intent_name = intent_display_name,
+ the_rest = display_name)
+
+ # A custom quality
+ if not is_read_only:
+ display_name = "{custom_profile_name} - {the_rest}".format(custom_profile_name = quality_model_item["name"],
+ the_rest = display_name)
+
+ return display_name
def _update(self):
Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
@@ -42,38 +293,71 @@ class QualityManagementModel(ListModel):
self.setItems([])
return
- quality_group_dict = self._quality_manager.getQualityGroups(global_stack)
- quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(global_stack)
+ container_tree = ContainerTree.getInstance()
+ quality_group_dict = container_tree.getCurrentQualityGroups()
+ quality_changes_group_list = container_tree.getCurrentQualityChangesGroups()
available_quality_types = set(quality_type for quality_type, quality_group in quality_group_dict.items()
if quality_group.is_available)
- if not available_quality_types and not quality_changes_group_dict:
+ if not available_quality_types and not quality_changes_group_list:
# Nothing to show
self.setItems([])
return
item_list = []
- # Create quality group items
+ # Create quality group items (intent category = "default")
for quality_group in quality_group_dict.values():
if not quality_group.is_available:
continue
+ layer_height = fetchLayerHeight(quality_group)
+
item = {"name": quality_group.name,
"is_read_only": True,
"quality_group": quality_group,
- "quality_changes_group": None}
+ "quality_type": quality_group.quality_type,
+ "quality_changes_group": None,
+ "intent_category": "default",
+ "section_name": catalog.i18nc("@label", "Default"),
+ "layer_height": layer_height, # layer_height is only used for sorting
+ }
item_list.append(item)
- # Sort by quality names
- item_list = sorted(item_list, key = lambda x: x["name"].upper())
+ # Sort by layer_height for built-in qualities
+ item_list = sorted(item_list, key = lambda x: x["layer_height"])
+
+ # Create intent items (non-default)
+ available_intent_list = IntentManager.getInstance().getCurrentAvailableIntents()
+ available_intent_list = [i for i in available_intent_list if i[0] != "default"]
+ result = []
+ for intent_category, quality_type in available_intent_list:
+ result.append({
+ "name": quality_group_dict[quality_type].name, # Use the quality name as the display name
+ "is_read_only": True,
+ "quality_group": quality_group_dict[quality_type],
+ "quality_type": quality_type,
+ "quality_changes_group": None,
+ "intent_category": intent_category,
+ "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: (list(intent_translations).index(x["intent_category"]), x["quality_type"]))
+ item_list += result
# Create quality_changes group items
quality_changes_item_list = []
- for quality_changes_group in quality_changes_group_dict.values():
+ for quality_changes_group in quality_changes_group_list:
+ # CURA-6913 Note that custom qualities can be based on "not supported", so the quality group can be None.
quality_group = quality_group_dict.get(quality_changes_group.quality_type)
+ quality_type = quality_changes_group.quality_type
item = {"name": quality_changes_group.name,
"is_read_only": False,
"quality_group": quality_group,
- "quality_changes_group": quality_changes_group}
+ "quality_type": quality_type,
+ "quality_changes_group": quality_changes_group,
+ "intent_category": quality_changes_group.intent_category,
+ "section_name": catalog.i18nc("@label", "Custom profiles"),
+ }
quality_changes_item_list.append(item)
# Sort quality_changes items by names and append to the item list
diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py
index 7ccc886bfe..3a79ceeaf1 100644
--- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py
+++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py
@@ -1,14 +1,14 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt, QTimer
-from UM.Application import Application
+import cura.CuraApplication # Imported this way to prevent circular dependencies.
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
-from UM.Settings.SettingFunction import SettingFunction
+from cura.Machines.ContainerTree import ContainerTree
+from cura.Machines.Models.MachineModelUtils import fetchLayerHeight
-from cura.Machines.QualityManager import QualityGroup
#
# QML Model for all built-in quality profiles. This model is used for the drop-down quality menu.
@@ -35,14 +35,17 @@ class QualityProfilesDropDownMenuModel(ListModel):
self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
self.addRoleName(self.IsExperimentalRole, "is_experimental")
- self._application = Application.getInstance()
- self._machine_manager = self._application.getMachineManager()
- self._quality_manager = Application.getInstance().getQualityManager()
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ machine_manager = application.getMachineManager()
- self._application.globalContainerStackChanged.connect(self._onChange)
- self._machine_manager.activeQualityGroupChanged.connect(self._onChange)
- self._machine_manager.extruderChanged.connect(self._onChange)
- self._quality_manager.qualitiesUpdated.connect(self._onChange)
+ application.globalContainerStackChanged.connect(self._onChange)
+ machine_manager.activeQualityGroupChanged.connect(self._onChange)
+ machine_manager.activeMaterialChanged.connect(self._onChange)
+ machine_manager.activeVariantChanged.connect(self._onChange)
+ machine_manager.extruderChanged.connect(self._onChange)
+
+ extruder_manager = application.getExtruderManager()
+ extruder_manager.extrudersChanged.connect(self._onChange)
self._layer_height_unit = "" # This is cached
@@ -51,7 +54,7 @@ class QualityProfilesDropDownMenuModel(ListModel):
self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._update)
- self._update()
+ self._onChange()
def _onChange(self) -> None:
self._update_timer.start()
@@ -59,25 +62,36 @@ class QualityProfilesDropDownMenuModel(ListModel):
def _update(self):
Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
- global_stack = self._machine_manager.activeMachine
+ # CURA-6836
+ # LabelBar is a repeater that creates labels for quality layer heights. Because of an optimization in
+ # UM.ListModel, the model will not remove all items and recreate new ones every time there's an update.
+ # Because LabelBar uses Repeater with Labels anchoring to "undefined" in certain cases, the anchoring will be
+ # kept the same as before.
+ self.setItems([])
+
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
if global_stack is None:
self.setItems([])
Logger.log("d", "No active GlobalStack, set quality profile model as empty.")
return
+ if not self._layer_height_unit:
+ unit = global_stack.definition.getProperty("layer_height", "unit")
+ if not unit:
+ unit = ""
+ self._layer_height_unit = unit
+
# Check for material compatibility
- if not self._machine_manager.activeMaterialsCompatible():
+ if not cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeMaterialsCompatible():
Logger.log("d", "No active material compatibility, set quality profile model as empty.")
self.setItems([])
return
- quality_group_dict = self._quality_manager.getQualityGroups(global_stack)
+ quality_group_dict = ContainerTree.getInstance().getCurrentQualityGroups()
item_list = []
- for key in sorted(quality_group_dict):
- quality_group = quality_group_dict[key]
-
- layer_height = self._fetchLayerHeight(quality_group)
+ for quality_group in quality_group_dict.values():
+ layer_height = fetchLayerHeight(quality_group)
item = {"name": quality_group.name,
"quality_type": quality_group.quality_type,
@@ -93,32 +107,3 @@ class QualityProfilesDropDownMenuModel(ListModel):
item_list = sorted(item_list, key = lambda x: x["layer_height"])
self.setItems(item_list)
-
- def _fetchLayerHeight(self, quality_group: "QualityGroup") -> float:
- global_stack = self._machine_manager.activeMachine
- if not self._layer_height_unit:
- unit = global_stack.definition.getProperty("layer_height", "unit")
- if not unit:
- unit = ""
- self._layer_height_unit = unit
-
- default_layer_height = global_stack.definition.getProperty("layer_height", "value")
-
- # Get layer_height from the quality profile for the GlobalStack
- if quality_group.node_for_global is None:
- return float(default_layer_height)
- container = quality_group.node_for_global.getContainer()
-
- layer_height = default_layer_height
- if container and container.hasProperty("layer_height", "value"):
- layer_height = container.getProperty("layer_height", "value")
- else:
- # Look for layer_height in the GlobalStack from material -> definition
- 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/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py
index 88005e69ca..6835ffb68f 100644
--- a/cura/Machines/Models/QualitySettingsModel.py
+++ b/cura/Machines/Models/QualitySettingsModel.py
@@ -1,9 +1,9 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
-from UM.Application import Application
+import cura.CuraApplication
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
from UM.Settings.ContainerRegistry import ContainerRegistry
@@ -35,15 +35,13 @@ class QualitySettingsModel(ListModel):
self.addRoleName(self.CategoryRole, "category")
self._container_registry = ContainerRegistry.getInstance()
- self._application = Application.getInstance()
- self._quality_manager = self._application.getQualityManager()
+ self._application = cura.CuraApplication.CuraApplication.getInstance()
+ self._application.getMachineManager().activeStackChanged.connect(self._update)
self._selected_position = self.GLOBAL_STACK_POSITION #Must be either GLOBAL_STACK_POSITION or an extruder position (0, 1, etc.)
self._selected_quality_item = None # The selected quality in the quality management page
self._i18n_catalog = None
- self._quality_manager.qualitiesUpdated.connect(self._update)
-
self._update()
selectedPositionChanged = pyqtSignal()
@@ -93,21 +91,33 @@ class QualitySettingsModel(ListModel):
quality_node = quality_group.nodes_for_extruders.get(str(self._selected_position))
settings_keys = quality_group.getAllKeys()
quality_containers = []
- if quality_node is not None and quality_node.getContainer() is not None:
- quality_containers.append(quality_node.getContainer())
+ if quality_node is not None and quality_node.container is not None:
+ quality_containers.append(quality_node.container)
# Here, if the user has selected a quality changes, then "quality_changes_group" will not be None, and we fetch
# the settings in that quality_changes_group.
if quality_changes_group is not None:
- if self._selected_position == self.GLOBAL_STACK_POSITION:
- quality_changes_node = quality_changes_group.node_for_global
+ container_registry = ContainerRegistry.getInstance()
+ global_containers = container_registry.findContainers(id = quality_changes_group.metadata_for_global["id"])
+ global_container = None if len(global_containers) == 0 else global_containers[0]
+ extruders_containers = {pos: container_registry.findContainers(id = quality_changes_group.metadata_per_extruder[pos]["id"]) for pos in quality_changes_group.metadata_per_extruder}
+ extruders_container = {pos: None if not containers else containers[0] for pos, containers in extruders_containers.items()}
+ if self._selected_position == self.GLOBAL_STACK_POSITION and global_container:
+ quality_changes_metadata = global_container.getMetaData()
else:
- quality_changes_node = quality_changes_group.nodes_for_extruders.get(str(self._selected_position))
- if quality_changes_node is not None and quality_changes_node.getContainer() is not None: # it can be None if number of extruders are changed during runtime
- quality_containers.insert(0, quality_changes_node.getContainer())
- settings_keys.update(quality_changes_group.getAllKeys())
+ quality_changes_metadata = extruders_container.get(str(self._selected_position))
+ if quality_changes_metadata is not None: # It can be None if number of extruders are changed during runtime.
+ container = container_registry.findContainers(id = quality_changes_metadata["id"])
+ if container:
+ quality_containers.insert(0, container[0])
- # We iterate over all definitions instead of settings in a quality/qualtiy_changes group is because in the GUI,
+ if global_container:
+ settings_keys.update(global_container.getAllKeys())
+ for container in extruders_container.values():
+ if container:
+ settings_keys.update(container.getAllKeys())
+
+ # We iterate over all definitions instead of settings in a quality/quality_changes group is because in the GUI,
# the settings are grouped together by categories, and we had to go over all the definitions to figure out
# which setting belongs in which category.
current_category = ""
diff --git a/cura/Settings/UserChangesModel.py b/cura/Machines/Models/UserChangesModel.py
similarity index 98%
rename from cura/Settings/UserChangesModel.py
rename to cura/Machines/Models/UserChangesModel.py
index 9a26e5607e..ec623f0f38 100644
--- a/cura/Settings/UserChangesModel.py
+++ b/cura/Machines/Models/UserChangesModel.py
@@ -10,7 +10,6 @@ from UM.Application import Application
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.i18n import i18nCatalog
from UM.Settings.SettingFunction import SettingFunction
-
from UM.Qt.ListModel import ListModel
@@ -51,7 +50,7 @@ class UserChangesModel(ListModel):
return
stacks = [global_stack]
- stacks.extend(global_stack.extruders.values())
+ stacks.extend(global_stack.extruderList)
# Check if the definition container has a translation file and ensure it's loaded.
definition = global_stack.getBottom()
diff --git a/cura/Machines/QualityChangesGroup.py b/cura/Machines/QualityChangesGroup.py
index 7844b935dc..655060070b 100644
--- a/cura/Machines/QualityChangesGroup.py
+++ b/cura/Machines/QualityChangesGroup.py
@@ -1,33 +1,37 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import TYPE_CHECKING
+from typing import Any, Dict, Optional
-from UM.Application import Application
-from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
-
-from .QualityGroup import QualityGroup
-
-if TYPE_CHECKING:
- from cura.Machines.QualityNode import QualityNode
+from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal
-class QualityChangesGroup(QualityGroup):
- def __init__(self, name: str, quality_type: str, parent = None) -> None:
- super().__init__(name, quality_type, parent)
- self._container_registry = Application.getInstance().getContainerRegistry()
+## Data struct to group several quality changes instance containers together.
+#
+# Each group represents one "custom profile" as the user sees it, which
+# contains an instance container for the global stack and one instance
+# container per extruder.
+class QualityChangesGroup(QObject):
- def addNode(self, node: "QualityNode") -> None:
- extruder_position = node.getMetaDataEntry("position")
+ def __init__(self, name: str, quality_type: str, intent_category: str, parent: Optional["QObject"] = None) -> None:
+ super().__init__(parent)
+ self._name = name
+ self.quality_type = quality_type
+ self.intent_category = intent_category
+ self.is_available = False
+ self.metadata_for_global = {} # type: Dict[str, Any]
+ self.metadata_per_extruder = {} # type: Dict[int, Dict[str, Any]]
- if extruder_position is None and self.node_for_global is not None or extruder_position in self.nodes_for_extruders: #We would be overwriting another node.
- ConfigurationErrorMessage.getInstance().addFaultyContainers(node.getMetaDataEntry("id"))
- return
+ nameChanged = pyqtSignal()
- if extruder_position is None: # Then we're a global quality changes profile.
- self.node_for_global = node
- else: # This is an extruder's quality changes profile.
- self.nodes_for_extruders[extruder_position] = node
+ def setName(self, name: str) -> None:
+ if self._name != name:
+ self._name = name
+ self.nameChanged.emit()
+
+ @pyqtProperty(str, fset = setName, notify = nameChanged)
+ def name(self) -> str:
+ return self._name
def __str__(self) -> str:
- return "%s[<%s>, available = %s]" % (self.__class__.__name__, self.name, self.is_available)
+ return "{class_name}[{name}, available = {is_available}]".format(class_name = self.__class__.__name__, name = self.name, is_available = self.is_available)
diff --git a/cura/Machines/QualityGroup.py b/cura/Machines/QualityGroup.py
index f5bcbb0de8..58ba3acc63 100644
--- a/cura/Machines/QualityGroup.py
+++ b/cura/Machines/QualityGroup.py
@@ -1,32 +1,38 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Dict, Optional, List, Set
from PyQt5.QtCore import QObject, pyqtSlot
+from UM.Logger import Logger
from UM.Util import parseBool
from cura.Machines.ContainerNode import ContainerNode
+## A QualityGroup represents a group of quality containers that must be applied
+# to each ContainerStack when it's used.
#
-# A QualityGroup represents a group of containers that must be applied to each ContainerStack when it's used.
-# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type
-# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3
-# as an example, suppose we choose quality type "normal", the actual InstanceContainers on each stack may look
-# as below:
-# GlobalStack ExtruderStack 1 ExtruderStack 2
-# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal
+# A concrete example: When there are two extruders and the user selects the
+# quality type "normal", this quality type must be applied to all stacks in a
+# machine, although each stack can have different containers. So one global
+# profile gets put on the global stack and one extruder profile gets put on
+# each extruder stack. This quality group then contains the following
+# profiles (for instance):
+# GlobalStack ExtruderStack 1 ExtruderStack 2
+# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal
#
-# This QualityGroup is mainly used in quality and quality_changes to group the containers that can be applied to
-# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead
-# of looking them up again.
-#
-class QualityGroup(QObject):
-
- def __init__(self, name: str, quality_type: str, parent = None) -> None:
- super().__init__(parent)
+# The purpose of these quality groups is to group the containers that can be
+# applied to a configuration, so that when a quality level is selected, the
+# container can directly be applied to each stack instead of looking them up
+# again.
+class QualityGroup:
+ ## Constructs a new group.
+ # \param name The user-visible name for the group.
+ # \param quality_type The quality level that each profile in this group
+ # has.
+ def __init__(self, name: str, quality_type: str) -> None:
self.name = name
self.node_for_global = None # type: Optional[ContainerNode]
self.nodes_for_extruders = {} # type: Dict[int, ContainerNode]
@@ -34,7 +40,6 @@ class QualityGroup(QObject):
self.is_available = False
self.is_experimental = False
- @pyqtSlot(result = str)
def getName(self) -> str:
return self.name
@@ -43,7 +48,7 @@ class QualityGroup(QObject):
for node in [self.node_for_global] + list(self.nodes_for_extruders.values()):
if node is None:
continue
- container = node.getContainer()
+ container = node.container
if container:
result.update(container.getAllKeys())
return result
@@ -60,6 +65,9 @@ class QualityGroup(QObject):
self.node_for_global = node
# Update is_experimental flag
+ if not node.container:
+ Logger.log("w", "Node {0} doesn't have a container.".format(node.container_id))
+ return
is_experimental = parseBool(node.getMetaDataEntry("is_experimental", False))
self.is_experimental |= is_experimental
@@ -67,5 +75,8 @@ class QualityGroup(QObject):
self.nodes_for_extruders[position] = node
# Update is_experimental flag
+ if not node.container:
+ Logger.log("w", "Node {0} doesn't have a container.".format(node.container_id))
+ return
is_experimental = parseBool(node.getMetaDataEntry("is_experimental", False))
self.is_experimental |= is_experimental
diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py
deleted file mode 100644
index 34cc9ce4b2..0000000000
--- a/cura/Machines/QualityManager.py
+++ /dev/null
@@ -1,550 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from typing import TYPE_CHECKING, Optional, cast, Dict, List, Set
-
-from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot
-
-from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
-from UM.Logger import Logger
-from UM.Util import parseBool
-from UM.Settings.InstanceContainer import InstanceContainer
-
-from cura.Settings.ExtruderStack import ExtruderStack
-
-from .QualityGroup import QualityGroup
-from .QualityNode import QualityNode
-
-if TYPE_CHECKING:
- from UM.Settings.Interfaces import DefinitionContainerInterface
- from cura.Settings.GlobalStack import GlobalStack
- from .QualityChangesGroup import QualityChangesGroup
- from cura.CuraApplication import CuraApplication
-
-
-#
-# Similar to MaterialManager, QualityManager maintains a number of maps and trees for quality profile lookup.
-# The models GUI and QML use are now only dependent on the QualityManager. That means as long as the data in
-# QualityManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI.
-#
-# For now, updating the lookup maps and trees here is very simple: we discard the old data completely and recreate them
-# again. This means the update is exactly the same as initialization. There are performance concerns about this approach
-# but so far the creation of the tables and maps is very fast and there is no noticeable slowness, we keep it like this
-# because it's simple.
-#
-class QualityManager(QObject):
-
- qualitiesUpdated = pyqtSignal()
-
- def __init__(self, application: "CuraApplication", parent = None) -> None:
- super().__init__(parent)
- self._application = application
- self._material_manager = self._application.getMaterialManager()
- self._container_registry = self._application.getContainerRegistry()
-
- self._empty_quality_container = self._application.empty_quality_container
- self._empty_quality_changes_container = self._application.empty_quality_changes_container
-
- # For quality lookup
- self._machine_nozzle_buildplate_material_quality_type_to_quality_dict = {} # type: Dict[str, QualityNode]
-
- # For quality_changes lookup
- self._machine_quality_type_to_quality_changes_dict = {} # type: Dict[str, QualityNode]
-
- self._default_machine_definition_id = "fdmprinter"
-
- self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged)
- self._container_registry.containerAdded.connect(self._onContainerMetadataChanged)
- self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged)
-
- # When a custom quality gets added/imported, there can be more than one InstanceContainers. In those cases,
- # we don't want to react on every container/metadata changed signal. The timer here is to buffer it a bit so
- # we don't react too many time.
- self._update_timer = QTimer(self)
- self._update_timer.setInterval(300)
- self._update_timer.setSingleShot(True)
- self._update_timer.timeout.connect(self._updateMaps)
-
- def initialize(self) -> None:
- # Initialize the lookup tree for quality profiles with following structure:
- # -> -> ->
- # ->
-
- self._machine_nozzle_buildplate_material_quality_type_to_quality_dict = {} # for quality lookup
- self._machine_quality_type_to_quality_changes_dict = {} # for quality_changes lookup
-
- quality_metadata_list = self._container_registry.findContainersMetadata(type = "quality")
- for metadata in quality_metadata_list:
- if metadata["id"] == "empty_quality":
- continue
-
- definition_id = metadata["definition"]
- quality_type = metadata["quality_type"]
-
- root_material_id = metadata.get("material")
- nozzle_name = metadata.get("variant")
- buildplate_name = metadata.get("buildplate")
- is_global_quality = metadata.get("global_quality", False)
- is_global_quality = is_global_quality or (root_material_id is None and nozzle_name is None and buildplate_name is None)
-
- # Sanity check: material+variant and is_global_quality cannot be present at the same time
- if is_global_quality and (root_material_id or nozzle_name):
- ConfigurationErrorMessage.getInstance().addFaultyContainers(metadata["id"])
- continue
-
- if definition_id not in self._machine_nozzle_buildplate_material_quality_type_to_quality_dict:
- self._machine_nozzle_buildplate_material_quality_type_to_quality_dict[definition_id] = QualityNode()
- machine_node = cast(QualityNode, self._machine_nozzle_buildplate_material_quality_type_to_quality_dict[definition_id])
-
- if is_global_quality:
- # For global qualities, save data in the machine node
- machine_node.addQualityMetadata(quality_type, metadata)
- continue
-
- current_node = machine_node
- intermediate_node_info_list = [nozzle_name, buildplate_name, root_material_id]
- current_intermediate_node_info_idx = 0
-
- while current_intermediate_node_info_idx < len(intermediate_node_info_list):
- node_name = intermediate_node_info_list[current_intermediate_node_info_idx]
- if node_name is not None:
- # There is specific information, update the current node to go deeper so we can add this quality
- # at the most specific branch in the lookup tree.
- if node_name not in current_node.children_map:
- current_node.children_map[node_name] = QualityNode()
- current_node = cast(QualityNode, current_node.children_map[node_name])
-
- current_intermediate_node_info_idx += 1
-
- current_node.addQualityMetadata(quality_type, metadata)
-
- # Initialize the lookup tree for quality_changes profiles with following structure:
- # -> ->
- quality_changes_metadata_list = self._container_registry.findContainersMetadata(type = "quality_changes")
- for metadata in quality_changes_metadata_list:
- if metadata["id"] == "empty_quality_changes":
- continue
-
- machine_definition_id = metadata["definition"]
- quality_type = metadata["quality_type"]
-
- if machine_definition_id not in self._machine_quality_type_to_quality_changes_dict:
- self._machine_quality_type_to_quality_changes_dict[machine_definition_id] = QualityNode()
- machine_node = self._machine_quality_type_to_quality_changes_dict[machine_definition_id]
- machine_node.addQualityChangesMetadata(quality_type, metadata)
-
- Logger.log("d", "Lookup tables updated.")
- self.qualitiesUpdated.emit()
-
- def _updateMaps(self) -> None:
- self.initialize()
-
- def _onContainerMetadataChanged(self, container: InstanceContainer) -> None:
- self._onContainerChanged(container)
-
- def _onContainerChanged(self, container: InstanceContainer) -> None:
- container_type = container.getMetaDataEntry("type")
- if container_type not in ("quality", "quality_changes"):
- return
-
- # update the cache table
- self._update_timer.start()
-
- # Updates the given quality groups' availabilities according to which extruders are being used/ enabled.
- def _updateQualityGroupsAvailability(self, machine: "GlobalStack", quality_group_list) -> None:
- used_extruders = set()
- for i in range(machine.getProperty("machine_extruder_count", "value")):
- if str(i) in machine.extruders and machine.extruders[str(i)].isEnabled:
- used_extruders.add(str(i))
-
- # Update the "is_available" flag for each quality group.
- for quality_group in quality_group_list:
- is_available = True
- if quality_group.node_for_global is None:
- is_available = False
- if is_available:
- for position in used_extruders:
- if position not in quality_group.nodes_for_extruders:
- is_available = False
- break
-
- quality_group.is_available = is_available
-
- # Returns a dict of "custom profile name" -> QualityChangesGroup
- def getQualityChangesGroups(self, machine: "GlobalStack") -> dict:
- machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition)
-
- machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id)
- if not machine_node:
- Logger.log("i", "Cannot find node for machine def [%s] in QualityChanges lookup table", machine_definition_id)
- return dict()
-
- # Update availability for each QualityChangesGroup:
- # A custom profile is always available as long as the quality_type it's based on is available
- quality_group_dict = self.getQualityGroups(machine)
- available_quality_type_list = [qt for qt, qg in quality_group_dict.items() if qg.is_available]
-
- # Iterate over all quality_types in the machine node
- quality_changes_group_dict = dict()
- for quality_type, quality_changes_node in machine_node.quality_type_map.items():
- for quality_changes_name, quality_changes_group in quality_changes_node.children_map.items():
- quality_changes_group_dict[quality_changes_name] = quality_changes_group
- quality_changes_group.is_available = quality_type in available_quality_type_list
-
- return quality_changes_group_dict
-
- #
- # Gets all quality groups for the given machine. Both available and none available ones will be included.
- # It returns a dictionary with "quality_type"s as keys and "QualityGroup"s as values.
- # Whether a QualityGroup is available can be unknown via the field QualityGroup.is_available.
- # For more details, see QualityGroup.
- #
- def getQualityGroups(self, machine: "GlobalStack") -> Dict[str, QualityGroup]:
- machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition)
-
- # This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks
- has_machine_specific_qualities = machine.getHasMachineQuality()
-
- # To find the quality container for the GlobalStack, check in the following fall-back manner:
- # (1) the machine-specific node
- # (2) the generic node
- machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(machine_definition_id)
- # Check if this machine has specific quality profiles for its extruders, if so, when looking up extruder
- # qualities, we should not fall back to use the global qualities.
- has_extruder_specific_qualities = False
- if machine_node:
- if machine_node.children_map:
- has_extruder_specific_qualities = True
-
- default_machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(self._default_machine_definition_id)
-
- nodes_to_check = [] # type: List[QualityNode]
- if machine_node is not None:
- nodes_to_check.append(machine_node)
- if default_machine_node is not None:
- nodes_to_check.append(default_machine_node)
-
- # Iterate over all quality_types in the machine node
- quality_group_dict = {}
- for node in nodes_to_check:
- if node and node.quality_type_map:
- quality_node = list(node.quality_type_map.values())[0]
- is_global_quality = parseBool(quality_node.getMetaDataEntry("global_quality", False))
- if not is_global_quality:
- continue
-
- for quality_type, quality_node in node.quality_type_map.items():
- quality_group = QualityGroup(quality_node.getMetaDataEntry("name", ""), quality_type)
- quality_group.setGlobalNode(quality_node)
- quality_group_dict[quality_type] = quality_group
- break
-
- buildplate_name = machine.getBuildplateName()
-
- # Iterate over all extruders to find quality containers for each extruder
- for position, extruder in machine.extruders.items():
- nozzle_name = None
- if extruder.variant.getId() != "empty_variant":
- nozzle_name = extruder.variant.getName()
-
- # This is a list of root material IDs to use for searching for suitable quality profiles.
- # The root material IDs in this list are in prioritized order.
- root_material_id_list = []
- has_material = False # flag indicating whether this extruder has a material assigned
- root_material_id = None
- if extruder.material.getId() != "empty_material":
- has_material = True
- root_material_id = extruder.material.getMetaDataEntry("base_file")
- # Convert possible generic_pla_175 -> generic_pla
- root_material_id = self._material_manager.getRootMaterialIDWithoutDiameter(root_material_id)
- root_material_id_list.append(root_material_id)
-
- # Also try to get the fallback materials
- fallback_ids = self._material_manager.getFallBackMaterialIdsByMaterial(extruder.material)
-
- if fallback_ids:
- root_material_id_list.extend(fallback_ids)
-
- # Weed out duplicates while preserving the order.
- seen = set() # type: Set[str]
- root_material_id_list = [x for x in root_material_id_list if x not in seen and not seen.add(x)] # type: ignore
-
- # Here we construct a list of nodes we want to look for qualities with the highest priority first.
- # The use case is that, when we look for qualities for a machine, we first want to search in the following
- # order:
- # 1. machine-nozzle-buildplate-and-material-specific qualities if exist
- # 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 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.
- node_info_list_0 = [nozzle_name, buildplate_name, root_material_id] # type: List[Optional[str]]
- nodes_to_check = []
-
- # This function tries to recursively find the deepest (the most specific) branch and add those nodes to
- # the search list in the order described above. So, by iterating over that search node list, we first look
- # in the more specific branches and then the less specific (generic) ones.
- def addNodesToCheck(node: Optional[QualityNode], nodes_to_check_list: List[QualityNode], node_info_list, node_info_idx: int) -> None:
- if node is None:
- return
-
- if node_info_idx < len(node_info_list):
- node_name = node_info_list[node_info_idx]
- if node_name is not None:
- current_node = node.getChildNode(node_name)
- if current_node is not None and has_material:
- addNodesToCheck(current_node, nodes_to_check_list, node_info_list, node_info_idx + 1)
-
- if has_material:
- for rmid in root_material_id_list:
- material_node = node.getChildNode(rmid)
- if material_node:
- nodes_to_check_list.append(material_node)
- break
-
- nodes_to_check_list.append(node)
-
- addNodesToCheck(machine_node, nodes_to_check, node_info_list_0, 0)
-
- # 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 is not None and machine_node.quality_type_map:
- nodes_to_check += [machine_node]
- elif default_machine_node is not None:
- nodes_to_check += [default_machine_node]
-
- for node_idx, node in enumerate(nodes_to_check):
- if node and node.quality_type_map:
- if has_extruder_specific_qualities:
- # Only include variant qualities; skip non global qualities
- quality_node = list(node.quality_type_map.values())[0]
- is_global_quality = parseBool(quality_node.getMetaDataEntry("global_quality", False))
- if is_global_quality:
- continue
-
- for quality_type, quality_node in node.quality_type_map.items():
- if quality_type not in quality_group_dict:
- quality_group = QualityGroup(quality_node.getMetaDataEntry("name", ""), quality_type)
- quality_group_dict[quality_type] = quality_group
-
- quality_group = quality_group_dict[quality_type]
- if position not in quality_group.nodes_for_extruders:
- quality_group.setExtruderNode(position, quality_node)
-
- # If the machine has its own specific qualities, for extruders, it should skip the global qualities
- # and use the material/variant specific qualities.
- if has_extruder_specific_qualities:
- if node_idx == len(nodes_to_check) - 1:
- break
-
- # Update availabilities for each quality group
- self._updateQualityGroupsAvailability(machine, quality_group_dict.values())
-
- return quality_group_dict
-
- def getQualityGroupsForMachineDefinition(self, machine: "GlobalStack") -> Dict[str, QualityGroup]:
- machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition)
-
- # To find the quality container for the GlobalStack, check in the following fall-back manner:
- # (1) the machine-specific node
- # (2) the generic node
- machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(machine_definition_id)
- default_machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(
- self._default_machine_definition_id)
- nodes_to_check = [machine_node, default_machine_node]
-
- # Iterate over all quality_types in the machine node
- quality_group_dict = dict()
- for node in nodes_to_check:
- if node and node.quality_type_map:
- for quality_type, quality_node in node.quality_type_map.items():
- quality_group = QualityGroup(quality_node.getMetaDataEntry("name", ""), quality_type)
- quality_group.setGlobalNode(quality_node)
- quality_group_dict[quality_type] = quality_group
- break
-
- return quality_group_dict
-
- def getDefaultQualityType(self, machine: "GlobalStack") -> Optional[QualityGroup]:
- preferred_quality_type = machine.definition.getMetaDataEntry("preferred_quality_type")
- quality_group_dict = self.getQualityGroups(machine)
- quality_group = quality_group_dict.get(preferred_quality_type)
- return quality_group
-
-
- #
- # Methods for GUI
- #
-
- #
- # Remove the given quality changes group.
- #
- @pyqtSlot(QObject)
- def removeQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup") -> None:
- Logger.log("i", "Removing quality changes group [%s]", quality_changes_group.name)
- removed_quality_changes_ids = set()
- for node in quality_changes_group.getAllNodes():
- 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.
- #
- @pyqtSlot(QObject, str, result = str)
- def renameQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", new_name: str) -> str:
- Logger.log("i", "Renaming QualityChangesGroup[%s] to [%s]", quality_changes_group.name, new_name)
- if new_name == quality_changes_group.name:
- Logger.log("i", "QualityChangesGroup name [%s] unchanged.", quality_changes_group.name)
- return new_name
-
- new_name = self._container_registry.uniqueName(new_name)
- for node in quality_changes_group.getAllNodes():
- container = node.getContainer()
- if container:
- container.setName(new_name)
-
- quality_changes_group.name = new_name
-
- self._application.getMachineManager().activeQualityChanged.emit()
- self._application.getMachineManager().activeQualityGroupChanged.emit()
-
- return new_name
-
- #
- # Duplicates the given quality.
- #
- @pyqtSlot(str, "QVariantMap")
- def duplicateQualityChanges(self, quality_changes_name: str, quality_model_item) -> None:
- global_stack = self._application.getGlobalContainerStack()
- if not global_stack:
- Logger.log("i", "No active global stack, cannot duplicate quality changes.")
- return
-
- quality_group = quality_model_item["quality_group"]
- quality_changes_group = quality_model_item["quality_changes_group"]
- if quality_changes_group is None:
- # create global quality changes only
- new_quality_changes = self._createQualityChanges(quality_group.quality_type, quality_changes_name,
- global_stack, None)
- self._container_registry.addContainer(new_quality_changes)
- else:
- new_name = self._container_registry.uniqueName(quality_changes_name)
- for node in quality_changes_group.getAllNodes():
- container = node.getContainer()
- if not container:
- continue
- new_id = self._container_registry.uniqueName(container.getId())
- self._container_registry.addContainer(container.duplicate(new_id, new_name))
-
- ## Create quality changes containers from the user containers in the active stacks.
- #
- # This will go through the global and extruder stacks and create quality_changes containers from
- # the user containers in each stack. These then replace the quality_changes containers in the
- # stack and clear the user settings.
- @pyqtSlot(str)
- def createQualityChanges(self, base_name: str) -> None:
- machine_manager = self._application.getMachineManager()
-
- global_stack = machine_manager.activeMachine
- if not global_stack:
- return
-
- active_quality_name = machine_manager.activeQualityOrQualityChangesName
- if active_quality_name == "":
- Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
- return
-
- machine_manager.blurSettings.emit()
- if base_name is None or base_name == "":
- base_name = active_quality_name
- unique_name = self._container_registry.uniqueName(base_name)
-
- # Go through the active stacks and create quality_changes containers from the user containers.
- stack_list = [global_stack] + list(global_stack.extruders.values())
- for stack in stack_list:
- user_container = stack.userChanges
- quality_container = stack.quality
- quality_changes_container = stack.qualityChanges
- if not quality_container or not quality_changes_container:
- Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
- continue
-
- quality_type = quality_container.getMetaDataEntry("quality_type")
- extruder_stack = None
- if isinstance(stack, ExtruderStack):
- extruder_stack = stack
- new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_stack)
- from cura.Settings.ContainerManager import ContainerManager
- ContainerManager.getInstance()._performMerge(new_changes, quality_changes_container, clear_settings = False)
- ContainerManager.getInstance()._performMerge(new_changes, user_container)
-
- self._container_registry.addContainer(new_changes)
-
- #
- # Create a quality changes container with the given setup.
- #
- def _createQualityChanges(self, quality_type: str, new_name: str, machine: "GlobalStack",
- extruder_stack: Optional["ExtruderStack"]) -> "InstanceContainer":
- base_id = machine.definition.getId() if extruder_stack is None else extruder_stack.getId()
- new_id = base_id + "_" + new_name
- new_id = new_id.lower().replace(" ", "_")
- new_id = self._container_registry.uniqueName(new_id)
-
- # Create a new quality_changes container for the quality.
- quality_changes = InstanceContainer(new_id)
- quality_changes.setName(new_name)
- quality_changes.setMetaDataEntry("type", "quality_changes")
- quality_changes.setMetaDataEntry("quality_type", quality_type)
-
- # If we are creating a container for an extruder, ensure we add that to the container
- if extruder_stack is not None:
- quality_changes.setMetaDataEntry("position", extruder_stack.getMetaDataEntry("position"))
-
- # If the machine specifies qualities should be filtered, ensure we match the current criteria.
- machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition)
- quality_changes.setDefinition(machine_definition_id)
-
- quality_changes.setMetaDataEntry("setting_version", self._application.SettingVersion)
- return quality_changes
-
-
-#
-# Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given
-# machine. The rule is as follows:
-# 1. By default, the machine definition ID for quality container search will be "fdmprinter", which is the generic
-# machine.
-# 2. If a machine has its own machine quality (with "has_machine_quality = True"), we should use the given machine's
-# own machine definition ID for quality search.
-# Example: for an Ultimaker 3, the definition ID should be "ultimaker3".
-# 3. When condition (2) is met, AND the machine has "quality_definition" defined in its definition file, then the
-# definition ID specified in "quality_definition" should be used.
-# Example: for an Ultimaker 3 Extended, it has "quality_definition = ultimaker3". This means Ultimaker 3 Extended
-# shares the same set of qualities profiles as Ultimaker 3.
-#
-def getMachineDefinitionIDForQualitySearch(machine_definition: "DefinitionContainerInterface",
- default_definition_id: str = "fdmprinter") -> str:
- machine_definition_id = default_definition_id
- if parseBool(machine_definition.getMetaDataEntry("has_machine_quality", False)):
- # Only use the machine's own quality definition ID if this machine has machine quality.
- machine_definition_id = machine_definition.getMetaDataEntry("quality_definition")
- if machine_definition_id is None:
- machine_definition_id = machine_definition.getId()
-
- return machine_definition_id
diff --git a/cura/Machines/QualityNode.py b/cura/Machines/QualityNode.py
index 991388a4bd..45cd898db5 100644
--- a/cura/Machines/QualityNode.py
+++ b/cura/Machines/QualityNode.py
@@ -1,38 +1,44 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import Optional, Dict, cast, Any
+from typing import Union, TYPE_CHECKING
-from .ContainerNode import ContainerNode
-from .QualityChangesGroup import QualityChangesGroup
+from UM.Settings.ContainerRegistry import ContainerRegistry
+from cura.Machines.ContainerNode import ContainerNode
+from cura.Machines.IntentNode import IntentNode
+import UM.FlameProfiler
+if TYPE_CHECKING:
+ from typing import Dict
+ from cura.Machines.MaterialNode import MaterialNode
+ from cura.Machines.MachineNode import MachineNode
+## Represents a quality profile in the container tree.
#
-# QualityNode is used for BOTH quality and quality_changes containers.
+# This may either be a normal quality profile or a global quality profile.
#
+# Its subcontainers are intent profiles.
class QualityNode(ContainerNode):
+ def __init__(self, container_id: str, parent: Union["MaterialNode", "MachineNode"]) -> None:
+ super().__init__(container_id)
+ self.parent = parent
+ self.intents = {} # type: Dict[str, IntentNode]
- def __init__(self, metadata: Optional[Dict[str, Any]] = None) -> None:
- super().__init__(metadata = metadata)
- self.quality_type_map = {} # type: Dict[str, QualityNode] # quality_type -> QualityNode for InstanceContainer
+ my_metadata = ContainerRegistry.getInstance().findContainersMetadata(id = container_id)[0]
+ self.quality_type = my_metadata["quality_type"]
+ # The material type of the parent doesn't need to be the same as this due to generic fallbacks.
+ self._material = my_metadata.get("material")
+ self._loadAll()
- def getChildNode(self, child_key: str) -> Optional["QualityNode"]:
- return self.children_map.get(child_key)
+ @UM.FlameProfiler.profile
+ def _loadAll(self) -> None:
+ container_registry = ContainerRegistry.getInstance()
- def addQualityMetadata(self, quality_type: str, metadata: Dict[str, Any]):
- if quality_type not in self.quality_type_map:
- self.quality_type_map[quality_type] = QualityNode(metadata)
+ # Find all intent profiles that fit the current configuration.
+ from cura.Machines.MachineNode import MachineNode
+ if not isinstance(self.parent, MachineNode): # Not a global profile.
+ for intent in container_registry.findInstanceContainersMetadata(type = "intent", definition = self.parent.variant.machine.quality_definition, variant = self.parent.variant.variant_name, material = self._material, quality_type = self.quality_type):
+ self.intents[intent["id"]] = IntentNode(intent["id"], quality = self)
- def getQualityNode(self, quality_type: str) -> Optional["QualityNode"]:
- return self.quality_type_map.get(quality_type)
-
- def addQualityChangesMetadata(self, quality_type: str, metadata: Dict[str, Any]):
- if quality_type not in self.quality_type_map:
- self.quality_type_map[quality_type] = QualityNode()
- quality_type_node = self.quality_type_map[quality_type]
-
- name = metadata["name"]
- if name not in quality_type_node.children_map:
- quality_type_node.children_map[name] = QualityChangesGroup(name, quality_type)
- quality_changes_group = quality_type_node.children_map[name]
- cast(QualityChangesGroup, quality_changes_group).addNode(QualityNode(metadata))
+ self.intents["empty_intent"] = IntentNode("empty_intent", quality = self)
+ # Otherwise, there are no intents for global profiles.
\ No newline at end of file
diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py
deleted file mode 100644
index eaaa9fc5f0..0000000000
--- a/cura/Machines/VariantManager.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from collections import OrderedDict
-from typing import Optional, TYPE_CHECKING, Dict
-
-from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
-from UM.Logger import Logger
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from UM.Util import parseBool
-
-from cura.Machines.ContainerNode import ContainerNode
-from cura.Machines.VariantType import VariantType, ALL_VARIANT_TYPES
-from cura.Settings.GlobalStack import GlobalStack
-
-if TYPE_CHECKING:
- from UM.Settings.DefinitionContainer import DefinitionContainer
-
-
-#
-# VariantManager is THE place to look for a specific variant. It maintains two variant lookup tables with the following
-# structure:
-#
-# [machine_definition_id] -> [variant_type] -> [variant_name] -> ContainerNode(metadata / container)
-# Example: "ultimaker3" -> "buildplate" -> "Glass" (if present) -> ContainerNode
-# -> ...
-# -> "nozzle" -> "AA 0.4"
-# -> "BB 0.8"
-# -> ...
-#
-# [machine_definition_id] -> [machine_buildplate_type] -> ContainerNode(metadata / container)
-# Example: "ultimaker3" -> "glass" (this is different from the variant name) -> ContainerNode
-#
-# Note that the "container" field is not loaded in the beginning because it would defeat the purpose of lazy-loading.
-# A container is loaded when getVariant() is called to load a variant InstanceContainer.
-#
-class VariantManager:
-
- def __init__(self, container_registry: ContainerRegistry) -> None:
- self._container_registry = container_registry
-
- self._machine_to_variant_dict_map = dict() # type: Dict[str, Dict["VariantType", Dict[str, ContainerNode]]]
- self._machine_to_buildplate_dict_map = dict() # type: Dict[str, Dict[str, ContainerNode]]
-
- self._exclude_variant_id_list = ["empty_variant"]
-
- #
- # Initializes the VariantManager including:
- # - initializing the variant lookup table based on the metadata in ContainerRegistry.
- #
- def initialize(self) -> None:
- self._machine_to_variant_dict_map = OrderedDict()
- self._machine_to_buildplate_dict_map = OrderedDict()
-
- # Cache all variants from the container registry to a variant map for better searching and organization.
- variant_metadata_list = self._container_registry.findContainersMetadata(type = "variant")
- for variant_metadata in variant_metadata_list:
- if variant_metadata["id"] in self._exclude_variant_id_list:
- Logger.log("d", "Exclude variant [%s]", variant_metadata["id"])
- continue
-
- variant_name = variant_metadata["name"]
- variant_definition = variant_metadata["definition"]
- if variant_definition not in self._machine_to_variant_dict_map:
- self._machine_to_variant_dict_map[variant_definition] = OrderedDict()
- for variant_type in ALL_VARIANT_TYPES:
- self._machine_to_variant_dict_map[variant_definition][variant_type] = dict()
-
- try:
- variant_type = variant_metadata["hardware_type"]
- except KeyError:
- Logger.log("w", "Variant %s does not specify a hardware_type; assuming 'nozzle'", variant_metadata["id"])
- variant_type = VariantType.NOZZLE
- variant_type = VariantType(variant_type)
- variant_dict = self._machine_to_variant_dict_map[variant_definition][variant_type]
- if variant_name in variant_dict:
- # ERROR: duplicated variant name.
- ConfigurationErrorMessage.getInstance().addFaultyContainers(variant_metadata["id"])
- continue #Then ignore this variant. This now chooses one of the two variants arbitrarily and deletes the other one! No guarantees!
-
- variant_dict[variant_name] = ContainerNode(metadata = variant_metadata)
-
- # If the variant is a buildplate then fill also the buildplate map
- if variant_type == VariantType.BUILD_PLATE:
- if variant_definition not in self._machine_to_buildplate_dict_map:
- self._machine_to_buildplate_dict_map[variant_definition] = OrderedDict()
-
- variant_container = self._container_registry.findContainers(type = "variant", id = variant_metadata["id"])[0]
- buildplate_type = variant_container.getProperty("machine_buildplate_type", "value")
- if buildplate_type not in self._machine_to_buildplate_dict_map[variant_definition]:
- self._machine_to_variant_dict_map[variant_definition][buildplate_type] = dict()
-
- self._machine_to_buildplate_dict_map[variant_definition][buildplate_type] = variant_dict[variant_name]
-
- #
- # Gets the variant InstanceContainer with the given information.
- # Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present.
- #
- def getVariantNode(self, machine_definition_id: str, variant_name: str,
- variant_type: Optional["VariantType"] = None) -> Optional["ContainerNode"]:
- if variant_type is None:
- variant_node = None
- variant_type_dict = self._machine_to_variant_dict_map[machine_definition_id]
- for variant_dict in variant_type_dict.values():
- if variant_name in variant_dict:
- variant_node = variant_dict[variant_name]
- break
- return variant_node
-
- return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {}).get(variant_name)
-
- def getVariantNodes(self, machine: "GlobalStack", variant_type: "VariantType") -> Dict[str, ContainerNode]:
- machine_definition_id = machine.definition.getId()
- return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {})
-
- #
- # Gets the default variant for the given machine definition.
- # If the optional GlobalStack is given, the metadata information will be fetched from the GlobalStack instead of
- # the DefinitionContainer. Because for machines such as UM2, you can enable Olsson Block, which will set
- # "has_variants" to True in the GlobalStack. In those cases, we need to fetch metadata from the GlobalStack or
- # it may not be correct.
- #
- def getDefaultVariantNode(self, machine_definition: "DefinitionContainer",
- variant_type: "VariantType",
- global_stack: Optional["GlobalStack"] = None) -> Optional["ContainerNode"]:
- machine_definition_id = machine_definition.getId()
- container_for_metadata_fetching = global_stack if global_stack is not None else machine_definition
-
- preferred_variant_name = None
- if variant_type == VariantType.BUILD_PLATE:
- if parseBool(container_for_metadata_fetching.getMetaDataEntry("has_variant_buildplates", False)):
- preferred_variant_name = container_for_metadata_fetching.getMetaDataEntry("preferred_variant_buildplate_name")
- else:
- if parseBool(container_for_metadata_fetching.getMetaDataEntry("has_variants", False)):
- preferred_variant_name = container_for_metadata_fetching.getMetaDataEntry("preferred_variant_name")
-
- node = None
- if preferred_variant_name:
- node = self.getVariantNode(machine_definition_id, preferred_variant_name, variant_type)
- return node
-
- def getBuildplateVariantNode(self, machine_definition_id: str, buildplate_type: str) -> Optional["ContainerNode"]:
- if machine_definition_id in self._machine_to_buildplate_dict_map:
- return self._machine_to_buildplate_dict_map[machine_definition_id].get(buildplate_type)
- return None
diff --git a/cura/Machines/VariantNode.py b/cura/Machines/VariantNode.py
new file mode 100644
index 0000000000..c9e3ec4913
--- /dev/null
+++ b/cura/Machines/VariantNode.py
@@ -0,0 +1,182 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+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.Machines.ContainerNode import ContainerNode
+from cura.Machines.MaterialNode import MaterialNode
+
+import UM.FlameProfiler
+
+if TYPE_CHECKING:
+ from typing import Dict
+ from cura.Machines.MachineNode import MachineNode
+
+
+## This class represents an extruder variant in the container tree.
+#
+# The subnodes of these nodes are materials.
+#
+# This node contains materials with ALL filament diameters underneath it. The
+# tree of this variant is not specific to one global stack, so because the
+# list of materials can be different per stack depending on the compatible
+# material diameter setting, we cannot filter them here. Filtering must be
+# done in the model.
+class VariantNode(ContainerNode):
+ def __init__(self, container_id: str, machine: "MachineNode") -> None:
+ super().__init__(container_id)
+ self.machine = machine
+ self.materials = {} # type: Dict[str, MaterialNode] # Mapping material base files to their nodes.
+ self.materialsChanged = Signal()
+
+ container_registry = ContainerRegistry.getInstance()
+ self.variant_name = container_registry.findContainersMetadata(id = container_id)[0]["name"] # Store our own name so that we can filter more easily.
+ container_registry.containerAdded.connect(self._materialAdded)
+ container_registry.containerRemoved.connect(self._materialRemoved)
+ self._loadAll()
+
+ ## (Re)loads all materials under this variant.
+ @UM.FlameProfiler.profile
+ def _loadAll(self) -> None:
+ container_registry = ContainerRegistry.getInstance()
+
+ if not self.machine.has_materials:
+ self.materials["empty_material"] = MaterialNode("empty_material", variant = self)
+ return # There should not be any materials loaded for this printer.
+
+ # Find all the materials for this variant's name.
+ else: # Printer has its own material profiles. Look for material profiles with this printer's definition.
+ base_materials = container_registry.findInstanceContainersMetadata(type = "material", definition = "fdmprinter")
+ printer_specific_materials = container_registry.findInstanceContainersMetadata(type = "material", definition = self.machine.container_id, variant_name = None)
+ variant_specific_materials = container_registry.findInstanceContainersMetadata(type = "material", definition = self.machine.container_id, variant_name = self.variant_name) # If empty_variant, this won't return anything.
+ materials_per_base_file = {material["base_file"]: material for material in base_materials}
+ materials_per_base_file.update({material["base_file"]: material for material in printer_specific_materials}) # Printer-specific profiles override global ones.
+ materials_per_base_file.update({material["base_file"]: material for material in variant_specific_materials}) # Variant-specific profiles override all of those.
+ materials = list(materials_per_base_file.values())
+
+ # Filter materials based on the exclude_materials property.
+ filtered_materials = [material for material in materials if material["id"] not in self.machine.exclude_materials]
+
+ for material in filtered_materials:
+ base_file = material["base_file"]
+ if base_file not in self.materials:
+ self.materials[base_file] = MaterialNode(material["id"], variant = self)
+ self.materials[base_file].materialChanged.connect(self.materialsChanged)
+ if not self.materials:
+ self.materials["empty_material"] = MaterialNode("empty_material", variant = self)
+
+ ## Finds the preferred material for this printer with this nozzle in one of
+ # the extruders.
+ #
+ # If the preferred material is not available, an arbitrary material is
+ # returned. If there is a configuration mistake (like a typo in the
+ # preferred material) this returns a random available material. If there
+ # are no available materials, this will return the empty material node.
+ # \param approximate_diameter The desired approximate diameter of the
+ # material.
+ # \return The node for the preferred material, or any arbitrary material
+ # 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 == base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
+ return material_node
+
+ # 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,
+ diameter = approximate_diameter,
+ variant_id = self.container_id,
+ fallback = fallback.container_id
+ ))
+ return fallback
+
+ ## When a material gets added to the set of profiles, we need to update our
+ # tree here.
+ @UM.FlameProfiler.profile
+ def _materialAdded(self, container: ContainerInterface) -> None:
+ if container.getMetaDataEntry("type") != "material":
+ return # Not interested.
+ if not ContainerRegistry.getInstance().findContainersMetadata(id = container.getId()):
+ # CURA-6889
+ # containerAdded and removed signals may be triggered in the next event cycle. If a container gets added
+ # and removed in the same event cycle, in the next cycle, the connections should just ignore the signals.
+ # The check here makes sure that the container in the signal still exists.
+ Logger.log("d", "Got container added signal for container [%s] but it no longer exists, do nothing.",
+ container.getId())
+ return
+ if not self.machine.has_materials:
+ return # We won't add any materials.
+ material_definition = container.getMetaDataEntry("definition")
+
+ base_file = container.getMetaDataEntry("base_file")
+ if base_file in self.machine.exclude_materials:
+ return # Material is forbidden for this printer.
+ if base_file not in self.materials: # Completely new base file. Always better than not having a file as long as it matches our set-up.
+ if material_definition != "fdmprinter" and material_definition != self.machine.container_id:
+ return
+ material_variant = container.getMetaDataEntry("variant_name")
+ if material_variant is not None and material_variant != self.variant_name:
+ return
+ else: # We already have this base profile. Replace the base profile if the new one is more specific.
+ new_definition = container.getMetaDataEntry("definition")
+ if new_definition == "fdmprinter":
+ return # Just as unspecific or worse.
+ material_variant = container.getMetaDataEntry("variant_name")
+ if new_definition != self.machine.container_id or material_variant != self.variant_name:
+ return # Doesn't match this set-up.
+ original_metadata = ContainerRegistry.getInstance().findContainersMetadata(id = self.materials[base_file].container_id)[0]
+ if "variant_name" in original_metadata or material_variant is None:
+ return # Original was already specific or just as unspecific as the new one.
+
+ if "empty_material" in self.materials:
+ del self.materials["empty_material"]
+ self.materials[base_file] = MaterialNode(container.getId(), variant = self)
+ self.materials[base_file].materialChanged.connect(self.materialsChanged)
+ self.materialsChanged.emit(self.materials[base_file])
+
+ @UM.FlameProfiler.profile
+ def _materialRemoved(self, container: ContainerInterface) -> None:
+ if container.getMetaDataEntry("type") != "material":
+ return # Only interested in materials.
+ base_file = container.getMetaDataEntry("base_file")
+ if base_file not in self.materials:
+ return # We don't track this material anyway. No need to remove it.
+
+ original_node = self.materials[base_file]
+ del self.materials[base_file]
+ self.materialsChanged.emit(original_node)
+
+ # Now a different material from the same base file may have been hidden because it was not as specific as the one we deleted.
+ # Search for any submaterials from that base file that are still left.
+ materials_same_base_file = ContainerRegistry.getInstance().findContainersMetadata(base_file = base_file)
+ if materials_same_base_file:
+ most_specific_submaterial = materials_same_base_file[0]
+ for submaterial in materials_same_base_file:
+ if submaterial["definition"] == self.machine.container_id:
+ if most_specific_submaterial["definition"] == "fdmprinter":
+ most_specific_submaterial = submaterial
+ if most_specific_submaterial.get("variant_name", "empty") == "empty" and submaterial.get("variant_name", "empty") == self.variant_name:
+ most_specific_submaterial = submaterial
+ self.materials[base_file] = MaterialNode(most_specific_submaterial["id"], variant = self)
+ self.materialsChanged.emit(self.materials[base_file])
+
+ if not self.materials: # The last available material just got deleted and there is nothing with the same base file to replace it.
+ self.materials["empty_material"] = MaterialNode("empty_material", variant = self)
+ self.materialsChanged.emit(self.materials["empty_material"])
\ No newline at end of file
diff --git a/cura/MultiplyObjectsJob.py b/cura/MultiplyObjectsJob.py
index e71bbf6668..5c25f70336 100644
--- a/cura/MultiplyObjectsJob.py
+++ b/cura/MultiplyObjectsJob.py
@@ -2,10 +2,12 @@
# Cura is released under the terms of the LGPLv3 or higher.
import copy
+from typing import List
from UM.Job import Job
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Message import Message
+from UM.Scene.SceneNode import SceneNode
from UM.i18n import i18nCatalog
i18n_catalog = i18nCatalog("cura")
@@ -23,7 +25,7 @@ class MultiplyObjectsJob(Job):
self._count = count
self._min_offset = min_offset
- def run(self):
+ def run(self) -> None:
status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime=0,
dismissable=False, progress=0, title = i18n_catalog.i18nc("@info:title", "Placing Objects"))
status_message.show()
@@ -33,13 +35,15 @@ class MultiplyObjectsJob(Job):
current_progress = 0
global_container_stack = Application.getInstance().getGlobalContainerStack()
+ if global_container_stack is None:
+ return # We can't do anything in this case.
machine_width = global_container_stack.getProperty("machine_width", "value")
machine_depth = global_container_stack.getProperty("machine_depth", "value")
root = scene.getRoot()
scale = 0.5
arranger = Arrange.create(x = machine_width, y = machine_depth, scene_root = root, scale = scale, min_offset = self._min_offset)
- processed_nodes = []
+ processed_nodes = [] # type: List[SceneNode]
nodes = []
not_fit_count = 0
@@ -67,7 +71,11 @@ class MultiplyObjectsJob(Job):
new_node = copy.deepcopy(node)
solution_found = False
if not node_too_big:
- solution_found = arranger.findNodePlacement(new_node, offset_shape_arr, hull_shape_arr)
+ if offset_shape_arr is not None and hull_shape_arr is not None:
+ solution_found = arranger.findNodePlacement(new_node, offset_shape_arr, hull_shape_arr)
+ else:
+ # The node has no shape, so no need to arrange it. The solution is simple: Do nothing.
+ solution_found = True
if node_too_big or not solution_found:
found_solution_for_all = False
diff --git a/cura/OAuth2/AuthorizationHelpers.py b/cura/OAuth2/AuthorizationHelpers.py
index 314b5631f8..9fc01ba50b 100644
--- a/cura/OAuth2/AuthorizationHelpers.py
+++ b/cura/OAuth2/AuthorizationHelpers.py
@@ -41,12 +41,16 @@ class AuthorizationHelpers:
"code_verifier": verification_code,
"scope": self._settings.CLIENT_SCOPES if self._settings.CLIENT_SCOPES is not None else "",
}
- return self.parseTokenResponse(requests.post(self._token_url, data = data)) # type: ignore
+ try:
+ return self.parseTokenResponse(requests.post(self._token_url, data = data)) # type: ignore
+ except requests.exceptions.ConnectionError:
+ return AuthenticationResponse(success=False, err_message="Unable to connect to remote server")
## Request the access token from the authorization server using a refresh token.
# \param refresh_token:
# \return An AuthenticationResponse object.
def getAccessTokenUsingRefreshToken(self, refresh_token: str) -> "AuthenticationResponse":
+ Logger.log("d", "Refreshing the access token.")
data = {
"client_id": self._settings.CLIENT_ID if self._settings.CLIENT_ID is not None else "",
"redirect_uri": self._settings.CALLBACK_URL if self._settings.CALLBACK_URL is not None else "",
@@ -54,7 +58,10 @@ class AuthorizationHelpers:
"refresh_token": refresh_token,
"scope": self._settings.CLIENT_SCOPES if self._settings.CLIENT_SCOPES is not None else "",
}
- return self.parseTokenResponse(requests.post(self._token_url, data = data)) # type: ignore
+ try:
+ return self.parseTokenResponse(requests.post(self._token_url, data = data)) # type: ignore
+ except requests.exceptions.ConnectionError:
+ return AuthenticationResponse(success=False, err_message="Unable to connect to remote server")
@staticmethod
## Parse the token response from the authorization server into an AuthenticationResponse object.
@@ -92,7 +99,7 @@ class AuthorizationHelpers:
})
except requests.exceptions.ConnectionError:
# Connection was suddenly dropped. Nothing we can do about that.
- Logger.logException("e", "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/AuthorizationRequestHandler.py b/cura/OAuth2/AuthorizationRequestHandler.py
index 66ecfc2787..83b94ed586 100644
--- a/cura/OAuth2/AuthorizationRequestHandler.py
+++ b/cura/OAuth2/AuthorizationRequestHandler.py
@@ -25,6 +25,10 @@ class AuthorizationRequestHandler(BaseHTTPRequestHandler):
self.authorization_callback = None # type: Optional[Callable[[AuthenticationResponse], None]]
self.verification_code = None # type: Optional[str]
+ # CURA-6609: Some browser seems to issue a HEAD instead of GET request as the callback.
+ def do_HEAD(self) -> None:
+ self.do_GET()
+
def do_GET(self) -> None:
# Extract values from the query string.
parsed_url = urlparse(self.path)
diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py
index 377ec080aa..0848623410 100644
--- a/cura/OAuth2/AuthorizationService.py
+++ b/cura/OAuth2/AuthorizationService.py
@@ -2,20 +2,26 @@
# Cura is released under the terms of the LGPLv3 or higher.
import json
-import webbrowser
from datetime import datetime, timedelta
from typing import Optional, TYPE_CHECKING
from urllib.parse import urlencode
+
import requests.exceptions
+from PyQt5.QtCore import QUrl
+from PyQt5.QtGui import QDesktopServices
from UM.Logger import Logger
+from UM.Message import Message
from UM.Signal import Signal
from cura.OAuth2.LocalAuthorizationServer import LocalAuthorizationServer
from cura.OAuth2.AuthorizationHelpers import AuthorizationHelpers, TOKEN_TIMESTAMP_FORMAT
from cura.OAuth2.Models import AuthenticationResponse
+from UM.i18n import i18nCatalog
+i18n_catalog = i18nCatalog("cura")
+
if TYPE_CHECKING:
from cura.OAuth2.Models import UserProfile, OAuth2Settings
from UM.Preferences import Preferences
@@ -30,6 +36,8 @@ class AuthorizationService:
# Emit signal when authentication failed.
onAuthenticationError = Signal()
+ accessTokenChanged = Signal()
+
def __init__(self, settings: "OAuth2Settings", preferences: Optional["Preferences"] = None) -> None:
self._settings = settings
self._auth_helpers = AuthorizationHelpers(settings)
@@ -39,6 +47,14 @@ class AuthorizationService:
self._preferences = preferences
self._server = LocalAuthorizationServer(self._auth_helpers, self._onAuthStateChanged, daemon=True)
+ self._unable_to_get_data_message = None # type: Optional[Message]
+
+ self.onAuthStateChanged.connect(self._authChanged)
+
+ def _authChanged(self, logged_in):
+ if logged_in and self._unable_to_get_data_message is not None:
+ self._unable_to_get_data_message.hide()
+
def initialize(self, preferences: Optional["Preferences"] = None) -> None:
if preferences is not None:
self._preferences = preferences
@@ -56,6 +72,7 @@ class AuthorizationService:
self._user_profile = self._parseJWT()
except requests.exceptions.ConnectionError:
# Unable to get connection, can't login.
+ Logger.logException("w", "Unable to validate user data with the remote server.")
return None
if not self._user_profile and self._auth_data:
@@ -71,6 +88,7 @@ class AuthorizationService:
def _parseJWT(self) -> Optional["UserProfile"]:
if not self._auth_data or self._auth_data.access_token is None:
# If no auth data exists, we should always log in again.
+ Logger.log("d", "There was no auth data or access token")
return None
user_data = self._auth_helpers.parseJWT(self._auth_data.access_token)
if user_data:
@@ -78,12 +96,16 @@ class AuthorizationService:
return user_data
# The JWT was expired or invalid and we should request a new one.
if self._auth_data.refresh_token is None:
+ Logger.log("w", "There was no refresh token in the auth data.")
return None
self._auth_data = self._auth_helpers.getAccessTokenUsingRefreshToken(self._auth_data.refresh_token)
if not self._auth_data or self._auth_data.access_token is None:
+ Logger.log("w", "Unable to use the refresh token to get a new access token.")
# The token could not be refreshed using the refresh token. We should login again.
return None
-
+ # Ensure it gets stored as otherwise we only have it in memory. The stored refresh token has been deleted
+ # from the server already.
+ self._storeAuthData(self._auth_data)
return self._auth_helpers.parseJWT(self._auth_data.access_token)
## Get the access token as provided by the repsonse data.
@@ -96,7 +118,7 @@ class AuthorizationService:
# We have a fallback on a date far in the past for currently stored auth data in cura.cfg.
received_at = datetime.strptime(self._auth_data.received_at, TOKEN_TIMESTAMP_FORMAT) \
if self._auth_data.received_at else datetime(2000, 1, 1)
- expiry_date = received_at + timedelta(seconds = float(self._auth_data.expires_in or 0))
+ expiry_date = received_at + timedelta(seconds = float(self._auth_data.expires_in or 0) - 60)
if datetime.now() > expiry_date:
self.refreshAccessToken()
@@ -107,8 +129,13 @@ class AuthorizationService:
if self._auth_data is None or self._auth_data.refresh_token is None:
Logger.log("w", "Unable to refresh access token, since there is no refresh token.")
return
- self._storeAuthData(self._auth_helpers.getAccessTokenUsingRefreshToken(self._auth_data.refresh_token))
- self.onAuthStateChanged.emit(logged_in = True)
+ response = self._auth_helpers.getAccessTokenUsingRefreshToken(self._auth_data.refresh_token)
+ if response.success:
+ self._storeAuthData(response)
+ self.onAuthStateChanged.emit(logged_in = True)
+ else:
+ Logger.log("w", "Failed to get a new access token from the server.")
+ self.onAuthStateChanged.emit(logged_in = False)
## Delete the authentication data that we have stored locally (eg; logout)
def deleteAuthData(self) -> None:
@@ -138,7 +165,7 @@ class AuthorizationService:
})
# Open the authorization page in a new browser window.
- webbrowser.open_new("{}?{}".format(self._auth_url, query_string))
+ QDesktopServices.openUrl(QUrl("{}?{}".format(self._auth_url, query_string)))
# Start a local web server to receive the callback URL on.
self._server.start(verification_code)
@@ -161,12 +188,22 @@ class AuthorizationService:
preferences_data = json.loads(self._preferences.getValue(self._settings.AUTH_DATA_PREFERENCE_KEY))
if preferences_data:
self._auth_data = AuthenticationResponse(**preferences_data)
- self.onAuthStateChanged.emit(logged_in = True)
+ # Also check if we can actually get the user profile information.
+ user_profile = self.getUserProfile()
+ if user_profile is not None:
+ self.onAuthStateChanged.emit(logged_in = True)
+ else:
+ if self._unable_to_get_data_message is not None:
+ self._unable_to_get_data_message.hide()
+
+ self._unable_to_get_data_message = Message(i18n_catalog.i18nc("@info", "Unable to reach the Ultimaker account server."), title = i18n_catalog.i18nc("@info:title", "Warning"))
+ self._unable_to_get_data_message.show()
except ValueError:
Logger.logException("w", "Could not load auth data from preferences")
## Store authentication data in preferences.
def _storeAuthData(self, auth_data: Optional[AuthenticationResponse] = None) -> None:
+ Logger.log("d", "Attempting to store the auth data")
if self._preferences is None:
Logger.log("e", "Unable to save authentication data, since no preference has been set!")
return
@@ -178,3 +215,6 @@ class AuthorizationService:
else:
self._user_profile = None
self._preferences.resetPreference(self._settings.AUTH_DATA_PREFERENCE_KEY)
+
+ self.accessTokenChanged.emit()
+
diff --git a/cura/OAuth2/LocalAuthorizationServer.py b/cura/OAuth2/LocalAuthorizationServer.py
index 25b2435012..a80b0deb28 100644
--- a/cura/OAuth2/LocalAuthorizationServer.py
+++ b/cura/OAuth2/LocalAuthorizationServer.py
@@ -63,6 +63,10 @@ class LocalAuthorizationServer:
Logger.log("d", "Stopping local oauth2 web server...")
if self._web_server:
- self._web_server.server_close()
+ try:
+ self._web_server.server_close()
+ except OSError:
+ # OS error can happen if the socket was already closed. We really don't care about that case.
+ pass
self._web_server = None
self._web_server_thread = None
diff --git a/cura/ObjectsModel.py b/cura/ObjectsModel.py
deleted file mode 100644
index 8354540783..0000000000
--- a/cura/ObjectsModel.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from PyQt5.QtCore import QTimer
-
-from UM.Application import Application
-from UM.Qt.ListModel import ListModel
-from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
-from UM.Scene.SceneNode import SceneNode
-from UM.Scene.Selection import Selection
-from UM.i18n import i18nCatalog
-from collections import defaultdict
-
-catalog = i18nCatalog("cura")
-
-
-## Keep track of all objects in the project
-class ObjectsModel(ListModel):
- def __init__(self):
- super().__init__()
-
- Application.getInstance().getController().getScene().sceneChanged.connect(self._updateDelayed)
- Application.getInstance().getPreferences().preferenceChanged.connect(self._updateDelayed)
-
- self._update_timer = QTimer()
- self._update_timer.setInterval(100)
- self._update_timer.setSingleShot(True)
- self._update_timer.timeout.connect(self._update)
-
- self._build_plate_number = -1
-
- def setActiveBuildPlate(self, nr):
- self._build_plate_number = nr
- self._update()
-
- def _updateDelayed(self, *args):
- self._update_timer.start()
-
- def _update(self, *args):
- nodes = []
- filter_current_build_plate = Application.getInstance().getPreferences().getValue("view/filter_current_build_plate")
- active_build_plate_number = self._build_plate_number
- group_nr = 1
- name_count_dict = defaultdict(int)
-
- for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
- if not isinstance(node, SceneNode):
- continue
- if (not node.getMeshData() and not node.callDecoration("getLayerData")) and not node.callDecoration("isGroup"):
- continue
- if node.getParent() and node.getParent().callDecoration("isGroup"):
- continue # Grouped nodes don't need resetting as their parent (the group) is resetted)
- if not node.callDecoration("isSliceable") and not node.callDecoration("isGroup"):
- continue
- node_build_plate_number = node.callDecoration("getBuildPlateNumber")
- if filter_current_build_plate and node_build_plate_number != active_build_plate_number:
- continue
-
- if not node.callDecoration("isGroup"):
- name = node.getName()
-
- else:
- name = catalog.i18nc("@label", "Group #{group_nr}").format(group_nr = str(group_nr))
- group_nr += 1
-
- if hasattr(node, "isOutsideBuildArea"):
- is_outside_build_area = node.isOutsideBuildArea()
- else:
- is_outside_build_area = False
-
- #check if we already have an instance of the object based on name
- name_count_dict[name] += 1
- name_count = name_count_dict[name]
-
- if name_count > 1:
- name = "{0}({1})".format(name, name_count-1)
- node.setName(name)
-
- nodes.append({
- "name": name,
- "isSelected": Selection.isSelected(node),
- "isOutsideBuildArea": is_outside_build_area,
- "buildPlateNumber": node_build_plate_number,
- "node": node
- })
-
- nodes = sorted(nodes, key=lambda n: n["name"])
- self.setItems(nodes)
-
- self.itemsChanged.emit()
-
- @staticmethod
- def createObjectsModel():
- return ObjectsModel()
diff --git a/cura/OneAtATimeIterator.py b/cura/OneAtATimeIterator.py
index a08f3ed2bf..b77e1f3982 100644
--- a/cura/OneAtATimeIterator.py
+++ b/cura/OneAtATimeIterator.py
@@ -1,149 +1,127 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-import sys
+from typing import List
-from shapely import affinity
-from shapely.geometry import Polygon
-
-from UM.Scene.Iterator.Iterator import Iterator
+from UM.Scene.Iterator import Iterator
from UM.Scene.SceneNode import SceneNode
+from functools import cmp_to_key
+## Iterator that returns a list of nodes in the order that they need to be printed
+# If there is no solution an empty list is returned.
+# Take note that the list of nodes can have children (that may or may not contain mesh data)
+class OneAtATimeIterator(Iterator.Iterator):
+ def __init__(self, scene_node) -> None:
+ super().__init__(scene_node) # Call super to make multiple inheritance work.
+ self._hit_map = [[]] # type: List[List[bool]] # For each node, which other nodes this hits. A grid of booleans on which nodes hit which.
+ self._original_node_list = [] # type: List[SceneNode] # The nodes that need to be checked for collisions.
-# Iterator that determines the object print order when one-at a time mode is enabled.
-#
-# In one-at-a-time mode, only one extruder can be enabled to print. In order to maximize the number of objects we can
-# print, we need to print from the corner that's closest to the extruder that's being used. Here is an illustration:
-#
-# +--------------------------------+
-# | |
-# | |
-# | | - Rectangle represents the complete print head including fans, etc.
-# | X X | y - X's are the nozzles
-# | (1) (2) | ^
-# | | |
-# +--------------------------------+ +--> x
-#
-# In this case, the nozzles are symmetric, nozzle (1) is closer to the bottom left corner while (2) is closer to the
-# bottom right. If we use nozzle (1) to print, then we better off printing from the bottom left corner so the print
-# head will not collide into an object on its top-right side, which is a very large unused area. Following the same
-# logic, if we are printing with nozzle (2), then it's better to print from the bottom-right side.
-#
-# This iterator determines the print order following the rules above.
-#
-class OneAtATimeIterator(Iterator):
-
- def __init__(self, scene_node):
- from cura.CuraApplication import CuraApplication
- self._global_stack = CuraApplication.getInstance().getGlobalContainerStack()
- self._original_node_list = []
-
- super().__init__(scene_node) # Call super to make multiple inheritance work.
-
- def getMachineNearestCornerToExtruder(self, global_stack):
- head_and_fans_coordinates = global_stack.getHeadAndFansCoordinates()
-
- used_extruder = None
- for extruder in global_stack.extruders.values():
- if extruder.isEnabled:
- used_extruder = extruder
- break
-
- extruder_offsets = [used_extruder.getProperty("machine_nozzle_offset_x", "value"),
- used_extruder.getProperty("machine_nozzle_offset_y", "value")]
-
- # find the corner that's closest to the origin
- min_distance2 = sys.maxsize
- min_coord = None
- for coord in head_and_fans_coordinates:
- x = coord[0] - extruder_offsets[0]
- y = coord[1] - extruder_offsets[1]
-
- distance2 = x**2 + y**2
- if distance2 <= min_distance2:
- min_distance2 = distance2
- min_coord = coord
-
- return min_coord
-
- def _checkForCollisions(self) -> bool:
- all_nodes = []
- for node in self._scene_node.getChildren():
- if not issubclass(type(node), SceneNode):
- continue
- convex_hull = node.callDecoration("getConvexHullHead")
- if not convex_hull:
- continue
-
- bounding_box = node.getBoundingBox()
- if not bounding_box:
- continue
- from UM.Math.Polygon import Polygon
- bounding_box_polygon = Polygon([[bounding_box.left, bounding_box.front],
- [bounding_box.left, bounding_box.back],
- [bounding_box.right, bounding_box.back],
- [bounding_box.right, bounding_box.front]])
-
- all_nodes.append({"node": node,
- "bounding_box": bounding_box_polygon,
- "convex_hull": convex_hull})
-
- has_collisions = False
- for i, node_dict in enumerate(all_nodes):
- for j, other_node_dict in enumerate(all_nodes):
- if i == j:
- continue
- if node_dict["bounding_box"].intersectsPolygon(other_node_dict["convex_hull"]):
- has_collisions = True
- break
-
- if has_collisions:
- break
-
- return has_collisions
-
- def _fillStack(self):
- min_coord = self.getMachineNearestCornerToExtruder(self._global_stack)
- transform_x = -int(round(min_coord[0] / abs(min_coord[0])))
- transform_y = -int(round(min_coord[1] / abs(min_coord[1])))
-
- machine_size = [self._global_stack.getProperty("machine_width", "value"),
- self._global_stack.getProperty("machine_depth", "value")]
-
- def flip_x(polygon):
- tm2 = [-1, 0, 0, 1, 0, 0]
- return affinity.affine_transform(affinity.translate(polygon, xoff = -machine_size[0]), tm2)
-
- def flip_y(polygon):
- tm2 = [1, 0, 0, -1, 0, 0]
- return affinity.affine_transform(affinity.translate(polygon, yoff = -machine_size[1]), tm2)
-
- if self._checkForCollisions():
- self._node_stack = []
- return
-
+ ## Fills the ``_node_stack`` with a list of scene nodes that need to be
+ # printed in order.
+ def _fillStack(self) -> None:
node_list = []
for node in self._scene_node.getChildren():
if not issubclass(type(node), SceneNode):
continue
- convex_hull = node.callDecoration("getConvexHull")
- if convex_hull:
- xmin = min(x for x, _ in convex_hull._points)
- xmax = max(x for x, _ in convex_hull._points)
- ymin = min(y for _, y in convex_hull._points)
- ymax = max(y for _, y in convex_hull._points)
+ if node.callDecoration("getConvexHull"):
+ node_list.append(node)
- convex_hull_polygon = Polygon.from_bounds(xmin, ymin, xmax, ymax)
- if transform_x < 0:
- convex_hull_polygon = flip_x(convex_hull_polygon)
- if transform_y < 0:
- convex_hull_polygon = flip_y(convex_hull_polygon)
- node_list.append({"node": node,
- "min_coord": [convex_hull_polygon.bounds[0], convex_hull_polygon.bounds[1]],
- })
+ if len(node_list) < 2:
+ self._node_stack = node_list[:]
+ return
- node_list = sorted(node_list, key = lambda d: d["min_coord"])
+ # Copy the list
+ self._original_node_list = node_list[:]
- self._node_stack = [d["node"] for d in node_list]
+ ## Initialise the hit map (pre-compute all hits between all objects)
+ self._hit_map = [[self._checkHit(i,j) for i in node_list] for j in node_list]
+
+ # Check if we have to files that block each other. If this is the case, there is no solution!
+ for a in range(0, len(node_list)):
+ for b in range(0, len(node_list)):
+ if a != b and self._hit_map[a][b] and self._hit_map[b][a]:
+ return
+
+ # Sort the original list so that items that block the most other objects are at the beginning.
+ # This does not decrease the worst case running time, but should improve it in most cases.
+ sorted(node_list, key = cmp_to_key(self._calculateScore))
+
+ todo_node_list = [_ObjectOrder([], node_list)]
+ while len(todo_node_list) > 0:
+ current = todo_node_list.pop()
+ for node in current.todo:
+ # Check if the object can be placed with what we have and still allows for a solution in the future
+ if not self._checkHitMultiple(node, current.order) and not self._checkBlockMultiple(node, current.todo):
+ # We found a possible result. Create new todo & order list.
+ new_todo_list = current.todo[:]
+ new_todo_list.remove(node)
+ new_order = current.order[:] + [node]
+ if len(new_todo_list) == 0:
+ # We have no more nodes to check, so quit looking.
+ self._node_stack = new_order
+ return
+ todo_node_list.append(_ObjectOrder(new_order, new_todo_list))
+ self._node_stack = [] #No result found!
+
+
+ # Check if first object can be printed before the provided list (using the hit map)
+ def _checkHitMultiple(self, node: SceneNode, other_nodes: List[SceneNode]) -> bool:
+ node_index = self._original_node_list.index(node)
+ for other_node in other_nodes:
+ other_node_index = self._original_node_list.index(other_node)
+ if self._hit_map[node_index][other_node_index]:
+ return True
+ return False
+
+ ## Check for a node whether it hits any of the other nodes.
+ # \param node The node to check whether it collides with the other nodes.
+ # \param other_nodes The nodes to check for collisions.
+ def _checkBlockMultiple(self, node: SceneNode, other_nodes: List[SceneNode]) -> bool:
+ node_index = self._original_node_list.index(node)
+ for other_node in other_nodes:
+ other_node_index = self._original_node_list.index(other_node)
+ if self._hit_map[other_node_index][node_index] and node_index != other_node_index:
+ return True
+ return False
+
+ ## Calculate score simply sums the number of other objects it 'blocks'
+ def _calculateScore(self, a: SceneNode, b: SceneNode) -> int:
+ score_a = sum(self._hit_map[self._original_node_list.index(a)])
+ score_b = sum(self._hit_map[self._original_node_list.index(b)])
+ return score_a - score_b
+
+ ## Checks if A can be printed before B
+ def _checkHit(self, a: SceneNode, b: SceneNode) -> bool:
+ if a == b:
+ return False
+
+ a_hit_hull = a.callDecoration("getConvexHullBoundary")
+ b_hit_hull = b.callDecoration("getConvexHullHeadFull")
+ overlap = a_hit_hull.intersectsPolygon(b_hit_hull)
+
+ if overlap:
+ return True
+
+ # Adhesion areas must never overlap, regardless of printing order
+ # This would cause over-extrusion
+ a_hit_hull = a.callDecoration("getAdhesionArea")
+ b_hit_hull = b.callDecoration("getAdhesionArea")
+ overlap = a_hit_hull.intersectsPolygon(b_hit_hull)
+
+ if overlap:
+ return True
+ else:
+ return False
+
+
+## Internal object used to keep track of a possible order in which to print objects.
+class _ObjectOrder:
+ ## Creates the _ObjectOrder instance.
+ # \param order List of indices in which to print objects, ordered by printing
+ # order.
+ # \param todo: List of indices which are not yet inserted into the order list.
+ def __init__(self, order: List[SceneNode], todo: List[SceneNode]):
+ self.order = order
+ self.todo = todo
diff --git a/cura/Operations/PlatformPhysicsOperation.py b/cura/Operations/PlatformPhysicsOperation.py
index 75c5b437bc..9571679c3c 100644
--- a/cura/Operations/PlatformPhysicsOperation.py
+++ b/cura/Operations/PlatformPhysicsOperation.py
@@ -29,4 +29,4 @@ class PlatformPhysicsOperation(Operation):
return group
def __repr__(self):
- return "PlatformPhysicsOperation(translation = {0})".format(self._translation)
+ return "PlatformPhysicsOp.(trans.={0})".format(self._translation)
diff --git a/cura/PlatformPhysics.py b/cura/PlatformPhysics.py
index 8ddcdbfb2f..a411478b16 100755
--- a/cura/PlatformPhysics.py
+++ b/cura/PlatformPhysics.py
@@ -40,8 +40,9 @@ class PlatformPhysics:
Application.getInstance().getPreferences().addPreference("physics/automatic_drop_down", True)
def _onSceneChanged(self, source):
- if not source.getMeshData():
+ if not source.callDecoration("isSliceable"):
return
+
self._change_timer.start()
def _onChangeTimerFinished(self):
@@ -49,18 +50,20 @@ class PlatformPhysics:
return
root = self._controller.getScene().getRoot()
+ build_volume = Application.getInstance().getBuildVolume()
+ build_volume.updateNodeBoundaryCheck()
# Keep a list of nodes that are moving. We use this so that we don't move two intersecting objects in the
# same direction.
transformed_nodes = []
- # We try to shuffle all the nodes to prevent "locked" situations, where iteration B inverts iteration A.
- # By shuffling the order of the nodes, this might happen a few times, but at some point it will resolve.
nodes = list(BreadthFirstIterator(root))
# Only check nodes inside build area.
nodes = [node for node in nodes if (hasattr(node, "_outside_buildarea") and not node._outside_buildarea)]
+ # We try to shuffle all the nodes to prevent "locked" situations, where iteration B inverts iteration A.
+ # By shuffling the order of the nodes, this might happen a few times, but at some point it will resolve.
random.shuffle(nodes)
for node in nodes:
if node is root or not isinstance(node, SceneNode) or node.getBoundingBox() is None:
@@ -76,7 +79,7 @@ class PlatformPhysics:
move_vector = move_vector.set(y = -bbox.bottom + z_offset)
# If there is no convex hull for the node, start calculating it and continue.
- if not node.getDecorator(ConvexHullDecorator):
+ if not node.getDecorator(ConvexHullDecorator) and not node.callDecoration("isNonPrintingMesh"):
node.addDecorator(ConvexHullDecorator())
# only push away objects if this node is a printing mesh
@@ -160,7 +163,6 @@ class PlatformPhysics:
op.push()
# After moving, we have to evaluate the boundary checks for nodes
- build_volume = Application.getInstance().getBuildVolume()
build_volume.updateNodeBoundaryCheck()
def _onToolOperationStarted(self, tool):
diff --git a/cura/PreviewPass.py b/cura/PreviewPass.py
index befb52ee5e..58205ba708 100644
--- a/cura/PreviewPass.py
+++ b/cura/PreviewPass.py
@@ -1,7 +1,8 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import Optional, TYPE_CHECKING
+from typing import Optional, TYPE_CHECKING, cast
+
from UM.Application import Application
from UM.Resources import Resources
@@ -12,6 +13,7 @@ from UM.View.RenderBatch import RenderBatch
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
+from cura.Scene.CuraSceneNode import CuraSceneNode
if TYPE_CHECKING:
from UM.View.GL.ShaderProgram import ShaderProgram
@@ -44,9 +46,9 @@ class PreviewPass(RenderPass):
self._renderer = Application.getInstance().getRenderer()
- self._shader = None #type: Optional[ShaderProgram]
- self._non_printing_shader = None #type: Optional[ShaderProgram]
- self._support_mesh_shader = None #type: Optional[ShaderProgram]
+ self._shader = None # type: Optional[ShaderProgram]
+ self._non_printing_shader = None # type: Optional[ShaderProgram]
+ self._support_mesh_shader = None # type: Optional[ShaderProgram]
self._scene = Application.getInstance().getController().getScene()
# Set the camera to be used by this render pass
@@ -62,6 +64,7 @@ class PreviewPass(RenderPass):
self._shader.setUniformValue("u_ambientColor", [0.1, 0.1, 0.1, 1.0])
self._shader.setUniformValue("u_specularColor", [0.6, 0.6, 0.6, 1.0])
self._shader.setUniformValue("u_shininess", 20.0)
+ self._shader.setUniformValue("u_faceId", -1) # Don't render any selected faces in the preview.
if not self._non_printing_shader:
if self._non_printing_shader:
@@ -83,30 +86,31 @@ class PreviewPass(RenderPass):
batch_support_mesh = RenderBatch(self._support_mesh_shader)
# Fill up the batch with objects that can be sliced.
- for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
- if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible():
- per_mesh_stack = node.callDecoration("getStack")
- if node.callDecoration("isNonThumbnailVisibleMesh"):
- # Non printing mesh
- continue
- elif per_mesh_stack is not None and per_mesh_stack.getProperty("support_mesh", "value"):
- # Support mesh
- uniforms = {}
- shade_factor = 0.6
- diffuse_color = node.getDiffuseColor()
- diffuse_color2 = [
- diffuse_color[0] * shade_factor,
- diffuse_color[1] * shade_factor,
- diffuse_color[2] * shade_factor,
- 1.0]
- uniforms["diffuse_color"] = prettier_color(diffuse_color)
- uniforms["diffuse_color_2"] = diffuse_color2
- batch_support_mesh.addItem(node.getWorldTransformation(), node.getMeshData(), uniforms = uniforms)
- else:
- # Normal scene node
- uniforms = {}
- uniforms["diffuse_color"] = prettier_color(node.getDiffuseColor())
- batch.addItem(node.getWorldTransformation(), node.getMeshData(), uniforms = uniforms)
+ for node in DepthFirstIterator(self._scene.getRoot()):
+ if hasattr(node, "_outside_buildarea") and not getattr(node, "_outside_buildarea"):
+ if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible():
+ per_mesh_stack = node.callDecoration("getStack")
+ if node.callDecoration("isNonThumbnailVisibleMesh"):
+ # Non printing mesh
+ continue
+ elif per_mesh_stack is not None and per_mesh_stack.getProperty("support_mesh", "value"):
+ # Support mesh
+ uniforms = {}
+ shade_factor = 0.6
+ diffuse_color = cast(CuraSceneNode, node).getDiffuseColor()
+ diffuse_color2 = [
+ diffuse_color[0] * shade_factor,
+ diffuse_color[1] * shade_factor,
+ diffuse_color[2] * shade_factor,
+ 1.0]
+ uniforms["diffuse_color"] = prettier_color(diffuse_color)
+ uniforms["diffuse_color_2"] = diffuse_color2
+ batch_support_mesh.addItem(node.getWorldTransformation(), node.getMeshData(), uniforms = uniforms)
+ else:
+ # Normal scene node
+ uniforms = {}
+ uniforms["diffuse_color"] = prettier_color(cast(CuraSceneNode, node).getDiffuseColor())
+ batch.addItem(node.getWorldTransformation(), node.getMeshData(), uniforms = uniforms)
self.bind()
diff --git a/cura/PrinterOutput/FirmwareUpdater.py b/cura/PrinterOutput/FirmwareUpdater.py
index c6d9513ee0..56e260a7f0 100644
--- a/cura/PrinterOutput/FirmwareUpdater.py
+++ b/cura/PrinterOutput/FirmwareUpdater.py
@@ -9,7 +9,7 @@ from typing import Union
MYPY = False
if MYPY:
- from cura.PrinterOutputDevice import PrinterOutputDevice
+ from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
class FirmwareUpdater(QObject):
firmwareProgressChanged = pyqtSignal()
@@ -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/PrinterOutput/GenericOutputController.py b/cura/PrinterOutput/GenericOutputController.py
index 1cb416787c..c160459776 100644
--- a/cura/PrinterOutput/GenericOutputController.py
+++ b/cura/PrinterOutput/GenericOutputController.py
@@ -3,14 +3,15 @@
from typing import TYPE_CHECKING, Set, Union, Optional
-from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
from PyQt5.QtCore import QTimer
+from .PrinterOutputController import PrinterOutputController
+
if TYPE_CHECKING:
- from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
- from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
- from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
- from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel
+ from .Models.PrintJobOutputModel import PrintJobOutputModel
+ from .Models.PrinterOutputModel import PrinterOutputModel
+ from .PrinterOutputDevice import PrinterOutputDevice
+ from .Models.ExtruderOutputModel import ExtruderOutputModel
class GenericOutputController(PrinterOutputController):
@@ -54,7 +55,7 @@ class GenericOutputController(PrinterOutputController):
self._preheat_hotends_timer.stop()
for extruder in self._preheat_hotends:
extruder.updateIsPreheating(False)
- self._preheat_hotends = set() # type: Set[ExtruderOutputModel]
+ self._preheat_hotends = set()
def moveHead(self, printer: "PrinterOutputModel", x, y, z, speed) -> None:
self._output_device.sendCommand("G91")
@@ -158,7 +159,7 @@ class GenericOutputController(PrinterOutputController):
def _onPreheatHotendsTimerFinished(self) -> None:
for extruder in self._preheat_hotends:
self.setTargetHotendTemperature(extruder.getPrinter(), extruder.getPosition(), 0)
- self._preheat_hotends = set() #type: Set[ExtruderOutputModel]
+ self._preheat_hotends = set()
# Cancel any ongoing preheating timers, without setting back the temperature to 0
# This can be used eg at the start of a print
@@ -166,7 +167,7 @@ class GenericOutputController(PrinterOutputController):
if self._preheat_hotends_timer.isActive():
for extruder in self._preheat_hotends:
extruder.updateIsPreheating(False)
- self._preheat_hotends = set() #type: Set[ExtruderOutputModel]
+ self._preheat_hotends = set()
self._preheat_hotends_timer.stop()
diff --git a/cura/PrinterOutput/MaterialOutputModel.py b/cura/PrinterOutput/MaterialOutputModel.py
deleted file mode 100644
index 64ebd3c94c..0000000000
--- a/cura/PrinterOutput/MaterialOutputModel.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot
-
-
-class MaterialOutputModel(QObject):
- def __init__(self, guid, type, color, brand, name, parent = None):
- super().__init__(parent)
- self._guid = guid
- self._type = type
- self._color = color
- self._brand = brand
- self._name = name
-
- @pyqtProperty(str, constant = True)
- def guid(self):
- return self._guid
-
- @pyqtProperty(str, constant=True)
- def type(self):
- return self._type
-
- @pyqtProperty(str, constant=True)
- def brand(self):
- return self._brand
-
- @pyqtProperty(str, constant=True)
- def color(self):
- return self._color
-
- @pyqtProperty(str, constant=True)
- def name(self):
- return self._name
\ No newline at end of file
diff --git a/cura/PrinterOutput/ExtruderConfigurationModel.py b/cura/PrinterOutput/Models/ExtruderConfigurationModel.py
similarity index 70%
rename from cura/PrinterOutput/ExtruderConfigurationModel.py
rename to cura/PrinterOutput/Models/ExtruderConfigurationModel.py
index da0ad6b0b2..4a1cf4916f 100644
--- a/cura/PrinterOutput/ExtruderConfigurationModel.py
+++ b/cura/PrinterOutput/Models/ExtruderConfigurationModel.py
@@ -4,7 +4,7 @@ from typing import Optional
from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal
-from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
+from .MaterialOutputModel import MaterialOutputModel
class ExtruderConfigurationModel(QObject):
@@ -25,15 +25,16 @@ class ExtruderConfigurationModel(QObject):
return self._position
def setMaterial(self, material: Optional[MaterialOutputModel]) -> None:
- if self._hotend_id != material:
- self._material = material
- self.extruderConfigurationChanged.emit()
+ if material is None or self._material == material:
+ return
+ self._material = material
+ self.extruderConfigurationChanged.emit()
@pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged)
def activeMaterial(self) -> Optional[MaterialOutputModel]:
return self._material
- @pyqtProperty(QObject, fset=setMaterial, notify=extruderConfigurationChanged)
+ @pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged)
def material(self) -> Optional[MaterialOutputModel]:
return self._material
@@ -62,9 +63,26 @@ class ExtruderConfigurationModel(QObject):
return " ".join(message_chunks)
def __eq__(self, other) -> bool:
- return hash(self) == hash(other)
+ if not isinstance(other, ExtruderConfigurationModel):
+ return False
+
+ if self._position != other.position:
+ return False
+ # Empty materials should be ignored for comparison
+ if self.activeMaterial is not None and other.activeMaterial is not None:
+ if self.activeMaterial.guid != other.activeMaterial.guid:
+ if self.activeMaterial.guid != "" and other.activeMaterial.guid != "":
+ return False
+ else:
+ # At this point there is no material, so it doesn't matter what the hotend is.
+ return True
+
+ if self.hotendID != other.hotendID:
+ return False
+
+ return True
# Calculating a hash function using the position of the extruder, the material GUID and the hotend id to check if is
# unique within a set
def __hash__(self):
- return hash(self._position) ^ (hash(self._material.guid) if self._material is not None else hash(0)) ^ hash(self._hotend_id)
\ No newline at end of file
+ return hash(self._position) ^ (hash(self._material.guid) if self._material is not None else hash(0)) ^ hash(self._hotend_id)
diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/Models/ExtruderOutputModel.py
similarity index 95%
rename from cura/PrinterOutput/ExtruderOutputModel.py
rename to cura/PrinterOutput/Models/ExtruderOutputModel.py
index 30d53bbd85..889e140312 100644
--- a/cura/PrinterOutput/ExtruderOutputModel.py
+++ b/cura/PrinterOutput/Models/ExtruderOutputModel.py
@@ -1,14 +1,15 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot
-from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
-
from typing import Optional, TYPE_CHECKING
+from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot
+
+from .ExtruderConfigurationModel import ExtruderConfigurationModel
+
if TYPE_CHECKING:
- from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
- from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
+ from .MaterialOutputModel import MaterialOutputModel
+ from .PrinterOutputModel import PrinterOutputModel
class ExtruderOutputModel(QObject):
diff --git a/cura/PrinterOutput/Models/MaterialOutputModel.py b/cura/PrinterOutput/Models/MaterialOutputModel.py
new file mode 100644
index 0000000000..3714824a89
--- /dev/null
+++ b/cura/PrinterOutput/Models/MaterialOutputModel.py
@@ -0,0 +1,44 @@
+# Copyright (c) 2017 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Optional
+
+from PyQt5.QtCore import pyqtProperty, QObject
+
+
+class MaterialOutputModel(QObject):
+ def __init__(self, guid: Optional[str], type: str, color: str, brand: str, name: str, parent = None) -> None:
+ super().__init__(parent)
+ self._guid = guid
+ self._type = type
+ self._color = color
+ self._brand = brand
+ self._name = name
+
+ @pyqtProperty(str, constant = True)
+ def guid(self) -> str:
+ return self._guid if self._guid else ""
+
+ @pyqtProperty(str, constant = True)
+ def type(self) -> str:
+ return self._type
+
+ @pyqtProperty(str, constant = True)
+ def brand(self) -> str:
+ return self._brand
+
+ @pyqtProperty(str, constant = True)
+ def color(self) -> str:
+ return self._color
+
+ @pyqtProperty(str, constant = True)
+ def name(self) -> str:
+ return self._name
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if type(other) is not MaterialOutputModel:
+ return False
+
+ return self.guid == other.guid and self.type == other.type and self.brand == other.brand and self.color == other.color and self.name == other.name
diff --git a/cura/PrinterOutput/Models/PrintJobOutputModel.py b/cura/PrinterOutput/Models/PrintJobOutputModel.py
new file mode 100644
index 0000000000..b4296a5494
--- /dev/null
+++ b/cura/PrinterOutput/Models/PrintJobOutputModel.py
@@ -0,0 +1,171 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Optional, TYPE_CHECKING, List
+
+from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot, QUrl
+from PyQt5.QtGui import QImage
+
+if TYPE_CHECKING:
+ from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
+ from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
+ from cura.PrinterOutput.Models.PrinterConfigurationModel import PrinterConfigurationModel
+
+
+class PrintJobOutputModel(QObject):
+ stateChanged = pyqtSignal()
+ timeTotalChanged = pyqtSignal()
+ timeElapsedChanged = pyqtSignal()
+ nameChanged = pyqtSignal()
+ keyChanged = pyqtSignal()
+ assignedPrinterChanged = pyqtSignal()
+ ownerChanged = pyqtSignal()
+ configurationChanged = pyqtSignal()
+ previewImageChanged = pyqtSignal()
+ compatibleMachineFamiliesChanged = pyqtSignal()
+
+ def __init__(self, output_controller: "PrinterOutputController", key: str = "", name: str = "", parent = None) -> None:
+ super().__init__(parent)
+ self._output_controller = output_controller
+ self._state = ""
+ self._time_total = 0
+ self._time_elapsed = 0
+ self._name = name # Human readable name
+ self._key = key # Unique identifier
+ self._assigned_printer = None # type: Optional[PrinterOutputModel]
+ self._owner = "" # Who started/owns the print job?
+
+ self._configuration = None # type: Optional[PrinterConfigurationModel]
+ self._compatible_machine_families = [] # type: List[str]
+ self._preview_image_id = 0
+
+ self._preview_image = None # type: Optional[QImage]
+
+ @pyqtProperty("QStringList", notify=compatibleMachineFamiliesChanged)
+ def compatibleMachineFamilies(self):
+ # Hack; Some versions of cluster will return a family more than once...
+ return list(set(self._compatible_machine_families))
+
+ def setCompatibleMachineFamilies(self, compatible_machine_families: List[str]) -> None:
+ if self._compatible_machine_families != compatible_machine_families:
+ self._compatible_machine_families = compatible_machine_families
+ self.compatibleMachineFamiliesChanged.emit()
+
+ @pyqtProperty(QUrl, notify=previewImageChanged)
+ def previewImageUrl(self):
+ self._preview_image_id += 1
+ # There is an image provider that is called "print_job_preview". In order to ensure that the image qml object, that
+ # requires a QUrl to function, updates correctly we add an increasing number. This causes to see the QUrl
+ # as new (instead of relying on cached version and thus forces an update.
+ temp = "image://print_job_preview/" + str(self._preview_image_id) + "/" + self._key
+ return QUrl(temp, QUrl.TolerantMode)
+
+ def getPreviewImage(self) -> Optional[QImage]:
+ return self._preview_image
+
+ def updatePreviewImage(self, preview_image: Optional[QImage]) -> None:
+ if self._preview_image != preview_image:
+ self._preview_image = preview_image
+ self.previewImageChanged.emit()
+
+ @pyqtProperty(QObject, notify=configurationChanged)
+ def configuration(self) -> Optional["PrinterConfigurationModel"]:
+ return self._configuration
+
+ def updateConfiguration(self, configuration: Optional["PrinterConfigurationModel"]) -> None:
+ if self._configuration != configuration:
+ self._configuration = configuration
+ self.configurationChanged.emit()
+
+ @pyqtProperty(str, notify=ownerChanged)
+ def owner(self):
+ return self._owner
+
+ def updateOwner(self, owner):
+ if self._owner != owner:
+ self._owner = owner
+ self.ownerChanged.emit()
+
+ @pyqtProperty(QObject, notify=assignedPrinterChanged)
+ def assignedPrinter(self):
+ return self._assigned_printer
+
+ def updateAssignedPrinter(self, assigned_printer: Optional["PrinterOutputModel"]) -> None:
+ if self._assigned_printer != assigned_printer:
+ old_printer = self._assigned_printer
+ self._assigned_printer = assigned_printer
+ if old_printer is not None:
+ # If the previously assigned printer is set, this job is moved away from it.
+ old_printer.updateActivePrintJob(None)
+ self.assignedPrinterChanged.emit()
+
+ @pyqtProperty(str, notify=keyChanged)
+ def key(self):
+ return self._key
+
+ def updateKey(self, key: str):
+ if self._key != key:
+ self._key = key
+ self.keyChanged.emit()
+
+ @pyqtProperty(str, notify = nameChanged)
+ def name(self):
+ return self._name
+
+ def updateName(self, name: str):
+ if self._name != name:
+ self._name = name
+ self.nameChanged.emit()
+
+ @pyqtProperty(int, notify = timeTotalChanged)
+ def timeTotal(self) -> int:
+ return self._time_total
+
+ @pyqtProperty(int, notify = timeElapsedChanged)
+ def timeElapsed(self) -> int:
+ return self._time_elapsed
+
+ @pyqtProperty(int, notify = timeElapsedChanged)
+ def timeRemaining(self) -> int:
+ # Never get a negative time remaining
+ return max(self.timeTotal - self.timeElapsed, 0)
+
+ @pyqtProperty(float, notify = timeElapsedChanged)
+ def progress(self) -> float:
+ result = float(self.timeElapsed) / max(self.timeTotal, 1.0) # Prevent a division by zero exception.
+ return min(result, 1.0) # Never get a progress past 1.0
+
+ @pyqtProperty(str, notify=stateChanged)
+ def state(self) -> str:
+ return self._state
+
+ @pyqtProperty(bool, notify=stateChanged)
+ def isActive(self) -> bool:
+ inactive_states = [
+ "pausing",
+ "paused",
+ "resuming",
+ "wait_cleanup"
+ ]
+ if self.state in inactive_states and self.timeRemaining > 0:
+ return False
+ return True
+
+ def updateTimeTotal(self, new_time_total):
+ if self._time_total != new_time_total:
+ self._time_total = new_time_total
+ self.timeTotalChanged.emit()
+
+ def updateTimeElapsed(self, new_time_elapsed):
+ if self._time_elapsed != new_time_elapsed:
+ self._time_elapsed = new_time_elapsed
+ self.timeElapsedChanged.emit()
+
+ def updateState(self, new_state):
+ if self._state != new_state:
+ self._state = new_state
+ self.stateChanged.emit()
+
+ @pyqtSlot(str)
+ def setState(self, state):
+ self._output_controller.setJobState(self, state)
diff --git a/cura/PrinterOutput/ConfigurationModel.py b/cura/PrinterOutput/Models/PrinterConfigurationModel.py
similarity index 72%
rename from cura/PrinterOutput/ConfigurationModel.py
rename to cura/PrinterOutput/Models/PrinterConfigurationModel.py
index 312e3cffb0..52c7b6f960 100644
--- a/cura/PrinterOutput/ConfigurationModel.py
+++ b/cura/PrinterOutput/Models/PrinterConfigurationModel.py
@@ -6,10 +6,10 @@ from typing import List
MYPY = False
if MYPY:
- from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
+ from cura.PrinterOutput.Models.ExtruderConfigurationModel import ExtruderConfigurationModel
-class ConfigurationModel(QObject):
+class PrinterConfigurationModel(QObject):
configurationChanged = pyqtSignal()
@@ -19,14 +19,14 @@ class ConfigurationModel(QObject):
self._extruder_configurations = [] # type: List[ExtruderConfigurationModel]
self._buildplate_configuration = ""
- def setPrinterType(self, printer_type):
+ def setPrinterType(self, printer_type: str) -> None:
self._printer_type = printer_type
@pyqtProperty(str, fset = setPrinterType, notify = configurationChanged)
def printerType(self) -> str:
return self._printer_type
- def setExtruderConfigurations(self, extruder_configurations: List["ExtruderConfigurationModel"]):
+ def setExtruderConfigurations(self, extruder_configurations: List["ExtruderConfigurationModel"]) -> None:
if self._extruder_configurations != extruder_configurations:
self._extruder_configurations = extruder_configurations
@@ -40,7 +40,7 @@ class ConfigurationModel(QObject):
return self._extruder_configurations
def setBuildplateConfiguration(self, buildplate_configuration: str) -> None:
- if self._buildplate_configuration != buildplate_configuration:
+ if self._buildplate_configuration != buildplate_configuration:
self._buildplate_configuration = buildplate_configuration
self.configurationChanged.emit()
@@ -58,6 +58,14 @@ class ConfigurationModel(QObject):
return False
return self._printer_type != ""
+ def hasAnyMaterialLoaded(self) -> bool:
+ if not self.isValid():
+ return False
+ for configuration in self._extruder_configurations:
+ if configuration.activeMaterial and configuration.activeMaterial.type != "empty":
+ return True
+ return False
+
def __str__(self):
message_chunks = []
message_chunks.append("Printer type: " + self._printer_type)
@@ -71,7 +79,23 @@ class ConfigurationModel(QObject):
return "\n".join(message_chunks)
def __eq__(self, other):
- return hash(self) == hash(other)
+ if not isinstance(other, PrinterConfigurationModel):
+ return False
+
+ if self.printerType != other.printerType:
+ return False
+
+ if self.buildplateConfiguration != other.buildplateConfiguration:
+ return False
+
+ if len(self.extruderConfigurations) != len(other.extruderConfigurations):
+ return False
+
+ for self_extruder, other_extruder in zip(sorted(self._extruder_configurations, key=lambda x: x.position), sorted(other.extruderConfigurations, key=lambda x: x.position)):
+ if self_extruder != other_extruder:
+ return False
+
+ return True
## The hash function is used to compare and create unique sets. The configuration is unique if the configuration
# of the extruders is unique (the order of the extruders matters), and the type and buildplate is the same.
@@ -86,4 +110,4 @@ class ConfigurationModel(QObject):
if first_extruder:
extruder_hash &= hash(first_extruder)
- return hash(self._printer_type) ^ extruder_hash ^ hash(self._buildplate_configuration)
\ No newline at end of file
+ return hash(self._printer_type) ^ extruder_hash ^ hash(self._buildplate_configuration)
diff --git a/cura/PrinterOutput/Models/PrinterOutputModel.py b/cura/PrinterOutput/Models/PrinterOutputModel.py
new file mode 100644
index 0000000000..37135bf663
--- /dev/null
+++ b/cura/PrinterOutput/Models/PrinterOutputModel.py
@@ -0,0 +1,350 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot, QUrl
+from typing import List, Dict, Optional, TYPE_CHECKING
+from UM.Math.Vector import Vector
+from cura.PrinterOutput.Peripheral import Peripheral
+from cura.PrinterOutput.Models.PrinterConfigurationModel import PrinterConfigurationModel
+from cura.PrinterOutput.Models.ExtruderOutputModel import ExtruderOutputModel
+from UM.Logger import Logger
+
+if TYPE_CHECKING:
+ from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
+ from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
+
+
+class PrinterOutputModel(QObject):
+ bedTemperatureChanged = pyqtSignal()
+ targetBedTemperatureChanged = pyqtSignal()
+ isPreheatingChanged = pyqtSignal()
+ stateChanged = pyqtSignal()
+ activePrintJobChanged = pyqtSignal()
+ nameChanged = pyqtSignal()
+ headPositionChanged = pyqtSignal()
+ keyChanged = pyqtSignal()
+ typeChanged = pyqtSignal()
+ buildplateChanged = pyqtSignal()
+ cameraUrlChanged = pyqtSignal()
+ configurationChanged = pyqtSignal()
+ canUpdateFirmwareChanged = pyqtSignal()
+
+ def __init__(self, output_controller: "PrinterOutputController", number_of_extruders: int = 1, parent=None, firmware_version = "") -> None:
+ super().__init__(parent)
+ self._bed_temperature = -1 # type: float # Use -1 for no heated bed.
+ self._target_bed_temperature = 0 # type: float
+ self._name = ""
+ self._key = "" # Unique identifier
+ self._unique_name = "" # Unique name (used in Connect)
+ self._controller = output_controller
+ self._controller.canUpdateFirmwareChanged.connect(self._onControllerCanUpdateFirmwareChanged)
+ self._extruders = [ExtruderOutputModel(printer = self, position = i) for i in range(number_of_extruders)]
+ self._active_printer_configuration = PrinterConfigurationModel() # Indicates the current configuration setup in this printer
+ self._head_position = Vector(0, 0, 0)
+ self._active_print_job = None # type: Optional[PrintJobOutputModel]
+ self._firmware_version = firmware_version
+ self._printer_state = "unknown"
+ self._is_preheating = False
+ self._printer_type = ""
+ self._buildplate = ""
+ self._peripherals = [] # type: List[Peripheral]
+
+ self._active_printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in
+ self._extruders]
+ self._active_printer_configuration.configurationChanged.connect(self.configurationChanged)
+ self._available_printer_configurations = [] # type: List[PrinterConfigurationModel]
+
+ self._camera_url = QUrl() # type: QUrl
+
+ @pyqtProperty(str, constant = True)
+ def firmwareVersion(self) -> str:
+ return self._firmware_version
+
+ def setCameraUrl(self, camera_url: "QUrl") -> None:
+ if self._camera_url != camera_url:
+ self._camera_url = camera_url
+ self.cameraUrlChanged.emit()
+
+ @pyqtProperty(QUrl, fset = setCameraUrl, notify = cameraUrlChanged)
+ def cameraUrl(self) -> "QUrl":
+ return self._camera_url
+
+ def updateIsPreheating(self, pre_heating: bool) -> None:
+ if self._is_preheating != pre_heating:
+ self._is_preheating = pre_heating
+ self.isPreheatingChanged.emit()
+
+ @pyqtProperty(bool, notify=isPreheatingChanged)
+ def isPreheating(self) -> bool:
+ return self._is_preheating
+
+ @pyqtProperty(str, notify = typeChanged)
+ def type(self) -> str:
+ return self._printer_type
+
+ def updateType(self, printer_type: str) -> None:
+ if self._printer_type != printer_type:
+ self._printer_type = printer_type
+ self._active_printer_configuration.printerType = self._printer_type
+ self.typeChanged.emit()
+ self.configurationChanged.emit()
+
+ @pyqtProperty(str, notify = buildplateChanged)
+ def buildplate(self) -> str:
+ return self._buildplate
+
+ def updateBuildplate(self, buildplate: str) -> None:
+ if self._buildplate != buildplate:
+ self._buildplate = buildplate
+ self._active_printer_configuration.buildplateConfiguration = self._buildplate
+ self.buildplateChanged.emit()
+ self.configurationChanged.emit()
+
+ @pyqtProperty(str, notify=keyChanged)
+ def key(self) -> str:
+ return self._key
+
+ def updateKey(self, key: str) -> None:
+ if self._key != key:
+ self._key = key
+ self.keyChanged.emit()
+
+ @pyqtSlot()
+ def homeHead(self) -> None:
+ self._controller.homeHead(self)
+
+ @pyqtSlot()
+ def homeBed(self) -> None:
+ self._controller.homeBed(self)
+
+ @pyqtSlot(str)
+ def sendRawCommand(self, command: str) -> None:
+ self._controller.sendRawCommand(self, command)
+
+ @pyqtProperty("QVariantList", constant = True)
+ def extruders(self) -> List["ExtruderOutputModel"]:
+ return self._extruders
+
+ @pyqtProperty(QVariant, notify = headPositionChanged)
+ def headPosition(self) -> Dict[str, float]:
+ return {"x": self._head_position.x, "y": self._head_position.y, "z": self.head_position.z}
+
+ def updateHeadPosition(self, x: float, y: float, z: float) -> None:
+ if self._head_position.x != x or self._head_position.y != y or self._head_position.z != z:
+ self._head_position = Vector(x, y, z)
+ self.headPositionChanged.emit()
+
+ @pyqtProperty(float, float, float)
+ @pyqtProperty(float, float, float, float)
+ def setHeadPosition(self, x: float, y: float, z: float, speed: float = 3000) -> None:
+ self.updateHeadPosition(x, y, z)
+ self._controller.setHeadPosition(self, x, y, z, speed)
+
+ @pyqtProperty(float)
+ @pyqtProperty(float, float)
+ def setHeadX(self, x: float, speed: float = 3000) -> None:
+ self.updateHeadPosition(x, self._head_position.y, self._head_position.z)
+ self._controller.setHeadPosition(self, x, self._head_position.y, self._head_position.z, speed)
+
+ @pyqtProperty(float)
+ @pyqtProperty(float, float)
+ def setHeadY(self, y: float, speed: float = 3000) -> None:
+ self.updateHeadPosition(self._head_position.x, y, self._head_position.z)
+ self._controller.setHeadPosition(self, self._head_position.x, y, self._head_position.z, speed)
+
+ @pyqtProperty(float)
+ @pyqtProperty(float, float)
+ def setHeadZ(self, z: float, speed:float = 3000) -> None:
+ self.updateHeadPosition(self._head_position.x, self._head_position.y, z)
+ self._controller.setHeadPosition(self, self._head_position.x, self._head_position.y, z, speed)
+
+ @pyqtSlot(float, float, float)
+ @pyqtSlot(float, float, float, float)
+ def moveHead(self, x: float = 0, y: float = 0, z: float = 0, speed: float = 3000) -> None:
+ self._controller.moveHead(self, x, y, z, speed)
+
+ ## Pre-heats the heated bed of the printer.
+ #
+ # \param temperature The temperature to heat the bed to, in degrees
+ # Celsius.
+ # \param duration How long the bed should stay warm, in seconds.
+ @pyqtSlot(float, float)
+ def preheatBed(self, temperature: float, duration: float) -> None:
+ self._controller.preheatBed(self, temperature, duration)
+
+ @pyqtSlot()
+ def cancelPreheatBed(self) -> None:
+ self._controller.cancelPreheatBed(self)
+
+ def getController(self) -> "PrinterOutputController":
+ return self._controller
+
+ @pyqtProperty(str, notify = nameChanged)
+ def name(self) -> str:
+ return self._name
+
+ def setName(self, name: str) -> None:
+ self.updateName(name)
+
+ def updateName(self, name: str) -> None:
+ if self._name != name:
+ self._name = name
+ self.nameChanged.emit()
+
+ @pyqtProperty(str, notify = nameChanged)
+ def uniqueName(self) -> str:
+ return self._unique_name
+
+ def updateUniqueName(self, unique_name: str) -> None:
+ if self._unique_name != unique_name:
+ self._unique_name = unique_name
+ self.nameChanged.emit()
+
+ ## Update the bed temperature. This only changes it locally.
+ def updateBedTemperature(self, temperature: float) -> None:
+ if self._bed_temperature != temperature:
+ self._bed_temperature = temperature
+ self.bedTemperatureChanged.emit()
+
+ def updateTargetBedTemperature(self, temperature: float) -> None:
+ if self._target_bed_temperature != temperature:
+ self._target_bed_temperature = temperature
+ self.targetBedTemperatureChanged.emit()
+
+ ## Set the target bed temperature. This ensures that it's actually sent to the remote.
+ @pyqtSlot(float)
+ def setTargetBedTemperature(self, temperature: float) -> None:
+ self._controller.setTargetBedTemperature(self, temperature)
+ self.updateTargetBedTemperature(temperature)
+
+ def updateActivePrintJob(self, print_job: Optional["PrintJobOutputModel"]) -> None:
+ if self._active_print_job != print_job:
+ old_print_job = self._active_print_job
+
+ if print_job is not None:
+ print_job.updateAssignedPrinter(self)
+ self._active_print_job = print_job
+
+ if old_print_job is not None:
+ old_print_job.updateAssignedPrinter(None)
+ self.activePrintJobChanged.emit()
+
+ def updateState(self, printer_state: str) -> None:
+ if self._printer_state != printer_state:
+ self._printer_state = printer_state
+ self.stateChanged.emit()
+
+ @pyqtProperty(QObject, notify = activePrintJobChanged)
+ def activePrintJob(self) -> Optional["PrintJobOutputModel"]:
+ return self._active_print_job
+
+ @pyqtProperty(str, notify = stateChanged)
+ def state(self) -> str:
+ return self._printer_state
+
+ @pyqtProperty(float, notify = bedTemperatureChanged)
+ def bedTemperature(self) -> float:
+ return self._bed_temperature
+
+ @pyqtProperty(float, notify = targetBedTemperatureChanged)
+ def targetBedTemperature(self) -> float:
+ return self._target_bed_temperature
+
+ # Does the printer support pre-heating the bed at all
+ @pyqtProperty(bool, constant = True)
+ def canPreHeatBed(self) -> bool:
+ if self._controller:
+ return self._controller.can_pre_heat_bed
+ return False
+
+ # Does the printer support pre-heating the bed at all
+ @pyqtProperty(bool, constant = True)
+ def canPreHeatHotends(self) -> bool:
+ if self._controller:
+ return self._controller.can_pre_heat_hotends
+ return False
+
+ # Does the printer support sending raw G-code at all
+ @pyqtProperty(bool, constant = True)
+ def canSendRawGcode(self) -> bool:
+ if self._controller:
+ return self._controller.can_send_raw_gcode
+ return False
+
+ # Does the printer support pause at all
+ @pyqtProperty(bool, constant = True)
+ def canPause(self) -> bool:
+ if self._controller:
+ return self._controller.can_pause
+ return False
+
+ # Does the printer support abort at all
+ @pyqtProperty(bool, constant = True)
+ def canAbort(self) -> bool:
+ if self._controller:
+ return self._controller.can_abort
+ return False
+
+ # Does the printer support manual control at all
+ @pyqtProperty(bool, constant = True)
+ def canControlManually(self) -> bool:
+ if self._controller:
+ return self._controller.can_control_manually
+ return False
+
+ # Does the printer support upgrading firmware
+ @pyqtProperty(bool, notify = canUpdateFirmwareChanged)
+ def canUpdateFirmware(self) -> bool:
+ if self._controller:
+ return self._controller.can_update_firmware
+ return False
+
+ # Stub to connect UM.Signal to pyqtSignal
+ def _onControllerCanUpdateFirmwareChanged(self) -> None:
+ self.canUpdateFirmwareChanged.emit()
+
+ # Returns the active configuration (material, variant and buildplate) of the current printer
+ @pyqtProperty(QObject, notify = configurationChanged)
+ def printerConfiguration(self) -> Optional[PrinterConfigurationModel]:
+ if self._active_printer_configuration.isValid():
+ return self._active_printer_configuration
+ return None
+
+ peripheralsChanged = pyqtSignal()
+
+ @pyqtProperty(str, notify = peripheralsChanged)
+ def peripherals(self) -> str:
+ return ", ".join([peripheral.name for peripheral in self._peripherals])
+
+ def addPeripheral(self, peripheral: Peripheral) -> None:
+ self._peripherals.append(peripheral)
+ self.peripheralsChanged.emit()
+
+ def removePeripheral(self, peripheral: Peripheral) -> None:
+ self._peripherals.remove(peripheral)
+ self.peripheralsChanged.emit()
+
+ availableConfigurationsChanged = pyqtSignal()
+
+ # The availableConfigurations are configuration options that a printer can switch to, but doesn't currently have
+ # active (eg; Automatic tool changes, material loaders, etc).
+ @pyqtProperty("QVariantList", notify = availableConfigurationsChanged)
+ def availableConfigurations(self) -> List[PrinterConfigurationModel]:
+ return self._available_printer_configurations
+
+ def addAvailableConfiguration(self, new_configuration: PrinterConfigurationModel) -> None:
+ if new_configuration not in self._available_printer_configurations:
+ self._available_printer_configurations.append(new_configuration)
+ self.availableConfigurationsChanged.emit()
+
+ def removeAvailableConfiguration(self, config_to_remove: PrinterConfigurationModel) -> None:
+ try:
+ self._available_printer_configurations.remove(config_to_remove)
+ except ValueError:
+ Logger.log("w", "Unable to remove configuration that isn't in the list of available configurations")
+ else:
+ self.availableConfigurationsChanged.emit()
+
+ def setAvailableConfigurations(self, new_configurations: List[PrinterConfigurationModel]) -> None:
+ self._available_printer_configurations = new_configurations
+ self.availableConfigurationsChanged.emit()
diff --git a/cura/PrinterOutput/Models/__init__.py b/cura/PrinterOutput/Models/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py
index bbeb87d5e3..60be5bc8f3 100644
--- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py
+++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py
@@ -7,7 +7,7 @@ from UM.Scene.SceneNode import SceneNode #For typing.
from cura.API import Account
from cura.CuraApplication import CuraApplication
-from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType
+from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType
from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication
@@ -18,6 +18,8 @@ from enum import IntEnum
import os # To get the username
import gzip
+from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
+
class AuthState(IntEnum):
NotAuthenticated = 1
@@ -33,8 +35,6 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], connection_type: ConnectionType = ConnectionType.NetworkConnection, parent: QObject = None) -> None:
super().__init__(device_id = device_id, connection_type = connection_type, parent = parent)
self._manager = None # type: Optional[QNetworkAccessManager]
- self._last_manager_create_time = None # type: Optional[float]
- self._recreate_network_manager_time = 30
self._timeout_time = 10 # After how many seconds of no response should a timeout occur?
self._last_response_time = None # type: Optional[float]
@@ -58,8 +58,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
self._gcode = [] # type: List[str]
self._connection_state_before_timeout = None # type: Optional[ConnectionState]
- def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False,
- file_handler: Optional[FileHandler] = None, **kwargs: str) -> None:
+ def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, limit_mimetypes: bool = False,
+ file_handler: Optional["FileHandler"] = None, filter_by_machine: bool = False, **kwargs) -> None:
raise NotImplementedError("requestWrite needs to be implemented")
def setAuthenticationState(self, authentication_state: AuthState) -> None:
@@ -131,12 +131,6 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
self.setConnectionState(ConnectionState.Closed)
- # We need to check if the manager needs to be re-created. If we don't, we get some issues when OSX goes to
- # sleep.
- if time_since_last_response > self._recreate_network_manager_time:
- if self._last_manager_create_time is None or time() - self._last_manager_create_time > self._recreate_network_manager_time:
- self._createNetworkManager()
- assert(self._manager is not None)
elif self._connection_state == ConnectionState.Closed:
# Go out of timeout.
if self._connection_state_before_timeout is not None: # sanity check, but it should never be None here
@@ -160,7 +154,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
part = QHttpPart()
if not content_header.startswith("form-data;"):
- content_header = "form_data; " + content_header
+ content_header = "form-data; " + content_header
part.setHeader(QNetworkRequest.ContentDispositionHeader, content_header)
if content_type is not None:
@@ -310,22 +304,36 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
def _createNetworkManager(self) -> None:
Logger.log("d", "Creating network manager")
if self._manager:
- self._manager.finished.disconnect(self.__handleOnFinished)
+ self._manager.finished.disconnect(self._handleOnFinished)
self._manager.authenticationRequired.disconnect(self._onAuthenticationRequired)
self._manager = QNetworkAccessManager()
- self._manager.finished.connect(self.__handleOnFinished)
- self._last_manager_create_time = time()
+ self._manager.finished.connect(self._handleOnFinished)
self._manager.authenticationRequired.connect(self._onAuthenticationRequired)
if self._properties.get(b"temporary", b"false") != b"true":
- CuraApplication.getInstance().getMachineManager().checkCorrectGroupName(self.getId(), self.name)
+ self._checkCorrectGroupName(self.getId(), self.name)
def _registerOnFinishedCallback(self, reply: QNetworkReply, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None:
if on_finished is not None:
self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = on_finished
- def __handleOnFinished(self, reply: QNetworkReply) -> None:
+ ## This method checks if the name of the group stored in the definition container is correct.
+ # After updating from 3.2 to 3.3 some group names may be temporary. If there is a mismatch in the name of the group
+ # then all the container stacks are updated, both the current and the hidden ones.
+ def _checkCorrectGroupName(self, device_id: str, group_name: str) -> None:
+ global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
+ active_machine_network_name = CuraApplication.getInstance().getMachineManager().activeMachineNetworkKey()
+ if global_container_stack and device_id == active_machine_network_name:
+ # Check if the group_name is correct. If not, update all the containers connected to the same printer
+ if CuraApplication.getInstance().getMachineManager().activeMachineNetworkGroupName != group_name:
+ metadata_filter = {"um_network_key": active_machine_network_name}
+ containers = CuraContainerRegistry.getInstance().findContainerStacks(type="machine",
+ **metadata_filter)
+ for container in containers:
+ container.setMetaDataEntry("group_name", group_name)
+
+ def _handleOnFinished(self, reply: QNetworkReply) -> None:
# Due to garbage collection, we need to cache certain bits of post operations.
# As we don't want to keep them around forever, delete them if we get a reply.
if reply.operation() == QNetworkAccessManager.PostOperation:
diff --git a/cura/PrinterOutput/Peripheral.py b/cura/PrinterOutput/Peripheral.py
new file mode 100644
index 0000000000..2693b82c36
--- /dev/null
+++ b/cura/PrinterOutput/Peripheral.py
@@ -0,0 +1,16 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+
+## Data class that represents a peripheral for a printer.
+#
+# Output device plug-ins may specify that the printer has a certain set of
+# peripherals. This set is then possibly shown in the interface of the monitor
+# stage.
+class Peripheral:
+ ## Constructs the peripheral.
+ # \param type A unique ID for the type of peripheral.
+ # \param name A human-readable name for the peripheral.
+ def __init__(self, peripheral_type: str, name: str) -> None:
+ self.type = peripheral_type
+ self.name = name
diff --git a/cura/PrinterOutput/PrintJobOutputModel.py b/cura/PrinterOutput/PrintJobOutputModel.py
index fb163ef065..df66412df3 100644
--- a/cura/PrinterOutput/PrintJobOutputModel.py
+++ b/cura/PrinterOutput/PrintJobOutputModel.py
@@ -1,172 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot
-from typing import Optional, TYPE_CHECKING, List
-
-from PyQt5.QtCore import QUrl
-from PyQt5.QtGui import QImage
-
-if TYPE_CHECKING:
- from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
- from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
- from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
-
-
-class PrintJobOutputModel(QObject):
- stateChanged = pyqtSignal()
- timeTotalChanged = pyqtSignal()
- timeElapsedChanged = pyqtSignal()
- nameChanged = pyqtSignal()
- keyChanged = pyqtSignal()
- assignedPrinterChanged = pyqtSignal()
- ownerChanged = pyqtSignal()
- configurationChanged = pyqtSignal()
- previewImageChanged = pyqtSignal()
- compatibleMachineFamiliesChanged = pyqtSignal()
-
- def __init__(self, output_controller: "PrinterOutputController", key: str = "", name: str = "", parent=None) -> None:
- super().__init__(parent)
- self._output_controller = output_controller
- self._state = ""
- self._time_total = 0
- self._time_elapsed = 0
- self._name = name # Human readable name
- self._key = key # Unique identifier
- self._assigned_printer = None # type: Optional[PrinterOutputModel]
- self._owner = "" # Who started/owns the print job?
-
- self._configuration = None # type: Optional[ConfigurationModel]
- self._compatible_machine_families = [] # type: List[str]
- self._preview_image_id = 0
-
- self._preview_image = None # type: Optional[QImage]
-
- @pyqtProperty("QStringList", notify=compatibleMachineFamiliesChanged)
- def compatibleMachineFamilies(self):
- # Hack; Some versions of cluster will return a family more than once...
- return list(set(self._compatible_machine_families))
-
- def setCompatibleMachineFamilies(self, compatible_machine_families: List[str]) -> None:
- if self._compatible_machine_families != compatible_machine_families:
- self._compatible_machine_families = compatible_machine_families
- self.compatibleMachineFamiliesChanged.emit()
-
- @pyqtProperty(QUrl, notify=previewImageChanged)
- def previewImageUrl(self):
- self._preview_image_id += 1
- # There is an image provider that is called "print_job_preview". In order to ensure that the image qml object, that
- # requires a QUrl to function, updates correctly we add an increasing number. This causes to see the QUrl
- # as new (instead of relying on cached version and thus forces an update.
- temp = "image://print_job_preview/" + str(self._preview_image_id) + "/" + self._key
- return QUrl(temp, QUrl.TolerantMode)
-
- def getPreviewImage(self) -> Optional[QImage]:
- return self._preview_image
-
- def updatePreviewImage(self, preview_image: Optional[QImage]) -> None:
- if self._preview_image != preview_image:
- self._preview_image = preview_image
- self.previewImageChanged.emit()
-
- @pyqtProperty(QObject, notify=configurationChanged)
- def configuration(self) -> Optional["ConfigurationModel"]:
- return self._configuration
-
- def updateConfiguration(self, configuration: Optional["ConfigurationModel"]) -> None:
- if self._configuration != configuration:
- self._configuration = configuration
- self.configurationChanged.emit()
-
- @pyqtProperty(str, notify=ownerChanged)
- def owner(self):
- return self._owner
-
- def updateOwner(self, owner):
- if self._owner != owner:
- self._owner = owner
- self.ownerChanged.emit()
-
- @pyqtProperty(QObject, notify=assignedPrinterChanged)
- def assignedPrinter(self):
- return self._assigned_printer
-
- def updateAssignedPrinter(self, assigned_printer: Optional["PrinterOutputModel"]) -> None:
- if self._assigned_printer != assigned_printer:
- old_printer = self._assigned_printer
- self._assigned_printer = assigned_printer
- if old_printer is not None:
- # If the previously assigned printer is set, this job is moved away from it.
- old_printer.updateActivePrintJob(None)
- self.assignedPrinterChanged.emit()
-
- @pyqtProperty(str, notify=keyChanged)
- def key(self):
- return self._key
-
- def updateKey(self, key: str):
- if self._key != key:
- self._key = key
- self.keyChanged.emit()
-
- @pyqtProperty(str, notify = nameChanged)
- def name(self):
- return self._name
-
- def updateName(self, name: str):
- if self._name != name:
- self._name = name
- self.nameChanged.emit()
-
- @pyqtProperty(int, notify = timeTotalChanged)
- def timeTotal(self) -> int:
- return self._time_total
-
- @pyqtProperty(int, notify = timeElapsedChanged)
- def timeElapsed(self) -> int:
- return self._time_elapsed
-
- @pyqtProperty(int, notify = timeElapsedChanged)
- def timeRemaining(self) -> int:
- # Never get a negative time remaining
- return max(self.timeTotal - self.timeElapsed, 0)
-
- @pyqtProperty(float, notify = timeElapsedChanged)
- def progress(self) -> float:
- result = float(self.timeElapsed) / max(self.timeTotal, 1.0) # Prevent a division by zero exception.
- return min(result, 1.0) # Never get a progress past 1.0
-
- @pyqtProperty(str, notify=stateChanged)
- def state(self) -> str:
- return self._state
-
- @pyqtProperty(bool, notify=stateChanged)
- def isActive(self) -> bool:
- inactiveStates = [
- "pausing",
- "paused",
- "resuming",
- "wait_cleanup"
- ]
- if self.state in inactiveStates and self.timeRemaining > 0:
- return False
- return True
-
- def updateTimeTotal(self, new_time_total):
- if self._time_total != new_time_total:
- self._time_total = new_time_total
- self.timeTotalChanged.emit()
-
- def updateTimeElapsed(self, new_time_elapsed):
- if self._time_elapsed != new_time_elapsed:
- self._time_elapsed = new_time_elapsed
- self.timeElapsedChanged.emit()
-
- def updateState(self, new_state):
- if self._state != new_state:
- self._state = new_state
- self.stateChanged.emit()
-
- @pyqtSlot(str)
- def setState(self, state):
- self._output_controller.setJobState(self, state)
+import warnings
+warnings.warn("Importing cura.PrinterOutput.PrintJobOutputModel has been deprecated since 4.1, use cura.PrinterOutput.Models.PrintJobOutputModel instead", DeprecationWarning, stacklevel=2)
+# We moved the the models to one submodule deeper
+from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
\ No newline at end of file
diff --git a/cura/PrinterOutput/PrinterOutputController.py b/cura/PrinterOutput/PrinterOutputController.py
index aa06ada8a3..3d710582ca 100644
--- a/cura/PrinterOutput/PrinterOutputController.py
+++ b/cura/PrinterOutput/PrinterOutputController.py
@@ -4,14 +4,12 @@
from UM.Logger import Logger
from UM.Signal import Signal
-from typing import Union
-
MYPY = False
if MYPY:
- from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
- from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel
- from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
- from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
+ from .Models.PrintJobOutputModel import PrintJobOutputModel
+ from .Models.ExtruderOutputModel import ExtruderOutputModel
+ from .Models.PrinterOutputModel import PrinterOutputModel
+ from .PrinterOutputDevice import PrinterOutputDevice
class PrinterOutputController:
diff --git a/cura/PrinterOutput/PrinterOutputDevice.py b/cura/PrinterOutput/PrinterOutputDevice.py
new file mode 100644
index 0000000000..b05e76ad2e
--- /dev/null
+++ b/cura/PrinterOutput/PrinterOutputDevice.py
@@ -0,0 +1,264 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from enum import IntEnum
+from typing import Callable, List, Optional, Union
+
+from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl
+from PyQt5.QtWidgets import QMessageBox
+
+from UM.Logger import Logger
+from UM.Signal import signalemitter
+from UM.Qt.QtApplication import QtApplication
+from UM.FlameProfiler import pyqtSlot
+from UM.i18n import i18nCatalog
+from UM.OutputDevice.OutputDevice import OutputDevice
+
+MYPY = False
+if MYPY:
+ from UM.FileHandler.FileHandler import FileHandler
+ from UM.Scene.SceneNode import SceneNode
+ from .Models.PrinterOutputModel import PrinterOutputModel
+ from .Models.PrinterConfigurationModel import PrinterConfigurationModel
+ from .FirmwareUpdater import FirmwareUpdater
+
+i18n_catalog = i18nCatalog("cura")
+
+
+## The current processing state of the backend.
+class ConnectionState(IntEnum):
+ Closed = 0
+ Connecting = 1
+ Connected = 2
+ Busy = 3
+ Error = 4
+
+
+class ConnectionType(IntEnum):
+ NotConnected = 0
+ UsbConnection = 1
+ NetworkConnection = 2
+ CloudConnection = 3
+
+
+## Printer output device adds extra interface options on top of output device.
+#
+# The assumption is made the printer is a FDM printer.
+#
+# Note that a number of settings are marked as "final". This is because decorators
+# are not inherited by children. To fix this we use the private counter part of those
+# functions to actually have the implementation.
+#
+# For all other uses it should be used in the same way as a "regular" OutputDevice.
+@signalemitter
+class PrinterOutputDevice(QObject, OutputDevice):
+
+ printersChanged = pyqtSignal()
+ connectionStateChanged = pyqtSignal(str)
+ acceptsCommandsChanged = pyqtSignal()
+
+ # Signal to indicate that the material of the active printer on the remote changed.
+ materialIdChanged = pyqtSignal()
+
+ # # Signal to indicate that the hotend of the active printer on the remote changed.
+ hotendIdChanged = pyqtSignal()
+
+ # Signal to indicate that the info text about the connection has changed.
+ connectionTextChanged = pyqtSignal()
+
+ # Signal to indicate that the configuration of one of the printers has changed.
+ uniqueConfigurationsChanged = pyqtSignal()
+
+ def __init__(self, device_id: str, connection_type: "ConnectionType" = ConnectionType.NotConnected, parent: QObject = None) -> None:
+ super().__init__(device_id = device_id, parent = parent) # type: ignore # MyPy complains with the multiple inheritance
+
+ self._printers = [] # type: List[PrinterOutputModel]
+ self._unique_configurations = [] # type: List[PrinterConfigurationModel]
+
+ self._monitor_view_qml_path = "" # type: str
+ self._monitor_component = None # type: Optional[QObject]
+ self._monitor_item = None # type: Optional[QObject]
+
+ self._control_view_qml_path = "" # type: str
+ self._control_component = None # type: Optional[QObject]
+ self._control_item = None # type: Optional[QObject]
+
+ self._accepts_commands = False # type: bool
+
+ self._update_timer = QTimer() # type: QTimer
+ self._update_timer.setInterval(2000) # TODO; Add preference for update interval
+ self._update_timer.setSingleShot(False)
+ self._update_timer.timeout.connect(self._update)
+
+ self._connection_state = ConnectionState.Closed # type: ConnectionState
+ self._connection_type = connection_type # type: ConnectionType
+
+ self._firmware_updater = None # type: Optional[FirmwareUpdater]
+ self._firmware_name = None # type: Optional[str]
+ self._address = "" # type: str
+ self._connection_text = "" # type: str
+ self.printersChanged.connect(self._onPrintersChanged)
+ QtApplication.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._updateUniqueConfigurations)
+
+ @pyqtProperty(str, notify = connectionTextChanged)
+ def address(self) -> str:
+ return self._address
+
+ def setConnectionText(self, connection_text):
+ if self._connection_text != connection_text:
+ self._connection_text = connection_text
+ self.connectionTextChanged.emit()
+
+ @pyqtProperty(str, constant=True)
+ def connectionText(self) -> str:
+ return self._connection_text
+
+ def materialHotendChangedMessage(self, callback: Callable[[int], None]) -> None:
+ Logger.log("w", "materialHotendChangedMessage needs to be implemented, returning 'Yes'")
+ callback(QMessageBox.Yes)
+
+ def isConnected(self) -> bool:
+ return self._connection_state != ConnectionState.Closed and self._connection_state != ConnectionState.Error
+
+ def setConnectionState(self, connection_state: "ConnectionState") -> None:
+ if self._connection_state != connection_state:
+ self._connection_state = connection_state
+ self.connectionStateChanged.emit(self._id)
+
+ @pyqtProperty(int, constant = True)
+ def connectionType(self) -> "ConnectionType":
+ return self._connection_type
+
+ @pyqtProperty(int, notify = connectionStateChanged)
+ def connectionState(self) -> "ConnectionState":
+ return self._connection_state
+
+ def _update(self) -> None:
+ pass
+
+ def _getPrinterByKey(self, key: str) -> Optional["PrinterOutputModel"]:
+ for printer in self._printers:
+ if printer.key == key:
+ return printer
+
+ return None
+
+ def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, limit_mimetypes: bool = False,
+ file_handler: Optional["FileHandler"] = None, filter_by_machine: bool = False, **kwargs) -> None:
+ raise NotImplementedError("requestWrite needs to be implemented")
+
+ @pyqtProperty(QObject, notify = printersChanged)
+ def activePrinter(self) -> Optional["PrinterOutputModel"]:
+ if len(self._printers):
+ return self._printers[0]
+ return None
+
+ @pyqtProperty("QVariantList", notify = printersChanged)
+ def printers(self) -> List["PrinterOutputModel"]:
+ return self._printers
+
+ @pyqtProperty(QObject, constant = True)
+ def monitorItem(self) -> QObject:
+ # Note that we specifically only check if the monitor component is created.
+ # It could be that it failed to actually create the qml item! If we check if the item was created, it will try to
+ # create the item (and fail) every time.
+ if not self._monitor_component:
+ self._createMonitorViewFromQML()
+ return self._monitor_item
+
+ @pyqtProperty(QObject, constant = True)
+ def controlItem(self) -> QObject:
+ if not self._control_component:
+ self._createControlViewFromQML()
+ return self._control_item
+
+ def _createControlViewFromQML(self) -> None:
+ if not self._control_view_qml_path:
+ return
+ if self._control_item is None:
+ self._control_item = QtApplication.getInstance().createQmlComponent(self._control_view_qml_path, {"OutputDevice": self})
+
+ def _createMonitorViewFromQML(self) -> None:
+ if not self._monitor_view_qml_path:
+ return
+
+ if self._monitor_item is None:
+ self._monitor_item = QtApplication.getInstance().createQmlComponent(self._monitor_view_qml_path, {"OutputDevice": self})
+
+ ## Attempt to establish connection
+ def connect(self) -> None:
+ self.setConnectionState(ConnectionState.Connecting)
+ self._update_timer.start()
+
+ ## Attempt to close the connection
+ def close(self) -> None:
+ self._update_timer.stop()
+ self.setConnectionState(ConnectionState.Closed)
+
+ ## Ensure that close gets called when object is destroyed
+ def __del__(self) -> None:
+ self.close()
+
+ @pyqtProperty(bool, notify = acceptsCommandsChanged)
+ def acceptsCommands(self) -> bool:
+ return self._accepts_commands
+
+ ## Set a flag to signal the UI that the printer is not (yet) ready to receive commands
+ def _setAcceptsCommands(self, accepts_commands: bool) -> None:
+ if self._accepts_commands != accepts_commands:
+ self._accepts_commands = accepts_commands
+
+ self.acceptsCommandsChanged.emit()
+
+ # Returns the unique configurations of the printers within this output device
+ @pyqtProperty("QVariantList", notify = uniqueConfigurationsChanged)
+ def uniqueConfigurations(self) -> List["PrinterConfigurationModel"]:
+ return self._unique_configurations
+
+ def _updateUniqueConfigurations(self) -> None:
+ all_configurations = set()
+ for printer in self._printers:
+ if printer.printerConfiguration is not None and printer.printerConfiguration.hasAnyMaterialLoaded():
+ all_configurations.add(printer.printerConfiguration)
+ all_configurations.update(printer.availableConfigurations)
+ if None in all_configurations: # Shouldn't happen, but it does. I don't see how it could ever happen. Skip adding that configuration. List could end up empty!
+ Logger.log("e", "Found a broken configuration in the synced list!")
+ all_configurations.remove(None)
+ new_configurations = sorted(all_configurations, key = lambda config: config.printerType or "")
+ if new_configurations != self._unique_configurations:
+ self._unique_configurations = new_configurations
+ self.uniqueConfigurationsChanged.emit()
+
+ # Returns the unique configurations of the printers within this output device
+ @pyqtProperty("QStringList", notify = uniqueConfigurationsChanged)
+ def uniquePrinterTypes(self) -> List[str]:
+ return list(sorted(set([configuration.printerType or "" for configuration in self._unique_configurations])))
+
+ def _onPrintersChanged(self) -> None:
+ for printer in self._printers:
+ printer.configurationChanged.connect(self._updateUniqueConfigurations)
+ printer.availableConfigurationsChanged.connect(self._updateUniqueConfigurations)
+
+ # At this point there may be non-updated configurations
+ self._updateUniqueConfigurations()
+
+ ## Set the device firmware name
+ #
+ # \param name The name of the firmware.
+ def _setFirmwareName(self, name: str) -> None:
+ self._firmware_name = name
+
+ ## Get the name of device firmware
+ #
+ # This name can be used to define device type
+ def getFirmwareName(self) -> Optional[str]:
+ return self._firmware_name
+
+ def getFirmwareUpdater(self) -> Optional["FirmwareUpdater"]:
+ return self._firmware_updater
+
+ @pyqtSlot(str)
+ def updateFirmware(self, firmware_file: Union[str, QUrl]) -> None:
+ if not self._firmware_updater:
+ return
+
+ self._firmware_updater.updateFirmware(firmware_file)
diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py
index 12884b5f9b..87020ce2d0 100644
--- a/cura/PrinterOutput/PrinterOutputModel.py
+++ b/cura/PrinterOutput/PrinterOutputModel.py
@@ -1,297 +1,4 @@
-# Copyright (c) 2019 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot, QUrl
-from typing import List, Dict, Optional
-from UM.Math.Vector import Vector
-from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
-from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel
-
-MYPY = False
-if MYPY:
- from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
- from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
-
-
-class PrinterOutputModel(QObject):
- bedTemperatureChanged = pyqtSignal()
- targetBedTemperatureChanged = pyqtSignal()
- isPreheatingChanged = pyqtSignal()
- stateChanged = pyqtSignal()
- activePrintJobChanged = pyqtSignal()
- nameChanged = pyqtSignal()
- headPositionChanged = pyqtSignal()
- keyChanged = pyqtSignal()
- typeChanged = pyqtSignal()
- buildplateChanged = pyqtSignal()
- cameraUrlChanged = pyqtSignal()
- configurationChanged = pyqtSignal()
- canUpdateFirmwareChanged = pyqtSignal()
-
- def __init__(self, output_controller: "PrinterOutputController", number_of_extruders: int = 1, parent=None, firmware_version = "") -> None:
- super().__init__(parent)
- self._bed_temperature = -1 # type: float # Use -1 for no heated bed.
- self._target_bed_temperature = 0 # type: float
- self._name = ""
- self._key = "" # Unique identifier
- self._controller = output_controller
- self._controller.canUpdateFirmwareChanged.connect(self._onControllerCanUpdateFirmwareChanged)
- self._extruders = [ExtruderOutputModel(printer = self, position = i) for i in range(number_of_extruders)]
- self._printer_configuration = ConfigurationModel() # Indicates the current configuration setup in this printer
- self._head_position = Vector(0, 0, 0)
- self._active_print_job = None # type: Optional[PrintJobOutputModel]
- self._firmware_version = firmware_version
- self._printer_state = "unknown"
- self._is_preheating = False
- self._printer_type = ""
- self._buildplate = ""
-
- self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in
- self._extruders]
-
- self._camera_url = QUrl() # type: QUrl
-
- @pyqtProperty(str, constant = True)
- def firmwareVersion(self) -> str:
- return self._firmware_version
-
- def setCameraUrl(self, camera_url: "QUrl") -> None:
- if self._camera_url != camera_url:
- self._camera_url = camera_url
- self.cameraUrlChanged.emit()
-
- @pyqtProperty(QUrl, fset = setCameraUrl, notify = cameraUrlChanged)
- def cameraUrl(self) -> "QUrl":
- return self._camera_url
-
- def updateIsPreheating(self, pre_heating: bool) -> None:
- if self._is_preheating != pre_heating:
- self._is_preheating = pre_heating
- self.isPreheatingChanged.emit()
-
- @pyqtProperty(bool, notify=isPreheatingChanged)
- def isPreheating(self) -> bool:
- return self._is_preheating
-
- @pyqtProperty(str, notify = typeChanged)
- def type(self) -> str:
- return self._printer_type
-
- def updateType(self, printer_type: str) -> None:
- if self._printer_type != printer_type:
- self._printer_type = printer_type
- self._printer_configuration.printerType = self._printer_type
- self.typeChanged.emit()
- self.configurationChanged.emit()
-
- @pyqtProperty(str, notify = buildplateChanged)
- def buildplate(self) -> str:
- return self._buildplate
-
- def updateBuildplate(self, buildplate: str) -> None:
- if self._buildplate != buildplate:
- self._buildplate = buildplate
- self._printer_configuration.buildplateConfiguration = self._buildplate
- self.buildplateChanged.emit()
- self.configurationChanged.emit()
-
- @pyqtProperty(str, notify=keyChanged)
- def key(self) -> str:
- return self._key
-
- def updateKey(self, key: str) -> None:
- if self._key != key:
- self._key = key
- self.keyChanged.emit()
-
- @pyqtSlot()
- def homeHead(self) -> None:
- self._controller.homeHead(self)
-
- @pyqtSlot()
- def homeBed(self) -> None:
- self._controller.homeBed(self)
-
- @pyqtSlot(str)
- def sendRawCommand(self, command: str) -> None:
- self._controller.sendRawCommand(self, command)
-
- @pyqtProperty("QVariantList", constant = True)
- def extruders(self) -> List["ExtruderOutputModel"]:
- return self._extruders
-
- @pyqtProperty(QVariant, notify = headPositionChanged)
- def headPosition(self) -> Dict[str, float]:
- return {"x": self._head_position.x, "y": self._head_position.y, "z": self.head_position.z}
-
- def updateHeadPosition(self, x: float, y: float, z: float) -> None:
- if self._head_position.x != x or self._head_position.y != y or self._head_position.z != z:
- self._head_position = Vector(x, y, z)
- self.headPositionChanged.emit()
-
- @pyqtProperty(float, float, float)
- @pyqtProperty(float, float, float, float)
- def setHeadPosition(self, x: float, y: float, z: float, speed: float = 3000) -> None:
- self.updateHeadPosition(x, y, z)
- self._controller.setHeadPosition(self, x, y, z, speed)
-
- @pyqtProperty(float)
- @pyqtProperty(float, float)
- def setHeadX(self, x: float, speed: float = 3000) -> None:
- self.updateHeadPosition(x, self._head_position.y, self._head_position.z)
- self._controller.setHeadPosition(self, x, self._head_position.y, self._head_position.z, speed)
-
- @pyqtProperty(float)
- @pyqtProperty(float, float)
- def setHeadY(self, y: float, speed: float = 3000) -> None:
- self.updateHeadPosition(self._head_position.x, y, self._head_position.z)
- self._controller.setHeadPosition(self, self._head_position.x, y, self._head_position.z, speed)
-
- @pyqtProperty(float)
- @pyqtProperty(float, float)
- def setHeadZ(self, z: float, speed:float = 3000) -> None:
- self.updateHeadPosition(self._head_position.x, self._head_position.y, z)
- self._controller.setHeadPosition(self, self._head_position.x, self._head_position.y, z, speed)
-
- @pyqtSlot(float, float, float)
- @pyqtSlot(float, float, float, float)
- def moveHead(self, x: float = 0, y: float = 0, z: float = 0, speed: float = 3000) -> None:
- self._controller.moveHead(self, x, y, z, speed)
-
- ## Pre-heats the heated bed of the printer.
- #
- # \param temperature The temperature to heat the bed to, in degrees
- # Celsius.
- # \param duration How long the bed should stay warm, in seconds.
- @pyqtSlot(float, float)
- def preheatBed(self, temperature: float, duration: float) -> None:
- self._controller.preheatBed(self, temperature, duration)
-
- @pyqtSlot()
- def cancelPreheatBed(self) -> None:
- self._controller.cancelPreheatBed(self)
-
- def getController(self) -> "PrinterOutputController":
- return self._controller
-
- @pyqtProperty(str, notify = nameChanged)
- def name(self) -> str:
- return self._name
-
- def setName(self, name: str) -> None:
- self.updateName(name)
-
- def updateName(self, name: str) -> None:
- if self._name != name:
- self._name = name
- self.nameChanged.emit()
-
- ## Update the bed temperature. This only changes it locally.
- def updateBedTemperature(self, temperature: float) -> None:
- if self._bed_temperature != temperature:
- self._bed_temperature = temperature
- self.bedTemperatureChanged.emit()
-
- def updateTargetBedTemperature(self, temperature: float) -> None:
- if self._target_bed_temperature != temperature:
- self._target_bed_temperature = temperature
- self.targetBedTemperatureChanged.emit()
-
- ## Set the target bed temperature. This ensures that it's actually sent to the remote.
- @pyqtSlot(float)
- def setTargetBedTemperature(self, temperature: float) -> None:
- self._controller.setTargetBedTemperature(self, temperature)
- self.updateTargetBedTemperature(temperature)
-
- def updateActivePrintJob(self, print_job: Optional["PrintJobOutputModel"]) -> None:
- if self._active_print_job != print_job:
- old_print_job = self._active_print_job
-
- if print_job is not None:
- print_job.updateAssignedPrinter(self)
- self._active_print_job = print_job
-
- if old_print_job is not None:
- old_print_job.updateAssignedPrinter(None)
- self.activePrintJobChanged.emit()
-
- def updateState(self, printer_state: str) -> None:
- if self._printer_state != printer_state:
- self._printer_state = printer_state
- self.stateChanged.emit()
-
- @pyqtProperty(QObject, notify = activePrintJobChanged)
- def activePrintJob(self) -> Optional["PrintJobOutputModel"]:
- return self._active_print_job
-
- @pyqtProperty(str, notify = stateChanged)
- def state(self) -> str:
- return self._printer_state
-
- @pyqtProperty(float, notify = bedTemperatureChanged)
- def bedTemperature(self) -> float:
- return self._bed_temperature
-
- @pyqtProperty(float, notify = targetBedTemperatureChanged)
- def targetBedTemperature(self) -> float:
- return self._target_bed_temperature
-
- # Does the printer support pre-heating the bed at all
- @pyqtProperty(bool, constant = True)
- def canPreHeatBed(self) -> bool:
- if self._controller:
- return self._controller.can_pre_heat_bed
- return False
-
- # Does the printer support pre-heating the bed at all
- @pyqtProperty(bool, constant = True)
- def canPreHeatHotends(self) -> bool:
- if self._controller:
- return self._controller.can_pre_heat_hotends
- return False
-
- # Does the printer support sending raw G-code at all
- @pyqtProperty(bool, constant = True)
- def canSendRawGcode(self) -> bool:
- if self._controller:
- return self._controller.can_send_raw_gcode
- return False
-
- # Does the printer support pause at all
- @pyqtProperty(bool, constant = True)
- def canPause(self) -> bool:
- if self._controller:
- return self._controller.can_pause
- return False
-
- # Does the printer support abort at all
- @pyqtProperty(bool, constant = True)
- def canAbort(self) -> bool:
- if self._controller:
- return self._controller.can_abort
- return False
-
- # Does the printer support manual control at all
- @pyqtProperty(bool, constant = True)
- def canControlManually(self) -> bool:
- if self._controller:
- return self._controller.can_control_manually
- return False
-
- # Does the printer support upgrading firmware
- @pyqtProperty(bool, notify = canUpdateFirmwareChanged)
- def canUpdateFirmware(self) -> bool:
- if self._controller:
- return self._controller.can_update_firmware
- return False
-
- # Stub to connect UM.Signal to pyqtSignal
- def _onControllerCanUpdateFirmwareChanged(self) -> None:
- self.canUpdateFirmwareChanged.emit()
-
- # Returns the configuration (material, variant and buildplate) of the current printer
- @pyqtProperty(QObject, notify = configurationChanged)
- def printerConfiguration(self) -> Optional[ConfigurationModel]:
- if self._printer_configuration.isValid():
- return self._printer_configuration
- return None
\ No newline at end of file
+import warnings
+warnings.warn("Importing cura.PrinterOutput.PrinterOutputModel has been deprecated since 4.1, use cura.PrinterOutput.Models.PrinterOutputModel instead", DeprecationWarning, stacklevel=2)
+# We moved the the models to one submodule deeper
+from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
\ No newline at end of file
diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py
index dbdf8c986c..51e563410c 100644
--- a/cura/PrinterOutputDevice.py
+++ b/cura/PrinterOutputDevice.py
@@ -1,261 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from enum import IntEnum
-from typing import Callable, List, Optional, Union
-
-from UM.Decorators import deprecated
-from UM.i18n import i18nCatalog
-from UM.OutputDevice.OutputDevice import OutputDevice
-from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl
-from PyQt5.QtWidgets import QMessageBox
-
-from UM.Logger import Logger
-from UM.Signal import signalemitter
-from UM.Qt.QtApplication import QtApplication
-from UM.FlameProfiler import pyqtSlot
-
-MYPY = False
-if MYPY:
- from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
- from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
- from cura.PrinterOutput.FirmwareUpdater import FirmwareUpdater
- from UM.FileHandler.FileHandler import FileHandler
- from UM.Scene.SceneNode import SceneNode
-
-i18n_catalog = i18nCatalog("cura")
-
-
-## The current processing state of the backend.
-class ConnectionState(IntEnum):
- Closed = 0
- Connecting = 1
- Connected = 2
- Busy = 3
- Error = 4
-
-
-class ConnectionType(IntEnum):
- NotConnected = 0
- UsbConnection = 1
- NetworkConnection = 2
- CloudConnection = 3
-
-
-## Printer output device adds extra interface options on top of output device.
-#
-# The assumption is made the printer is a FDM printer.
-#
-# Note that a number of settings are marked as "final". This is because decorators
-# are not inherited by children. To fix this we use the private counter part of those
-# functions to actually have the implementation.
-#
-# For all other uses it should be used in the same way as a "regular" OutputDevice.
-@signalemitter
-class PrinterOutputDevice(QObject, OutputDevice):
-
- printersChanged = pyqtSignal()
- connectionStateChanged = pyqtSignal(str)
- acceptsCommandsChanged = pyqtSignal()
-
- # Signal to indicate that the material of the active printer on the remote changed.
- materialIdChanged = pyqtSignal()
-
- # # Signal to indicate that the hotend of the active printer on the remote changed.
- hotendIdChanged = pyqtSignal()
-
- # Signal to indicate that the info text about the connection has changed.
- connectionTextChanged = pyqtSignal()
-
- # Signal to indicate that the configuration of one of the printers has changed.
- uniqueConfigurationsChanged = pyqtSignal()
-
- def __init__(self, device_id: str, connection_type: "ConnectionType" = ConnectionType.NotConnected, parent: QObject = None) -> None:
- super().__init__(device_id = device_id, parent = parent) # type: ignore # MyPy complains with the multiple inheritance
-
- self._printers = [] # type: List[PrinterOutputModel]
- self._unique_configurations = [] # type: List[ConfigurationModel]
-
- self._monitor_view_qml_path = "" # type: str
- self._monitor_component = None # type: Optional[QObject]
- self._monitor_item = None # type: Optional[QObject]
-
- self._control_view_qml_path = "" # type: str
- self._control_component = None # type: Optional[QObject]
- self._control_item = None # type: Optional[QObject]
-
- self._accepts_commands = False # type: bool
-
- self._update_timer = QTimer() # type: QTimer
- self._update_timer.setInterval(2000) # TODO; Add preference for update interval
- self._update_timer.setSingleShot(False)
- self._update_timer.timeout.connect(self._update)
-
- self._connection_state = ConnectionState.Closed # type: ConnectionState
- self._connection_type = connection_type # type: ConnectionType
-
- self._firmware_updater = None # type: Optional[FirmwareUpdater]
- self._firmware_name = None # type: Optional[str]
- self._address = "" # type: str
- self._connection_text = "" # type: str
- self.printersChanged.connect(self._onPrintersChanged)
- QtApplication.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._updateUniqueConfigurations)
-
- @pyqtProperty(str, notify = connectionTextChanged)
- def address(self) -> str:
- return self._address
-
- def setConnectionText(self, connection_text):
- if self._connection_text != connection_text:
- self._connection_text = connection_text
- self.connectionTextChanged.emit()
-
- @pyqtProperty(str, constant=True)
- def connectionText(self) -> str:
- return self._connection_text
-
- def materialHotendChangedMessage(self, callback: Callable[[int], None]) -> None:
- Logger.log("w", "materialHotendChangedMessage needs to be implemented, returning 'Yes'")
- callback(QMessageBox.Yes)
-
- def isConnected(self) -> bool:
- return self._connection_state != ConnectionState.Closed and self._connection_state != ConnectionState.Error
-
- def setConnectionState(self, connection_state: "ConnectionState") -> None:
- if self._connection_state != connection_state:
- self._connection_state = connection_state
- self.connectionStateChanged.emit(self._id)
-
- @pyqtProperty(int, constant = True)
- def connectionType(self) -> "ConnectionType":
- return self._connection_type
-
- @pyqtProperty(int, notify = connectionStateChanged)
- def connectionState(self) -> "ConnectionState":
- return self._connection_state
-
- def _update(self) -> None:
- pass
-
- def _getPrinterByKey(self, key: str) -> Optional["PrinterOutputModel"]:
- for printer in self._printers:
- if printer.key == key:
- return printer
-
- return None
-
- def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, limit_mimetypes: bool = False,
- file_handler: Optional["FileHandler"] = None, **kwargs: str) -> None:
- raise NotImplementedError("requestWrite needs to be implemented")
-
- @pyqtProperty(QObject, notify = printersChanged)
- def activePrinter(self) -> Optional["PrinterOutputModel"]:
- if len(self._printers):
- return self._printers[0]
- return None
-
- @pyqtProperty("QVariantList", notify = printersChanged)
- def printers(self) -> List["PrinterOutputModel"]:
- return self._printers
-
- @pyqtProperty(QObject, constant = True)
- def monitorItem(self) -> QObject:
- # Note that we specifically only check if the monitor component is created.
- # It could be that it failed to actually create the qml item! If we check if the item was created, it will try to
- # create the item (and fail) every time.
- if not self._monitor_component:
- self._createMonitorViewFromQML()
- return self._monitor_item
-
- @pyqtProperty(QObject, constant = True)
- def controlItem(self) -> QObject:
- if not self._control_component:
- self._createControlViewFromQML()
- return self._control_item
-
- def _createControlViewFromQML(self) -> None:
- if not self._control_view_qml_path:
- return
- if self._control_item is None:
- self._control_item = QtApplication.getInstance().createQmlComponent(self._control_view_qml_path, {"OutputDevice": self})
-
- def _createMonitorViewFromQML(self) -> None:
- if not self._monitor_view_qml_path:
- return
-
- if self._monitor_item is None:
- self._monitor_item = QtApplication.getInstance().createQmlComponent(self._monitor_view_qml_path, {"OutputDevice": self})
-
- ## Attempt to establish connection
- def connect(self) -> None:
- self.setConnectionState(ConnectionState.Connecting)
- self._update_timer.start()
-
- ## Attempt to close the connection
- def close(self) -> None:
- self._update_timer.stop()
- self.setConnectionState(ConnectionState.Closed)
-
- ## Ensure that close gets called when object is destroyed
- def __del__(self) -> None:
- self.close()
-
- @pyqtProperty(bool, notify = acceptsCommandsChanged)
- def acceptsCommands(self) -> bool:
- return self._accepts_commands
-
- @deprecated("Please use the protected function instead", "3.2")
- def setAcceptsCommands(self, accepts_commands: bool) -> None:
- self._setAcceptsCommands(accepts_commands)
-
- ## Set a flag to signal the UI that the printer is not (yet) ready to receive commands
- def _setAcceptsCommands(self, accepts_commands: bool) -> None:
- if self._accepts_commands != accepts_commands:
- self._accepts_commands = accepts_commands
-
- self.acceptsCommandsChanged.emit()
-
- # Returns the unique configurations of the printers within this output device
- @pyqtProperty("QVariantList", notify = uniqueConfigurationsChanged)
- def uniqueConfigurations(self) -> List["ConfigurationModel"]:
- return self._unique_configurations
-
- def _updateUniqueConfigurations(self) -> None:
- self._unique_configurations = sorted(
- {printer.printerConfiguration for printer in self._printers if printer.printerConfiguration is not None},
- key=lambda config: config.printerType,
- )
- self.uniqueConfigurationsChanged.emit()
-
- # Returns the unique configurations of the printers within this output device
- @pyqtProperty("QStringList", notify = uniqueConfigurationsChanged)
- def uniquePrinterTypes(self) -> List[str]:
- return list(sorted(set([configuration.printerType for configuration in self._unique_configurations])))
-
- def _onPrintersChanged(self) -> None:
- for printer in self._printers:
- printer.configurationChanged.connect(self._updateUniqueConfigurations)
-
- # At this point there may be non-updated configurations
- self._updateUniqueConfigurations()
-
- ## Set the device firmware name
- #
- # \param name The name of the firmware.
- def _setFirmwareName(self, name: str) -> None:
- self._firmware_name = name
-
- ## Get the name of device firmware
- #
- # This name can be used to define device type
- def getFirmwareName(self) -> Optional[str]:
- return self._firmware_name
-
- def getFirmwareUpdater(self) -> Optional["FirmwareUpdater"]:
- return self._firmware_updater
-
- @pyqtSlot(str)
- def updateFirmware(self, firmware_file: Union[str, QUrl]) -> None:
- if not self._firmware_updater:
- return
-
- self._firmware_updater.updateFirmware(firmware_file)
+import warnings
+warnings.warn("Importing cura.PrinterOutputDevice has been deprecated since 4.1, use cura.PrinterOutput.PrinterOutputDevice instead", DeprecationWarning, stacklevel=2)
+# We moved the PrinterOutput device to it's own submodule.
+from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice, ConnectionState
\ No newline at end of file
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/ConvexHullDecorator.py b/cura/Scene/ConvexHullDecorator.py
index da71f6920e..2a160f6069 100644
--- a/cura/Scene/ConvexHullDecorator.py
+++ b/cura/Scene/ConvexHullDecorator.py
@@ -60,13 +60,15 @@ class ConvexHullDecorator(SceneNodeDecorator):
previous_node = self._node
# Disconnect from previous node signals
if previous_node is not None and node is not previous_node:
- previous_node.transformationChanged.disconnect(self._onChanged)
- previous_node.parentChanged.disconnect(self._onChanged)
+ previous_node.boundingBoxChanged.disconnect(self._onChanged)
super().setNode(node)
- # Mypy doesn't understand that self._node is no longer optional, so just use the node.
- node.transformationChanged.connect(self._onChanged)
- node.parentChanged.connect(self._onChanged)
+
+ node.boundingBoxChanged.connect(self._onChanged)
+
+ per_object_stack = node.callDecoration("getStack")
+ if per_object_stack:
+ per_object_stack.propertyChanged.connect(self._onSettingValueChanged)
self._onChanged()
@@ -74,26 +76,46 @@ class ConvexHullDecorator(SceneNodeDecorator):
def __deepcopy__(self, memo):
return ConvexHullDecorator()
- ## Get the unmodified 2D projected convex hull of the node (if any)
- def getConvexHull(self) -> Optional[Polygon]:
+ ## The polygon representing the 2D adhesion area.
+ # If no adhesion is used, the regular convex hull is returned
+ def getAdhesionArea(self) -> Optional[Polygon]:
if self._node is None:
return None
hull = self._compute2DConvexHull()
+ if hull is None:
+ return None
- if self._global_stack and self._node is not None and hull is not None:
- # Parent can be None if node is just loaded.
- if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and not self.hasGroupAsParent(self._node):
- hull = hull.getMinkowskiHull(Polygon(numpy.array(self._global_stack.getProperty("machine_head_polygon", "value"), numpy.float32)))
- hull = self._add2DAdhesionMargin(hull)
- return hull
+ return self._add2DAdhesionMargin(hull)
- ## Get the convex hull of the node with the full head size
+ ## Get the unmodified 2D projected convex hull of the node (if any)
+ # In case of one-at-a-time, this includes adhesion and head+fans clearance
+ def getConvexHull(self) -> Optional[Polygon]:
+ if self._node is None:
+ return None
+ if self._node.callDecoration("isNonPrintingMesh"):
+ return None
+
+ # Parent can be None if node is just loaded.
+ if self._isSingularOneAtATimeNode():
+ hull = self.getConvexHullHeadFull()
+ if hull is None:
+ return None
+ hull = self._add2DAdhesionMargin(hull)
+ return hull
+
+ return self._compute2DConvexHull()
+
+ ## For one at the time this is the convex hull of the node with the full head size
+ # In case of printing all at once this is None.
def getConvexHullHeadFull(self) -> Optional[Polygon]:
if self._node is None:
return None
- return self._compute2DConvexHeadFull()
+ if self._isSingularOneAtATimeNode():
+ return self._compute2DConvexHeadFull()
+
+ return None
@staticmethod
def hasGroupAsParent(node: "SceneNode") -> bool:
@@ -103,34 +125,47 @@ class ConvexHullDecorator(SceneNodeDecorator):
return bool(parent.callDecoration("isGroup"))
## Get convex hull of the object + head size
- # In case of printing all at once this is the same as the convex hull.
+ # In case of printing all at once this is None.
# For one at the time this is area with intersection of mirrored head
def getConvexHullHead(self) -> Optional[Polygon]:
if self._node is None:
return None
-
- if self._global_stack:
- if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and not self.hasGroupAsParent(self._node):
- head_with_fans = self._compute2DConvexHeadMin()
- if head_with_fans is None:
- return None
- head_with_fans_with_adhesion_margin = self._add2DAdhesionMargin(head_with_fans)
- return head_with_fans_with_adhesion_margin
+ if self._node.callDecoration("isNonPrintingMesh"):
+ return None
+ if self._isSingularOneAtATimeNode():
+ head_with_fans = self._compute2DConvexHeadMin()
+ if head_with_fans is None:
+ return None
+ head_with_fans_with_adhesion_margin = self._add2DAdhesionMargin(head_with_fans)
+ return head_with_fans_with_adhesion_margin
return None
## Get convex hull of the node
- # In case of printing all at once this is the same as the convex hull.
+ # In case of printing all at once this None??
# For one at the time this is the area without the head.
def getConvexHullBoundary(self) -> Optional[Polygon]:
if self._node is None:
return None
- if self._global_stack:
- if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and not self.hasGroupAsParent(self._node):
- # Printing one at a time and it's not an object in a group
- return self._compute2DConvexHull()
+ if self._node.callDecoration("isNonPrintingMesh"):
+ return None
+
+ if self._isSingularOneAtATimeNode():
+ # Printing one at a time and it's not an object in a group
+ return self._compute2DConvexHull()
return None
+ ## Get the buildplate polygon where will be printed
+ # In case of printing all at once this is the same as convex hull (no individual adhesion)
+ # For one at the time this includes the adhesion area
+ def getPrintingArea(self) -> Optional[Polygon]:
+ if self._isSingularOneAtATimeNode():
+ # In one-at-a-time mode, every printed object gets it's own adhesion
+ printing_area = self.getAdhesionArea()
+ else:
+ printing_area = self.getConvexHull()
+ return printing_area
+
## The same as recomputeConvexHull, but using a timer if it was set.
def recomputeConvexHullDelayed(self) -> None:
if self._recompute_convex_hull_timer is not None:
@@ -153,10 +188,9 @@ class ConvexHullDecorator(SceneNodeDecorator):
self._convex_hull_node = None
return
- convex_hull = self.getConvexHull()
if self._convex_hull_node:
self._convex_hull_node.setParent(None)
- hull_node = ConvexHullNode.ConvexHullNode(self._node, convex_hull, self._raft_thickness, root)
+ hull_node = ConvexHullNode.ConvexHullNode(self._node, self.getPrintingArea(), self._raft_thickness, root)
self._convex_hull_node = hull_node
def _onSettingValueChanged(self, key: str, property_name: str) -> None:
@@ -259,9 +293,13 @@ class ConvexHullDecorator(SceneNodeDecorator):
return offset_hull
def _getHeadAndFans(self) -> Polygon:
- if self._global_stack:
- return Polygon(numpy.array(self._global_stack.getHeadAndFansCoordinates(), numpy.float32))
- return Polygon()
+ if not self._global_stack:
+ return Polygon()
+
+ polygon = Polygon(numpy.array(self._global_stack.getHeadAndFansCoordinates(), numpy.float32))
+ offset_x = self._getSettingProperty("machine_nozzle_offset_x", "value")
+ offset_y = self._getSettingProperty("machine_nozzle_offset_y", "value")
+ return polygon.translate(-offset_x, -offset_y)
def _compute2DConvexHeadFull(self) -> Optional[Polygon]:
convex_hull = self._compute2DConvexHull()
@@ -393,6 +431,14 @@ class ConvexHullDecorator(SceneNodeDecorator):
return True
return self.__isDescendant(root, node.getParent())
+ ## True if print_sequence is one_at_a_time and _node is not part of a group
+ def _isSingularOneAtATimeNode(self) -> bool:
+ if self._node is None:
+ return False
+ return self._global_stack is not None \
+ and self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" \
+ and not self.hasGroupAsParent(self._node)
+
_affected_settings = [
"adhesion_type", "raft_margin", "print_sequence",
"skirt_gap", "skirt_line_count", "skirt_brim_line_width", "skirt_distance", "brim_line_count"]
@@ -400,4 +446,4 @@ class ConvexHullDecorator(SceneNodeDecorator):
## Settings that change the convex hull.
#
# If these settings change, the convex hull should be recalculated.
- _influencing_settings = {"xy_offset", "xy_offset_layer_0", "mold_enabled", "mold_width"}
+ _influencing_settings = {"xy_offset", "xy_offset_layer_0", "mold_enabled", "mold_width", "anti_overhang_mesh", "infill_mesh", "cutting_mesh"}
diff --git a/cura/Scene/ConvexHullNode.py b/cura/Scene/ConvexHullNode.py
index 90bf536308..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.
@@ -43,7 +46,8 @@ class ConvexHullNode(SceneNode):
# The node this mesh is "watching"
self._node = node
- self._convex_hull_head_mesh = None
+ # Area of the head + fans for display as a shadow on the buildplate
+ self._convex_hull_head_mesh = None # type: Optional[MeshData]
self._node.decoratorsChanged.connect(self._onNodeDecoratorsChanged)
self._onNodeDecoratorsChanged(self._node)
@@ -76,14 +80,17 @@ class ConvexHullNode(SceneNode):
if self.getParent():
if self.getMeshData() and isinstance(self._node, SceneNode) and self._node.callDecoration("getBuildPlateNumber") == Application.getInstance().getMultiBuildPlateModel().activeBuildPlate:
+ # The object itself (+ adhesion in one-at-a-time mode)
renderer.queueNode(self, transparent = True, shader = ConvexHullNode.shader, backface_cull = True, sort = -8)
if self._convex_hull_head_mesh:
+ # The full head. Rendered as a hint to the user: If this area overlaps another object A; this object
+ # cannot be printed after A, because the head would hit A while printing the current object
renderer.queueNode(self, shader = ConvexHullNode.shader, transparent = True, mesh = self._convex_hull_head_mesh, backface_cull = True, sort = -8)
return True
def _onNodeDecoratorsChanged(self, node: SceneNode) -> None:
- convex_hull_head = self._node.callDecoration("getConvexHullHead")
+ convex_hull_head = self._node.callDecoration("getConvexHullHeadFull")
if convex_hull_head:
convex_hull_head_builder = MeshBuilder()
convex_hull_head_builder.addConvexPolygon(convex_hull_head.getPoints(), self._mesh_height - self._thickness)
diff --git a/cura/Scene/CuraSceneController.py b/cura/Scene/CuraSceneController.py
index 4b19271538..91ff26cadc 100644
--- a/cura/Scene/CuraSceneController.py
+++ b/cura/Scene/CuraSceneController.py
@@ -3,7 +3,8 @@ from UM.Logger import Logger
from PyQt5.QtCore import Qt, pyqtSlot, QObject
from PyQt5.QtWidgets import QApplication
-from cura.ObjectsModel import ObjectsModel
+from UM.Scene.Camera import Camera
+from cura.UI.ObjectsModel import ObjectsModel
from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
from UM.Application import Application
@@ -33,7 +34,7 @@ class CuraSceneController(QObject):
source = args[0]
else:
source = None
- if not isinstance(source, SceneNode):
+ if not isinstance(source, SceneNode) or isinstance(source, Camera):
return
max_build_plate = self._calcMaxBuildPlate()
changed = False
diff --git a/cura/Scene/CuraSceneNode.py b/cura/Scene/CuraSceneNode.py
index 259c273329..eb609def5a 100644
--- a/cura/Scene/CuraSceneNode.py
+++ b/cura/Scene/CuraSceneNode.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from copy import deepcopy
@@ -6,13 +6,14 @@ from typing import cast, Dict, List, Optional
from UM.Application import Application
from UM.Math.AxisAlignedBox import AxisAlignedBox
-from UM.Math.Polygon import Polygon #For typing.
+from UM.Math.Polygon import Polygon # For typing.
from UM.Scene.SceneNode import SceneNode
-from UM.Scene.SceneNodeDecorator import SceneNodeDecorator #To cast the deepcopy of every decorator back to SceneNodeDecorator.
+from UM.Scene.SceneNodeDecorator import SceneNodeDecorator # To cast the deepcopy of every decorator back to SceneNodeDecorator.
+
+import cura.CuraApplication # To get the build plate.
+from cura.Settings.ExtruderStack import ExtruderStack # For typing.
+from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator # For per-object settings.
-import cura.CuraApplication #To get the build plate.
-from cura.Settings.ExtruderStack import ExtruderStack #For typing.
-from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator #For per-object settings.
## Scene nodes that are models are only seen when selecting the corresponding build plate
# Note that many other nodes can just be UM SceneNode objects.
@@ -20,7 +21,7 @@ class CuraSceneNode(SceneNode):
def __init__(self, parent: Optional["SceneNode"] = None, visible: bool = True, name: str = "", no_setting_override: bool = False) -> None:
super().__init__(parent = parent, visible = visible, name = name)
if not no_setting_override:
- self.addDecorator(SettingOverrideDecorator()) # now we always have a getActiveExtruderPosition, unless explicitly disabled
+ self.addDecorator(SettingOverrideDecorator()) # Now we always have a getActiveExtruderPosition, unless explicitly disabled
self._outside_buildarea = False
def setOutsideBuildArea(self, new_value: bool) -> None:
@@ -58,7 +59,7 @@ class CuraSceneNode(SceneNode):
if extruder_id is not None:
if extruder_id == extruder.getId():
return extruder
- else: # If the id is unknown, then return the extruder in the position 0
+ else: # If the id is unknown, then return the extruder in the position 0
try:
if extruder.getMetaDataEntry("position", default = "0") == "0": # Check if the position is zero
return extruder
@@ -85,24 +86,14 @@ class CuraSceneNode(SceneNode):
1.0
]
- ## Return if the provided bbox collides with the bbox of this scene node
- def collidesWithBbox(self, check_bbox: AxisAlignedBox) -> bool:
- bbox = self.getBoundingBox()
- if bbox is not None:
- # Mark the node as outside the build volume if the bounding box test fails.
- if check_bbox.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
- return True
-
- return False
-
## Return if any area collides with the convex hull of this scene node
- def collidesWithArea(self, areas: List[Polygon]) -> bool:
- convex_hull = self.callDecoration("getConvexHull")
+ def collidesWithAreas(self, areas: List[Polygon]) -> bool:
+ convex_hull = self.callDecoration("getPrintingArea")
if convex_hull:
if not convex_hull.isValid():
return False
- # Check for collisions between disallowed areas and the object
+ # Check for collisions between provided areas and the object
for area in areas:
overlap = convex_hull.intersectsPolygon(area)
if overlap is None:
@@ -112,21 +103,24 @@ class CuraSceneNode(SceneNode):
## Override of SceneNode._calculateAABB to exclude non-printing-meshes from bounding box
def _calculateAABB(self) -> None:
+ self._aabb = None
if self._mesh_data:
- aabb = self._mesh_data.getExtents(self.getWorldTransformation())
+ self._aabb = self._mesh_data.getExtents(self.getWorldTransformation())
else: # If there is no mesh_data, use a boundingbox that encompasses the local (0,0,0)
position = self.getWorldPosition()
- aabb = AxisAlignedBox(minimum = position, maximum = position)
+ self._aabb = AxisAlignedBox(minimum=position, maximum=position)
- for child in self._children:
+ for child in self.getAllChildren():
if child.callDecoration("isNonPrintingMesh"):
# Non-printing-meshes inside a group should not affect push apart or drop to build plate
continue
- if aabb is None:
- aabb = child.getBoundingBox()
+ if not child.getMeshData():
+ # Nodes without mesh data should not affect bounding boxes of their parents.
+ continue
+ if self._aabb is None:
+ self._aabb = child.getBoundingBox()
else:
- aabb = aabb + child.getBoundingBox()
- self._aabb = aabb
+ self._aabb = self._aabb + child.getBoundingBox()
## Taken from SceneNode, but replaced SceneNode with CuraSceneNode
def __deepcopy__(self, memo: Dict[int, object]) -> "CuraSceneNode":
diff --git a/cura/Scene/GCodeListDecorator.py b/cura/Scene/GCodeListDecorator.py
index d3dadb3f23..6c52fb89bf 100644
--- a/cura/Scene/GCodeListDecorator.py
+++ b/cura/Scene/GCodeListDecorator.py
@@ -1,11 +1,18 @@
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
-from typing import List
+from typing import List, Optional
class GCodeListDecorator(SceneNodeDecorator):
def __init__(self) -> None:
super().__init__()
self._gcode_list = [] # type: List[str]
+ self._filename = None # type: Optional[str]
+
+ def getGcodeFileName(self) -> Optional[str]:
+ return self._filename
+
+ def setGcodeFileName(self, filename: str) -> None:
+ self._filename = filename
def getGCodeList(self) -> List[str]:
return self._gcode_list
diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py
index 133e04e8fc..92f06929d2 100644
--- a/cura/Settings/ContainerManager.py
+++ b/cura/Settings/ContainerManager.py
@@ -1,15 +1,14 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import os
import urllib.parse
import uuid
-from typing import Dict, Union, Any, TYPE_CHECKING, List
+from typing import Any, cast, Dict, List, TYPE_CHECKING, Union
from PyQt5.QtCore import QObject, QUrl
from PyQt5.QtWidgets import QMessageBox
-
from UM.i18n import i18nCatalog
from UM.FlameProfiler import pyqtSlot
from UM.Logger import Logger
@@ -17,21 +16,19 @@ from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError
from UM.Platform import Platform
from UM.SaveFile import SaveFile
from UM.Settings.ContainerFormatError import ContainerFormatError
+from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.DefinitionContainer import DefinitionContainer
from UM.Settings.InstanceContainer import InstanceContainer
+import cura.CuraApplication
+from cura.Machines.ContainerTree import ContainerTree
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
from cura.Machines.ContainerNode import ContainerNode
from cura.Machines.MaterialNode import MaterialNode
from cura.Machines.QualityChangesGroup import QualityChangesGroup
- from UM.PluginRegistry import PluginRegistry
- from cura.Settings.MachineManager import MachineManager
- from cura.Machines.MaterialManager import MaterialManager
- from cura.Machines.QualityManager import QualityManager
- from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
catalog = i18nCatalog("cura")
@@ -47,20 +44,16 @@ class ContainerManager(QObject):
if ContainerManager.__instance is not None:
raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__)
ContainerManager.__instance = self
+ try:
+ super().__init__(parent = application)
+ except TypeError:
+ super().__init__()
- super().__init__(parent = application)
-
- self._application = application # type: CuraApplication
- self._plugin_registry = self._application.getPluginRegistry() # type: PluginRegistry
- self._container_registry = self._application.getContainerRegistry() # type: CuraContainerRegistry
- self._machine_manager = self._application.getMachineManager() # type: MachineManager
- self._material_manager = self._application.getMaterialManager() # type: MaterialManager
- self._quality_manager = self._application.getQualityManager() # type: QualityManager
self._container_name_filters = {} # type: Dict[str, Dict[str, Any]]
@pyqtSlot(str, str, result=str)
def getContainerMetaDataEntry(self, container_id: str, entry_names: str) -> str:
- metadatas = self._container_registry.findContainersMetadata(id = container_id)
+ metadatas = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry().findContainersMetadata(id = container_id)
if not metadatas:
Logger.log("w", "Could not get metadata of container %s because it was not found.", container_id)
return ""
@@ -89,15 +82,19 @@ class ContainerManager(QObject):
# Update: In order for QML to use objects and sub objects, those (sub) objects must all be QObject. Is that what we want?
@pyqtSlot("QVariant", str, str)
def setContainerMetaDataEntry(self, container_node: "ContainerNode", entry_name: str, entry_value: str) -> bool:
+ if container_node.container is None:
+ Logger.log("w", "Container node {0} doesn't have a container.".format(container_node.container_id))
+ return False
root_material_id = container_node.getMetaDataEntry("base_file", "")
- if self._container_registry.isReadOnly(root_material_id):
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ if container_registry.isReadOnly(root_material_id):
Logger.log("w", "Cannot set metadata of read-only container %s.", root_material_id)
return False
-
- material_group = self._material_manager.getMaterialGroup(root_material_id)
- if material_group is None:
- Logger.log("w", "Unable to find material group for: %s.", root_material_id)
+ root_material_query = container_registry.findContainers(id = root_material_id)
+ if not root_material_query:
+ Logger.log("w", "Unable to find root material: {root_material}.".format(root_material = root_material_id))
return False
+ root_material = root_material_query[0]
entries = entry_name.split("/")
entry_name = entries.pop()
@@ -105,7 +102,7 @@ class ContainerManager(QObject):
sub_item_changed = False
if entries:
root_name = entries.pop(0)
- root = material_group.root_material_node.getMetaDataEntry(root_name)
+ root = root_material.getMetaDataEntry(root_name)
item = root
for _ in range(len(entries)):
@@ -118,16 +115,14 @@ class ContainerManager(QObject):
entry_name = root_name
entry_value = root
- container = material_group.root_material_node.getContainer()
- if container is not None:
- container.setMetaDataEntry(entry_name, entry_value)
- if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed.
- container.metaDataChanged.emit(container)
+ root_material.setMetaDataEntry(entry_name, entry_value)
+ if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed.
+ root_material.metaDataChanged.emit(root_material)
return True
@pyqtSlot(str, result = str)
def makeUniqueName(self, original_name: str) -> str:
- return self._container_registry.uniqueName(original_name)
+ return cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry().uniqueName(original_name)
## Get a list of string that can be used as name filters for a Qt File Dialog
#
@@ -182,7 +177,7 @@ class ContainerManager(QObject):
else:
mime_type = self._container_name_filters[file_type]["mime"]
- containers = self._container_registry.findContainers(id = container_id)
+ containers = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry().findContainers(id = container_id)
if not containers:
return {"status": "error", "message": "Container not found"}
container = containers[0]
@@ -240,18 +235,19 @@ class ContainerManager(QObject):
except MimeTypeNotFoundError:
return {"status": "error", "message": "Could not determine mime type of file"}
- container_type = self._container_registry.getContainerForMimeType(mime_type)
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ container_type = container_registry.getContainerForMimeType(mime_type)
if not container_type:
return {"status": "error", "message": "Could not find a container to handle the specified file."}
container_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_url)))
- container_id = self._container_registry.uniqueName(container_id)
+ container_id = container_registry.uniqueName(container_id)
container = container_type(container_id)
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:
@@ -261,7 +257,7 @@ class ContainerManager(QObject):
container.setDirty(True)
- self._container_registry.addContainer(container)
+ container_registry.addContainer(container)
return {"status": "success", "message": "Successfully imported container {0}".format(container.getName())}
@@ -273,44 +269,55 @@ class ContainerManager(QObject):
# \return \type{bool} True if successful, False if not.
@pyqtSlot(result = bool)
def updateQualityChanges(self) -> bool:
- global_stack = self._machine_manager.activeMachine
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ global_stack = application.getMachineManager().activeMachine
if not global_stack:
return False
- self._machine_manager.blurSettings.emit()
+ application.getMachineManager().blurSettings.emit()
current_quality_changes_name = global_stack.qualityChanges.getName()
current_quality_type = global_stack.quality.getMetaDataEntry("quality_type")
extruder_stacks = list(global_stack.extruders.values())
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ machine_definition_id = ContainerTree.getInstance().machines[global_stack.definition.getId()].quality_definition
for stack in [global_stack] + extruder_stacks:
# Find the quality_changes container for this stack and merge the contents of the top container into it.
quality_changes = stack.qualityChanges
if quality_changes.getId() == "empty_quality_changes":
- quality_changes = self._quality_manager._createQualityChanges(current_quality_type, current_quality_changes_name,
- global_stack, stack)
- self._container_registry.addContainer(quality_changes)
+ quality_changes = InstanceContainer(container_registry.uniqueName((stack.getId() + "_" + current_quality_changes_name).lower().replace(" ", "_")))
+ quality_changes.setName(current_quality_changes_name)
+ quality_changes.setMetaDataEntry("type", "quality_changes")
+ quality_changes.setMetaDataEntry("quality_type", current_quality_type)
+ if stack.getMetaDataEntry("position") is not None: # Extruder stacks.
+ quality_changes.setMetaDataEntry("position", stack.getMetaDataEntry("position"))
+ quality_changes.setMetaDataEntry("intent_category", stack.quality.getMetaDataEntry("intent_category", "default"))
+ quality_changes.setMetaDataEntry("setting_version", application.SettingVersion)
+ quality_changes.setDefinition(machine_definition_id)
+ container_registry.addContainer(quality_changes)
stack.qualityChanges = quality_changes
- if not quality_changes or self._container_registry.isReadOnly(quality_changes.getId()):
+ if not quality_changes or container_registry.isReadOnly(quality_changes.getId()):
Logger.log("e", "Could not update quality of a nonexistant or read only quality profile in stack %s", stack.getId())
continue
self._performMerge(quality_changes, stack.getTop())
- self._machine_manager.activeQualityChangesGroupChanged.emit()
+ cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeQualityChangesGroupChanged.emit()
return True
## Clear the top-most (user) containers of the active stacks.
@pyqtSlot()
def clearUserContainers(self) -> None:
- self._machine_manager.blurSettings.emit()
+ machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
+ machine_manager.blurSettings.emit()
send_emits_containers = []
# Go through global and extruder stacks and clear their topmost container (the user settings).
- global_stack = self._machine_manager.activeMachine
+ global_stack = machine_manager.activeMachine
extruder_stacks = list(global_stack.extruders.values())
for stack in [global_stack] + extruder_stacks:
container = stack.userChanges
@@ -318,40 +325,38 @@ class ContainerManager(QObject):
send_emits_containers.append(container)
# user changes are possibly added to make the current setup match the current enabled extruders
- self._machine_manager.correctExtruderSettings()
+ machine_manager.correctExtruderSettings()
for container in send_emits_containers:
container.sendPostponedEmits()
## Get a list of materials that have the same GUID as the reference material
#
- # \param material_id \type{str} the id of the material for which to get the linked materials.
- # \return \type{list} a list of names of materials with the same GUID
+ # \param material_node The node representing the material for which to get
+ # the same GUID.
+ # \param exclude_self Whether to include the name of the material you
+ # provided.
+ # \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):
- guid = material_node.getMetaDataEntry("GUID", "")
-
- self_root_material_id = material_node.getMetaDataEntry("base_file")
- material_group_list = self._material_manager.getMaterialGroupListByGUID(guid)
-
- linked_material_names = []
- if material_group_list:
- for material_group in material_group_list:
- if exclude_self and material_group.name == self_root_material_id:
- continue
- linked_material_names.append(material_group.root_material_node.getMetaDataEntry("name", ""))
- return linked_material_names
+ def getLinkedMaterials(self, material_node: "MaterialNode", exclude_self: bool = False) -> List[str]:
+ same_guid = ContainerRegistry.getInstance().findInstanceContainersMetadata(GUID = material_node.guid)
+ if exclude_self:
+ return list({meta["name"] for meta in same_guid if meta["base_file"] != material_node.base_file})
+ else:
+ 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.
@pyqtSlot("QVariant")
def unlinkMaterial(self, material_node: "MaterialNode") -> None:
# Get the material group
- material_group = self._material_manager.getMaterialGroup(material_node.getMetaDataEntry("base_file", ""))
-
- if material_group is None:
+ if material_node.container is None: # Failed to lazy-load this container.
+ return
+ root_material_query = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry().findInstanceContainers(id = material_node.getMetaDataEntry("base_file", ""))
+ if not root_material_query:
Logger.log("w", "Unable to find material group for %s", material_node)
return
+ root_material = root_material_query[0]
# Generate a new GUID
new_guid = str(uuid.uuid4())
@@ -359,9 +364,7 @@ class ContainerManager(QObject):
# Update the GUID
# NOTE: We only need to set the root material container because XmlMaterialProfile.setMetaDataEntry() will
# take care of the derived containers too
- container = material_group.root_material_node.getContainer()
- if container is not None:
- container.setMetaDataEntry("GUID", new_guid)
+ root_material.setMetaDataEntry("GUID", new_guid)
def _performMerge(self, merge_into: InstanceContainer, merge: InstanceContainer, clear_settings: bool = True) -> None:
if merge == merge_into:
@@ -375,14 +378,16 @@ class ContainerManager(QObject):
def _updateContainerNameFilters(self) -> None:
self._container_name_filters = {}
- for plugin_id, container_type in self._container_registry.getContainerTypes():
+ plugin_registry = cura.CuraApplication.CuraApplication.getInstance().getPluginRegistry()
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ for plugin_id, container_type in container_registry.getContainerTypes():
# Ignore default container types since those are not plugins
if container_type in (InstanceContainer, ContainerStack, DefinitionContainer):
continue
serialize_type = ""
try:
- plugin_metadata = self._plugin_registry.getMetaData(plugin_id)
+ plugin_metadata = plugin_registry.getMetaData(plugin_id)
if plugin_metadata:
serialize_type = plugin_metadata["settings_container"]["type"]
else:
@@ -390,7 +395,7 @@ class ContainerManager(QObject):
except KeyError as e:
continue
- mime_type = self._container_registry.getMimeTypeForContainer(container_type)
+ mime_type = container_registry.getMimeTypeForContainer(container_type)
if mime_type is None:
continue
entry = {
@@ -426,7 +431,7 @@ class ContainerManager(QObject):
path = file_url.toLocalFile()
if not path:
return {"status": "error", "message": catalog.i18nc("@info:status", "Invalid file URL:") + " " + str(file_url)}
- return self._container_registry.importProfile(path)
+ return cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry().importProfile(path)
@pyqtSlot(QObject, QUrl, str)
def exportQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", file_url: QUrl, file_type: str) -> None:
@@ -436,8 +441,11 @@ class ContainerManager(QObject):
if not path:
return
- container_list = [n.getContainer() for n in quality_changes_group.getAllNodes() if n.getContainer() is not None]
- self._container_registry.exportQualityProfile(container_list, path, file_type)
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
+ container_list = [cast(InstanceContainer, container_registry.findContainers(id = quality_changes_group.metadata_for_global["id"])[0])] # type: List[InstanceContainer]
+ for metadata in quality_changes_group.metadata_per_extruder.values():
+ container_list.append(cast(InstanceContainer, container_registry.findContainers(id = metadata["id"])[0]))
+ cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry().exportQualityProfile(container_list, path, file_type)
__instance = None # type: ContainerManager
diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py
index 9f44d075e0..f6028e9d4d 100644
--- a/cura/Settings/CuraContainerRegistry.py
+++ b/cura/Settings/CuraContainerRegistry.py
@@ -1,11 +1,11 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import os
import re
import configparser
-from typing import cast, Dict, Optional
+from typing import Any, cast, Dict, Optional, List, Union
from PyQt5.QtWidgets import QMessageBox
from UM.Decorators import override
@@ -20,14 +20,16 @@ from UM.Logger import Logger
from UM.Message import Message
from UM.Platform import Platform
from UM.PluginRegistry import PluginRegistry # For getting the possible profile writers to write with.
-from UM.Util import parseBool
from UM.Resources import Resources
+from UM.Util import parseBool
+from cura.ReaderWriters.ProfileWriter import ProfileWriter
from . import ExtruderStack
from . import GlobalStack
import cura.CuraApplication
-from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
+from cura.Settings.cura_empty_instance_containers import empty_quality_container
+from cura.Machines.ContainerTree import ContainerTree
from cura.ReaderWriters.ProfileReader import NoProfileException, ProfileReader
from UM.i18n import i18nCatalog
@@ -50,10 +52,10 @@ class CuraContainerRegistry(ContainerRegistry):
# This will also try to convert a ContainerStack to either Extruder or
# Global stack based on metadata information.
@override(ContainerRegistry)
- def addContainer(self, container):
+ def addContainer(self, container: ContainerInterface) -> None:
# Note: Intentional check with type() because we want to ignore subclasses
if type(container) == ContainerStack:
- container = self._convertContainerStack(container)
+ container = self._convertContainerStack(cast(ContainerStack, container))
if isinstance(container, InstanceContainer) and type(container) != type(self.getEmptyInstanceContainer()):
# Check against setting version of the definition.
@@ -61,7 +63,7 @@ class CuraContainerRegistry(ContainerRegistry):
actual_setting_version = int(container.getMetaDataEntry("setting_version", default = 0))
if required_setting_version != actual_setting_version:
Logger.log("w", "Instance container {container_id} is outdated. Its setting version is {actual_setting_version} but it should be {required_setting_version}.".format(container_id = container.getId(), actual_setting_version = actual_setting_version, required_setting_version = required_setting_version))
- return #Don't add.
+ return # Don't add.
super().addContainer(container)
@@ -71,9 +73,9 @@ class CuraContainerRegistry(ContainerRegistry):
# \param new_name \type{string} Base name, which may not be unique
# \param fallback_name \type{string} Name to use when (stripped) new_name is empty
# \return \type{string} Name that is unique for the specified type and name/id
- def createUniqueName(self, container_type, current_name, new_name, fallback_name):
+ def createUniqueName(self, container_type: str, current_name: str, new_name: str, fallback_name: str) -> str:
new_name = new_name.strip()
- num_check = re.compile("(.*?)\s*#\d+$").match(new_name)
+ num_check = re.compile(r"(.*?)\s*#\d+$").match(new_name)
if num_check:
new_name = num_check.group(1)
if new_name == "":
@@ -92,7 +94,7 @@ class CuraContainerRegistry(ContainerRegistry):
# Both the id and the name are checked, because they may not be the same and it is better if they are both unique
# \param container_type \type{string} Type of the container (machine, quality, ...)
# \param container_name \type{string} Name to check
- def _containerExists(self, container_type, container_name):
+ def _containerExists(self, container_type: str, container_name: str):
container_class = ContainerStack if container_type == "machine" else InstanceContainer
return self.findContainersMetadata(container_type = container_class, id = container_name, type = container_type, ignore_case = True) or \
@@ -100,16 +102,18 @@ class CuraContainerRegistry(ContainerRegistry):
## Exports an profile to a file
#
- # \param instance_ids \type{list} the IDs of the profiles to export.
+ # \param container_list \type{list} the containers to export. This is not
+ # necessarily in any order!
# \param file_name \type{str} the full path and filename to export to.
# \param file_type \type{str} the file type with the format " (*.)"
- def exportQualityProfile(self, container_list, file_name, file_type):
+ # \return True if the export succeeded, false otherwise.
+ def exportQualityProfile(self, container_list: List[InstanceContainer], file_name: str, file_type: str) -> bool:
# Parse the fileType to deduce what plugin can save the file format.
# fileType has the format " (*.)"
split = file_type.rfind(" (*.") # Find where the description ends and the extension starts.
if split < 0: # Not found. Invalid format.
Logger.log("e", "Invalid file format identifier %s", file_type)
- return
+ return False
description = file_type[:split]
extension = file_type[split + 4:-1] # Leave out the " (*." and ")".
if not file_name.endswith("." + extension): # Auto-fill the extension if the user did not provide any.
@@ -121,10 +125,12 @@ class CuraContainerRegistry(ContainerRegistry):
result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"),
catalog.i18nc("@label Don't translate the XML tag !", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_name))
if result == QMessageBox.No:
- return
+ return False
profile_writer = self._findProfileWriter(extension, description)
try:
+ if profile_writer is None:
+ raise Exception("Unable to find a profile writer")
success = profile_writer.write(file_name, container_list)
except Exception as e:
Logger.log("e", "Failed to export profile to %s: %s", file_name, str(e))
@@ -132,23 +138,24 @@ class CuraContainerRegistry(ContainerRegistry):
lifetime = 0,
title = catalog.i18nc("@info:title", "Error"))
m.show()
- return
+ return False
if not success:
Logger.log("w", "Failed to export profile to %s: Writer plugin reported failure.", file_name)
m = Message(catalog.i18nc("@info:status Don't translate the XML tag !", "Failed to export profile to {0}: Writer plugin reported failure.", file_name),
lifetime = 0,
title = catalog.i18nc("@info:title", "Error"))
m.show()
- return
+ return False
m = Message(catalog.i18nc("@info:status Don't translate the XML tag !", "Exported profile to {0}", file_name),
title = catalog.i18nc("@info:title", "Export succeeded"))
m.show()
+ return True
## Gets the plugin object matching the criteria
# \param extension
# \param description
# \return The plugin object matching the given extension and description.
- def _findProfileWriter(self, extension, description):
+ def _findProfileWriter(self, extension: str, description: str) -> Optional[ProfileWriter]:
plugin_registry = PluginRegistry.getInstance()
for plugin_id, meta_data in self._getIOPlugins("profile_writer"):
for supported_type in meta_data["profile_writer"]: # All file types this plugin can supposedly write.
@@ -156,7 +163,7 @@ class CuraContainerRegistry(ContainerRegistry):
if supported_extension == extension: # This plugin supports a file type with the same extension.
supported_description = supported_type.get("description", None)
if supported_description == description: # The description is also identical. Assume it's the same file type.
- return plugin_registry.getPluginObject(plugin_id)
+ return cast(ProfileWriter, plugin_registry.getPluginObject(plugin_id))
return None
## Imports a profile from a file
@@ -169,17 +176,18 @@ class CuraContainerRegistry(ContainerRegistry):
if not file_name:
return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags !", "Failed to import profile from {0}: {1}", file_name, "Invalid path")}
- plugin_registry = PluginRegistry.getInstance()
- extension = file_name.split(".")[-1]
-
global_stack = Application.getInstance().getGlobalContainerStack()
if not global_stack:
return {"status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags !", "Can't import profile from {0} before a printer is added.", file_name)}
+ container_tree = ContainerTree.getInstance()
machine_extruders = []
for position in sorted(global_stack.extruders):
machine_extruders.append(global_stack.extruders[position])
+ plugin_registry = PluginRegistry.getInstance()
+ extension = file_name.split(".")[-1]
+
for plugin_id, meta_data in self._getIOPlugins("profile_reader"):
if meta_data["profile_reader"][0]["extension"] != extension:
continue
@@ -221,7 +229,7 @@ class CuraContainerRegistry(ContainerRegistry):
# Make sure we have a profile_definition in the file:
if profile_definition is None:
break
- machine_definitions = self.findDefinitionContainers(id = profile_definition)
+ machine_definitions = self.findContainers(id = profile_definition)
if not machine_definitions:
Logger.log("e", "Incorrect profile [%s]. Unknown machine type [%s]", file_name, profile_definition)
return {"status": "error",
@@ -231,17 +239,17 @@ class CuraContainerRegistry(ContainerRegistry):
# Get the expected machine definition.
# i.e.: We expect gcode for a UM2 Extended to be defined as normal UM2 gcode...
- profile_definition = getMachineDefinitionIDForQualitySearch(machine_definition)
- expected_machine_definition = getMachineDefinitionIDForQualitySearch(global_stack.definition)
+ has_machine_quality = parseBool(machine_definition.getMetaDataEntry("has_machine_quality", "false"))
+ profile_definition = machine_definition.getMetaDataEntry("quality_definition", machine_definition.getId()) if has_machine_quality else "fdmprinter"
+ expected_machine_definition = container_tree.machines[global_stack.definition.getId()].quality_definition
# And check if the profile_definition matches either one (showing error if not):
if profile_definition != expected_machine_definition:
- Logger.log("e", "Profile [%s] is for machine [%s] but the current active machine is [%s]. Will not import the profile", file_name, profile_definition, expected_machine_definition)
- return { "status": "error",
- "message": catalog.i18nc("@info:status Don't translate the XML tags !", "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it.", file_name, profile_definition, expected_machine_definition)}
+ Logger.log("d", "Profile {file_name} is for machine {profile_definition}, but the current active machine is {expected_machine_definition}. Changing profile's definition.".format(file_name = file_name, profile_definition = profile_definition, expected_machine_definition = expected_machine_definition))
+ global_profile.setMetaDataEntry("definition", expected_machine_definition)
+ for extruder_profile in extruder_profiles:
+ extruder_profile.setMetaDataEntry("definition", expected_machine_definition)
- # Fix the global quality profile's definition field in case it's not correct
- global_profile.setMetaDataEntry("definition", expected_machine_definition)
quality_name = global_profile.getName()
quality_type = global_profile.getMetaDataEntry("quality_type")
@@ -264,10 +272,9 @@ class CuraContainerRegistry(ContainerRegistry):
profile.setMetaDataEntry("type", "quality_changes")
profile.setMetaDataEntry("definition", expected_machine_definition)
profile.setMetaDataEntry("quality_type", quality_type)
- profile.setMetaDataEntry("position", "0")
profile.setDirty(True)
if idx == 0:
- # move all per-extruder settings to the first extruder's quality_changes
+ # Move all per-extruder settings to the first extruder's quality_changes
for qc_setting_key in global_profile.getAllKeys():
settable_per_extruder = global_stack.getProperty(qc_setting_key, "settable_per_extruder")
if settable_per_extruder:
@@ -281,13 +288,14 @@ class CuraContainerRegistry(ContainerRegistry):
profile.addInstance(new_instance)
profile.setDirty(True)
- global_profile.removeInstance(qc_setting_key, postpone_emit=True)
+ global_profile.removeInstance(qc_setting_key, postpone_emit = True)
extruder_profiles.append(profile)
for profile in extruder_profiles:
profile_or_list.append(profile)
# Import all profiles
+ profile_ids_added = [] # type: List[str]
for profile_index, profile in enumerate(profile_or_list):
if profile_index == 0:
# This is assumed to be the global profile
@@ -303,16 +311,20 @@ class CuraContainerRegistry(ContainerRegistry):
profile.setMetaDataEntry("position", extruder_position)
profile_id = (extruder_id + "_" + name_seed).lower().replace(" ", "_")
- else: #More extruders in the imported file than in the machine.
- continue #Delete the additional profiles.
+ else: # More extruders in the imported file than in the machine.
+ continue # Delete the additional profiles.
result = self._configureProfile(profile, profile_id, new_name, expected_machine_definition)
if result is not None:
- return {"status": "error", "message": catalog.i18nc(
- "@info:status Don't translate the XML tags or !",
- "Failed to import profile from {0}:",
- file_name) + " " + result + ""}
+ # Remove any profiles that did got added.
+ for profile_id in profile_ids_added:
+ self.removeContainer(profile_id)
+ return {"status": "error", "message": catalog.i18nc(
+ "@info:status Don't translate the XML tag !",
+ "Failed to import profile from {0}:",
+ file_name) + " " + result}
+ profile_ids_added.append(profile.getId())
return {"status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile_or_list[0].getName())}
# This message is throw when the profile reader doesn't find any profile in the file
@@ -322,11 +334,28 @@ class CuraContainerRegistry(ContainerRegistry):
return {"status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type or is corrupted.", file_name)}
@override(ContainerRegistry)
- def load(self):
+ def load(self) -> None:
super().load()
self._registerSingleExtrusionMachinesExtruderStacks()
self._connectUpgradedExtruderStacksToMachines()
+ ## Check if the metadata for a container is okay before adding it.
+ #
+ # This overrides the one from UM.Settings.ContainerRegistry because we
+ # also require that the setting_version is correct.
+ @override(ContainerRegistry)
+ def _isMetadataValid(self, metadata: Optional[Dict[str, Any]]) -> bool:
+ if metadata is None:
+ return False
+ if "setting_version" not in metadata:
+ return False
+ try:
+ if int(metadata["setting_version"]) != cura.CuraApplication.CuraApplication.SettingVersion:
+ return False
+ except ValueError: #Not parsable as int.
+ return False
+ return True
+
## Update an imported profile to match the current machine configuration.
#
# \param profile The profile to configure.
@@ -358,21 +387,40 @@ class CuraContainerRegistry(ContainerRegistry):
global_stack = Application.getInstance().getGlobalContainerStack()
if global_stack is None:
return None
- definition_id = getMachineDefinitionIDForQualitySearch(global_stack.definition)
+ definition_id = ContainerTree.getInstance().machines[global_stack.definition.getId()].quality_definition
profile.setDefinition(definition_id)
# Check to make sure the imported profile actually makes sense in context of the current configuration.
# This prevents issues where importing a "draft" profile for a machine without "draft" qualities would report as
# successfully imported but then fail to show up.
- quality_manager = cura.CuraApplication.CuraApplication.getInstance()._quality_manager
- quality_group_dict = quality_manager.getQualityGroupsForMachineDefinition(global_stack)
- if quality_type not in quality_group_dict:
+ quality_group_dict = ContainerTree.getInstance().getCurrentQualityGroups()
+ # "not_supported" profiles can be imported.
+ if quality_type != empty_quality_container.getMetaDataEntry("quality_type") and quality_type not in quality_group_dict:
return catalog.i18nc("@info:status", "Could not find a quality type {0} for the current configuration.", quality_type)
ContainerRegistry.getInstance().addContainer(profile)
return None
+ @override(ContainerRegistry)
+ def saveDirtyContainers(self) -> None:
+ # Lock file for "more" atomically loading and saving to/from config dir.
+ with self.lockFile():
+ # Save base files first
+ for instance in self.findDirtyContainers(container_type=InstanceContainer):
+ if instance.getMetaDataEntry("removed"):
+ continue
+ if instance.getId() == instance.getMetaData().get("base_file"):
+ self.saveContainer(instance)
+
+ for instance in self.findDirtyContainers(container_type=InstanceContainer):
+ if instance.getMetaDataEntry("removed"):
+ continue
+ self.saveContainer(instance)
+
+ for stack in self.findContainerStacks():
+ self.saveContainer(stack)
+
## Gets a list of profile writer plugins
# \return List of tuples of (plugin_id, meta_data).
def _getIOPlugins(self, io_type):
@@ -386,32 +434,8 @@ class CuraContainerRegistry(ContainerRegistry):
result.append( (plugin_id, meta_data) )
return result
- ## Returns true if the current machine requires its own materials
- # \return True if the current machine requires its own materials
- def _machineHasOwnMaterials(self):
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if global_container_stack:
- return global_container_stack.getMetaDataEntry("has_materials", False)
- return False
-
- ## Gets the ID of the active material
- # \return the ID of the active material or the empty string
- def _activeMaterialId(self):
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if global_container_stack and global_container_stack.material:
- return global_container_stack.material.getId()
- return ""
-
- ## Returns true if the current machine requires its own quality profiles
- # \return true if the current machine requires its own quality profiles
- def _machineHasOwnQualities(self):
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if global_container_stack:
- return parseBool(global_container_stack.getMetaDataEntry("has_machine_quality", False))
- return False
-
## Convert an "old-style" pure ContainerStack to either an Extruder or Global stack.
- def _convertContainerStack(self, container):
+ def _convertContainerStack(self, container: ContainerStack) -> Union[ExtruderStack.ExtruderStack, GlobalStack.GlobalStack]:
assert type(container) == ContainerStack
container_type = container.getMetaDataEntry("type")
@@ -435,14 +459,14 @@ class CuraContainerRegistry(ContainerRegistry):
return new_stack
- def _registerSingleExtrusionMachinesExtruderStacks(self):
+ def _registerSingleExtrusionMachinesExtruderStacks(self) -> None:
machines = self.findContainerStacks(type = "machine", machine_extruder_trains = {"0": "fdmextruder"})
for machine in machines:
extruder_stacks = self.findContainerStacks(type = "extruder_train", machine = machine.getId())
if not extruder_stacks:
self.addExtruderStackForSingleExtrusionMachine(machine, "fdmextruder")
- def _onContainerAdded(self, container):
+ def _onContainerAdded(self, container: ContainerInterface) -> None:
# We don't have all the machines loaded in the beginning, so in order to add the missing extruder stack
# for single extrusion machines, we subscribe to the containerAdded signal, and whenever a global stack
# is added, we check to see if an extruder stack needs to be added.
@@ -521,7 +545,7 @@ class CuraContainerRegistry(ContainerRegistry):
user_container.setMetaDataEntry("position", extruder_stack.getMetaDataEntry("position"))
if machine.userChanges:
- # for the newly created extruder stack, we need to move all "per-extruder" settings to the user changes
+ # For the newly created extruder stack, we need to move all "per-extruder" settings to the user changes
# container to the extruder stack.
for user_setting_key in machine.userChanges.getAllKeys():
settable_per_extruder = machine.getProperty(user_setting_key, "settable_per_extruder")
@@ -583,7 +607,7 @@ class CuraContainerRegistry(ContainerRegistry):
extruder_quality_changes_container.setMetaDataEntry("position", extruder_definition.getMetaDataEntry("position"))
extruder_stack.qualityChanges = self.findInstanceContainers(id = quality_changes_id)[0]
else:
- # if we still cannot find a quality changes container for the extruder, create a new one
+ # If we still cannot find a quality changes container for the extruder, create a new one
container_name = machine_quality_changes.getName()
container_id = self.uniqueName(extruder_stack.getId() + "_qc_" + container_name)
extruder_quality_changes_container = InstanceContainer(container_id, parent = application)
@@ -592,6 +616,7 @@ class CuraContainerRegistry(ContainerRegistry):
extruder_quality_changes_container.setMetaDataEntry("setting_version", application.SettingVersion)
extruder_quality_changes_container.setMetaDataEntry("position", extruder_definition.getMetaDataEntry("position"))
extruder_quality_changes_container.setMetaDataEntry("quality_type", machine_quality_changes.getMetaDataEntry("quality_type"))
+ extruder_quality_changes_container.setMetaDataEntry("intent_category", "default") # Intent categories weren't a thing back then.
extruder_quality_changes_container.setDefinition(machine_quality_changes.getDefinition().getId())
self.addContainer(extruder_quality_changes_container)
@@ -601,7 +626,7 @@ class CuraContainerRegistry(ContainerRegistry):
Logger.log("w", "Could not find quality_changes named [%s] for extruder [%s]",
machine_quality_changes.getName(), extruder_stack.getId())
else:
- # move all per-extruder settings to the extruder's quality changes
+ # Move all per-extruder settings to the extruder's quality changes
for qc_setting_key in machine_quality_changes.getAllKeys():
settable_per_extruder = machine.getProperty(qc_setting_key, "settable_per_extruder")
if settable_per_extruder:
@@ -642,7 +667,7 @@ class CuraContainerRegistry(ContainerRegistry):
if qc_name not in qc_groups:
qc_groups[qc_name] = []
qc_groups[qc_name].append(qc)
- # try to find from the quality changes cura directory too
+ # Try to find from the quality changes cura directory too
quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine_quality_changes.getName())
if quality_changes_container:
qc_groups[qc_name].append(quality_changes_container)
@@ -656,7 +681,7 @@ class CuraContainerRegistry(ContainerRegistry):
else:
qc_dict["global"] = qc
if qc_dict["global"] is not None and len(qc_dict["extruders"]) == 1:
- # move per-extruder settings
+ # Move per-extruder settings
for qc_setting_key in qc_dict["global"].getAllKeys():
settable_per_extruder = machine.getProperty(qc_setting_key, "settable_per_extruder")
if settable_per_extruder:
@@ -676,7 +701,7 @@ class CuraContainerRegistry(ContainerRegistry):
return extruder_stack
- def _findQualityChangesContainerInCuraFolder(self, name):
+ def _findQualityChangesContainerInCuraFolder(self, name: str) -> Optional[InstanceContainer]:
quality_changes_dir = Resources.getPath(cura.CuraApplication.CuraApplication.ResourceTypes.QualityChangesInstanceContainer)
instance_container = None
@@ -689,18 +714,18 @@ class CuraContainerRegistry(ContainerRegistry):
parser = configparser.ConfigParser(interpolation = None)
try:
parser.read([file_path])
- except:
- # skip, it is not a valid stack file
+ except Exception:
+ # Skip, it is not a valid stack file
continue
if not parser.has_option("general", "name"):
continue
if parser["general"]["name"] == name:
- # load the container
+ # Load the container
container_id = os.path.basename(file_path).replace(".inst.cfg", "")
if self.findInstanceContainers(id = container_id):
- # this container is already in the registry, skip it
+ # This container is already in the registry, skip it
continue
instance_container = InstanceContainer(container_id)
@@ -721,7 +746,7 @@ class CuraContainerRegistry(ContainerRegistry):
# due to problems with loading order, some stacks may not have the proper next stack
# set after upgrading, because the proper global stack was not yet loaded. This method
# makes sure those extruders also get the right stack set.
- def _connectUpgradedExtruderStacksToMachines(self):
+ def _connectUpgradedExtruderStacksToMachines(self) -> None:
extruder_stacks = self.findContainers(container_type = ExtruderStack.ExtruderStack)
for extruder_stack in extruder_stacks:
if extruder_stack.getNextStack():
@@ -734,8 +759,8 @@ class CuraContainerRegistry(ContainerRegistry):
else:
Logger.log("w", "Could not find machine {machine} for extruder {extruder}", machine = extruder_stack.getMetaDataEntry("machine"), extruder = extruder_stack.getId())
- #Override just for the type.
+ # Override just for the type.
@classmethod
@override(ContainerRegistry)
def getInstance(cls, *args, **kwargs) -> "CuraContainerRegistry":
- return cast(CuraContainerRegistry, super().getInstance(*args, **kwargs))
\ No newline at end of file
+ return cast(CuraContainerRegistry, super().getInstance(*args, **kwargs))
diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py
index 042b065226..1455e140a8 100755
--- a/cura/Settings/CuraContainerStack.py
+++ b/cura/Settings/CuraContainerStack.py
@@ -87,6 +87,19 @@ class CuraContainerStack(ContainerStack):
def qualityChanges(self) -> InstanceContainer:
return cast(InstanceContainer, self._containers[_ContainerIndexes.QualityChanges])
+ ## Set the intent container.
+ #
+ # \param new_intent The new intent container. It is expected to have a "type" metadata entry with the value "intent".
+ def setIntent(self, new_intent: InstanceContainer, postpone_emit: bool = False) -> None:
+ self.replaceContainer(_ContainerIndexes.Intent, new_intent, postpone_emit = postpone_emit)
+
+ ## Get the quality container.
+ #
+ # \return The intent container. Should always be a valid container, but can be equal to the empty InstanceContainer.
+ @pyqtProperty(InstanceContainer, fset = setIntent, notify = pyqtContainersChanged)
+ def intent(self) -> InstanceContainer:
+ return cast(InstanceContainer, self._containers[_ContainerIndexes.Intent])
+
## Set the quality container.
#
# \param new_quality The new quality container. It is expected to have a "type" metadata entry with the value "quality".
@@ -330,16 +343,18 @@ class CuraContainerStack(ContainerStack):
class _ContainerIndexes:
UserChanges = 0
QualityChanges = 1
- Quality = 2
- Material = 3
- Variant = 4
- DefinitionChanges = 5
- Definition = 6
+ Intent = 2
+ Quality = 3
+ Material = 4
+ Variant = 5
+ DefinitionChanges = 6
+ Definition = 7
# Simple hash map to map from index to "type" metadata entry
IndexTypeMap = {
UserChanges: "user",
QualityChanges: "quality_changes",
+ Intent: "intent",
Quality: "quality",
Material: "material",
Variant: "variant",
diff --git a/cura/Settings/CuraFormulaFunctions.py b/cura/Settings/CuraFormulaFunctions.py
index 9ef80bd3d4..b35069da6f 100644
--- a/cura/Settings/CuraFormulaFunctions.py
+++ b/cura/Settings/CuraFormulaFunctions.py
@@ -40,9 +40,16 @@ class CuraFormulaFunctions:
global_stack = machine_manager.activeMachine
try:
- extruder_stack = global_stack.extruders[str(extruder_position)]
- except KeyError:
- Logger.log("w", "Value for %s of extruder %s was requested, but that extruder is not available" % (property_key, extruder_position))
+ extruder_stack = global_stack.extruderList[int(extruder_position)]
+ except IndexError:
+ if extruder_position != 0:
+ Logger.log("w", "Value for %s of extruder %s was requested, but that extruder is not available. Returning the result form extruder 0 instead" % (property_key, extruder_position))
+ # This fixes a very specific fringe case; If a profile was created for a custom printer and one of the
+ # extruder settings has been set to non zero and the profile is loaded for a machine that has only a single extruder
+ # it would cause all kinds of issues (and eventually a crash).
+ # See https://github.com/Ultimaker/Cura/issues/5535
+ return self.getValueInExtruder(0, property_key, context)
+ Logger.log("w", "Value for %s of extruder %s was requested, but that extruder is not available. " % (property_key, extruder_position))
return None
value = extruder_stack.getRawProperty(property_key, "value", context = context)
@@ -97,11 +104,14 @@ class CuraFormulaFunctions:
machine_manager = self._application.getMachineManager()
global_stack = machine_manager.activeMachine
- extruder_stack = global_stack.extruders[str(extruder_position)]
+ try:
+ extruder_stack = global_stack.extruderList[extruder_position]
+ except IndexError:
+ Logger.log("w", "Unable to find extruder on in index %s", extruder_position)
+ else:
+ context = self.createContextForDefaultValueEvaluation(extruder_stack)
- context = self.createContextForDefaultValueEvaluation(extruder_stack)
-
- return self.getValueInExtruder(extruder_position, property_key, context = context)
+ return self.getValueInExtruder(extruder_position, property_key, context = context)
# Gets all default setting values as a list from all extruders of the currently active machine.
# The default values are those excluding the values in the user_changes container.
diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py
index c98c63f529..61a04e1be6 100644
--- a/cura/Settings/CuraStackBuilder.py
+++ b/cura/Settings/CuraStackBuilder.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional
@@ -8,7 +8,8 @@ from UM.Logger import Logger
from UM.Settings.Interfaces import DefinitionContainerInterface
from UM.Settings.InstanceContainer import InstanceContainer
-from cura.Machines.VariantType import VariantType
+from cura.Machines.ContainerTree import ContainerTree
+from cura.Machines.MachineNode import MachineNode
from .GlobalStack import GlobalStack
from .ExtruderStack import ExtruderStack
@@ -26,9 +27,8 @@ class CuraStackBuilder:
def createMachine(cls, name: str, definition_id: str) -> Optional[GlobalStack]:
from cura.CuraApplication import CuraApplication
application = CuraApplication.getInstance()
- variant_manager = application.getVariantManager()
- quality_manager = application.getQualityManager()
registry = application.getContainerRegistry()
+ container_tree = ContainerTree.getInstance()
definitions = registry.findDefinitionContainers(id = definition_id)
if not definitions:
@@ -37,14 +37,7 @@ class CuraStackBuilder:
return None
machine_definition = definitions[0]
-
- # get variant container for the global stack
- global_variant_container = application.empty_variant_container
- global_variant_node = variant_manager.getDefaultVariantNode(machine_definition, VariantType.BUILD_PLATE)
- if global_variant_node:
- global_variant_container = global_variant_node.getContainer()
- if not global_variant_container:
- global_variant_container = application.empty_variant_container
+ machine_node = container_tree.machines[machine_definition.getId()]
generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName())
# Make sure the new name does not collide with any definition or (quality) profile
@@ -56,9 +49,9 @@ class CuraStackBuilder:
new_global_stack = cls.createGlobalStack(
new_stack_id = generated_name,
definition = machine_definition,
- variant_container = global_variant_container,
+ variant_container = application.empty_variant_container,
material_container = application.empty_material_container,
- quality_container = application.empty_quality_container,
+ quality_container = machine_node.preferredGlobalQuality().container,
)
new_global_stack.setName(generated_name)
@@ -67,33 +60,9 @@ class CuraStackBuilder:
for position in extruder_dict:
cls.createExtruderStackWithDefaultSetup(new_global_stack, position)
- for new_extruder in new_global_stack.extruders.values(): #Only register the extruders if we're sure that all of them are correct.
+ for new_extruder in new_global_stack.extruders.values(): # Only register the extruders if we're sure that all of them are correct.
registry.addContainer(new_extruder)
- preferred_quality_type = machine_definition.getMetaDataEntry("preferred_quality_type")
- quality_group_dict = quality_manager.getQualityGroups(new_global_stack)
- if not quality_group_dict:
- # There is no available quality group, set all quality containers to empty.
- new_global_stack.quality = application.empty_quality_container
- for extruder_stack in new_global_stack.extruders.values():
- extruder_stack.quality = application.empty_quality_container
- else:
- # Set the quality containers to the preferred quality type if available, otherwise use the first quality
- # type that's available.
- if preferred_quality_type not in quality_group_dict:
- Logger.log("w", "The preferred quality {quality_type} doesn't exist for this set-up. Choosing a random one.".format(quality_type = preferred_quality_type))
- preferred_quality_type = next(iter(quality_group_dict))
- quality_group = quality_group_dict.get(preferred_quality_type)
-
- new_global_stack.quality = quality_group.node_for_global.getContainer()
- if not new_global_stack.quality:
- new_global_stack.quality = application.empty_quality_container
- for position, extruder_stack in new_global_stack.extruders.items():
- if position in quality_group.nodes_for_extruders and quality_group.nodes_for_extruders[position].getContainer():
- extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer()
- else:
- extruder_stack.quality = application.empty_quality_container
-
# Register the global stack after the extruder stacks are created. This prevents the registry from adding another
# extruder stack because the global stack didn't have one yet (which is enforced since Cura 3.1).
registry.addContainer(new_global_stack)
@@ -108,31 +77,32 @@ class CuraStackBuilder:
def createExtruderStackWithDefaultSetup(cls, global_stack: "GlobalStack", extruder_position: int) -> None:
from cura.CuraApplication import CuraApplication
application = CuraApplication.getInstance()
- variant_manager = application.getVariantManager()
- material_manager = application.getMaterialManager()
registry = application.getContainerRegistry()
- # get variant container for extruders
- extruder_variant_container = application.empty_variant_container
- extruder_variant_node = variant_manager.getDefaultVariantNode(global_stack.definition, VariantType.NOZZLE,
- global_stack = global_stack)
- extruder_variant_name = None
- if extruder_variant_node:
- extruder_variant_container = extruder_variant_node.getContainer()
- if not extruder_variant_container:
- extruder_variant_container = application.empty_variant_container
- extruder_variant_name = extruder_variant_container.getName()
-
+ # Get the extruder definition.
extruder_definition_dict = global_stack.getMetaDataEntry("machine_extruder_trains")
extruder_definition_id = extruder_definition_dict[str(extruder_position)]
- extruder_definition = registry.findDefinitionContainers(id = extruder_definition_id)[0]
+ try:
+ extruder_definition = registry.findDefinitionContainers(id = extruder_definition_id)[0]
+ 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]" % extruder_definition_id
+ Logger.logException("e", msg)
+ raise IndexError(msg)
- # get material container for extruders
- material_container = application.empty_material_container
- material_node = material_manager.getDefaultMaterial(global_stack, str(extruder_position), extruder_variant_name,
- extruder_definition = extruder_definition)
- if material_node and material_node.getContainer():
- material_container = material_node.getContainer()
+ # Find out what filament diameter we need.
+ approximate_diameter = round(extruder_definition.getProperty("material_diameter", "value")) # Can't be modified by definition changes since we are just initialising the stack here.
+
+ # Find the preferred containers.
+ machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
+ extruder_variant_node = machine_node.variants.get(machine_node.preferred_variant_name)
+ if not extruder_variant_node:
+ Logger.log("w", "Could not find preferred nozzle {nozzle_name}. Falling back to {fallback}.".format(nozzle_name = machine_node.preferred_variant_name, fallback = next(iter(machine_node.variants))))
+ extruder_variant_node = next(iter(machine_node.variants.values()))
+ extruder_variant_container = extruder_variant_node.container
+ material_node = extruder_variant_node.preferredMaterial(approximate_diameter)
+ material_container = material_node.container
+ quality_node = material_node.preferredQuality()
new_extruder_id = registry.uniqueName(extruder_definition_id)
new_extruder = cls.createExtruderStack(
@@ -142,7 +112,7 @@ class CuraStackBuilder:
position = extruder_position,
variant_container = extruder_variant_container,
material_container = material_container,
- quality_container = application.empty_quality_container
+ quality_container = quality_node.container
)
new_extruder.setNextStack(global_stack)
@@ -184,6 +154,7 @@ class CuraStackBuilder:
stack.variant = variant_container
stack.material = material_container
stack.quality = quality_container
+ stack.intent = application.empty_intent_container
stack.qualityChanges = application.empty_quality_changes_container
stack.userChanges = user_container
@@ -232,6 +203,7 @@ class CuraStackBuilder:
stack.variant = variant_container
stack.material = material_container
stack.quality = quality_container
+ stack.intent = application.empty_intent_container
stack.qualityChanges = application.empty_quality_changes_container
stack.userChanges = user_container
diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py
index f8dccb4ba6..62bf396878 100755
--- a/cura/Settings/ExtruderManager.py
+++ b/cura/Settings/ExtruderManager.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt.
@@ -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.Settings.ContainerStack import ContainerStack
from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING, Union
@@ -42,8 +41,6 @@ class ExtruderManager(QObject):
# TODO; I have no idea why this is a union of ID's and extruder stacks. This needs to be fixed at some point.
self._selected_object_extruders = [] # type: List[Union[str, "ExtruderStack"]]
- self._addCurrentMachineExtruders()
-
Selection.selectionChanged.connect(self.resetSelectedObjectExtruders)
## Signal to notify other components when the list of extruders for a machine definition changes.
@@ -74,7 +71,7 @@ class ExtruderManager(QObject):
global_container_stack = self._application.getGlobalContainerStack()
if global_container_stack:
- extruder_stack_ids = {position: extruder.id for position, extruder in global_container_stack.extruders.items()}
+ extruder_stack_ids = {extruder.getMetaDataEntry("position", ""): extruder.id for extruder in global_container_stack.extruderList}
return extruder_stack_ids
@@ -91,16 +88,6 @@ class ExtruderManager(QObject):
def activeExtruderIndex(self) -> int:
return self._active_extruder_index
- ## Gets the extruder name of an extruder of the currently active machine.
- #
- # \param index The index of the extruder whose name to get.
- @pyqtSlot(int, result = str)
- def getExtruderName(self, index: int) -> str:
- try:
- return self.getActiveExtruderStacks()[index].getName()
- except IndexError:
- return ""
-
## Emitted whenever the selectedObjectExtruders property changes.
selectedObjectExtrudersChanged = pyqtSignal()
@@ -114,7 +101,7 @@ class ExtruderManager(QObject):
selected_nodes = [] # type: List["SceneNode"]
for node in Selection.getAllSelectedObjects():
if node.callDecoration("isGroup"):
- for grouped_node in BreadthFirstIterator(node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+ for grouped_node in BreadthFirstIterator(node):
if grouped_node.callDecoration("isGroup"):
continue
@@ -131,7 +118,7 @@ class ExtruderManager(QObject):
elif current_extruder_trains:
object_extruders.add(current_extruder_trains[0].getId())
- self._selected_object_extruders = list(object_extruders) # type: List[Union[str, "ExtruderStack"]]
+ self._selected_object_extruders = list(object_extruders)
return self._selected_object_extruders
@@ -140,7 +127,7 @@ class ExtruderManager(QObject):
# This will trigger a recalculation of the extruders used for the
# selection.
def resetSelectedObjectExtruders(self) -> None:
- self._selected_object_extruders = [] # type: List[Union[str, "ExtruderStack"]]
+ self._selected_object_extruders = []
self.selectedObjectExtrudersChanged.emit()
@pyqtSlot(result = QObject)
@@ -180,7 +167,7 @@ class ExtruderManager(QObject):
# \param setting_key \type{str} The setting to get the property of.
# \param property \type{str} The property to get.
# \return \type{List} the list of results
- def getAllExtruderSettings(self, setting_key: str, prop: str) -> List:
+ def getAllExtruderSettings(self, setting_key: str, prop: str) -> List[Any]:
result = []
for extruder_stack in self.getActiveExtruderStacks():
@@ -205,7 +192,7 @@ class ExtruderManager(QObject):
# list.
#
# \return A list of extruder stacks.
- def getUsedExtruderStacks(self) -> List["ContainerStack"]:
+ def getUsedExtruderStacks(self) -> List["ExtruderStack"]:
global_stack = self._application.getGlobalContainerStack()
container_registry = ContainerRegistry.getInstance()
@@ -224,7 +211,16 @@ class ExtruderManager(QObject):
# Get the extruders of all printable meshes in the scene
meshes = [node for node in DepthFirstIterator(scene_root) if isinstance(node, SceneNode) and node.isSelectable()] #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+
+ # Exclude anti-overhang meshes
+ mesh_list = []
for mesh in meshes:
+ stack = mesh.callDecoration("getStack")
+ if stack is not None and (stack.getProperty("anti_overhang_mesh", "value") or stack.getProperty("support_mesh", "value")):
+ continue
+ mesh_list.append(mesh)
+
+ for mesh in mesh_list:
extruder_stack_id = mesh.callDecoration("getActiveExtruder")
if not extruder_stack_id:
# No per-object settings for this node
@@ -270,7 +266,8 @@ class ExtruderManager(QObject):
extruder_str_nr = str(global_stack.getProperty("adhesion_extruder_nr", "value"))
if extruder_str_nr == "-1":
extruder_str_nr = self._application.getMachineManager().defaultExtruderPosition
- used_extruder_stack_ids.add(self.extruderIds[extruder_str_nr])
+ if extruder_str_nr in self.extruderIds:
+ used_extruder_stack_ids.add(self.extruderIds[extruder_str_nr])
try:
return [container_registry.findContainerStacks(id = stack_id)[0] for stack_id in used_extruder_stack_ids]
@@ -311,48 +308,47 @@ class ExtruderManager(QObject):
self.resetSelectedObjectExtruders()
- ## Adds the extruders of the currently active machine.
- def _addCurrentMachineExtruders(self) -> None:
- global_stack = self._application.getGlobalContainerStack()
+ ## Adds the extruders to the selected machine.
+ def addMachineExtruders(self, global_stack: GlobalStack) -> None:
extruders_changed = False
+ container_registry = ContainerRegistry.getInstance()
+ global_stack_id = global_stack.getId()
- if global_stack:
- container_registry = ContainerRegistry.getInstance()
- global_stack_id = global_stack.getId()
+ # Gets the extruder trains that we just created as well as any that still existed.
+ extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = global_stack_id)
- # Gets the extruder trains that we just created as well as any that still existed.
- extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = global_stack_id)
+ # Make sure the extruder trains for the new machine can be placed in the set of sets
+ if global_stack_id not in self._extruder_trains:
+ self._extruder_trains[global_stack_id] = {}
+ extruders_changed = True
- # Make sure the extruder trains for the new machine can be placed in the set of sets
- if global_stack_id not in self._extruder_trains:
- self._extruder_trains[global_stack_id] = {}
- extruders_changed = True
+ # Register the extruder trains by position
+ for extruder_train in extruder_trains:
+ extruder_position = extruder_train.getMetaDataEntry("position")
+ self._extruder_trains[global_stack_id][extruder_position] = extruder_train
- # Register the extruder trains by position
- for extruder_train in extruder_trains:
- extruder_position = extruder_train.getMetaDataEntry("position")
- self._extruder_trains[global_stack_id][extruder_position] = extruder_train
+ # regardless of what the next stack is, we have to set it again, because of signal routing. ???
+ extruder_train.setParent(global_stack)
+ extruder_train.setNextStack(global_stack)
+ extruders_changed = True
- # regardless of what the next stack is, we have to set it again, because of signal routing. ???
- extruder_train.setParent(global_stack)
- extruder_train.setNextStack(global_stack)
- extruders_changed = True
-
- self._fixSingleExtrusionMachineExtruderDefinition(global_stack)
- if extruders_changed:
- self.extrudersChanged.emit(global_stack_id)
- self.setActiveExtruderIndex(0)
- self.activeExtruderChanged.emit()
+ self.fixSingleExtrusionMachineExtruderDefinition(global_stack)
+ if extruders_changed:
+ self.extrudersChanged.emit(global_stack_id)
# After 3.4, all single-extrusion machines have their own extruder definition files instead of reusing
# "fdmextruder". We need to check a machine here so its extruder definition is correct according to this.
- def _fixSingleExtrusionMachineExtruderDefinition(self, global_stack: "GlobalStack") -> None:
+ def fixSingleExtrusionMachineExtruderDefinition(self, global_stack: "GlobalStack") -> None:
container_registry = ContainerRegistry.getInstance()
expected_extruder_definition_0_id = global_stack.getMetaDataEntry("machine_extruder_trains")["0"]
- extruder_stack_0 = global_stack.extruders.get("0")
+ try:
+ extruder_stack_0 = global_stack.extruderList[0]
+ except IndexError:
+ extruder_stack_0 = None
+
# At this point, extruder stacks for this machine may not have been loaded yet. In this case, need to look in
# the container registry as well.
- if not global_stack.extruders:
+ if not global_stack.extruderList:
extruder_trains = container_registry.findContainerStacks(type = "extruder_train",
machine = global_stack.getId())
if extruder_trains:
@@ -370,7 +366,13 @@ class ExtruderManager(QObject):
elif extruder_stack_0.definition.getId() != expected_extruder_definition_0_id:
Logger.log("e", "Single extruder printer [{printer}] expected extruder [{expected}], but got [{got}]. I'm making it [{expected}].".format(
printer = global_stack.getId(), expected = expected_extruder_definition_0_id, got = extruder_stack_0.definition.getId()))
- extruder_definition = container_registry.findDefinitionContainers(id = expected_extruder_definition_0_id)[0]
+ try:
+ extruder_definition = container_registry.findDefinitionContainers(id = expected_extruder_definition_0_id)[0]
+ 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)
+ raise IndexError(msg)
extruder_stack_0.definition = extruder_definition
## Get all extruder values for a certain setting.
diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py
index edb0e7d41f..5d4b3e38b1 100644
--- a/cura/Settings/ExtruderStack.py
+++ b/cura/Settings/ExtruderStack.py
@@ -51,6 +51,10 @@ class ExtruderStack(CuraContainerStack):
def getNextStack(self) -> Optional["GlobalStack"]:
return super().getNextStack()
+ @pyqtProperty(int, constant = True)
+ def position(self) -> int:
+ return int(self.getMetaDataEntry("position"))
+
def setEnabled(self, enabled: bool) -> None:
if self.getMetaDataEntry("enabled", True) == enabled: # No change.
return # Don't emit a signal then.
@@ -135,12 +139,15 @@ class ExtruderStack(CuraContainerStack):
if limit_to_extruder == -1:
limit_to_extruder = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition)
limit_to_extruder = str(limit_to_extruder)
+
if (limit_to_extruder is not None and limit_to_extruder != "-1") and self.getMetaDataEntry("position") != str(limit_to_extruder):
- if str(limit_to_extruder) in self.getNextStack().extruders:
- result = self.getNextStack().extruders[str(limit_to_extruder)].getProperty(key, property_name, context)
+ try:
+ result = self.getNextStack().extruderList[int(limit_to_extruder)].getProperty(key, property_name, context)
if result is not None:
context.popContainer()
return result
+ except IndexError:
+ pass
result = super().getProperty(key, property_name, context)
context.popContainer()
diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py
index 3940af7ecc..d3a8842aa3 100755
--- a/cura/Settings/GlobalStack.py
+++ b/cura/Settings/GlobalStack.py
@@ -1,12 +1,14 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from collections import defaultdict
import threading
from typing import Any, Dict, Optional, Set, TYPE_CHECKING, List
+import uuid
+
from PyQt5.QtCore import pyqtProperty, pyqtSlot, pyqtSignal
-from UM.Decorators import override
+from UM.Decorators import deprecated, override
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.SettingInstance import InstanceState
@@ -18,6 +20,7 @@ from UM.Platform import Platform
from UM.Util import parseBool
import cura.CuraApplication
+from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
from . import Exceptions
from .CuraContainerStack import CuraContainerStack
@@ -34,6 +37,12 @@ class GlobalStack(CuraContainerStack):
self.setMetaDataEntry("type", "machine") # For backward compatibility
+ # TL;DR: If Cura is looking for printers that belong to the same group, it should use "group_id".
+ # Each GlobalStack by default belongs to a group which is identified via "group_id". This group_id is used to
+ # figure out which GlobalStacks are in the printer cluster for example without knowing the implementation
+ # details such as the um_network_key or some other identifier that's used by the underlying device plugin.
+ self.setMetaDataEntry("group_id", str(uuid.uuid4())) # Assign a new GlobalStack to a unique group by default
+
self._extruders = {} # type: Dict[str, "ExtruderStack"]
# This property is used to track which settings we are calculating the "resolve" for
@@ -53,17 +62,26 @@ class GlobalStack(CuraContainerStack):
#
# \return The extruders registered with this stack.
@pyqtProperty("QVariantMap", notify = extrudersChanged)
+ @deprecated("Please use extruderList instead.", "4.4")
def extruders(self) -> Dict[str, "ExtruderStack"]:
return self._extruders
@pyqtProperty("QVariantList", notify = extrudersChanged)
def extruderList(self) -> List["ExtruderStack"]:
- result_tuple_list = sorted(list(self.extruders.items()), key=lambda x: int(x[0]))
+ result_tuple_list = sorted(list(self._extruders.items()), key=lambda x: int(x[0]))
result_list = [item[1] for item in result_tuple_list]
machine_extruder_count = self.getProperty("machine_extruder_count", "value")
return result_list[:machine_extruder_count]
+ @pyqtProperty(int, constant = True)
+ def maxExtruderCount(self):
+ return len(self.getMetaDataEntry("machine_extruder_trains"))
+
+ @pyqtProperty(bool, notify=configuredConnectionTypesChanged)
+ def supportsNetworkConnection(self):
+ return self.getMetaDataEntry("supports_network_connection", False)
+
@classmethod
def getLoadingPriority(cls) -> int:
return 2
@@ -81,7 +99,28 @@ class GlobalStack(CuraContainerStack):
# Requesting it from the metadata actually gets them as strings (as that's what you get from serializing).
# But we do want them returned as a list of ints (so the rest of the code can directly compare)
connection_types = self.getMetaDataEntry("connection_type", "").split(",")
- return [int(connection_type) for connection_type in connection_types if connection_type != ""]
+ result = []
+ for connection_type in connection_types:
+ if connection_type != "":
+ try:
+ result.append(int(connection_type))
+ except ValueError:
+ # We got invalid data, probably a None.
+ pass
+ return result
+
+ # Returns a boolean indicating if this machine has a remote connection. A machine is considered as remotely
+ # connected if its connection types contain one of the following values:
+ # - ConnectionType.NetworkConnection
+ # - ConnectionType.CloudConnection
+ @pyqtProperty(bool, notify = configuredConnectionTypesChanged)
+ def hasRemoteConnection(self) -> bool:
+ has_remote_connection = False
+
+ for connection_type in self.configuredConnectionTypes:
+ has_remote_connection |= connection_type in [ConnectionType.NetworkConnection.value,
+ ConnectionType.CloudConnection.value]
+ return has_remote_connection
## \sa configuredConnectionTypes
def addConfiguredConnectionType(self, connection_type: int) -> None:
@@ -94,7 +133,7 @@ class GlobalStack(CuraContainerStack):
## \sa configuredConnectionTypes
def removeConfiguredConnectionType(self, connection_type: int) -> None:
configured_connection_types = self.configuredConnectionTypes
- if connection_type in self.configured_connection_types:
+ if connection_type in configured_connection_types:
# Store the values as a string.
configured_connection_types.remove(connection_type)
self.setMetaDataEntry("connection_type", ",".join([str(c_type) for c_type in configured_connection_types]))
@@ -106,6 +145,14 @@ class GlobalStack(CuraContainerStack):
return "machine_stack"
return configuration_type
+ def getIntentCategory(self) -> str:
+ intent_category = "default"
+ for extruder in self.extruderList:
+ category = extruder.intent.getMetaDataEntry("intent_category", "default")
+ if category != "default" and category != intent_category:
+ intent_category = category
+ return intent_category
+
def getBuildplateName(self) -> Optional[str]:
name = None
if self.variant.getId() != "empty_variant":
@@ -200,7 +247,7 @@ class GlobalStack(CuraContainerStack):
# Determine whether or not we should try to get the "resolve" property instead of the
# requested property.
def _shouldResolve(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> bool:
- if property_name is not "value":
+ if property_name != "value":
# Do not try to resolve anything but the "value" property
return False
@@ -240,14 +287,17 @@ class GlobalStack(CuraContainerStack):
def getHeadAndFansCoordinates(self):
return self.getProperty("machine_head_with_fans_polygon", "value")
- def getHasMaterials(self) -> bool:
+ @pyqtProperty(bool, constant = True)
+ def hasMaterials(self) -> bool:
return parseBool(self.getMetaDataEntry("has_materials", False))
- def getHasVariants(self) -> bool:
+ @pyqtProperty(bool, constant = True)
+ def hasVariants(self) -> bool:
return parseBool(self.getMetaDataEntry("has_variants", False))
- def getHasMachineQuality(self) -> bool:
- return parseBool(self.getMetaDataEntry("has_machine_quality", False))
+ @pyqtProperty(bool, constant = True)
+ def hasVariantBuildplates(self) -> bool:
+ return parseBool(self.getMetaDataEntry("has_variant_buildplates", False))
## Get default firmware file name if one is specified in the firmware
@pyqtSlot(result = str)
@@ -275,6 +325,17 @@ class GlobalStack(CuraContainerStack):
Logger.log("w", "Firmware file %s not found.", hex_file)
return ""
+ def getName(self) -> str:
+ return self._metadata.get("group_name", self._metadata.get("name", ""))
+
+ def setName(self, name: "str") -> None:
+ super().setName(name)
+
+ nameChanged = pyqtSignal()
+ name = pyqtProperty(str, fget=getName, fset=setName, notify=nameChanged)
+
+
+
## private:
global_stack_mime = MimeType(
name = "application/x-cura-globalstack",
diff --git a/cura/Settings/IntentManager.py b/cura/Settings/IntentManager.py
new file mode 100644
index 0000000000..5133b401b4
--- /dev/null
+++ b/cura/Settings/IntentManager.py
@@ -0,0 +1,179 @@
+# 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
+
+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
+
+if TYPE_CHECKING:
+ from UM.Settings.InstanceContainer import InstanceContainer
+
+
+## Front-end for querying which intents are available for a certain
+# configuration.
+class IntentManager(QObject):
+ __instance = None
+
+ ## This class is a singleton.
+ @classmethod
+ def getInstance(cls):
+ if not cls.__instance:
+ cls.__instance = IntentManager()
+ return cls.__instance
+
+ intentCategoryChanged = pyqtSignal() #Triggered when we switch categories.
+
+ ## Gets the metadata dictionaries of all intent profiles for a given
+ # configuration.
+ #
+ # \param definition_id ID of the printer.
+ # \param nozzle_name Name of the nozzle.
+ # \param material_base_file The base_file of the material.
+ # \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]]:
+ intent_metadatas = [] # type: List[Dict[str, Any]]
+ try:
+ materials = ContainerTree.getInstance().machines[definition_id].variants[nozzle_name].materials
+ except KeyError:
+ Logger.log("w", "Unable to find the machine %s or the variant %s", definition_id, 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())
+ return intent_metadatas
+
+ ## Collects and returns all intent categories available for the given
+ # parameters. Note that the 'default' category is always available.
+ #
+ # \param definition_id ID of the printer.
+ # \param nozzle_name Name of the nozzle.
+ # \param material_id ID of the material.
+ # \return A set of intent category names.
+ def intentCategories(self, definition_id: str, nozzle_id: str, material_id: str) -> List[str]:
+ categories = set()
+ for intent in self.intentMetadatas(definition_id, nozzle_id, material_id):
+ categories.add(intent["intent_category"])
+ categories.add("default") #The "empty" intent is not an actual profile specific to the configuration but we do want it to appear in the categories list.
+ return list(categories)
+
+ ## List of intents to be displayed in the interface.
+ #
+ # For the interface this will have to be broken up into the different
+ # intent categories. That is up to the model there.
+ #
+ # \return A list of tuples of intent_category and quality_type. The actual
+ # instance may vary per extruder.
+ def getCurrentAvailableIntents(self) -> List[Tuple[str, str]]:
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ global_stack = application.getGlobalContainerStack()
+ if global_stack is None:
+ return [("default", "normal")]
+ # TODO: We now do this (return a default) if the global stack is missing, but not in the code below,
+ # even though there should always be defaults. The problem then is what to do with the quality_types.
+ # Currently _also_ inconsistent with 'currentAvailableIntentCategories', which _does_ return default.
+ quality_groups = ContainerTree.getInstance().getCurrentQualityGroups()
+ available_quality_types = {quality_group.quality_type for quality_group in quality_groups.values() if quality_group.node_for_global is not None}
+
+ final_intent_ids = set() # type: Set[str]
+ current_definition_id = global_stack.definition.getId()
+ for extruder_stack in global_stack.extruderList:
+ if not extruder_stack.isEnabled:
+ continue
+ nozzle_name = extruder_stack.variant.getMetaDataEntry("name")
+ material_id = extruder_stack.material.getMetaDataEntry("base_file")
+ final_intent_ids |= {metadata["id"] for metadata in self.intentMetadatas(current_definition_id, nozzle_name, material_id) if metadata.get("quality_type") in available_quality_types}
+
+ result = set() # type: Set[Tuple[str, str]]
+ for intent_id in final_intent_ids:
+ intent_metadata = application.getContainerRegistry().findContainersMetadata(id = intent_id)[0]
+ result.add((intent_metadata["intent_category"], intent_metadata["quality_type"]))
+ return list(result)
+
+ ## List of intent categories available in either of the extruders.
+ #
+ # This is purposefully inconsistent with the way that the quality types
+ # are listed. The quality types will show all quality types available in
+ # the printer using any configuration. This will only list the intent
+ # categories that are available using the current configuration (but the
+ # union over the extruders).
+ # \return List of all categories in the current configurations of all
+ # extruders.
+ def currentAvailableIntentCategories(self) -> List[str]:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return ["default"]
+ current_definition_id = global_stack.definition.getId()
+ final_intent_categories = set() # type: Set[str]
+ for extruder_stack in global_stack.extruderList:
+ if not extruder_stack.isEnabled:
+ continue
+ nozzle_name = extruder_stack.variant.getMetaDataEntry("name")
+ material_id = extruder_stack.material.getMetaDataEntry("base_file")
+ final_intent_categories.update(self.intentCategories(current_definition_id, nozzle_name, material_id))
+ return list(final_intent_categories)
+
+ ## 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":
+ return empty_intent_container
+
+ @pyqtProperty(str, notify = intentCategoryChanged)
+ def currentIntentCategory(self) -> str:
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ active_extruder_stack = application.getMachineManager().activeStack
+ if active_extruder_stack is None:
+ return ""
+ return active_extruder_stack.intent.getMetaDataEntry("intent_category", "")
+
+ ## Apply intent on the stacks.
+ @pyqtSlot(str, str)
+ def selectIntent(self, intent_category: str, quality_type: str) -> None:
+ Logger.log("i", "Attempting to set intent_category to [%s] and quality type to [%s]", intent_category, quality_type)
+ old_intent_category = self.currentIntentCategory
+ application = cura.CuraApplication.CuraApplication.getInstance()
+ global_stack = application.getGlobalContainerStack()
+ if global_stack is None:
+ return
+ current_definition_id = global_stack.definition.getId()
+ machine_node = ContainerTree.getInstance().machines[current_definition_id]
+ for extruder_stack in global_stack.extruderList:
+ nozzle_name = extruder_stack.variant.getMetaDataEntry("name")
+ material_id = extruder_stack.material.getMetaDataEntry("base_file")
+
+ material_node = machine_node.variants[nozzle_name].materials[material_id]
+
+ # Since we want to switch to a certain quality type, check the tree if we have one.
+ quality_node = None
+ for q_node in material_node.qualities.values():
+ if q_node.quality_type == quality_type:
+ quality_node = q_node
+
+ if quality_node is None:
+ Logger.log("w", "Unable to find quality_type [%s] for extruder [%s]", quality_type, extruder_stack.getId())
+ continue
+
+ # Check that quality node if we can find a matching intent.
+ intent_id = None
+ for id, intent_node in quality_node.intents.items():
+ if intent_node.intent_category == intent_category:
+ intent_id = id
+ intent = application.getContainerRegistry().findContainers(id = intent_id)
+ if intent:
+ extruder_stack.intent = intent[0]
+ else:
+ extruder_stack.intent = self.getDefaultIntent()
+ application.getMachineManager().setQualityGroupByQualityType(quality_type)
+ if old_intent_category != intent_category:
+ self.intentCategoryChanged.emit()
diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py
index 03b04cc3bb..de6e270a86 100755
--- a/cura/Settings/MachineManager.py
+++ b/cura/Settings/MachineManager.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import time
@@ -6,13 +6,14 @@ import re
import unicodedata
from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast
+from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
+
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
+from UM.Decorators import deprecated
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.Interfaces import ContainerInterface
from UM.Signal import Signal
-
-from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
from UM.FlameProfiler import pyqtSlot
from UM import Util
from UM.Logger import Logger
@@ -21,33 +22,34 @@ from UM.Message import Message
from UM.Settings.SettingFunction import SettingFunction
from UM.Signal import postponeSignals, CompressTechnique
-from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
-from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionType
-from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
-from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
-from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
+import cura.CuraApplication # Imported like this to prevent circular references.
+
+from cura.Machines.ContainerNode import ContainerNode
+from cura.Machines.ContainerTree import ContainerTree
+from cura.Machines.Models.IntentCategoryModel import IntentCategoryModel
+
+from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice, ConnectionType
+from cura.PrinterOutput.Models.PrinterConfigurationModel import PrinterConfigurationModel
+from cura.PrinterOutput.Models.ExtruderConfigurationModel import ExtruderConfigurationModel
+from cura.PrinterOutput.Models.MaterialOutputModel import MaterialOutputModel
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.ExtruderStack import ExtruderStack
from cura.Settings.cura_empty_instance_containers import (empty_definition_changes_container, empty_variant_container,
empty_material_container, empty_quality_container,
- empty_quality_changes_container)
+ empty_quality_changes_container, empty_intent_container)
from .CuraStackBuilder import CuraStackBuilder
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
-
+from cura.Settings.GlobalStack import GlobalStack
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
- from cura.Settings.CuraContainerStack import CuraContainerStack
- from cura.Settings.GlobalStack import GlobalStack
- from cura.Machines.MaterialManager import MaterialManager
- from cura.Machines.QualityManager import QualityManager
- from cura.Machines.VariantManager import VariantManager
- from cura.Machines.ContainerNode import ContainerNode
+ from cura.Machines.MaterialNode import MaterialNode
from cura.Machines.QualityChangesGroup import QualityChangesGroup
from cura.Machines.QualityGroup import QualityGroup
+ from cura.Machines.VariantNode import VariantNode
class MachineManager(QObject):
@@ -58,8 +60,6 @@ class MachineManager(QObject):
self._global_container_stack = None # type: Optional[GlobalStack]
self._current_root_material_id = {} # type: Dict[str, str]
- self._current_quality_group = None # type: Optional[QualityGroup]
- self._current_quality_changes_group = None # type: Optional[QualityChangesGroup]
self._default_extruder_position = "0" # to be updated when extruders are switched on and off
@@ -95,7 +95,6 @@ class MachineManager(QObject):
extruder_manager.activeExtruderChanged.connect(self.activeQualityChanged)
self.globalContainerChanged.connect(self.activeStackChanged)
- self.globalValueChanged.connect(self.activeStackValueChanged)
ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeStackChanged)
self.activeStackChanged.connect(self.activeStackValueChanged)
@@ -106,7 +105,7 @@ class MachineManager(QObject):
# There might already be some output devices by the time the signal is connected
self._onOutputDevicesChanged()
- self._current_printer_configuration = ConfigurationModel() # Indicates the current configuration setup in this printer
+ self._current_printer_configuration = PrinterConfigurationModel() # Indicates the current configuration setup in this printer
self.activeMaterialChanged.connect(self._onCurrentConfigurationChanged)
self.activeVariantChanged.connect(self._onCurrentConfigurationChanged)
# Force to compute the current configuration
@@ -118,22 +117,20 @@ class MachineManager(QObject):
if containers:
containers[0].nameChanged.connect(self._onMaterialNameChanged)
- self._material_manager = self._application.getMaterialManager() # type: MaterialManager
- self._variant_manager = self._application.getVariantManager() # type: VariantManager
- self._quality_manager = self._application.getQualityManager() # type: QualityManager
-
- # When the materials lookup table gets updated, it can mean that a material has its name changed, which should
- # be reflected on the GUI. This signal emission makes sure that it happens.
- self._material_manager.materialsUpdated.connect(self.rootMaterialChanged)
- # When the materials get updated, it can be that an activated material's diameter gets changed. In that case,
- # a material update should be triggered to make sure that the machine still has compatible materials activated.
- self._material_manager.materialsUpdated.connect(self._updateUponMaterialMetadataChange)
self.rootMaterialChanged.connect(self._onRootMaterialChanged)
# Emit the printerConnectedStatusChanged when either globalContainerChanged or outputDevicesChanged are emitted
self.globalContainerChanged.connect(self.printerConnectedStatusChanged)
self.outputDevicesChanged.connect(self.printerConnectedStatusChanged)
+ # For updating active quality display name
+ self.activeQualityChanged.connect(self.activeQualityDisplayNameChanged)
+ self.activeIntentChanged.connect(self.activeQualityDisplayNameChanged)
+ self.activeQualityGroupChanged.connect(self.activeQualityDisplayNameChanged)
+ self.activeQualityChangesGroupChanged.connect(self.activeQualityDisplayNameChanged)
+
+ activeQualityDisplayNameChanged = pyqtSignal()
+
activeQualityGroupChanged = pyqtSignal()
activeQualityChangesGroupChanged = pyqtSignal()
@@ -141,10 +138,10 @@ class MachineManager(QObject):
activeMaterialChanged = pyqtSignal()
activeVariantChanged = pyqtSignal()
activeQualityChanged = pyqtSignal()
- activeStackChanged = pyqtSignal() # Emitted whenever the active stack is changed (ie: when changing between extruders, changing a profile, but not when changing a value)
- extruderChanged = pyqtSignal()
+ activeIntentChanged = pyqtSignal()
+ activeStackChanged = pyqtSignal() # Emitted whenever the active extruder stack is changed (ie: when switching the active extruder tab or changing between printers)
+ extruderChanged = pyqtSignal() # Emitted whenever an extruder is activated or deactivated or the default extruder changes.
- globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed.
activeStackValueChanged = pyqtSignal() # Emitted whenever a value inside the active stack is changed.
activeStackValidationChanged = pyqtSignal() # Emitted whenever a validation inside active container is changed
stacksValidationChanged = pyqtSignal() # Emitted whenever a validation is changed
@@ -171,10 +168,9 @@ class MachineManager(QObject):
self._printer_output_devices.append(printer_output_device)
self.outputDevicesChanged.emit()
- self.printerConnectedStatusChanged.emit()
@pyqtProperty(QObject, notify = currentConfigurationChanged)
- def currentConfiguration(self) -> ConfigurationModel:
+ def currentConfiguration(self) -> PrinterConfigurationModel:
return self._current_printer_configuration
def _onCurrentConfigurationChanged(self) -> None:
@@ -183,9 +179,11 @@ class MachineManager(QObject):
# Create the configuration model with the current data in Cura
self._current_printer_configuration.printerType = self._global_container_stack.definition.getName()
- self._current_printer_configuration.extruderConfigurations = []
- for extruder in self._global_container_stack.extruders.values():
- extruder_configuration = ExtruderConfigurationModel()
+
+ if len(self._current_printer_configuration.extruderConfigurations) != len(self._global_container_stack.extruderList):
+ self._current_printer_configuration.extruderConfigurations = [ExtruderConfigurationModel() for extruder in self._global_container_stack.extruderList]
+
+ for extruder, extruder_configuration in zip(self._global_container_stack.extruderList, self._current_printer_configuration.extruderConfigurations):
# For compare just the GUID is needed at this moment
mat_type = extruder.material.getMetaDataEntry("material") if extruder.material != empty_material_container else None
mat_guid = extruder.material.getMetaDataEntry("GUID") if extruder.material != empty_material_container else None
@@ -197,15 +195,15 @@ class MachineManager(QObject):
extruder_configuration.position = int(extruder.getMetaDataEntry("position"))
extruder_configuration.material = material_model
extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != empty_variant_container else None
- self._current_printer_configuration.extruderConfigurations.append(extruder_configuration)
# An empty build plate configuration from the network printer is presented as an empty string, so use "" for an
# empty build plate.
- self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.getProperty("machine_buildplate_type", "value") if self._global_container_stack.variant != empty_variant_container else ""
+ self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.getProperty("machine_buildplate_type", "value")\
+ if self._global_container_stack.variant != empty_variant_container else self._global_container_stack.getProperty("machine_buildplate_type", "default_value")
self.currentConfigurationChanged.emit()
@pyqtSlot(QObject, result = bool)
- def matchesConfiguration(self, configuration: ConfigurationModel) -> bool:
+ def matchesConfiguration(self, configuration: PrinterConfigurationModel) -> bool:
return self._current_printer_configuration == configuration
@pyqtProperty("QVariantList", notify = outputDevicesChanged)
@@ -219,12 +217,9 @@ class MachineManager(QObject):
return 0
return len(general_definition_containers[0].getAllKeys())
+ ## Triggered when the global container stack is changed in CuraApplication.
def _onGlobalContainerChanged(self) -> None:
if self._global_container_stack:
- try:
- self._global_container_stack.nameChanged.disconnect(self._onMachineNameChanged)
- except TypeError: # pyQtSignal gives a TypeError when disconnecting from something that was already disconnected.
- pass
try:
self._global_container_stack.containersChanged.disconnect(self._onContainersChanged)
except TypeError:
@@ -249,7 +244,6 @@ class MachineManager(QObject):
if self._global_container_stack:
self._application.getPreferences().setValue("cura/active_machine", self._global_container_stack.getId())
- self._global_container_stack.nameChanged.connect(self._onMachineNameChanged)
self._global_container_stack.containersChanged.connect(self._onContainersChanged)
self._global_container_stack.propertyChanged.connect(self._onPropertyChanged)
@@ -269,23 +263,19 @@ class MachineManager(QObject):
extruder_stack.propertyChanged.connect(self._onPropertyChanged)
extruder_stack.containersChanged.connect(self._onContainersChanged)
+ self._onRootMaterialChanged()
+
self.activeQualityGroupChanged.emit()
def _onActiveExtruderStackChanged(self) -> None:
self.blurSettings.emit() # Ensure no-one has focus.
- old_active_container_stack = self._active_container_stack
-
self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack()
- if old_active_container_stack != self._active_container_stack:
- # Many methods and properties related to the active quality actually depend
- # on _active_container_stack. If it changes, then the properties change.
- self.activeQualityChanged.emit()
-
def __emitChangedSignals(self) -> None:
self.activeQualityChanged.emit()
self.activeVariantChanged.emit()
self.activeMaterialChanged.emit()
+ self.activeIntentChanged.emit()
self.rootMaterialChanged.emit()
self.numberExtrudersEnabledChanged.emit()
@@ -298,83 +288,39 @@ class MachineManager(QObject):
# Notify UI items, such as the "changed" star in profile pull down menu.
self.activeStackValueChanged.emit()
- ## Given a global_stack, make sure that it's all valid by searching for this quality group and applying it again
- def _initMachineState(self, global_stack: "CuraContainerStack") -> None:
- material_dict = {}
- for position, extruder in global_stack.extruders.items():
- material_dict[position] = extruder.material.getMetaDataEntry("base_file")
- self._current_root_material_id = material_dict
-
- # Update materials to make sure that the diameters match with the machine's
- for position in global_stack.extruders:
- self.updateMaterialWithVariant(position)
-
- global_quality = global_stack.quality
- quality_type = global_quality.getMetaDataEntry("quality_type")
- global_quality_changes = global_stack.qualityChanges
- global_quality_changes_name = global_quality_changes.getName()
-
- # Try to set the same quality/quality_changes as the machine specified.
- # If the quality/quality_changes is not available, switch to the default or the first quality that's available.
- same_quality_found = False
- quality_groups = self._application.getQualityManager().getQualityGroups(global_stack)
-
- if global_quality_changes.getId() != "empty_quality_changes":
- quality_changes_groups = self._application.getQualityManager().getQualityChangesGroups(global_stack)
- new_quality_changes_group = quality_changes_groups.get(global_quality_changes_name)
- if new_quality_changes_group is not None:
- self._setQualityChangesGroup(new_quality_changes_group)
- same_quality_found = True
- Logger.log("i", "Machine '%s' quality changes set to '%s'",
- global_stack.getName(), new_quality_changes_group.name)
- else:
- new_quality_group = quality_groups.get(quality_type)
- if new_quality_group is not None:
- self._setQualityGroup(new_quality_group, empty_quality_changes = True)
- same_quality_found = True
- Logger.log("i", "Machine '%s' quality set to '%s'",
- global_stack.getName(), new_quality_group.quality_type)
-
- # Could not find the specified quality/quality_changes, switch to the preferred quality if available,
- # otherwise the first quality that's available, otherwise empty (not supported).
- if not same_quality_found:
- Logger.log("i", "Machine '%s' could not find quality_type '%s' and quality_changes '%s'. "
- "Available quality types are [%s]. Switching to default quality.",
- global_stack.getName(), quality_type, global_quality_changes_name,
- ", ".join(quality_groups.keys()))
- preferred_quality_type = global_stack.getMetaDataEntry("preferred_quality_type")
- quality_group = quality_groups.get(preferred_quality_type)
- if quality_group is None:
- if quality_groups:
- quality_group = list(quality_groups.values())[0]
- self._setQualityGroup(quality_group, empty_quality_changes = True)
-
@pyqtSlot(str)
def setActiveMachine(self, stack_id: str) -> None:
self.blurSettings.emit() # Ensure no-one has focus.
container_registry = CuraContainerRegistry.getInstance()
-
containers = container_registry.findContainerStacks(id = stack_id)
if not containers:
return
- global_stack = containers[0]
+ global_stack = cast(GlobalStack, containers[0])
# Make sure that the default machine actions for this machine have been added
self._application.getMachineActionManager().addDefaultMachineActions(global_stack)
- ExtruderManager.getInstance()._fixSingleExtrusionMachineExtruderDefinition(global_stack)
+ extruder_manager = ExtruderManager.getInstance()
+ extruder_manager.fixSingleExtrusionMachineExtruderDefinition(global_stack)
if not global_stack.isValid():
# Mark global stack as invalid
ConfigurationErrorMessage.getInstance().addFaultyContainers(global_stack.getId())
return # We're done here
- ExtruderManager.getInstance().setActiveExtruderIndex(0) # Switch to first extruder
+
self._global_container_stack = global_stack
+ extruder_manager.addMachineExtruders(global_stack)
self._application.setGlobalContainerStack(global_stack)
- ExtruderManager.getInstance()._globalContainerStackChanged()
- self._initMachineState(global_stack)
- self._onGlobalContainerChanged()
+
+ # Switch to the first enabled extruder
+ self.updateDefaultExtruder()
+ default_extruder_position = int(self.defaultExtruderPosition)
+ old_active_extruder_index = extruder_manager.activeExtruderIndex
+ extruder_manager.setActiveExtruderIndex(default_extruder_position)
+ if old_active_extruder_index == default_extruder_position:
+ # This signal might not have been emitted yet (if it didn't change) but we still want the models to update that depend on it because we changed the contents of the containers too.
+ extruder_manager.activeExtruderChanged.emit()
self.__emitChangedSignals()
@@ -389,12 +335,21 @@ class MachineManager(QObject):
machines = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
for machine in machines:
if machine.definition.getId() == definition_id:
- return machine
+ return cast(GlobalStack, machine)
return None
+ @pyqtSlot(str)
@pyqtSlot(str, str)
- def addMachine(self, name: str, definition_id: str) -> None:
- new_stack = CuraStackBuilder.createMachine(name, definition_id)
+ def addMachine(self, definition_id: str, name: Optional[str] = None) -> None:
+ Logger.log("i", "Trying to add a machine with the definition id [%s]", definition_id)
+ if name is None:
+ definitions = CuraContainerRegistry.getInstance().findDefinitionContainers(id = definition_id)
+ if definitions:
+ name = definitions[0].getName()
+ else:
+ name = definition_id
+
+ new_stack = CuraStackBuilder.createMachine(cast(str, name), definition_id)
if new_stack:
# Instead of setting the global container stack here, we set the active machine and so the signals are emitted
self.setActiveMachine(new_stack.getId())
@@ -457,6 +412,7 @@ class MachineManager(QObject):
# \param key \type{str} the name of the key to delete
@pyqtSlot(str)
def clearUserSettingAllCurrentStacks(self, key: str) -> None:
+ Logger.log("i", "Clearing the setting [%s] from all stacks", key)
if not self._global_container_stack:
return
@@ -491,24 +447,6 @@ class MachineManager(QObject):
def stacksHaveErrors(self) -> bool:
return bool(self._stacks_have_errors)
- @pyqtProperty(str, notify = globalContainerChanged)
- def activeMachineDefinitionName(self) -> str:
- if self._global_container_stack:
- return self._global_container_stack.definition.getName()
- return ""
-
- @pyqtProperty(str, notify = globalContainerChanged)
- def activeMachineName(self) -> str:
- if self._global_container_stack:
- return self._global_container_stack.getMetaDataEntry("group_name", self._global_container_stack.getName())
- return ""
-
- @pyqtProperty(str, notify = globalContainerChanged)
- def activeMachineId(self) -> str:
- if self._global_container_stack:
- return self._global_container_stack.getId()
- return ""
-
@pyqtProperty(str, notify = globalContainerChanged)
def activeMachineFirmwareVersion(self) -> str:
if not self._printer_output_devices:
@@ -525,23 +463,6 @@ class MachineManager(QObject):
def printerConnected(self) -> bool:
return bool(self._printer_output_devices)
- @pyqtProperty(bool, notify = printerConnectedStatusChanged)
- def activeMachineHasRemoteConnection(self) -> bool:
- if self._global_container_stack:
- has_remote_connection = False
-
- for connection_type in self._global_container_stack.configuredConnectionTypes:
- has_remote_connection |= connection_type in [ConnectionType.NetworkConnection.value,
- ConnectionType.CloudConnection.value]
- return has_remote_connection
- return False
-
- @pyqtProperty("QVariantList", notify=globalContainerChanged)
- def activeMachineConfiguredConnectionTypes(self):
- if self._global_container_stack:
- return self._global_container_stack.configuredConnectionTypes
- return []
-
@pyqtProperty(bool, notify = printerConnectedStatusChanged)
def activeMachineIsGroup(self) -> bool:
return bool(self._printer_output_devices) and len(self._printer_output_devices[0].printers) > 1
@@ -585,7 +506,7 @@ class MachineManager(QObject):
def activeStack(self) -> Optional["ExtruderStack"]:
return self._active_container_stack
- @pyqtProperty(str, notify=activeMaterialChanged)
+ @pyqtProperty(str, notify = activeMaterialChanged)
def activeMaterialId(self) -> str:
if self._active_container_stack:
material = self._active_container_stack.material
@@ -593,44 +514,20 @@ class MachineManager(QObject):
return material.getId()
return ""
- ## Gets a dict with the active materials ids set in all extruder stacks and the global stack
- # (when there is one extruder, the material is set in the global stack)
- #
- # \return The material ids in all stacks
- @pyqtProperty("QVariantMap", notify = activeMaterialChanged)
- def allActiveMaterialIds(self) -> Dict[str, str]:
- result = {}
-
- active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
- for stack in active_stacks:
- material_container = stack.material
- if not material_container:
- continue
- result[stack.getId()] = material_container.getId()
-
- return result
-
## Gets the layer height of the currently active quality profile.
#
# This is indicated together with the name of the active quality profile.
#
# \return The layer height of the currently active quality profile. If
- # there is no quality profile, this returns 0.
+ # there is no quality profile, this returns the default layer height.
@pyqtProperty(float, notify = activeQualityGroupChanged)
def activeQualityLayerHeight(self) -> float:
if not self._global_container_stack:
return 0
- if self._current_quality_changes_group:
- value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = self._global_container_stack.qualityChanges.getId())
- if isinstance(value, SettingFunction):
- value = value(self._global_container_stack)
- return value
- elif self._current_quality_group:
- value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = self._global_container_stack.quality.getId())
- if isinstance(value, SettingFunction):
- value = value(self._global_container_stack)
- return value
- return 0
+ value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = self._global_container_stack.qualityChanges.getId())
+ if isinstance(value, SettingFunction):
+ value = value(self._global_container_stack)
+ return value
@pyqtProperty(str, notify = activeVariantChanged)
def globalVariantName(self) -> str:
@@ -642,27 +539,57 @@ class MachineManager(QObject):
@pyqtProperty(str, notify = activeQualityGroupChanged)
def activeQualityType(self) -> str:
- quality_type = ""
- if self._active_container_stack:
- if self._current_quality_group:
- quality_type = self._current_quality_group.quality_type
- return quality_type
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_stack:
+ return ""
+ return global_stack.quality.getMetaDataEntry("quality_type")
@pyqtProperty(bool, notify = activeQualityGroupChanged)
def isActiveQualitySupported(self) -> bool:
- is_supported = False
- if self._global_container_stack:
- if self._current_quality_group:
- is_supported = self._current_quality_group.is_available
- return is_supported
+ global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_container_stack:
+ return False
+ active_quality_group = self.activeQualityGroup()
+ if active_quality_group is None:
+ return False
+ return active_quality_group.is_available
@pyqtProperty(bool, notify = activeQualityGroupChanged)
def isActiveQualityExperimental(self) -> bool:
- is_experimental = False
- if self._global_container_stack:
- if self._current_quality_group:
- is_experimental = self._current_quality_group.is_experimental
- return is_experimental
+ global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_container_stack:
+ return False
+ active_quality_group = self.activeQualityGroup()
+ if active_quality_group is None:
+ return False
+ return active_quality_group.is_experimental
+
+ @pyqtProperty(str, notify = activeIntentChanged)
+ def activeIntentCategory(self) -> str:
+ global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+
+ if not global_container_stack:
+ return ""
+ return global_container_stack.getIntentCategory()
+
+ # Provies a list of extruder positions that have a different intent from the active one.
+ @pyqtProperty("QStringList", notify=activeIntentChanged)
+ def extruderPositionsWithNonActiveIntent(self):
+ global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+
+ if not global_container_stack:
+ return []
+
+ active_intent_category = self.activeIntentCategory
+ result = []
+ for extruder in global_container_stack.extruderList:
+ if not extruder.isEnabled:
+ continue
+ category = extruder.intent.getMetaDataEntry("intent_category", "default")
+ if category != active_intent_category:
+ result.append(str(int(extruder.getMetaDataEntry("position")) + 1))
+
+ return result
## Returns whether there is anything unsupported in the current set-up.
#
@@ -673,7 +600,7 @@ class MachineManager(QObject):
def isCurrentSetupSupported(self) -> bool:
if not self._global_container_stack:
return False
- for stack in [self._global_container_stack] + list(self._global_container_stack.extruders.values()):
+ for stack in [self._global_container_stack] + self._global_container_stack.extruderList:
for container in stack.getContainers():
if not container:
return False
@@ -681,11 +608,6 @@ class MachineManager(QObject):
return False
return True
- ## Check if a container is read_only
- @pyqtSlot(str, result = bool)
- def isReadOnly(self, container_id: str) -> bool:
- return CuraContainerRegistry.getInstance().isReadOnly(container_id)
-
## Copy the value of the setting of the current extruder to all other extruders as well as the global container.
@pyqtSlot(str)
def copyValueToExtruders(self, key: str) -> None:
@@ -704,8 +626,8 @@ class MachineManager(QObject):
def copyAllValuesToExtruders(self) -> None:
if self._active_container_stack is None or self._global_container_stack is None:
return
- extruder_stacks = list(self._global_container_stack.extruders.values())
- for extruder_stack in extruder_stacks:
+
+ for extruder_stack in self._global_container_stack.extruderList:
if extruder_stack != self._active_container_stack:
for key in self._active_container_stack.userChanges.getAllKeys():
new_value = self._active_container_stack.getProperty(key, "value")
@@ -713,47 +635,14 @@ class MachineManager(QObject):
# Check if the value has to be replaced
extruder_stack.userChanges.setProperty(key, "value", new_value)
- @pyqtProperty(str, notify = activeVariantChanged)
- def activeVariantName(self) -> str:
- if self._active_container_stack:
- variant = self._active_container_stack.variant
- if variant:
- return variant.getName()
-
- return ""
-
- @pyqtProperty(str, notify = activeVariantChanged)
- def activeVariantId(self) -> str:
- if self._active_container_stack:
- variant = self._active_container_stack.variant
- if variant:
- return variant.getId()
-
- return ""
-
- @pyqtProperty(str, notify = activeVariantChanged)
- def activeVariantBuildplateName(self) -> str:
- if self._global_container_stack:
- variant = self._global_container_stack.variant
- if variant:
- return variant.getName()
-
- return ""
-
- @pyqtProperty(str, notify = globalContainerChanged)
- def activeDefinitionId(self) -> str:
- if self._global_container_stack:
- return self._global_container_stack.definition.id
-
- return ""
-
## Get the Definition ID to use to select quality profiles for the currently active machine
# \returns DefinitionID (string) if found, empty string otherwise
@pyqtProperty(str, notify = globalContainerChanged)
def activeQualityDefinitionId(self) -> str:
- if self._global_container_stack:
- return getMachineDefinitionIDForQualitySearch(self._global_container_stack.definition)
- return ""
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_stack:
+ return ""
+ return ContainerTree.getInstance().machines[global_stack.definition.getId()].quality_definition
## Gets how the active definition calls variants
# Caveat: per-definition-variant-title is currently not translated (though the fallback is)
@@ -776,6 +665,7 @@ class MachineManager(QObject):
@pyqtSlot(str)
def removeMachine(self, machine_id: str) -> None:
+ Logger.log("i", "Attempting to remove a machine with the id [%s]", machine_id)
# If the machine that is being removed is the currently active machine, set another machine as the active machine.
activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id)
@@ -787,7 +677,6 @@ class MachineManager(QObject):
self.setActiveMachine(other_machine_stacks[0]["id"])
metadata = CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)[0]
- network_key = metadata.get("um_network_key", None)
ExtruderManager.getInstance().removeMachineExtruders(machine_id)
containers = CuraContainerRegistry.getInstance().findInstanceContainersMetadata(type = "user", machine = machine_id)
for container in containers:
@@ -795,31 +684,14 @@ class MachineManager(QObject):
CuraContainerRegistry.getInstance().removeContainer(machine_id)
# If the printer that is being removed is a network printer, the hidden printers have to be also removed
- if network_key:
- metadata_filter = {"um_network_key": network_key}
+ group_id = metadata.get("group_id", None)
+ if group_id:
+ metadata_filter = {"group_id": group_id}
hidden_containers = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
if hidden_containers:
# This reuses the method and remove all printers recursively
self.removeMachine(hidden_containers[0].getId())
- @pyqtProperty(bool, notify = globalContainerChanged)
- def hasMaterials(self) -> bool:
- if self._global_container_stack:
- return Util.parseBool(self._global_container_stack.getMetaDataEntry("has_materials", False))
- return False
-
- @pyqtProperty(bool, notify = globalContainerChanged)
- def hasVariants(self) -> bool:
- if self._global_container_stack:
- return Util.parseBool(self._global_container_stack.getMetaDataEntry("has_variants", False))
- return False
-
- @pyqtProperty(bool, notify = globalContainerChanged)
- def hasVariantBuildplates(self) -> bool:
- if self._global_container_stack:
- return Util.parseBool(self._global_container_stack.getMetaDataEntry("has_variant_buildplates", False))
- return False
-
## The selected buildplate is compatible if it is compatible with all the materials in all the extruders
@pyqtProperty(bool, notify = activeMaterialChanged)
def variantBuildplateCompatible(self) -> bool:
@@ -827,15 +699,15 @@ class MachineManager(QObject):
return True
buildplate_compatible = True # It is compatible by default
- extruder_stacks = self._global_container_stack.extruders.values()
- for stack in extruder_stacks:
+ for stack in self._global_container_stack.extruderList:
if not stack.isEnabled:
continue
material_container = stack.material
if material_container == empty_material_container:
continue
if material_container.getMetaDataEntry("buildplate_compatible"):
- buildplate_compatible = buildplate_compatible and material_container.getMetaDataEntry("buildplate_compatible")[self.activeVariantBuildplateName]
+ active_buildplate_name = self.activeMachine.variant.name
+ buildplate_compatible = buildplate_compatible and material_container.getMetaDataEntry("buildplate_compatible")[active_buildplate_name]
return buildplate_compatible
@@ -851,8 +723,8 @@ class MachineManager(QObject):
# (material_left_compatible or material_left_usable) and
# (material_right_compatible or material_right_usable)
result = not self.variantBuildplateCompatible
- extruder_stacks = self._global_container_stack.extruders.values()
- for stack in extruder_stacks:
+
+ for stack in self._global_container_stack.extruderList:
material_container = stack.material
if material_container == empty_material_container:
continue
@@ -880,20 +752,15 @@ class MachineManager(QObject):
result = [] # type: List[str]
for setting_instance in container.findInstances():
setting_key = setting_instance.definition.key
- setting_enabled = self._global_container_stack.getProperty(setting_key, "enabled")
- if not setting_enabled:
- # A setting is not visible anymore
- result.append(setting_key)
- Logger.log("d", "Reset setting [%s] from [%s] because the setting is no longer enabled", setting_key, container)
- continue
-
if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
continue
old_value = container.getProperty(setting_key, "value")
+ if isinstance(old_value, SettingFunction):
+ old_value = old_value(self._global_container_stack)
if int(old_value) < 0:
continue
- if int(old_value) >= extruder_count or not self._global_container_stack.extruders[str(old_value)].isEnabled:
+ if int(old_value) >= extruder_count or not self._global_container_stack.extruderList[int(old_value)].isEnabled:
result.append(setting_key)
Logger.log("d", "Reset setting [%s] in [%s] because its old value [%s] is no longer valid", setting_key, container, old_value)
return result
@@ -909,9 +776,8 @@ class MachineManager(QObject):
# Apply quality changes that are incompatible to user changes, so we do not change the quality changes itself.
self._global_container_stack.userChanges.setProperty(setting_key, "value", self._default_extruder_position)
if add_user_changes:
- caution_message = Message(catalog.i18nc(
- "@info:generic",
- "Settings have been changed to match the current availability of extruders: [%s]" % ", ".join(add_user_changes)),
+ caution_message = Message(
+ catalog.i18nc("@info:message Followed by a list of settings.", "Settings have been changed to match the current availability of extruders:") + " [{settings_list}]".format(settings_list = ", ".join(add_user_changes)),
lifetime = 0,
title = catalog.i18nc("@info:title", "Settings updated"))
caution_message.show()
@@ -939,7 +805,7 @@ class MachineManager(QObject):
# Check to see if any objects are set to print with an extruder that will no longer exist
root_node = self._application.getController().getScene().getRoot()
- for node in DepthFirstIterator(root_node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+ for node in DepthFirstIterator(root_node):
if node.getMeshData():
extruder_nr = node.callDecoration("getActiveExtruderPosition")
@@ -964,7 +830,7 @@ class MachineManager(QObject):
if settable_per_extruder:
limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder"))
extruder_position = max(0, limit_to_extruder)
- extruder_stack = self.getExtruder(extruder_position)
+ extruder_stack = self._global_container_stack.extruderList[extruder_position]
if extruder_stack:
extruder_stack.userChanges.setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value"))
else:
@@ -975,21 +841,15 @@ class MachineManager(QObject):
self._application.globalContainerStackChanged.emit()
self.forceUpdateAllSettings()
- @pyqtSlot(int, result = QObject)
- def getExtruder(self, position: int) -> Optional[ExtruderStack]:
- if self._global_container_stack:
- return self._global_container_stack.extruders.get(str(position))
- return None
-
def updateDefaultExtruder(self) -> None:
if self._global_container_stack is None:
return
- extruder_items = sorted(self._global_container_stack.extruders.items())
+
old_position = self._default_extruder_position
new_default_position = "0"
- for position, extruder in extruder_items:
+ for extruder in self._global_container_stack.extruderList:
if extruder.isEnabled:
- new_default_position = position
+ new_default_position = extruder.getMetaDataEntry("position", "0")
break
if new_default_position != old_position:
self._default_extruder_position = new_default_position
@@ -1001,7 +861,7 @@ class MachineManager(QObject):
definition_changes_container = self._global_container_stack.definitionChanges
machine_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
extruder_count = 0
- for position, extruder in self._global_container_stack.extruders.items():
+ for position, extruder in enumerate(self._global_container_stack.extruderList):
if extruder.isEnabled and int(position) < machine_extruder_count:
extruder_count += 1
if self.numberExtrudersEnabled != extruder_count:
@@ -1012,7 +872,10 @@ class MachineManager(QObject):
def numberExtrudersEnabled(self) -> int:
if self._global_container_stack is None:
return 1
- return self._global_container_stack.definitionChanges.getProperty("extruders_enabled_count", "value")
+ extruders_enabled_count = self._global_container_stack.definitionChanges.getProperty("extruders_enabled_count", "value")
+ if extruders_enabled_count is None:
+ extruders_enabled_count = len(self._global_container_stack.extruderList)
+ return extruders_enabled_count
@pyqtProperty(str, notify = extruderChanged)
def defaultExtruderPosition(self) -> str:
@@ -1025,16 +888,16 @@ class MachineManager(QObject):
return
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
property_names = ["value", "resolve", "validationState"]
- for container in [self._global_container_stack] + list(self._global_container_stack.extruders.values()):
+ for container in [self._global_container_stack] + self._global_container_stack.extruderList:
for setting_key in container.getAllKeys():
container.propertiesChanged.emit(setting_key, property_names)
@pyqtSlot(int, bool)
def setExtruderEnabled(self, position: int, enabled: bool) -> None:
- extruder = self.getExtruder(position)
- if not extruder or self._global_container_stack is None:
+ if self._global_container_stack is None:
Logger.log("w", "Could not find extruder on position %s", position)
return
+ extruder = self._global_container_stack.extruderList[position]
extruder.setEnabled(enabled)
self.updateDefaultExtruder()
@@ -1056,28 +919,25 @@ class MachineManager(QObject):
self.forceUpdateAllSettings()
# Also trigger the build plate compatibility to update
self.activeMaterialChanged.emit()
-
- def _onMachineNameChanged(self) -> None:
- self.globalContainerChanged.emit()
+ self.activeIntentChanged.emit()
def _onMaterialNameChanged(self) -> None:
self.activeMaterialChanged.emit()
- def _onQualityNameChanged(self) -> None:
- self.activeQualityChanged.emit()
-
+ ## Get the signals that signal that the containers changed for all stacks.
+ #
+ # This includes the global stack and all extruder stacks. So if any
+ # container changed anywhere.
def _getContainerChangedSignals(self) -> List[Signal]:
if self._global_container_stack is None:
return []
- stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
- stacks.append(self._global_container_stack)
- return [ s.containersChanged for s in stacks ]
+ return [s.containersChanged for s in ExtruderManager.getInstance().getActiveExtruderStacks() + [self._global_container_stack]]
@pyqtSlot(str, str, str)
def setSettingForAllExtruders(self, setting_name: str, property_name: str, property_value: str) -> None:
if self._global_container_stack is None:
return
- for key, extruder in self._global_container_stack.extruders.items():
+ for extruder in self._global_container_stack.extruderList:
container = extruder.userChanges
container.setProperty(setting_name, property_name, property_value)
@@ -1087,59 +947,46 @@ class MachineManager(QObject):
def resetSettingForAllExtruders(self, setting_name: str) -> None:
if self._global_container_stack is None:
return
- for key, extruder in self._global_container_stack.extruders.items():
+ for extruder in self._global_container_stack.extruderList:
container = extruder.userChanges
container.removeInstance(setting_name)
- @pyqtProperty("QVariantList", notify = globalContainerChanged)
- def currentExtruderPositions(self) -> List[str]:
- if self._global_container_stack is None:
- return []
- return sorted(list(self._global_container_stack.extruders.keys()))
-
## Update _current_root_material_id when the current root material was changed.
def _onRootMaterialChanged(self) -> None:
self._current_root_material_id = {}
+ changed = False
+
if self._global_container_stack:
- for position in self._global_container_stack.extruders:
- self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file")
+ for extruder in self._global_container_stack.extruderList:
+ material_id = extruder.material.getMetaDataEntry("base_file")
+ position = extruder.getMetaDataEntry("position")
+ if position not in self._current_root_material_id or material_id != self._current_root_material_id[position]:
+ changed = True
+ self._current_root_material_id[position] = material_id
+
+ if changed:
+ self.activeMaterialChanged.emit()
@pyqtProperty("QVariant", notify = rootMaterialChanged)
def currentRootMaterialId(self) -> Dict[str, str]:
return self._current_root_material_id
- ## Return the variant names in the extruder stack(s).
- ## For the variant in the global stack, use activeVariantBuildplateName
- @pyqtProperty("QVariant", notify = activeVariantChanged)
- def activeVariantNames(self) -> Dict[str, str]:
- result = {}
-
- active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
- for stack in active_stacks:
- variant_container = stack.variant
- position = stack.getMetaDataEntry("position")
- if variant_container and variant_container != empty_variant_container:
- result[position] = variant_container.getName()
-
- return result
-
# Sets all quality and quality_changes containers to empty_quality and empty_quality_changes containers
# for all stacks in the currently active machine.
#
def _setEmptyQuality(self) -> None:
if self._global_container_stack is None:
return
- self._current_quality_group = None
- self._current_quality_changes_group = None
self._global_container_stack.quality = empty_quality_container
self._global_container_stack.qualityChanges = empty_quality_changes_container
- for extruder in self._global_container_stack.extruders.values():
+ for extruder in self._global_container_stack.extruderList:
extruder.quality = empty_quality_container
extruder.qualityChanges = empty_quality_changes_container
self.activeQualityGroupChanged.emit()
self.activeQualityChangesGroupChanged.emit()
+ self._updateIntentWithQuality()
def _setQualityGroup(self, quality_group: Optional["QualityGroup"], empty_quality_changes: bool = True) -> None:
if self._global_container_stack is None:
@@ -1148,37 +995,33 @@ class MachineManager(QObject):
self._setEmptyQuality()
return
- if quality_group.node_for_global is None or quality_group.node_for_global.getContainer() is None:
+ if quality_group.node_for_global is None or quality_group.node_for_global.container is None:
return
for node in quality_group.nodes_for_extruders.values():
- if node.getContainer() is None:
+ if node.container is None:
return
- self._current_quality_group = quality_group
- if empty_quality_changes:
- self._current_quality_changes_group = None
-
# Set quality and quality_changes for the GlobalStack
- self._global_container_stack.quality = quality_group.node_for_global.getContainer()
+ self._global_container_stack.quality = quality_group.node_for_global.container
if empty_quality_changes:
self._global_container_stack.qualityChanges = empty_quality_changes_container
# Set quality and quality_changes for each ExtruderStack
for position, node in quality_group.nodes_for_extruders.items():
- self._global_container_stack.extruders[str(position)].quality = node.getContainer()
+ self._global_container_stack.extruders[str(position)].quality = node.container
if empty_quality_changes:
self._global_container_stack.extruders[str(position)].qualityChanges = empty_quality_changes_container
self.activeQualityGroupChanged.emit()
self.activeQualityChangesGroupChanged.emit()
+ self._updateIntentWithQuality()
def _fixQualityChangesGroupToNotSupported(self, quality_changes_group: "QualityChangesGroup") -> None:
- nodes = [quality_changes_group.node_for_global] + list(quality_changes_group.nodes_for_extruders.values())
- containers = [n.getContainer() for n in nodes if n is not None]
- for container in containers:
- if container:
- container.setMetaDataEntry("quality_type", "not_supported")
+ metadatas = [quality_changes_group.metadata_for_global] + list(quality_changes_group.metadata_per_extruder.values())
+ for metadata in metadatas:
+ metadata["quality_type"] = "not_supported" # This actually changes the metadata of the container since they are stored by reference!
quality_changes_group.quality_type = "not_supported"
+ quality_changes_group.intent_category = "default"
def _setQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup") -> None:
if self._global_container_stack is None:
@@ -1187,67 +1030,76 @@ class MachineManager(QObject):
# A custom quality can be created based on "not supported".
# In that case, do not set quality containers to empty.
quality_group = None
- if quality_type != "not_supported":
- quality_group_dict = self._quality_manager.getQualityGroups(self._global_container_stack)
- quality_group = quality_group_dict.get(quality_type)
+ if quality_type != "not_supported": # Find the quality group that the quality changes was based on.
+ quality_group = ContainerTree.getInstance().getCurrentQualityGroups().get(quality_type)
if quality_group is None:
self._fixQualityChangesGroupToNotSupported(quality_changes_group)
+ container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
quality_changes_container = empty_quality_changes_container
- quality_container = empty_quality_container # type: Optional[InstanceContainer]
- if quality_changes_group.node_for_global and quality_changes_group.node_for_global.getContainer():
- quality_changes_container = cast(InstanceContainer, quality_changes_group.node_for_global.getContainer())
- if quality_group is not None and quality_group.node_for_global and quality_group.node_for_global.getContainer():
- quality_container = quality_group.node_for_global.getContainer()
+ quality_container = empty_quality_container # type: InstanceContainer
+ if quality_changes_group.metadata_for_global:
+ global_containers = container_registry.findContainers(id = quality_changes_group.metadata_for_global["id"])
+ if global_containers:
+ quality_changes_container = global_containers[0]
+ if quality_changes_group.metadata_for_global:
+ containers = container_registry.findContainers(id = quality_changes_group.metadata_for_global["id"])
+ if containers:
+ quality_changes_container = cast(InstanceContainer, containers[0])
+ if quality_group is not None and quality_group.node_for_global and quality_group.node_for_global.container:
+ quality_container = quality_group.node_for_global.container
self._global_container_stack.quality = quality_container
self._global_container_stack.qualityChanges = quality_changes_container
for position, extruder in self._global_container_stack.extruders.items():
- quality_changes_node = quality_changes_group.nodes_for_extruders.get(position)
quality_node = None
if quality_group is not None:
- quality_node = quality_group.nodes_for_extruders.get(position)
+ quality_node = quality_group.nodes_for_extruders.get(int(position))
quality_changes_container = empty_quality_changes_container
quality_container = empty_quality_container
- if quality_changes_node and quality_changes_node.getContainer():
- quality_changes_container = cast(InstanceContainer, quality_changes_node.getContainer())
- if quality_node and quality_node.getContainer():
- quality_container = quality_node.getContainer()
+ quality_changes_metadata = quality_changes_group.metadata_per_extruder.get(int(position))
+ if quality_changes_metadata:
+ containers = container_registry.findContainers(id = quality_changes_metadata["id"])
+ if containers:
+ quality_changes_container = cast(InstanceContainer, containers[0])
+ if quality_node and quality_node.container:
+ quality_container = quality_node.container
extruder.quality = quality_container
extruder.qualityChanges = quality_changes_container
- self._current_quality_group = quality_group
- self._current_quality_changes_group = quality_changes_group
+ self.setIntentByCategory(quality_changes_group.intent_category)
+
self.activeQualityGroupChanged.emit()
self.activeQualityChangesGroupChanged.emit()
- def _setVariantNode(self, position: str, container_node: "ContainerNode") -> None:
- if container_node.getContainer() is None or self._global_container_stack is None:
+ def _setVariantNode(self, position: str, variant_node: "VariantNode") -> None:
+ if self._global_container_stack is None:
return
- self._global_container_stack.extruders[position].variant = container_node.getContainer()
+ self._global_container_stack.extruders[position].variant = variant_node.container
self.activeVariantChanged.emit()
def _setGlobalVariant(self, container_node: "ContainerNode") -> None:
if self._global_container_stack is None:
return
- self._global_container_stack.variant = container_node.getContainer()
+ self._global_container_stack.variant = container_node.container
if not self._global_container_stack.variant:
self._global_container_stack.variant = self._application.empty_variant_container
- def _setMaterial(self, position: str, container_node: Optional["ContainerNode"] = None) -> None:
+ def _setMaterial(self, position: str, material_node: Optional["MaterialNode"] = None) -> None:
if self._global_container_stack is None:
return
- if container_node and container_node.getContainer():
- self._global_container_stack.extruders[position].material = container_node.getContainer()
- root_material_id = container_node.getMetaDataEntry("base_file", None)
+ if material_node and material_node.container:
+ material_container = material_node.container
+ self._global_container_stack.extruders[position].material = material_container
+ root_material_id = material_container.getMetaDataEntry("base_file", None)
else:
- self._global_container_stack.extruders[position].material = empty_material_container
+ self._global_container_stack.extruderList[int(position)].material = empty_material_container
root_material_id = None
# The _current_root_material_id is used in the MaterialMenu to see which material is selected
- if root_material_id != self._current_root_material_id[position]:
+ if position not in self._current_root_material_id or root_material_id != self._current_root_material_id[position]:
self._current_root_material_id[position] = root_material_id
self.rootMaterialChanged.emit()
@@ -1255,22 +1107,21 @@ class MachineManager(QObject):
# Check material - variant compatibility
if self._global_container_stack is not None:
if Util.parseBool(self._global_container_stack.getMetaDataEntry("has_materials", False)):
- for position, extruder in self._global_container_stack.extruders.items():
- if extruder.isEnabled and not extruder.material.getMetaDataEntry("compatible"):
- return False
+ for extruder in self._global_container_stack.extruderList:
+ if not extruder.isEnabled:
+ continue
if not extruder.material.getMetaDataEntry("compatible"):
return False
return True
## Update current quality type and machine after setting material
def _updateQualityWithMaterial(self, *args: Any) -> None:
- if self._global_container_stack is None:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
return
- Logger.log("i", "Updating quality/quality_changes due to material change")
- current_quality_type = None
- if self._current_quality_group:
- current_quality_type = self._current_quality_group.quality_type
- candidate_quality_groups = self._quality_manager.getQualityGroups(self._global_container_stack)
+ Logger.log("d", "Updating quality/quality_changes due to material change")
+ current_quality_type = global_stack.quality.getMetaDataEntry("quality_type")
+ candidate_quality_groups = ContainerTree.getInstance().getCurrentQualityGroups()
available_quality_types = {qt for qt, g in candidate_quality_groups.items() if g.is_available}
Logger.log("d", "Current quality type = [%s]", current_quality_type)
@@ -1281,7 +1132,7 @@ class MachineManager(QObject):
return
if not available_quality_types:
- if self._current_quality_changes_group is None:
+ if global_stack.qualityChanges == empty_quality_changes_container:
Logger.log("i", "No available quality types found, setting all qualities to empty (Not Supported).")
self._setEmptyQuality()
return
@@ -1294,6 +1145,9 @@ class MachineManager(QObject):
# The current quality type is not available so we use the preferred quality type if it's available,
# otherwise use one of the available quality types.
quality_type = sorted(list(available_quality_types))[0]
+ if self._global_container_stack is None:
+ Logger.log("e", "Global stack not present!")
+ return
preferred_quality_type = self._global_container_stack.getMetaDataEntry("preferred_quality_type")
if preferred_quality_type in available_quality_types:
quality_type = preferred_quality_type
@@ -1302,7 +1156,40 @@ class MachineManager(QObject):
current_quality_type, quality_type)
self._setQualityGroup(candidate_quality_groups[quality_type], empty_quality_changes = True)
- def updateMaterialWithVariant(self, position: Optional[str]) -> None:
+ ## Update the current intent after the quality changed
+ def _updateIntentWithQuality(self):
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return
+ Logger.log("d", "Updating intent due to quality change")
+
+ category = "default"
+
+ for extruder in global_stack.extruderList:
+ if not extruder.isEnabled:
+ continue
+ current_category = extruder.intent.getMetaDataEntry("intent_category", "default")
+ if current_category != "default" and current_category != category:
+ category = current_category
+ continue
+ # It's also possible that the qualityChanges has an opinion about the intent_category.
+ # This is in the case that a QC was made on an intent, but none of the materials have that intent.
+ # If the user switches back, we do want the intent to be selected again.
+ #
+ # Do not ask empty quality changes for intent category.
+ if extruder.qualityChanges.getId() == empty_quality_changes_container.getId():
+ continue
+ current_category = extruder.qualityChanges.getMetaDataEntry("intent_category", "default")
+ if current_category != "default" and current_category != category:
+ category = current_category
+ self.setIntentByCategory(category)
+
+ ## Update the material profile in the current stacks when the variant is
+ # changed.
+ # \param position The extruder stack to update. If provided with None, all
+ # extruder stacks will be updated.
+ @pyqtSlot()
+ def updateMaterialWithVariant(self, position: Optional[str] = None) -> None:
if self._global_container_stack is None:
return
if position is None:
@@ -1310,37 +1197,31 @@ class MachineManager(QObject):
else:
position_list = [position]
- buildplate_name = None
- if self._global_container_stack.variant.getId() != "empty_variant":
- buildplate_name = self._global_container_stack.variant.getName()
-
for position_item in position_list:
- extruder = self._global_container_stack.extruders[position_item]
+ try:
+ extruder = self._global_container_stack.extruderList[int(position_item)]
+ except IndexError:
+ continue
current_material_base_name = extruder.material.getMetaDataEntry("base_file")
- current_nozzle_name = None
- if extruder.variant.getId() != empty_variant_container.getId():
- current_nozzle_name = extruder.variant.getMetaDataEntry("name")
+ current_nozzle_name = extruder.variant.getMetaDataEntry("name")
- material_diameter = extruder.getCompatibleMaterialDiameter()
- candidate_materials = self._material_manager.getAvailableMaterials(
- self._global_container_stack.definition,
- current_nozzle_name,
- buildplate_name,
- material_diameter)
+ # If we can keep the current material after the switch, try to do so.
+ nozzle_node = ContainerTree.getInstance().machines[self._global_container_stack.definition.getId()].variants[current_nozzle_name]
+ candidate_materials = nozzle_node.materials
+ old_approximate_material_diameter = int(extruder.material.getMetaDataEntry("approximate_diameter", default = 3))
+ new_approximate_material_diameter = int(self._global_container_stack.extruderList[int(position_item)].getApproximateMaterialDiameter())
- if not candidate_materials:
- self._setMaterial(position_item, container_node = None)
- continue
-
- if current_material_base_name in candidate_materials:
+ # Only switch to the old candidate material if the approximate material diameter of the extruder stays the
+ # same.
+ if new_approximate_material_diameter == old_approximate_material_diameter and \
+ current_material_base_name in candidate_materials: # The current material is also available after the switch. Retain it.
new_material = candidate_materials[current_material_base_name]
self._setMaterial(position_item, new_material)
- continue
-
- # The current material is not available, find the preferred one
- material_node = self._material_manager.getDefaultMaterial(self._global_container_stack, position_item, current_nozzle_name)
- if material_node is not None:
+ else:
+ # The current material is not available, find the preferred one.
+ approximate_material_diameter = int(self._global_container_stack.extruderList[int(position_item)].getApproximateMaterialDiameter())
+ material_node = nozzle_node.preferredMaterial(approximate_material_diameter)
self._setMaterial(position_item, material_node)
## Given a printer definition name, select the right machine instance. In case it doesn't exist, create a new
@@ -1348,35 +1229,41 @@ class MachineManager(QObject):
@pyqtSlot(str)
def switchPrinterType(self, machine_name: str) -> None:
# Don't switch if the user tries to change to the same type of printer
- if self._global_container_stack is None or self.activeMachineDefinitionName == machine_name:
+ if self._global_container_stack is None or self._global_container_stack.definition.name == machine_name:
return
+ Logger.log("i", "Attempting to switch the printer type to [%s]", machine_name)
# Get the definition id corresponding to this machine name
machine_definition_id = CuraContainerRegistry.getInstance().findDefinitionContainers(name = machine_name)[0].getId()
# Try to find a machine with the same network key
- new_machine = self.getMachine(machine_definition_id, metadata_filter = {"um_network_key": self.activeMachineNetworkKey()})
+ metadata_filter = {"group_id": self._global_container_stack.getMetaDataEntry("group_id")}
+ new_machine = self.getMachine(machine_definition_id, metadata_filter = metadata_filter)
# If there is no machine, then create a new one and set it to the non-hidden instance
if not new_machine:
new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_sync", machine_definition_id)
if not new_machine:
return
- new_machine.setMetaDataEntry("um_network_key", self.activeMachineNetworkKey())
- new_machine.setMetaDataEntry("group_name", self.activeMachineNetworkGroupName)
- new_machine.setMetaDataEntry("hidden", False)
- new_machine.setMetaDataEntry("connection_type", self._global_container_stack.getMetaDataEntry("connection_type"))
+
+ for metadata_key in self._global_container_stack.getMetaData():
+ if metadata_key in new_machine.getMetaData():
+ continue # Don't copy the already preset stuff.
+ new_machine.setMetaDataEntry(metadata_key, self._global_container_stack.getMetaDataEntry(metadata_key))
+ # Special case, group_id should be overwritten!
+ new_machine.setMetaDataEntry("group_id", self._global_container_stack.getMetaDataEntry("group_id"))
else:
Logger.log("i", "Found a %s with the key %s. Let's use it!", machine_name, self.activeMachineNetworkKey())
- new_machine.setMetaDataEntry("hidden", False)
# Set the current printer instance to hidden (the metadata entry must exist)
+ new_machine.setMetaDataEntry("hidden", False)
self._global_container_stack.setMetaDataEntry("hidden", True)
self.setActiveMachine(new_machine.getId())
@pyqtSlot(QObject)
- def applyRemoteConfiguration(self, configuration: ConfigurationModel) -> None:
+ def applyRemoteConfiguration(self, configuration: PrinterConfigurationModel) -> None:
if self._global_container_stack is None:
return
self.blurSettings.emit()
+ container_registry = CuraContainerRegistry.getInstance()
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
self.switchPrinterType(configuration.printerType)
@@ -1388,15 +1275,16 @@ class MachineManager(QObject):
need_to_show_message = False
for extruder_configuration in configuration.extruderConfigurations:
- extruder_has_hotend = extruder_configuration.hotendID != ""
- extruder_has_material = extruder_configuration.material.guid != ""
+ # We support "" or None, since the cloud uses None instead of empty strings
+ extruder_has_hotend = extruder_configuration.hotendID and extruder_configuration.hotendID != ""
+ extruder_has_material = extruder_configuration.material.guid and extruder_configuration.material.guid != ""
# If the machine doesn't have a hotend or material, disable this extruder
if not extruder_has_hotend or not extruder_has_material:
extruders_to_disable.add(extruder_configuration.position)
# If there's no material and/or nozzle on the printer, enable the first extruder and disable the rest.
- if len(extruders_to_disable) == len(self._global_container_stack.extruders):
+ if len(extruders_to_disable) == len(self._global_container_stack.extruderList):
extruders_to_disable.remove(min(extruders_to_disable))
for extruder_configuration in configuration.extruderConfigurations:
@@ -1404,41 +1292,33 @@ class MachineManager(QObject):
# If the machine doesn't have a hotend or material, disable this extruder
if int(position) in extruders_to_disable:
- self._global_container_stack.extruders[position].setEnabled(False)
+ self._global_container_stack.extruderList[int(position)].setEnabled(False)
need_to_show_message = True
disabled_used_extruder_position_set.add(int(position))
else:
- variant_container_node = self._variant_manager.getVariantNode(self._global_container_stack.definition.getId(),
- extruder_configuration.hotendID)
- material_container_node = self._material_manager.getMaterialNodeByType(self._global_container_stack,
- position,
- extruder_configuration.hotendID,
- configuration.buildplateConfiguration,
- extruder_configuration.material.guid)
- if variant_container_node:
- self._setVariantNode(position, variant_container_node)
- else:
- self._global_container_stack.extruders[position].variant = empty_variant_container
+ machine_node = ContainerTree.getInstance().machines.get(self._global_container_stack.definition.getId())
+ variant_node = machine_node.variants.get(extruder_configuration.hotendID)
+ if variant_node is None:
+ continue
+ self._setVariantNode(position, variant_node)
- if material_container_node:
- self._setMaterial(position, material_container_node)
- else:
- self._global_container_stack.extruders[position].material = empty_material_container
+ # Find the material profile that the printer has stored.
+ # This might find one of the duplicates if the user duplicated the material to sync with. But that's okay; both have this GUID so both are correct.
+ approximate_diameter = int(self._global_container_stack.extruderList[int(position)].getApproximateMaterialDiameter())
+ materials_with_guid = container_registry.findInstanceContainersMetadata(GUID = extruder_configuration.material.guid, approximate_diameter = str(approximate_diameter), ignore_case = True)
+ material_container_node = variant_node.preferredMaterial(approximate_diameter)
+ if materials_with_guid: # We also have the material profile that the printer wants to share.
+ base_file = materials_with_guid[0]["base_file"]
+ material_container_node = variant_node.materials.get(base_file, material_container_node)
+
+ self._setMaterial(position, material_container_node)
self._global_container_stack.extruders[position].setEnabled(True)
self.updateMaterialWithVariant(position)
+ self.updateDefaultExtruder()
self.updateNumberExtrudersEnabled()
-
- if configuration.buildplateConfiguration is not None:
- global_variant_container_node = self._variant_manager.getBuildplateVariantNode(self._global_container_stack.definition.getId(), configuration.buildplateConfiguration)
- if global_variant_container_node:
- self._setGlobalVariant(global_variant_container_node)
- else:
- self._global_container_stack.variant = empty_variant_container
- else:
- self._global_container_stack.variant = empty_variant_container
self._updateQualityWithMaterial()
if need_to_show_message:
@@ -1447,7 +1327,7 @@ class MachineManager(QObject):
# Show human-readable extruder names such as "Extruder Left", "Extruder Front" instead of "Extruder 1, 2, 3".
extruder_names = []
for extruder_position in sorted(disabled_used_extruder_position_set):
- extruder_stack = self._global_container_stack.extruders[str(extruder_position)]
+ extruder_stack = self._global_container_stack.extruderList[int(extruder_position)]
extruder_name = extruder_stack.definition.getName()
extruder_names.append(extruder_name)
extruders_str = ", ".join(extruder_names)
@@ -1460,31 +1340,6 @@ class MachineManager(QObject):
if self.hasUserSettings and self._application.getPreferences().getValue("cura/active_mode") == 1:
self._application.discardOrKeepProfileChanges()
- ## Find all container stacks that has the pair 'key = value' in its metadata and replaces the value with 'new_value'
- def replaceContainersMetadata(self, key: str, value: str, new_value: str) -> None:
- machines = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine")
- for machine in machines:
- if machine.getMetaDataEntry(key) == value:
- machine.setMetaDataEntry(key, new_value)
-
- ## This method checks if the name of the group stored in the definition container is correct.
- # After updating from 3.2 to 3.3 some group names may be temporary. If there is a mismatch in the name of the group
- # then all the container stacks are updated, both the current and the hidden ones.
- def checkCorrectGroupName(self, device_id: str, group_name: str) -> None:
- if self._global_container_stack and device_id == self.activeMachineNetworkKey():
- # Check if the group_name is correct. If not, update all the containers connected to the same printer
- if self.activeMachineNetworkGroupName != group_name:
- metadata_filter = {"um_network_key": self.activeMachineNetworkKey()}
- containers = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
- for container in containers:
- container.setMetaDataEntry("group_name", group_name)
-
- ## This method checks if there is an instance connected to the given network_key
- def existNetworkInstances(self, network_key: str) -> bool:
- metadata_filter = {"um_network_key": network_key}
- containers = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
- return bool(containers)
-
@pyqtSlot("QVariant")
def setGlobalVariant(self, container_node: "ContainerNode") -> None:
self.blurSettings.emit()
@@ -1497,17 +1352,12 @@ class MachineManager(QObject):
def setMaterialById(self, position: str, root_material_id: str) -> None:
if self._global_container_stack is None:
return
- buildplate_name = None
- if self._global_container_stack.variant.getId() != "empty_variant":
- buildplate_name = self._global_container_stack.variant.getName()
machine_definition_id = self._global_container_stack.definition.id
position = str(position)
- extruder_stack = self._global_container_stack.extruders[position]
+ extruder_stack = self._global_container_stack.extruderList[int(position)]
nozzle_name = extruder_stack.variant.getName()
- material_diameter = extruder_stack.getApproximateMaterialDiameter()
- material_node = self._material_manager.getMaterialNode(machine_definition_id, nozzle_name, buildplate_name,
- material_diameter, root_material_id)
+ material_node = ContainerTree.getInstance().machines[machine_definition_id].variants[nozzle_name].materials[root_material_id]
self.setMaterial(position, material_node)
## Global_stack: if you want to provide your own global_stack instead of the current active one
@@ -1515,7 +1365,7 @@ class MachineManager(QObject):
@pyqtSlot(str, "QVariant")
def setMaterial(self, position: str, container_node, global_stack: Optional["GlobalStack"] = None) -> None:
if global_stack is not None and global_stack != self._global_container_stack:
- global_stack.extruders[position].material = container_node.getContainer()
+ global_stack.extruders[position].material = container_node.container
return
position = str(position)
self.blurSettings.emit()
@@ -1532,15 +1382,16 @@ class MachineManager(QObject):
if self._global_container_stack is None:
return
machine_definition_id = self._global_container_stack.definition.id
- variant_node = self._variant_manager.getVariantNode(machine_definition_id, variant_name)
+ machine_node = ContainerTree.getInstance().machines.get(machine_definition_id)
+ variant_node = machine_node.variants.get(variant_name)
self.setVariant(position, variant_node)
@pyqtSlot(str, "QVariant")
- def setVariant(self, position: str, container_node: "ContainerNode") -> None:
+ def setVariant(self, position: str, variant_node: "VariantNode") -> None:
position = str(position)
self.blurSettings.emit()
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
- self._setVariantNode(position, container_node)
+ self._setVariantNode(position, variant_node)
self.updateMaterialWithVariant(position)
self._updateQualityWithMaterial()
@@ -1553,9 +1404,7 @@ class MachineManager(QObject):
if self._global_container_stack is None:
return
# Get all the quality groups for this global stack and filter out by quality_type
- quality_group_dict = self._quality_manager.getQualityGroups(self._global_container_stack)
- quality_group = quality_group_dict[quality_type]
- self.setQualityGroup(quality_group)
+ self.setQualityGroup(ContainerTree.getInstance().getCurrentQualityGroups()[quality_type])
## Optionally provide global_stack if you want to use your own
# The active global_stack is treated differently.
@@ -1569,11 +1418,11 @@ class MachineManager(QObject):
Logger.log("e", "Could not set quality group [%s] because it has no node_for_global", str(quality_group))
return
# This is not changing the quality for the active machine !!!!!!!!
- global_stack.quality = quality_group.node_for_global.getContainer()
- for extruder_nr, extruder_stack in global_stack.extruders.items():
+ global_stack.quality = quality_group.node_for_global.container
+ for extruder_nr, extruder_stack in enumerate(global_stack.extruderList):
quality_container = empty_quality_container
if extruder_nr in quality_group.nodes_for_extruders:
- container = quality_group.nodes_for_extruders[extruder_nr].getContainer()
+ container = quality_group.nodes_for_extruders[extruder_nr].container
quality_container = container if container is not None else quality_container
extruder_stack.quality = quality_container
return
@@ -1586,9 +1435,91 @@ class MachineManager(QObject):
if not no_dialog and self.hasUserSettings and self._application.getPreferences().getValue("cura/active_mode") == 1:
self._application.discardOrKeepProfileChanges()
- @pyqtProperty(QObject, fset = setQualityGroup, notify = activeQualityGroupChanged)
+ # The display name map of currently active quality.
+ # The display name has 2 parts, a main part and a suffix part.
+ # This display name is:
+ # - For built-in qualities (quality/intent): the quality type name, such as "Fine", "Normal", etc.
+ # - For custom qualities: - -
+ # Examples:
+ # - "my_profile - Fine" (only based on a default quality, no intent involved)
+ # - "my_profile - Engineering - Fine" (based on an intent)
+ @pyqtProperty("QVariantMap", notify = activeQualityDisplayNameChanged)
+ def activeQualityDisplayNameMap(self) -> Dict[str, str]:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return {"main": "",
+ "suffix": ""}
+
+ display_name = global_stack.quality.getName()
+
+ intent_category = self.activeIntentCategory
+ if intent_category != "default":
+ intent_display_name = IntentCategoryModel.translation(intent_category,
+ "name",
+ catalog.i18nc("@label", "Unknown"))
+ display_name = "{intent_name} - {the_rest}".format(intent_name = intent_display_name,
+ the_rest = display_name)
+
+ main_part = display_name
+ suffix_part = ""
+
+ # Not a custom quality
+ if global_stack.qualityChanges != empty_quality_changes_container:
+ main_part = self.activeQualityOrQualityChangesName
+ suffix_part = display_name
+
+ return {"main": main_part,
+ "suffix": suffix_part}
+
+ ## Change the intent category of the current printer.
+ #
+ # All extruders can change their profiles. If an intent profile is
+ # available with the desired intent category, that one will get chosen.
+ # Otherwise the intent profile will be left to the empty profile, which
+ # represents the "default" intent category.
+ # \param intent_category The intent category to change to.
+ @pyqtSlot(str)
+ def setIntentByCategory(self, intent_category: str) -> None:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return
+ container_tree = ContainerTree.getInstance()
+ for extruder in global_stack.extruderList:
+ definition_id = global_stack.definition.getId()
+ variant_name = extruder.variant.getName()
+ material_base_file = extruder.material.getMetaDataEntry("base_file")
+ quality_id = extruder.quality.getId()
+ if quality_id == empty_quality_container.getId():
+ extruder.intent = empty_intent_container
+ continue
+ quality_node = container_tree.machines[definition_id].variants[variant_name].materials[material_base_file].qualities[quality_id]
+
+ for intent_node in quality_node.intents.values():
+ if intent_node.intent_category == intent_category: # Found an intent with the correct category.
+ extruder.intent = intent_node.container
+ break
+ else: # No intent had the correct category.
+ extruder.intent = empty_intent_container
+
+ ## Get the currently activated quality group.
+ #
+ # If no printer is added yet or the printer doesn't have quality profiles,
+ # this returns ``None``.
+ # \return The currently active quality group.
def activeQualityGroup(self) -> Optional["QualityGroup"]:
- return self._current_quality_group
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_stack or global_stack.quality == empty_quality_container:
+ return None
+ return ContainerTree.getInstance().getCurrentQualityGroups().get(self.activeQualityType)
+
+ ## Get the name of the active quality group.
+ # \return The name of the active quality group.
+ @pyqtProperty(str, notify = activeQualityGroupChanged)
+ def activeQualityGroupName(self) -> str:
+ quality_group = self.activeQualityGroup()
+ if quality_group is None:
+ return ""
+ return quality_group.getName()
@pyqtSlot(QObject)
def setQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", no_dialog: bool = False) -> None:
@@ -1605,30 +1536,50 @@ class MachineManager(QObject):
if self._global_container_stack is None:
return
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
- self._setQualityGroup(self._current_quality_group)
+ self._setQualityGroup(self.activeQualityGroup())
for stack in [self._global_container_stack] + list(self._global_container_stack.extruders.values()):
stack.userChanges.clear()
@pyqtProperty(QObject, fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged)
def activeQualityChangesGroup(self) -> Optional["QualityChangesGroup"]:
- return self._current_quality_changes_group
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None or global_stack.qualityChanges == empty_quality_changes_container:
+ return None
+
+ all_group_list = ContainerTree.getInstance().getCurrentQualityChangesGroups()
+ the_group = None
+ for group in all_group_list: # Match on the container ID of the global stack to find the quality changes group belonging to the active configuration.
+ if group.metadata_for_global and group.metadata_for_global["id"] == global_stack.qualityChanges.getId():
+ the_group = group
+ break
+
+ return the_group
@pyqtProperty(bool, notify = activeQualityChangesGroupChanged)
def hasCustomQuality(self) -> bool:
- return self._current_quality_changes_group is not None
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ return global_stack is None or global_stack.qualityChanges != empty_quality_changes_container
@pyqtProperty(str, notify = activeQualityGroupChanged)
def activeQualityOrQualityChangesName(self) -> str:
- name = empty_quality_container.getName()
- if self._current_quality_changes_group:
- name = self._current_quality_changes_group.name
- elif self._current_quality_group:
- name = self._current_quality_group.name
- return name
+ global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if not global_container_stack:
+ return empty_quality_container.getName()
+ if global_container_stack.qualityChanges != empty_quality_changes_container:
+ return global_container_stack.qualityChanges.getName()
+ return global_container_stack.quality.getName()
@pyqtProperty(bool, notify = activeQualityGroupChanged)
def hasNotSupportedQuality(self) -> bool:
- return self._current_quality_group is None and self._current_quality_changes_group is None
+ global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ return (not global_container_stack is None) and global_container_stack.quality == empty_quality_container and global_container_stack.qualityChanges == empty_quality_changes_container
+
+ @pyqtProperty(bool, notify = activeQualityGroupChanged)
+ def isActiveQualityCustom(self) -> bool:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return False
+ return global_stack.qualityChanges != empty_quality_changes_container
def _updateUponMaterialMetadataChange(self) -> None:
if self._global_container_stack is None:
diff --git a/cura/Settings/PerObjectContainerStack.py b/cura/Settings/PerObjectContainerStack.py
index 3589029517..a4f1f6ed06 100644
--- a/cura/Settings/PerObjectContainerStack.py
+++ b/cura/Settings/PerObjectContainerStack.py
@@ -12,6 +12,10 @@ from .CuraContainerStack import CuraContainerStack
class PerObjectContainerStack(CuraContainerStack):
+ def isDirty(self):
+ # This stack should never be auto saved, so always return that there is nothing to save.
+ return False
+
@override(CuraContainerStack)
def getProperty(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> Any:
if context is None:
@@ -34,7 +38,7 @@ class PerObjectContainerStack(CuraContainerStack):
if limit_to_extruder is not None:
limit_to_extruder = str(limit_to_extruder)
- # if this stack has the limit_to_extruder "not overriden", use the original limit_to_extruder as the current
+ # if this stack has the limit_to_extruder "not overridden", use the original limit_to_extruder as the current
# limit_to_extruder, so the values retrieved will be from the perspective of the original limit_to_extruder
# stack.
if limit_to_extruder == "-1":
@@ -42,7 +46,7 @@ class PerObjectContainerStack(CuraContainerStack):
limit_to_extruder = context.context["original_limit_to_extruder"]
if limit_to_extruder is not None and limit_to_extruder != "-1" and limit_to_extruder in global_stack.extruders:
- # set the original limit_to_extruder if this is the first stack that has a non-overriden limit_to_extruder
+ # set the original limit_to_extruder if this is the first stack that has a non-overridden limit_to_extruder
if "original_limit_to_extruder" not in context.context:
context.context["original_limit_to_extruder"] = limit_to_extruder
diff --git a/cura/Settings/SettingInheritanceManager.py b/cura/Settings/SettingInheritanceManager.py
index 12b541c3d8..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.
@@ -88,8 +89,8 @@ class SettingInheritanceManager(QObject):
self.settingsWithIntheritanceChanged.emit()
@pyqtSlot()
- def forceUpdate(self) -> None:
- self._update()
+ def scheduleUpdate(self) -> None:
+ self._update_timer.start()
def _onActiveExtruderChanged(self) -> None:
new_active_stack = ExtruderManager.getInstance().getActiveExtruderStack()
@@ -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/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py
index 429e6d16ec..2fa5234ec3 100644
--- a/cura/Settings/SettingOverrideDecorator.py
+++ b/cura/Settings/SettingOverrideDecorator.py
@@ -73,8 +73,8 @@ class SettingOverrideDecorator(SceneNodeDecorator):
# use value from the stack because there can be a delay in signal triggering and "_is_non_printing_mesh"
# has not been updated yet.
- deep_copy._is_non_printing_mesh = self.evaluateIsNonPrintingMesh()
- deep_copy._is_non_thumbnail_visible_mesh = self.evaluateIsNonThumbnailVisibleMesh()
+ deep_copy._is_non_printing_mesh = self._evaluateIsNonPrintingMesh()
+ deep_copy._is_non_thumbnail_visible_mesh = self._evaluateIsNonThumbnailVisibleMesh()
return deep_copy
@@ -102,21 +102,21 @@ class SettingOverrideDecorator(SceneNodeDecorator):
def isNonPrintingMesh(self):
return self._is_non_printing_mesh
- def evaluateIsNonPrintingMesh(self):
+ def _evaluateIsNonPrintingMesh(self):
return any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings)
def isNonThumbnailVisibleMesh(self):
return self._is_non_thumbnail_visible_mesh
- def evaluateIsNonThumbnailVisibleMesh(self):
+ def _evaluateIsNonThumbnailVisibleMesh(self):
return any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_thumbnail_visible_settings)
- def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function
+ def _onSettingChanged(self, setting_key, property_name): # Reminder: 'property' is a built-in function
+ # We're only interested in a few settings and only if it's value changed.
if property_name == "value":
# Trigger slice/need slicing if the value has changed.
- self._is_non_printing_mesh = self.evaluateIsNonPrintingMesh()
- self._is_non_thumbnail_visible_mesh = self.evaluateIsNonThumbnailVisibleMesh()
-
+ self._is_non_printing_mesh = self._evaluateIsNonPrintingMesh()
+ self._is_non_thumbnail_visible_mesh = self._evaluateIsNonThumbnailVisibleMesh()
Application.getInstance().getBackend().needsSlicing()
Application.getInstance().getBackend().tickle()
diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py
index b1896a9205..3923435e63 100644
--- a/cura/Settings/SimpleModeSettingsManager.py
+++ b/cura/Settings/SimpleModeSettingsManager.py
@@ -39,8 +39,8 @@ class SimpleModeSettingsManager(QObject):
user_setting_keys.update(global_stack.userChanges.getAllKeys())
# check user settings in the extruder stacks
- if global_stack.extruders:
- for extruder_stack in global_stack.extruders.values():
+ if global_stack.extruderList:
+ for extruder_stack in global_stack.extruderList:
user_setting_keys.update(extruder_stack.userChanges.getAllKeys())
# remove settings that are visible in recommended (we don't show the reset button for those)
diff --git a/cura/Settings/cura_empty_instance_containers.py b/cura/Settings/cura_empty_instance_containers.py
index d76407ed79..b142c53c11 100644
--- a/cura/Settings/cura_empty_instance_containers.py
+++ b/cura/Settings/cura_empty_instance_containers.py
@@ -1,9 +1,11 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import copy
from UM.Settings.constant_instance_containers import EMPTY_CONTAINER_ID, empty_container
+from UM.i18n import i18nCatalog
+catalog = i18nCatalog("cura")
# Empty definition changes
@@ -23,12 +25,15 @@ EMPTY_MATERIAL_CONTAINER_ID = "empty_material"
empty_material_container = copy.deepcopy(empty_container)
empty_material_container.setMetaDataEntry("id", EMPTY_MATERIAL_CONTAINER_ID)
empty_material_container.setMetaDataEntry("type", "material")
+empty_material_container.setMetaDataEntry("base_file", "empty_material")
+empty_material_container.setMetaDataEntry("GUID", "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF")
+empty_material_container.setMetaDataEntry("material", "empty")
# Empty quality
EMPTY_QUALITY_CONTAINER_ID = "empty_quality"
empty_quality_container = copy.deepcopy(empty_container)
empty_quality_container.setMetaDataEntry("id", EMPTY_QUALITY_CONTAINER_ID)
-empty_quality_container.setName("Not Supported")
+empty_quality_container.setName(catalog.i18nc("@info:not supported profile", "Not supported"))
empty_quality_container.setMetaDataEntry("quality_type", "not_supported")
empty_quality_container.setMetaDataEntry("type", "quality")
empty_quality_container.setMetaDataEntry("supported", False)
@@ -39,6 +44,32 @@ empty_quality_changes_container = copy.deepcopy(empty_container)
empty_quality_changes_container.setMetaDataEntry("id", EMPTY_QUALITY_CHANGES_CONTAINER_ID)
empty_quality_changes_container.setMetaDataEntry("type", "quality_changes")
empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported")
+empty_quality_changes_container.setMetaDataEntry("intent_category", "not_supported")
+
+# Empty intent
+EMPTY_INTENT_CONTAINER_ID = "empty_intent"
+empty_intent_container = copy.deepcopy(empty_container)
+empty_intent_container.setMetaDataEntry("id", EMPTY_INTENT_CONTAINER_ID)
+empty_intent_container.setMetaDataEntry("type", "intent")
+empty_intent_container.setMetaDataEntry("intent_category", "default")
+empty_intent_container.setName(catalog.i18nc("@info:No intent profile selected", "Default"))
+
+
+# All empty container IDs set
+ALL_EMPTY_CONTAINER_ID_SET = {
+ EMPTY_CONTAINER_ID,
+ EMPTY_DEFINITION_CHANGES_CONTAINER_ID,
+ EMPTY_VARIANT_CONTAINER_ID,
+ EMPTY_MATERIAL_CONTAINER_ID,
+ EMPTY_QUALITY_CONTAINER_ID,
+ EMPTY_QUALITY_CHANGES_CONTAINER_ID,
+ EMPTY_INTENT_CONTAINER_ID
+}
+
+
+# Convenience function to check if a container ID represents an empty container.
+def isEmptyContainer(container_id: str) -> bool:
+ return container_id in ALL_EMPTY_CONTAINER_ID_SET
__all__ = ["EMPTY_CONTAINER_ID",
@@ -52,5 +83,9 @@ __all__ = ["EMPTY_CONTAINER_ID",
"EMPTY_QUALITY_CHANGES_CONTAINER_ID",
"empty_quality_changes_container",
"EMPTY_QUALITY_CONTAINER_ID",
- "empty_quality_container"
+ "empty_quality_container",
+ "ALL_EMPTY_CONTAINER_ID_SET",
+ "isEmptyContainer",
+ "EMPTY_INTENT_CONTAINER_ID",
+ "empty_intent_container"
]
diff --git a/cura/SingleInstance.py b/cura/SingleInstance.py
index cf07b143c6..6fcf0da6cf 100644
--- a/cura/SingleInstance.py
+++ b/cura/SingleInstance.py
@@ -87,7 +87,7 @@ class SingleInstance:
if command == "clear-all":
self._application.callLater(lambda: self._application.deleteAll())
- # Command: Load a model file
+ # Command: Load a model or project file
elif command == "open":
self._application.callLater(lambda f = payload["filePath"]: self._application._openFile(f))
diff --git a/cura/Snapshot.py b/cura/Snapshot.py
index b730c1fdcf..353b5ae17c 100644
--- a/cura/Snapshot.py
+++ b/cura/Snapshot.py
@@ -48,12 +48,12 @@ class Snapshot:
# determine zoom and look at
bbox = None
for node in DepthFirstIterator(root):
- if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible() and not node.callDecoration("isNonThumbnailVisibleMesh"):
- if bbox is None:
- bbox = node.getBoundingBox()
- else:
- bbox = bbox + node.getBoundingBox()
-
+ if not getattr(node, "_outside_buildarea", False):
+ if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible() and not node.callDecoration("isNonThumbnailVisibleMesh"):
+ if bbox is None:
+ bbox = node.getBoundingBox()
+ else:
+ bbox = bbox + node.getBoundingBox()
# If there is no bounding box, it means that there is no model in the buildplate
if bbox is None:
return None
@@ -66,7 +66,7 @@ class Snapshot:
looking_from_offset = Vector(-1, 1, 2)
if size > 0:
# determine the watch distance depending on the size
- looking_from_offset = looking_from_offset * size * 1.3
+ looking_from_offset = looking_from_offset * size * 1.75
camera.setPosition(look_at + looking_from_offset)
camera.lookAt(look_at)
@@ -85,8 +85,10 @@ class Snapshot:
preview_pass.setCamera(camera)
preview_pass.render()
pixel_output = preview_pass.getOutput()
-
- min_x, max_x, min_y, max_y = Snapshot.getImageBoundaries(pixel_output)
+ try:
+ min_x, max_x, min_y, max_y = Snapshot.getImageBoundaries(pixel_output)
+ except ValueError:
+ return None
size = max((max_x - min_x) / render_width, (max_y - min_y) / render_height)
if size > 0.5 or satisfied:
diff --git a/cura/Stages/CuraStage.py b/cura/Stages/CuraStage.py
index 844b0d0768..6c4d46dd72 100644
--- a/cura/Stages/CuraStage.py
+++ b/cura/Stages/CuraStage.py
@@ -1,29 +1,32 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from PyQt5.QtCore import pyqtProperty, QUrl
-
-from UM.Stage import Stage
-
-
-# Since Cura has a few pre-defined "space claims" for the locations of certain components, we've provided some structure
-# to indicate this.
-# * The StageMenuComponent is the horizontal area below the stage bar. This should be used to show stage specific
-# buttons and elements. This component will be drawn over the bar & main component.
-# * The MainComponent is the component that will be drawn starting from the bottom of the stageBar and fills the rest
-# of the screen.
-class CuraStage(Stage):
- def __init__(self, parent = None) -> None:
- super().__init__(parent)
-
- @pyqtProperty(str, constant = True)
- def stageId(self) -> str:
- return self.getPluginId()
-
- @pyqtProperty(QUrl, constant = True)
- def mainComponent(self) -> QUrl:
- return self.getDisplayComponent("main")
-
- @pyqtProperty(QUrl, constant = True)
- def stageMenuComponent(self) -> QUrl:
- return self.getDisplayComponent("menu")
\ No newline at end of file
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import pyqtProperty, QUrl
+
+from UM.Stage import Stage
+
+
+# Since Cura has a few pre-defined "space claims" for the locations of certain components, we've provided some structure
+# to indicate this.
+# * The StageMenuComponent is the horizontal area below the stage bar. This should be used to show stage specific
+# buttons and elements. This component will be drawn over the bar & main component.
+# * The MainComponent is the component that will be drawn starting from the bottom of the stageBar and fills the rest
+# of the screen.
+class CuraStage(Stage):
+ def __init__(self, parent = None) -> None:
+ super().__init__(parent)
+
+ @pyqtProperty(str, constant = True)
+ def stageId(self) -> str:
+ return self.getPluginId()
+
+ @pyqtProperty(QUrl, constant = True)
+ def mainComponent(self) -> QUrl:
+ return self.getDisplayComponent("main")
+
+ @pyqtProperty(QUrl, constant = True)
+ def stageMenuComponent(self) -> QUrl:
+ return self.getDisplayComponent("menu")
+
+
+__all__ = ["CuraStage"]
diff --git a/cura/Stages/__init__.py b/cura/Stages/__init__.py
index 2977645166..e69de29bb2 100644
--- a/cura/Stages/__init__.py
+++ b/cura/Stages/__init__.py
@@ -1,2 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
diff --git a/cura/UI/AddPrinterPagesModel.py b/cura/UI/AddPrinterPagesModel.py
new file mode 100644
index 0000000000..d40da59b2a
--- /dev/null
+++ b/cura/UI/AddPrinterPagesModel.py
@@ -0,0 +1,31 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from .WelcomePagesModel import WelcomePagesModel
+
+
+#
+# This Qt ListModel is more or less the same the WelcomePagesModel, except that this model is only for adding a printer,
+# so only the steps for adding a printer is included.
+#
+class AddPrinterPagesModel(WelcomePagesModel):
+
+ def initialize(self) -> None:
+ self._pages.append({"id": "add_network_or_local_printer",
+ "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
+ "next_page_id": "machine_actions",
+ "next_page_button_text": self._catalog.i18nc("@action:button", "Add"),
+ "previous_page_button_text": self._catalog.i18nc("@action:button", "Cancel"),
+ })
+ self._pages.append({"id": "add_printer_by_ip",
+ "page_url": self._getBuiltinWelcomePagePath("AddPrinterByIpContent.qml"),
+ "next_page_id": "machine_actions",
+ })
+ self._pages.append({"id": "machine_actions",
+ "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
+ "should_show_function": self.shouldShowMachineActions,
+ })
+ self.setItems(self._pages)
+
+
+__all__ = ["AddPrinterPagesModel"]
diff --git a/cura/CuraSplashScreen.py b/cura/UI/CuraSplashScreen.py
similarity index 94%
rename from cura/CuraSplashScreen.py
rename to cura/UI/CuraSplashScreen.py
index 77c9ad1427..05231c106d 100644
--- a/cura/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)
diff --git a/cura/MachineActionManager.py b/cura/UI/MachineActionManager.py
similarity index 98%
rename from cura/MachineActionManager.py
rename to cura/UI/MachineActionManager.py
index db0f7bfbff..aa90e909e2 100644
--- a/cura/MachineActionManager.py
+++ b/cura/UI/MachineActionManager.py
@@ -12,7 +12,7 @@ from UM.PluginRegistry import PluginRegistry # So MachineAction can be added as
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
from cura.Settings.GlobalStack import GlobalStack
- from .MachineAction import MachineAction
+ from cura.MachineAction import MachineAction
## Raised when trying to add an unknown machine action as a required action
@@ -136,7 +136,7 @@ class MachineActionManager(QObject):
# action multiple times).
# \param definition_id The ID of the definition that you want to get the "on added" actions for.
# \returns List of actions.
- @pyqtSlot(str, result="QVariantList")
+ @pyqtSlot(str, result = "QVariantList")
def getFirstStartActions(self, definition_id: str) -> List["MachineAction"]:
if definition_id in self._first_start_actions:
return self._first_start_actions[definition_id]
diff --git a/cura/UI/MachineSettingsManager.py b/cura/UI/MachineSettingsManager.py
new file mode 100644
index 0000000000..671bb0ece0
--- /dev/null
+++ b/cura/UI/MachineSettingsManager.py
@@ -0,0 +1,84 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Optional, TYPE_CHECKING
+from PyQt5.QtCore import QObject, pyqtSlot
+
+from UM.i18n import i18nCatalog
+
+from cura.Machines.ContainerTree import ContainerTree
+
+if TYPE_CHECKING:
+ from cura.CuraApplication import CuraApplication
+
+
+#
+# This manager provides (convenience) functions to the Machine Settings Dialog QML to update certain machine settings.
+#
+class MachineSettingsManager(QObject):
+
+ def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
+ super().__init__(parent)
+ self._i18n_catalog = i18nCatalog("cura")
+
+ self._application = application
+
+ # Force rebuilding the build volume by reloading the global container stack. This is a bit of a hack, but it seems
+ # quite enough.
+ @pyqtSlot()
+ def forceUpdate(self) -> None:
+ self._application.getMachineManager().globalContainerChanged.emit()
+
+ # Function for the Machine Settings panel (QML) to update the compatible material diameter after a user has changed
+ # an extruder's compatible material diameter. This ensures that after the modification, changes can be notified
+ # and updated right away.
+ @pyqtSlot(int)
+ def updateMaterialForDiameter(self, extruder_position: int) -> None:
+ # Updates the material container to a material that matches the material diameter set for the printer
+ self._application.getMachineManager().updateMaterialWithVariant(str(extruder_position))
+
+ @pyqtSlot(int)
+ def setMachineExtruderCount(self, extruder_count: int) -> None:
+ # Note: this method was in this class before, but since it's quite generic and other plugins also need it
+ # it was moved to the machine manager instead. Now this method just calls the machine manager.
+ self._application.getMachineManager().setActiveMachineExtruderCount(extruder_count)
+
+ # Function for the Machine Settings panel (QML) to update after the user changes "Number of Extruders".
+ #
+ # fieldOfView: The Ultimaker 2 family (not 2+) does not have materials in Cura by default, because the material is
+ # to be set on the printer. But when switching to Marlin flavor, the printer firmware can not change/insert material
+ # settings on the fly so they need to be configured in Cura. So when switching between gcode flavors, materials may
+ # need to be enabled/disabled.
+ @pyqtSlot()
+ def updateHasMaterialsMetadata(self):
+ machine_manager = self._application.getMachineManager()
+ global_stack = machine_manager.activeMachine
+
+ definition = global_stack.definition
+ if definition.getProperty("machine_gcode_flavor", "value") != "UltiGCode" or definition.getMetaDataEntry(
+ "has_materials", False):
+ # In other words: only continue for the UM2 (extended), but not for the UM2+
+ return
+
+ extruder_positions = list(global_stack.extruders.keys())
+ has_materials = global_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
+
+ material_node = None
+ if has_materials:
+ global_stack.setMetaDataEntry("has_materials", True)
+ else:
+ # The metadata entry is stored in an ini, and ini files are parsed as strings only.
+ # Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
+ if "has_materials" in global_stack.getMetaData():
+ global_stack.removeMetaDataEntry("has_materials")
+
+ # set materials
+ for position in extruder_positions:
+ if has_materials:
+ extruder = global_stack.extruderList[int(position)]
+ approximate_diameter = extruder.getApproximateMaterialDiameter()
+ variant_node = ContainerTree.getInstance().machines[global_stack.definition.getId()].variants[extruder.variant.getName()]
+ material_node = variant_node.preferredMaterial(approximate_diameter)
+ machine_manager.setMaterial(position, material_node)
+
+ self.forceUpdate()
diff --git a/cura/UI/ObjectsModel.py b/cura/UI/ObjectsModel.py
new file mode 100644
index 0000000000..5526b41098
--- /dev/null
+++ b/cura/UI/ObjectsModel.py
@@ -0,0 +1,184 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from UM.Logger import Logger
+import re
+from typing import Any, Dict, List, Optional, Union
+
+from PyQt5.QtCore import QTimer, Qt
+
+from UM.Application import Application
+from UM.Qt.ListModel import ListModel
+from UM.Scene.Camera import Camera
+from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
+from UM.Scene.SceneNode import SceneNode
+from UM.Scene.Selection import Selection
+from UM.i18n import i18nCatalog
+
+catalog = i18nCatalog("cura")
+
+
+# Simple convenience class to keep stuff together. Since we're still stuck on python 3.5, we can't use the full
+# typed named tuple, so we have to do it like this.
+# Once we are at python 3.6, feel free to change this to a named tuple.
+class _NodeInfo:
+ def __init__(self, index_to_node: Optional[Dict[int, SceneNode]] = None, nodes_to_rename: Optional[List[SceneNode]] = None, is_group: bool = False) -> None:
+ if index_to_node is None:
+ index_to_node = {}
+ if nodes_to_rename is None:
+ nodes_to_rename = []
+ self.index_to_node = index_to_node # type: Dict[int, SceneNode]
+ self.nodes_to_rename = nodes_to_rename # type: List[SceneNode]
+ self.is_group = is_group # type: bool
+
+
+## Keep track of all objects in the project
+class ObjectsModel(ListModel):
+ NameRole = Qt.UserRole + 1
+ SelectedRole = Qt.UserRole + 2
+ OutsideAreaRole = Qt.UserRole + 3
+ BuilplateNumberRole = Qt.UserRole + 4
+ NodeRole = Qt.UserRole + 5
+
+ def __init__(self, parent = None) -> None:
+ super().__init__(parent)
+
+ self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.SelectedRole, "selected")
+ self.addRoleName(self.OutsideAreaRole, "outside_build_area")
+ self.addRoleName(self.BuilplateNumberRole, "buildplate_number")
+ self.addRoleName(self.NodeRole, "node")
+
+ Application.getInstance().getController().getScene().sceneChanged.connect(self._updateSceneDelayed)
+ Application.getInstance().getPreferences().preferenceChanged.connect(self._updateDelayed)
+ Selection.selectionChanged.connect(self._updateDelayed)
+
+ self._update_timer = QTimer()
+ self._update_timer.setInterval(200)
+ self._update_timer.setSingleShot(True)
+ self._update_timer.timeout.connect(self._update)
+
+ self._build_plate_number = -1
+
+ self._group_name_template = catalog.i18nc("@label", "Group #{group_nr}")
+ self._group_name_prefix = self._group_name_template.split("#")[0]
+
+ self._naming_regex = re.compile("^(.+)\(([0-9]+)\)$")
+
+ def setActiveBuildPlate(self, nr: int) -> None:
+ if self._build_plate_number != nr:
+ self._build_plate_number = nr
+ self._update()
+
+ def _updateSceneDelayed(self, source) -> None:
+ if not isinstance(source, Camera):
+ self._update_timer.start()
+
+ def _updateDelayed(self, *args) -> None:
+ self._update_timer.start()
+
+ def _shouldNodeBeHandled(self, node: SceneNode) -> bool:
+ is_group = bool(node.callDecoration("isGroup"))
+ if not node.callDecoration("isSliceable") and not is_group:
+ return False
+
+ parent = node.getParent()
+ if parent and parent.callDecoration("isGroup"):
+ return False # Grouped nodes don't need resetting as their parent (the group) is resetted)
+
+ node_build_plate_number = node.callDecoration("getBuildPlateNumber")
+ if Application.getInstance().getPreferences().getValue("view/filter_current_build_plate") and node_build_plate_number != self._build_plate_number:
+ return False
+
+ return True
+
+ def _renameNodes(self, node_info_dict: Dict[str, _NodeInfo]) -> List[SceneNode]:
+ # Go through all names and find out the names for all nodes that need to be renamed.
+ all_nodes = [] # type: List[SceneNode]
+ for name, node_info in node_info_dict.items():
+ # First add the ones that do not need to be renamed.
+ for node in node_info.index_to_node.values():
+ all_nodes.append(node)
+
+ # Generate new names for the nodes that need to be renamed
+ current_index = 0
+ for node in node_info.nodes_to_rename:
+ current_index += 1
+ while current_index in node_info.index_to_node:
+ current_index += 1
+
+ if not node_info.is_group:
+ new_group_name = "{0}({1})".format(name, current_index)
+ else:
+ new_group_name = "{0}#{1}".format(name, current_index)
+
+ old_name = node.getName()
+ node.setName(new_group_name)
+ Logger.log("d", "Node [%s] renamed to [%s]", old_name, new_group_name)
+ all_nodes.append(node)
+ return all_nodes
+
+ def _update(self, *args) -> None:
+ nodes = [] # type: List[Dict[str, Union[str, int, bool, SceneNode]]]
+ name_to_node_info_dict = {} # type: Dict[str, _NodeInfo]
+ for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()): # type: ignore
+ if not self._shouldNodeBeHandled(node):
+ continue
+
+ is_group = bool(node.callDecoration("isGroup"))
+
+ force_rename = False
+ if not is_group:
+ # Handle names for individual nodes
+ name = node.getName()
+
+ name_match = self._naming_regex.fullmatch(name)
+ if name_match is None:
+ original_name = name
+ name_index = 0
+ else:
+ original_name = name_match.groups()[0]
+ name_index = int(name_match.groups()[1])
+ else:
+ # Handle names for grouped nodes
+ original_name = self._group_name_prefix
+
+ current_name = node.getName()
+ if current_name.startswith(self._group_name_prefix):
+ name_index = int(current_name.split("#")[-1])
+ else:
+ # Force rename this group because this node has not been named as a group yet, probably because
+ # it's a newly created group.
+ name_index = 0
+ force_rename = True
+
+ if original_name not in name_to_node_info_dict:
+ # Keep track of 2 things:
+ # - known indices for nodes which doesn't need to be renamed
+ # - a list of nodes that need to be renamed. When renaming then, we should avoid using the known indices.
+ name_to_node_info_dict[original_name] = _NodeInfo(is_group = is_group)
+ node_info = name_to_node_info_dict[original_name]
+ if not force_rename and name_index not in node_info.index_to_node:
+ node_info.index_to_node[name_index] = node
+ else:
+ node_info.nodes_to_rename.append(node)
+
+ all_nodes = self._renameNodes(name_to_node_info_dict)
+
+ for node in all_nodes:
+ if hasattr(node, "isOutsideBuildArea"):
+ is_outside_build_area = node.isOutsideBuildArea() # type: ignore
+ else:
+ is_outside_build_area = False
+
+ node_build_plate_number = node.callDecoration("getBuildPlateNumber")
+
+ nodes.append({
+ "name": node.getName(),
+ "selected": Selection.isSelected(node),
+ "outside_build_area": is_outside_build_area,
+ "buildplate_number": node_build_plate_number,
+ "node": node
+ })
+
+ nodes = sorted(nodes, key=lambda n: n["name"])
+ self.setItems(nodes)
diff --git a/cura/PrintInformation.py b/cura/UI/PrintInformation.py
similarity index 98%
rename from cura/PrintInformation.py
rename to cura/UI/PrintInformation.py
index ba7c74fd6d..abf1083836 100644
--- a/cura/PrintInformation.py
+++ b/cura/UI/PrintInformation.py
@@ -5,8 +5,7 @@ import json
import math
import os
import unicodedata
-import re # To create abbreviations for printer names.
-from typing import Dict, List, Optional
+from typing import Dict, List, Optional, TYPE_CHECKING
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot
@@ -16,8 +15,6 @@ from UM.Scene.SceneNode import SceneNode
from UM.i18n import i18nCatalog
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError
-from typing import TYPE_CHECKING
-
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
@@ -84,6 +81,7 @@ class PrintInformation(QObject):
"support_interface": catalog.i18nc("@tooltip", "Support Interface"),
"support": catalog.i18nc("@tooltip", "Support"),
"skirt": catalog.i18nc("@tooltip", "Skirt"),
+ "prime_tower": catalog.i18nc("@tooltip", "Prime Tower"),
"travel": catalog.i18nc("@tooltip", "Travel"),
"retract": catalog.i18nc("@tooltip", "Retractions"),
"none": catalog.i18nc("@tooltip", "Other")
@@ -199,11 +197,7 @@ class PrintInformation(QObject):
material_preference_values = json.loads(self._application.getInstance().getPreferences().getValue("cura/material_settings"))
- extruder_stacks = global_stack.extruders
-
- for position in extruder_stacks:
- extruder_stack = extruder_stacks[position]
- index = int(position)
+ for index, extruder_stack in enumerate(global_stack.extruderList):
if index >= len(self._material_amounts):
continue
amount = self._material_amounts[index]
diff --git a/cura/UI/RecommendedMode.py b/cura/UI/RecommendedMode.py
new file mode 100644
index 0000000000..47b617740a
--- /dev/null
+++ b/cura/UI/RecommendedMode.py
@@ -0,0 +1,49 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import QObject, pyqtSlot
+
+from cura import CuraApplication
+
+#
+# This object contains helper/convenience functions for Recommended mode.
+#
+class RecommendedMode(QObject):
+
+ # Sets to use the adhesion or not for the "Adhesion" CheckBox in Recommended mode.
+ @pyqtSlot(bool)
+ def setAdhesion(self, checked: bool) -> None:
+ application = CuraApplication.CuraApplication.getInstance()
+ global_stack = application.getMachineManager().activeMachine
+ if global_stack is None:
+ return
+
+ # Remove the adhesion type value set by the user.
+ adhesion_type_key = "adhesion_type"
+ user_changes_container = global_stack.userChanges
+ if adhesion_type_key in user_changes_container.getAllKeys():
+ user_changes_container.removeInstance(adhesion_type_key)
+
+ # Get the default value of adhesion type after user's value has been removed.
+ # skirt and none are counted as "no adhesion", the others are considered as "with adhesion". The conditions are
+ # as the following:
+ # - if the user checks the adhesion checkbox, get the default value (including the custom quality) for adhesion
+ # type.
+ # (1) If the default value is "skirt" or "none" (no adhesion), set adhesion_type to "brim".
+ # (2) If the default value is "with adhesion", do nothing.
+ # - if the user unchecks the adhesion checkbox, get the default value (including the custom quality) for
+ # adhesion type.
+ # (1) If the default value is "skirt" or "none" (no adhesion), do nothing.
+ # (2) Otherwise, set adhesion_type to "skirt".
+ value = global_stack.getProperty(adhesion_type_key, "value")
+ if checked:
+ if value in ("skirt", "none"):
+ value = "brim"
+ else:
+ if value not in ("skirt", "none"):
+ value = "skirt"
+
+ user_changes_container.setProperty(adhesion_type_key, "value", value)
+
+
+__all__ = ["RecommendedMode"]
diff --git a/cura/UI/TextManager.py b/cura/UI/TextManager.py
new file mode 100644
index 0000000000..86838a0b48
--- /dev/null
+++ b/cura/UI/TextManager.py
@@ -0,0 +1,69 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+import collections
+from typing import Optional, Dict, List, cast
+
+from PyQt5.QtCore import QObject, pyqtSlot
+
+from UM.Resources import Resources
+from UM.Version import Version
+
+
+#
+# This manager provides means to load texts to QML.
+#
+class TextManager(QObject):
+
+ def __init__(self, parent: Optional["QObject"] = None) -> None:
+ super().__init__(parent)
+
+ self._change_log_text = ""
+
+ @pyqtSlot(result = str)
+ def getChangeLogText(self) -> str:
+ if not self._change_log_text:
+ self._change_log_text = self._loadChangeLogText()
+ return self._change_log_text
+
+ def _loadChangeLogText(self) -> str:
+ # Load change log texts and organize them with a dict
+ file_path = Resources.getPath(Resources.Texts, "change_log.txt")
+ change_logs_dict = {} # type: Dict[Version, Dict[str, List[str]]]
+ with open(file_path, "r", encoding = "utf-8") as f:
+ open_version = None # type: Optional[Version]
+ open_header = "" # Initialise to an empty header in case there is no "*" in the first line of the changelog
+ for line in f:
+ line = line.replace("\n", "")
+ if "[" in line and "]" in line:
+ line = line.replace("[", "")
+ line = line.replace("]", "")
+ open_version = Version(line)
+ if open_version > Version([14, 99, 99]): # Bit of a hack: We released the 15.x.x versions before 2.x
+ open_version = Version([0, open_version.getMinor(), open_version.getRevision(), open_version.getPostfixVersion()])
+ open_header = ""
+ change_logs_dict[open_version] = collections.OrderedDict()
+ elif line.startswith("*"):
+ open_header = line.replace("*", "")
+ change_logs_dict[cast(Version, open_version)][open_header] = []
+ elif line != "":
+ if open_header not in change_logs_dict[cast(Version, open_version)]:
+ change_logs_dict[cast(Version, open_version)][open_header] = []
+ change_logs_dict[cast(Version, open_version)][open_header].append(line)
+
+ # Format changelog text
+ content = ""
+ for version in sorted(change_logs_dict.keys(), reverse = True):
+ text_version = version
+ if version < Version([1, 0, 0]): # Bit of a hack: We released the 15.x.x versions before 2.x
+ text_version = Version([15, version.getMinor(), version.getRevision(), version.getPostfixVersion()])
+ content += "
" + str(text_version) + "
"
+ content += ""
+ for change in change_logs_dict[version]:
+ if str(change) != "":
+ content += "" + str(change) + " "
+ for line in change_logs_dict[version][change]:
+ content += str(line) + " "
+ content += " "
+
+ return content
diff --git a/cura/UI/WelcomePagesModel.py b/cura/UI/WelcomePagesModel.py
new file mode 100644
index 0000000000..c16ec3763e
--- /dev/null
+++ b/cura/UI/WelcomePagesModel.py
@@ -0,0 +1,294 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from collections import deque
+import os
+from typing import TYPE_CHECKING, Optional, List, Dict, Any
+
+from PyQt5.QtCore import QUrl, Qt, pyqtSlot, pyqtProperty, pyqtSignal
+
+from UM.i18n import i18nCatalog
+from UM.Logger import Logger
+from UM.Qt.ListModel import ListModel
+from UM.Resources import Resources
+
+if TYPE_CHECKING:
+ from PyQt5.QtCore import QObject
+ from cura.CuraApplication import CuraApplication
+
+
+#
+# This is the Qt ListModel that contains all welcome pages data. Each page is a page that can be shown as a step in the
+# welcome wizard dialog. Each item in this ListModel represents a page, which contains the following fields:
+#
+# - id : A unique page_id which can be used in function goToPage(page_id)
+# - page_url : The QUrl to the QML file that contains the content of this page
+# - next_page_id : (OPTIONAL) The next page ID to go to when this page finished. This is optional. If this is not
+# provided, it will go to the page with the current index + 1
+# - next_page_button_text: (OPTIONAL) The text to show for the "next" button, by default it's the translated text of
+# "Next". Note that each step QML can decide whether to use this text or not, so it's not
+# mandatory.
+# - should_show_function : (OPTIONAL) An optional function that returns True/False indicating if this page should be
+# shown. By default all pages should be shown. If a function returns False, that page will
+# be skipped and its next page will be shown.
+#
+# Note that in any case, a page that has its "should_show_function" == False will ALWAYS be skipped.
+#
+class WelcomePagesModel(ListModel):
+
+ IdRole = Qt.UserRole + 1 # Page ID
+ PageUrlRole = Qt.UserRole + 2 # URL to the page's QML file
+ NextPageIdRole = Qt.UserRole + 3 # The next page ID it should go to
+ NextPageButtonTextRole = Qt.UserRole + 4 # The text for the next page button
+ PreviousPageButtonTextRole = Qt.UserRole + 5 # The text for the previous page button
+
+ def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
+ super().__init__(parent)
+
+ self.addRoleName(self.IdRole, "id")
+ self.addRoleName(self.PageUrlRole, "page_url")
+ self.addRoleName(self.NextPageIdRole, "next_page_id")
+ self.addRoleName(self.NextPageButtonTextRole, "next_page_button_text")
+ self.addRoleName(self.PreviousPageButtonTextRole, "previous_page_button_text")
+
+ self._application = application
+ self._catalog = i18nCatalog("cura")
+
+ self._default_next_button_text = self._catalog.i18nc("@action:button", "Next")
+
+ self._pages = [] # type: List[Dict[str, Any]]
+
+ self._current_page_index = 0
+ # Store all the previous page indices so it can go back.
+ self._previous_page_indices_stack = deque() # type: deque
+
+ # If the welcome flow should be shown. It can show the complete flow or just the changelog depending on the
+ # specific case. See initialize() for how this variable is set.
+ self._should_show_welcome_flow = False
+
+ allFinished = pyqtSignal() # emitted when all steps have been finished
+ currentPageIndexChanged = pyqtSignal()
+
+ @pyqtProperty(int, notify = currentPageIndexChanged)
+ def currentPageIndex(self) -> int:
+ return self._current_page_index
+
+ # Returns a float number in [0, 1] which indicates the current progress.
+ @pyqtProperty(float, notify = currentPageIndexChanged)
+ def currentProgress(self) -> float:
+ if len(self._items) == 0:
+ return 0
+ else:
+ return self._current_page_index / len(self._items)
+
+ # Indicates if the current page is the last page.
+ @pyqtProperty(bool, notify = currentPageIndexChanged)
+ def isCurrentPageLast(self) -> bool:
+ return self._current_page_index == len(self._items) - 1
+
+ def _setCurrentPageIndex(self, page_index: int) -> None:
+ if page_index != self._current_page_index:
+ self._previous_page_indices_stack.append(self._current_page_index)
+ self._current_page_index = page_index
+ self.currentPageIndexChanged.emit()
+
+ # Ends the Welcome-Pages. Put as a separate function for cases like the 'decline' in the User-Agreement.
+ @pyqtSlot()
+ def atEnd(self) -> None:
+ self.allFinished.emit()
+ self.resetState()
+
+ # Goes to the next page.
+ # If "from_index" is given, it will look for the next page to show starting from the "from_index" page instead of
+ # the "self._current_page_index".
+ @pyqtSlot()
+ def goToNextPage(self, from_index: Optional[int] = None) -> None:
+ # Look for the next page that should be shown
+ current_index = self._current_page_index if from_index is None else from_index
+ while True:
+ page_item = self._items[current_index]
+
+ # Check if there's a "next_page_id" assigned. If so, go to that page. Otherwise, go to the page with the
+ # current index + 1.
+ next_page_id = page_item.get("next_page_id")
+ next_page_index = current_index + 1
+ if next_page_id:
+ idx = self.getPageIndexById(next_page_id)
+ if idx is None:
+ # FIXME: If we cannot find the next page, we cannot do anything here.
+ Logger.log("e", "Cannot find page with ID [%s]", next_page_id)
+ return
+ next_page_index = idx
+
+ # If we have reached the last page, emit allFinished signal and reset.
+ if next_page_index == len(self._items):
+ self.atEnd()
+ return
+
+ # Check if the this page should be shown (default yes), if not, keep looking for the next one.
+ next_page_item = self.getItem(next_page_index)
+ if self._shouldPageBeShown(next_page_index):
+ break
+
+ Logger.log("d", "Page [%s] should not be displayed, look for the next page.", next_page_item["id"])
+ current_index = next_page_index
+
+ # Move to the next page
+ self._setCurrentPageIndex(next_page_index)
+
+ # Goes to the previous page. If there's no previous page, do nothing.
+ @pyqtSlot()
+ def goToPreviousPage(self) -> None:
+ if len(self._previous_page_indices_stack) == 0:
+ Logger.log("i", "No previous page, do nothing")
+ return
+
+ previous_page_index = self._previous_page_indices_stack.pop()
+ self._current_page_index = previous_page_index
+ self.currentPageIndexChanged.emit()
+
+ # Sets the current page to the given page ID. If the page ID is not found, do nothing.
+ @pyqtSlot(str)
+ def goToPage(self, page_id: str) -> None:
+ page_index = self.getPageIndexById(page_id)
+ if page_index is None:
+ # FIXME: If we cannot find the next page, we cannot do anything here.
+ Logger.log("e", "Cannot find page with ID [%s], go to the next page by default", page_index)
+ self.goToNextPage()
+ return
+
+ if self._shouldPageBeShown(page_index):
+ # Move to that page if it should be shown
+ self._setCurrentPageIndex(page_index)
+ else:
+ # Find the next page to show starting from the "page_index"
+ self.goToNextPage(from_index = page_index)
+
+ # Checks if the page with the given index should be shown by calling the "should_show_function" associated with it.
+ # If the function is not present, returns True (show page by default).
+ def _shouldPageBeShown(self, page_index: int) -> bool:
+ next_page_item = self.getItem(page_index)
+ should_show_function = next_page_item.get("should_show_function", lambda: True)
+ return should_show_function()
+
+ # Resets the state of the WelcomePagesModel. This functions does the following:
+ # - Resets current_page_index to 0
+ # - Clears the previous page indices stack
+ @pyqtSlot()
+ def resetState(self) -> None:
+ self._current_page_index = 0
+ self._previous_page_indices_stack.clear()
+
+ self.currentPageIndexChanged.emit()
+
+ shouldShowWelcomeFlowChanged = pyqtSignal()
+
+ @pyqtProperty(bool, notify = shouldShowWelcomeFlowChanged)
+ def shouldShowWelcomeFlow(self) -> bool:
+ return self._should_show_welcome_flow
+
+ # Gets the page index with the given page ID. If the page ID doesn't exist, returns None.
+ def getPageIndexById(self, page_id: str) -> Optional[int]:
+ page_idx = None
+ for idx, page_item in enumerate(self._items):
+ if page_item["id"] == page_id:
+ page_idx = idx
+ break
+ return page_idx
+
+ # Convenience function to get QUrl path to pages that's located in "resources/qml/WelcomePages".
+ def _getBuiltinWelcomePagePath(self, page_filename: str) -> "QUrl":
+ from cura.CuraApplication import CuraApplication
+ return QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles,
+ os.path.join("WelcomePages", page_filename)))
+
+ # FIXME: HACKs for optimization that we don't update the model every time the active machine gets changed.
+ def _onActiveMachineChanged(self) -> None:
+ self._application.getMachineManager().globalContainerChanged.disconnect(self._onActiveMachineChanged)
+ self._initialize(update_should_show_flag = False)
+
+ def initialize(self) -> None:
+ self._application.getMachineManager().globalContainerChanged.connect(self._onActiveMachineChanged)
+ self._initialize()
+
+ def _initialize(self, update_should_show_flag: bool = True) -> None:
+ show_whatsnew_only = False
+ if update_should_show_flag:
+ has_active_machine = self._application.getMachineManager().activeMachine is not None
+ has_app_just_upgraded = self._application.hasJustUpdatedFromOldVersion()
+
+ # Only show the what's new dialog if there's no machine and we have just upgraded
+ show_complete_flow = not has_active_machine
+ show_whatsnew_only = has_active_machine and has_app_just_upgraded
+
+ # FIXME: This is a hack. Because of the circular dependency between MachineManager, ExtruderManager, and
+ # possibly some others, setting the initial active machine is not done when the MachineManager gets initialized.
+ # So at this point, we don't know if there will be an active machine or not. It could be that the active machine
+ # files are corrupted so we cannot rely on Preferences either. This makes sure that once the active machine
+ # gets changed, this model updates the flags, so it can decide whether to show the welcome flow or not.
+ should_show_welcome_flow = show_complete_flow or show_whatsnew_only
+ if should_show_welcome_flow != self._should_show_welcome_flow:
+ self._should_show_welcome_flow = should_show_welcome_flow
+ self.shouldShowWelcomeFlowChanged.emit()
+
+ # All pages
+ all_pages_list = [{"id": "welcome",
+ "page_url": self._getBuiltinWelcomePagePath("WelcomeContent.qml"),
+ },
+ {"id": "user_agreement",
+ "page_url": self._getBuiltinWelcomePagePath("UserAgreementContent.qml"),
+ },
+ {"id": "whats_new",
+ "page_url": self._getBuiltinWelcomePagePath("WhatsNewContent.qml"),
+ },
+ {"id": "data_collections",
+ "page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"),
+ },
+ {"id": "add_network_or_local_printer",
+ "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
+ "next_page_id": "machine_actions",
+ },
+ {"id": "add_printer_by_ip",
+ "page_url": self._getBuiltinWelcomePagePath("AddPrinterByIpContent.qml"),
+ "next_page_id": "machine_actions",
+ },
+ {"id": "machine_actions",
+ "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
+ "next_page_id": "cloud",
+ "should_show_function": self.shouldShowMachineActions,
+ },
+ {"id": "cloud",
+ "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
+ },
+ ]
+
+ pages_to_show = all_pages_list
+ if show_whatsnew_only:
+ pages_to_show = list(filter(lambda x: x["id"] == "whats_new", all_pages_list))
+
+ self._pages = pages_to_show
+ self.setItems(self._pages)
+
+ # For convenience, inject the default "next" button text to each item if it's not present.
+ def setItems(self, items: List[Dict[str, Any]]) -> None:
+ for item in items:
+ if "next_page_button_text" not in item:
+ item["next_page_button_text"] = self._default_next_button_text
+
+ super().setItems(items)
+
+ # Indicates if the machine action panel should be shown by checking if there's any first start machine actions
+ # available.
+ def shouldShowMachineActions(self) -> bool:
+ global_stack = self._application.getMachineManager().activeMachine
+ if global_stack is None:
+ return False
+
+ definition_id = global_stack.definition.getId()
+ first_start_actions = self._application.getMachineActionManager().getFirstStartActions(definition_id)
+ return len([action for action in first_start_actions if action.needsUserInteraction()]) > 0
+
+ def addPage(self) -> None:
+ pass
+
+
+__all__ = ["WelcomePagesModel"]
diff --git a/cura/UI/WhatsNewPagesModel.py b/cura/UI/WhatsNewPagesModel.py
new file mode 100644
index 0000000000..5b968ae574
--- /dev/null
+++ b/cura/UI/WhatsNewPagesModel.py
@@ -0,0 +1,22 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from .WelcomePagesModel import WelcomePagesModel
+
+
+#
+# This Qt ListModel is more or less the same the WelcomePagesModel, except that this model is only for showing the
+# "what's new" page. This is also used in the "Help" menu to show the changes log.
+#
+class WhatsNewPagesModel(WelcomePagesModel):
+
+ def initialize(self) -> None:
+ self._pages = []
+ self._pages.append({"id": "whats_new",
+ "page_url": self._getBuiltinWelcomePagePath("WhatsNewContent.qml"),
+ "next_page_button_text": self._catalog.i18nc("@action:button", "Close"),
+ })
+ self.setItems(self._pages)
+
+
+__all__ = ["WhatsNewPagesModel"]
diff --git a/cura/UI/__init__.py b/cura/UI/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cura/Utils/Decorators.py b/cura/Utils/Decorators.py
new file mode 100644
index 0000000000..9275ee6ce9
--- /dev/null
+++ b/cura/Utils/Decorators.py
@@ -0,0 +1,30 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+import functools
+import re
+from typing import Callable
+
+# An API version must be a semantic version "x.y.z" where ".z" is optional. So the valid formats are as follows:
+# - x.y.z
+# - x.y
+SEMANTIC_VERSION_REGEX = re.compile(r"^[0-9]+\.[0-9]+(\.[0-9]+)?$")
+
+
+## Decorator for functions that belong to a set of APIs. For now, this should only be used for officially supported
+# APIs, meaning that those APIs should be versioned and maintained.
+#
+# \param since_version The earliest version since when this API becomes supported. This means that since this version,
+# this API function is supposed to behave the same. This parameter is not used. It's just a
+# documentation.
+def api(since_version: str) -> Callable:
+ # Make sure that APi versions are semantic versions
+ if not SEMANTIC_VERSION_REGEX.fullmatch(since_version):
+ raise ValueError("API since_version [%s] is not a semantic version." % since_version)
+
+ def api_decorator(function):
+ @functools.wraps(function)
+ def api_wrapper(*args, **kwargs):
+ return function(*args, **kwargs)
+ return api_wrapper
+ return api_decorator
diff --git a/cura/Utils/NetworkingUtil.py b/cura/Utils/NetworkingUtil.py
new file mode 100644
index 0000000000..b13f7903b9
--- /dev/null
+++ b/cura/Utils/NetworkingUtil.py
@@ -0,0 +1,44 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+import socket
+from typing import Optional
+
+from PyQt5.QtCore import QObject, pyqtSlot
+
+
+#
+# This is a QObject because some of the functions can be used (and are useful) in QML.
+#
+class NetworkingUtil(QObject):
+
+ def __init__(self, parent: Optional["QObject"] = None) -> None:
+ super().__init__(parent = parent)
+
+ # Checks if the given string is a valid IPv4 address.
+ @pyqtSlot(str, result = bool)
+ def isIPv4(self, address: str) -> bool:
+ try:
+ socket.inet_pton(socket.AF_INET, address)
+ result = True
+ except:
+ result = False
+ return result
+
+ # Checks if the given string is a valid IPv6 address.
+ @pyqtSlot(str, result = bool)
+ def isIPv6(self, address: str) -> bool:
+ try:
+ socket.inet_pton(socket.AF_INET6, address)
+ result = True
+ except:
+ result = False
+ return result
+
+ # Checks if the given string is a valid IPv4 or IPv6 address.
+ @pyqtSlot(str, result = bool)
+ def isValidIP(self, address: str) -> bool:
+ return self.isIPv4(address) or self.isIPv6(address)
+
+
+__all__ = ["NetworkingUtil"]
diff --git a/cura_app.py b/cura_app.py
index 3224a5b99b..e14b4410bc 100755
--- a/cura_app.py
+++ b/cura_app.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import argparse
@@ -23,13 +23,17 @@ known_args = vars(parser.parse_known_args()[0])
if not known_args["debug"]:
def get_cura_dir_path():
if Platform.isWindows():
- return os.path.expanduser("~/AppData/Roaming/" + CuraAppName)
+ appdata_path = os.getenv("APPDATA")
+ if not appdata_path: #Defensive against the environment variable missing (should never happen).
+ appdata_path = "."
+ return os.path.join(appdata_path, CuraAppName)
elif Platform.isLinux():
return os.path.expanduser("~/.local/share/" + CuraAppName)
elif Platform.isOSX():
return os.path.expanduser("~/Library/Logs/" + CuraAppName)
- if hasattr(sys, "frozen"):
+ # Do not redirect stdout and stderr to files if we are running CLI.
+ if hasattr(sys, "frozen") and "cli" not in os.path.basename(sys.argv[0]).lower():
dirpath = get_cura_dir_path()
os.makedirs(dirpath, exist_ok = True)
sys.stdout = open(os.path.join(dirpath, "stdout.log"), "w", encoding = "utf-8")
@@ -56,6 +60,14 @@ if Platform.isWindows() and hasattr(sys, "frozen"):
except KeyError:
pass
+# GITHUB issue #6194: https://github.com/Ultimaker/Cura/issues/6194
+# With AppImage 2 on Linux, the current working directory will be somewhere in /tmp//usr, which is owned
+# by root. For some reason, QDesktopServices.openUrl() requires to have a usable current working directory,
+# otherwise it doesn't work. This is a workaround on Linux that before we call QDesktopServices.openUrl(), we
+# switch to a directory where the user has the ownership.
+if Platform.isLinux() and hasattr(sys, "frozen"):
+ os.chdir(os.path.expanduser("~"))
+
# WORKAROUND: GITHUB-704 GITHUB-708
# It looks like setuptools creates a .pth file in
# the default /usr/lib which causes the default site-packages
@@ -119,7 +131,10 @@ def exceptHook(hook_type, value, traceback):
# Set exception hook to use the crash dialog handler
sys.excepthook = exceptHook
# Enable dumping traceback for all threads
-faulthandler.enable(all_threads = True)
+if sys.stderr:
+ faulthandler.enable(file = sys.stderr, all_threads = True)
+else:
+ faulthandler.enable(file = sys.stdout, all_threads = True)
# Workaround for a race condition on certain systems where there
# is a race condition between Arcus and PyQt. Importing Arcus
@@ -129,5 +144,37 @@ import Arcus #@UnusedImport
import Savitar #@UnusedImport
from cura.CuraApplication import CuraApplication
+
+# WORKAROUND: CURA-6739
+# The CTM file loading module in Trimesh requires the OpenCTM library to be dynamically loaded. It uses
+# ctypes.util.find_library() to find libopenctm.dylib, but this doesn't seem to look in the ".app" application folder
+# on Mac OS X. Adding the search path to environment variables such as DYLD_LIBRARY_PATH and DYLD_FALLBACK_LIBRARY_PATH
+# makes it work. The workaround here uses DYLD_FALLBACK_LIBRARY_PATH.
+if Platform.isOSX() and getattr(sys, "frozen", False):
+ old_env = os.environ.get("DYLD_FALLBACK_LIBRARY_PATH", "")
+ # This is where libopenctm.so is in the .app folder.
+ search_path = os.path.join(CuraApplication.getInstallPrefix(), "MacOS")
+ path_list = old_env.split(":")
+ if search_path not in path_list:
+ path_list.append(search_path)
+ os.environ["DYLD_FALLBACK_LIBRARY_PATH"] = ":".join(path_list)
+ import trimesh.exchange.load
+ os.environ["DYLD_FALLBACK_LIBRARY_PATH"] = old_env
+
+# WORKAROUND: CURA-6739
+# Similar CTM file loading fix for Linux, but NOTE THAT this doesn't work directly with Python 3.5.7. There's a fix
+# for ctypes.util.find_library() in Python 3.6 and 3.7. That fix makes sure that find_library() will check
+# LD_LIBRARY_PATH. With Python 3.5, that fix needs to be backported to make this workaround work.
+if Platform.isLinux() and getattr(sys, "frozen", False):
+ old_env = os.environ.get("LD_LIBRARY_PATH", "")
+ # This is where libopenctm.so is in the AppImage.
+ search_path = os.path.join(CuraApplication.getInstallPrefix(), "bin")
+ path_list = old_env.split(":")
+ if search_path not in path_list:
+ path_list.append(search_path)
+ os.environ["LD_LIBRARY_PATH"] = ":".join(path_list)
+ import trimesh.exchange.load
+ os.environ["LD_LIBRARY_PATH"] = old_env
+
app = CuraApplication()
app.run()
diff --git a/docker/build.sh b/docker/build.sh
new file mode 100755
index 0000000000..eb20b18c0d
--- /dev/null
+++ b/docker/build.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+# Abort at the first error.
+set -e
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+PROJECT_DIR="$( cd "${SCRIPT_DIR}/.." && pwd )"
+
+# Make sure that environment variables are set properly
+source /opt/rh/devtoolset-7/enable
+export PATH="${CURA_BUILD_ENV_PATH}/bin:${PATH}"
+export PKG_CONFIG_PATH="${CURA_BUILD_ENV_PATH}/lib/pkgconfig:${PKG_CONFIG_PATH}"
+
+cd "${PROJECT_DIR}"
+
+#
+# Clone Uranium and set PYTHONPATH first
+#
+
+# Check the branch to use:
+# 1. Use the Uranium branch with the branch same if it exists.
+# 2. Otherwise, use the default branch name "master"
+URANIUM_BRANCH="${CI_COMMIT_REF_NAME:-master}"
+output="$(git ls-remote --heads https://github.com/Ultimaker/Uranium.git "${URANIUM_BRANCH}")"
+if [ -z "${output}" ]; then
+ echo "Could not find Uranium banch ${URANIUM_BRANCH}, fallback to use master."
+ URANIUM_BRANCH="master"
+fi
+
+echo "Using Uranium branch ${URANIUM_BRANCH} ..."
+git clone --depth=1 -b "${URANIUM_BRANCH}" https://github.com/Ultimaker/Uranium.git "${PROJECT_DIR}"/Uranium
+export PYTHONPATH="${PROJECT_DIR}/Uranium:.:${PYTHONPATH}"
+
+mkdir build
+cd build
+cmake3 \
+ -DCMAKE_BUILD_TYPE=Debug \
+ -DCMAKE_PREFIX_PATH="${CURA_BUILD_ENV_PATH}" \
+ -DURANIUM_DIR="${PROJECT_DIR}/Uranium" \
+ -DBUILD_TESTS=ON \
+ ..
+make
+ctest3 --output-on-failure -T Test
diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py
index 49c6995d18..20eb9b29dc 100755
--- a/plugins/3MFReader/ThreeMFReader.py
+++ b/plugins/3MFReader/ThreeMFReader.py
@@ -1,7 +1,7 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import Optional
+from typing import List, Optional, Union, TYPE_CHECKING
import os.path
import zipfile
@@ -9,27 +9,26 @@ import numpy
import Savitar
-from UM.Application import Application
from UM.Logger import Logger
from UM.Math.Matrix import Matrix
from UM.Math.Vector import Vector
from UM.Mesh.MeshBuilder import MeshBuilder
from UM.Mesh.MeshReader import MeshReader
from UM.Scene.GroupDecorator import GroupDecorator
+from UM.Scene.SceneNode import SceneNode #For typing.
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType
+from cura.CuraApplication import CuraApplication
+from cura.Machines.ContainerTree import ContainerTree
from cura.Settings.ExtruderManager import ExtruderManager
from cura.Scene.CuraSceneNode import CuraSceneNode
from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
from cura.Scene.ZOffsetDecorator import ZOffsetDecorator
-from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
-
-MYPY = False
try:
- if not MYPY:
+ if not TYPE_CHECKING:
import xml.etree.cElementTree as ET
except ImportError:
Logger.log("w", "Unable to load cElementTree, switching to slower version")
@@ -55,7 +54,7 @@ class ThreeMFReader(MeshReader):
self._unit = None
self._object_count = 0 # Used to name objects as there is no node name yet.
- def _createMatrixFromTransformationString(self, transformation):
+ def _createMatrixFromTransformationString(self, transformation: str) -> Matrix:
if transformation == "":
return Matrix()
@@ -85,13 +84,13 @@ class ThreeMFReader(MeshReader):
return temp_mat
- ## Convenience function that converts a SceneNode object (as obtained from libSavitar) to a Uranium scene node.
- # \returns Uranium scene node.
- def _convertSavitarNodeToUMNode(self, savitar_node):
+ ## Convenience function that converts a SceneNode object (as obtained from libSavitar) to a scene node.
+ # \returns Scene node.
+ def _convertSavitarNodeToUMNode(self, savitar_node: Savitar.SceneNode) -> Optional[SceneNode]:
self._object_count += 1
node_name = "Object %s" % self._object_count
- active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
+ active_build_plate = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
um_node = CuraSceneNode() # This adds a SettingOverrideDecorator
um_node.addDecorator(BuildPlateDecorator(active_build_plate))
@@ -122,7 +121,7 @@ class ThreeMFReader(MeshReader):
# Add the setting override decorator, so we can add settings to this node.
if settings:
- global_container_stack = Application.getInstance().getGlobalContainerStack()
+ global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
# Ensure the correct next container for the SettingOverride decorator is set.
if global_container_stack:
@@ -132,7 +131,7 @@ class ThreeMFReader(MeshReader):
um_node.callDecoration("setActiveExtruder", default_stack.getId())
# Get the definition & set it
- definition_id = getMachineDefinitionIDForQualitySearch(global_container_stack.definition)
+ definition_id = ContainerTree.getInstance().machines[global_container_stack.definition.getId()].quality_definition
um_node.callDecoration("getStack").getTop().setDefinition(definition_id)
setting_container = um_node.callDecoration("getStack").getTop()
@@ -161,7 +160,7 @@ class ThreeMFReader(MeshReader):
um_node.addDecorator(sliceable_decorator)
return um_node
- def _read(self, file_name):
+ def _read(self, file_name: str) -> Union[SceneNode, List[SceneNode]]:
result = []
self._object_count = 0 # Used to name objects as there is no node name yet.
# The base object of 3mf is a zipped archive.
@@ -181,12 +180,13 @@ class ThreeMFReader(MeshReader):
mesh_data = um_node.getMeshData()
if mesh_data is not None:
extents = mesh_data.getExtents()
- center_vector = Vector(extents.center.x, extents.center.y, extents.center.z)
- transform_matrix.setByTranslation(center_vector)
+ if extents is not None:
+ center_vector = Vector(extents.center.x, extents.center.y, extents.center.z)
+ transform_matrix.setByTranslation(center_vector)
transform_matrix.multiply(um_node.getLocalTransformation())
um_node.setTransformation(transform_matrix)
- global_container_stack = Application.getInstance().getGlobalContainerStack()
+ global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
# Create a transformation Matrix to convert from 3mf worldspace into ours.
# First step: flip the y and z axis.
@@ -215,17 +215,20 @@ class ThreeMFReader(MeshReader):
um_node.setTransformation(um_node.getLocalTransformation().preMultiply(transformation_matrix))
# Check if the model is positioned below the build plate and honor that when loading project files.
- if um_node.getMeshData() is not None:
- minimum_z_value = um_node.getMeshData().getExtents(um_node.getWorldTransformation()).minimum.y # y is z in transformation coordinates
- if minimum_z_value < 0:
- um_node.addDecorator(ZOffsetDecorator())
- um_node.callDecoration("setZOffset", minimum_z_value)
+ node_meshdata = um_node.getMeshData()
+ if node_meshdata is not None:
+ aabb = node_meshdata.getExtents(um_node.getWorldTransformation())
+ if aabb is not None:
+ minimum_z_value = aabb.minimum.y # y is z in transformation coordinates
+ if minimum_z_value < 0:
+ um_node.addDecorator(ZOffsetDecorator())
+ um_node.callDecoration("setZOffset", minimum_z_value)
result.append(um_node)
except Exception:
Logger.logException("e", "An exception occurred in 3mf reader.")
- return None
+ return []
return result
diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py
index bf190f7e39..dd35484c31 100755
--- a/plugins/3MFReader/ThreeMFWorkspaceReader.py
+++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py
@@ -1,10 +1,10 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from configparser import ConfigParser
import zipfile
import os
-from typing import Dict, List, Tuple, cast
+from typing import cast, Dict, List, Optional, Tuple
import xml.etree.ElementTree as ET
@@ -14,7 +14,6 @@ from UM.Application import Application
from UM.Logger import Logger
from UM.Message import Message
from UM.i18n import i18nCatalog
-from UM.Signal import postponeSignals, CompressTechnique
from UM.Settings.ContainerFormatError import ContainerFormatError
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.DefinitionContainer import DefinitionContainer
@@ -24,21 +23,25 @@ from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType
from UM.Job import Job
from UM.Preferences import Preferences
-from cura.Machines.VariantType import VariantType
+from cura.Machines.ContainerTree import ContainerTree
from cura.Settings.CuraStackBuilder import CuraStackBuilder
+from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.ExtruderStack import ExtruderStack
from cura.Settings.GlobalStack import GlobalStack
+from cura.Settings.IntentManager import IntentManager
from cura.Settings.CuraContainerStack import _ContainerIndexes
from cura.CuraApplication import CuraApplication
from cura.Utils.Threading import call_on_qt_thread
+from PyQt5.QtCore import QCoreApplication
+
from .WorkspaceDialog import WorkspaceDialog
i18n_catalog = i18nCatalog("cura")
class ContainerInfo:
- def __init__(self, file_name: str, serialized: str, parser: ConfigParser) -> None:
+ def __init__(self, file_name: Optional[str], serialized: Optional[str], parser: Optional[ConfigParser]) -> None:
self.file_name = file_name
self.serialized = serialized
self.parser = parser
@@ -58,7 +61,11 @@ class MachineInfo:
self.container_id = None
self.name = None
self.definition_id = None
+
+ self.metadata_dict = {} # type: Dict[str, str]
+
self.quality_type = None
+ self.intent_category = None
self.custom_quality_name = None
self.quality_changes_info = None
self.variant_info = None
@@ -78,6 +85,7 @@ class ExtruderInfo:
self.definition_changes_info = None
self.user_changes_info = None
+ self.intent_info = None
## Base implementation for reading 3MF workspace files.
@@ -226,6 +234,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
else:
Logger.log("w", "Unknown definition container type %s for %s",
definition_container_type, definition_container_file)
+ QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
Job.yieldThread()
if machine_definition_container_count != 1:
@@ -252,13 +261,16 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
containers_found_dict["material"] = True
if not self._container_registry.isReadOnly(container_id): # Only non readonly materials can be in conflict
material_conflict = True
+ QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
Job.yieldThread()
# Check if any quality_changes instance container is in conflict.
instance_container_files = [name for name in cura_file_names if name.endswith(self._instance_container_suffix)]
quality_name = ""
custom_quality_name = ""
- num_settings_overriden_by_quality_changes = 0 # How many settings are changed by the quality changes
+ intent_name = ""
+ intent_category = ""
+ num_settings_overridden_by_quality_changes = 0 # How many settings are changed by the quality changes
num_user_settings = 0
quality_changes_conflict = False
@@ -296,7 +308,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
custom_quality_name = parser["general"]["name"]
values = parser["values"] if parser.has_section("values") else dict()
- num_settings_overriden_by_quality_changes += len(values)
+ num_settings_overridden_by_quality_changes += len(values)
# Check if quality changes already exists.
quality_changes = self._container_registry.findInstanceContainers(name = custom_quality_name,
type = "quality_changes")
@@ -315,13 +327,17 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
elif container_type == "quality":
if not quality_name:
quality_name = parser["general"]["name"]
+ elif container_type == "intent":
+ if not intent_name:
+ intent_name = parser["general"]["name"]
+ intent_category = parser["metadata"]["intent_category"]
elif container_type == "user":
num_user_settings += len(parser["values"])
elif container_type in self._ignored_instance_container_types:
# Ignore certain instance container types
Logger.log("w", "Ignoring instance container [%s] with type [%s]", container_id, container_type)
continue
-
+ QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
Job.yieldThread()
if self._machine_info.quality_changes_info.global_info is None:
@@ -340,7 +356,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# To simplify this, only check if the global stack exists or not
global_stack_id = self._stripFileToId(global_stack_file)
serialized = archive.open(global_stack_file).read().decode("utf-8")
+ serialized = GlobalStack._updateSerialized(serialized, global_stack_file)
machine_name = self._getMachineNameFromSerializedStack(serialized)
+ self._machine_info.metadata_dict = self._getMetaDataDictFromSerializedStack(serialized)
+
stacks = self._container_registry.findContainerStacks(name = machine_name, type = "machine")
self._is_same_machine_type = True
existing_global_stack = None
@@ -396,7 +415,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
variant_id = parser["containers"][str(_ContainerIndexes.Variant)]
if variant_id not in ("empty", "empty_variant"):
self._machine_info.variant_info = instance_container_info_dict[variant_id]
-
+ QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
Job.yieldThread()
# if the global stack is found, we check if there are conflicts in the extruder stacks
@@ -418,18 +437,26 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if parser.has_option("metadata", "enabled"):
extruder_info.enabled = parser["metadata"]["enabled"]
if variant_id not in ("empty", "empty_variant"):
- extruder_info.variant_info = instance_container_info_dict[variant_id]
+ if variant_id in instance_container_info_dict:
+ extruder_info.variant_info = instance_container_info_dict[variant_id]
+
if material_id not in ("empty", "empty_material"):
root_material_id = reverse_material_id_dict[material_id]
extruder_info.root_material_id = root_material_id
+
definition_changes_id = parser["containers"][str(_ContainerIndexes.DefinitionChanges)]
if definition_changes_id not in ("empty", "empty_definition_changes"):
extruder_info.definition_changes_info = instance_container_info_dict[definition_changes_id]
+
user_changes_id = parser["containers"][str(_ContainerIndexes.UserChanges)]
if user_changes_id not in ("empty", "empty_user_changes"):
extruder_info.user_changes_info = instance_container_info_dict[user_changes_id]
self._machine_info.extruder_info_dict[position] = extruder_info
+ intent_id = parser["containers"][str(_ContainerIndexes.Intent)]
+ if intent_id not in ("empty", "empty_intent"):
+ extruder_info.intent_info = instance_container_info_dict[intent_id]
+
if not machine_conflict and containers_found_dict["machine"]:
if position not in global_stack.extruders:
continue
@@ -494,6 +521,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._machine_info.definition_id = machine_definition_id
self._machine_info.quality_type = quality_type
self._machine_info.custom_quality_name = quality_name
+ self._machine_info.intent_category = intent_category
if machine_conflict and not self._is_same_machine_type:
machine_conflict = False
@@ -514,7 +542,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._dialog.setNumVisibleSettings(num_visible_settings)
self._dialog.setQualityName(quality_name)
self._dialog.setQualityType(quality_type)
- self._dialog.setNumSettingsOverridenByQualityChanges(num_settings_overriden_by_quality_changes)
+ self._dialog.setIntentName(intent_name)
+ self._dialog.setNumSettingsOverriddenByQualityChanges(num_settings_overridden_by_quality_changes)
self._dialog.setNumUserSettings(num_user_settings)
self._dialog.setActiveMode(active_mode)
self._dialog.setMachineName(machine_name)
@@ -557,26 +586,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# \param file_name
@call_on_qt_thread
def read(self, file_name):
- container_registry = ContainerRegistry.getInstance()
- signals = [container_registry.containerAdded,
- container_registry.containerRemoved,
- container_registry.containerMetaDataChanged]
- #
- # We now have different managers updating their lookup tables upon container changes. It is critical to make
- # sure that the managers have a complete set of data when they update.
- #
- # In project loading, lots of the container-related signals are loosely emitted, which can create timing gaps
- # for incomplete data update or other kinds of issues to happen.
- #
- # To avoid this, we postpone all signals so they don't get emitted immediately. But, please also be aware that,
- # because of this, do not expect to have the latest data in the lookup tables in project loading.
- #
- with postponeSignals(*signals, compress = CompressTechnique.NoCompression):
- return self._read(file_name)
-
- def _read(self, file_name):
application = CuraApplication.getInstance()
- material_manager = application.getMaterialManager()
archive = zipfile.ZipFile(file_name, "r")
@@ -647,6 +657,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
definition_container = self._container_registry.findDefinitionContainers(id = "fdmprinter")[0] #Fall back to defaults.
self._container_registry.addContainer(definition_container)
Job.yieldThread()
+ QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
Logger.log("d", "Workspace loading is checking materials...")
# Get all the material files and check if they exist. If not, add them.
@@ -673,7 +684,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if self._resolve_strategies["material"] == "override":
# Remove the old materials and then deserialize the one from the project
root_material_id = material_container.getMetaDataEntry("base_file")
- material_manager.removeMaterialByRootId(root_material_id)
+ application.getContainerRegistry().removeContainer(root_material_id)
elif self._resolve_strategies["material"] == "new":
# Note that we *must* deserialize it with a new ID, as multiple containers will be
# auto created & added.
@@ -696,6 +707,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
material_container.setDirty(True)
self._container_registry.addContainer(material_container)
Job.yieldThread()
+ QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
# Handle quality changes if any
self._processQualityChanges(global_stack)
@@ -726,9 +738,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if self._machine_info.quality_changes_info is None:
return
- application = CuraApplication.getInstance()
- quality_manager = application.getQualityManager()
-
# If we have custom profiles, load them
quality_changes_name = self._machine_info.quality_changes_info.name
if self._machine_info.quality_changes_info is not None:
@@ -736,12 +745,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._machine_info.quality_changes_info.name)
# Get the correct extruder definition IDs for quality changes
- from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
- machine_definition_id_for_quality = getMachineDefinitionIDForQualitySearch(global_stack.definition)
+ machine_definition_id_for_quality = ContainerTree.getInstance().machines[global_stack.definition.getId()].quality_definition
machine_definition_for_quality = self._container_registry.findDefinitionContainers(id = machine_definition_id_for_quality)[0]
quality_changes_info = self._machine_info.quality_changes_info
quality_changes_quality_type = quality_changes_info.global_info.parser["metadata"]["quality_type"]
+ quality_changes_intent_category_per_extruder = {position: info.parser["metadata"].get("intent_category", "default") for position, info in quality_changes_info.extruder_info_dict.items()}
quality_changes_name = quality_changes_info.name
create_new = self._resolve_strategies.get("quality_changes") != "override"
@@ -752,13 +761,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
quality_changes_name = self._container_registry.uniqueName(quality_changes_name)
for position, container_info in container_info_dict.items():
extruder_stack = None
+ intent_category = None # type: Optional[str]
if position is not None:
extruder_stack = global_stack.extruders[position]
- container = quality_manager._createQualityChanges(quality_changes_quality_type,
- quality_changes_name,
- global_stack, extruder_stack)
+ intent_category = quality_changes_intent_category_per_extruder[position]
+ container = self._createNewQualityChanges(quality_changes_quality_type, intent_category, quality_changes_name, global_stack, extruder_stack)
container_info.container = container
- container.setDirty(True)
self._container_registry.addContainer(container)
Logger.log("d", "Created new quality changes container [%s]", container.getId())
@@ -781,12 +789,15 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if not quality_changes_info.extruder_info_dict:
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.
+ if not global_stack.extruders:
+ ExtruderManager.getInstance().fixSingleExtrusionMachineExtruderDefinition(global_stack)
extruder_stack = global_stack.extruders["0"]
+ intent_category = quality_changes_intent_category_per_extruder["0"]
- container = quality_manager._createQualityChanges(quality_changes_quality_type, quality_changes_name,
- global_stack, extruder_stack)
+ container = self._createNewQualityChanges(quality_changes_quality_type, intent_category, quality_changes_name, global_stack, extruder_stack)
container_info.container = container
- container.setDirty(True)
self._container_registry.addContainer(container)
Logger.log("d", "Created new quality changes container [%s]", container.getId())
@@ -812,16 +823,57 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if container_info.container is None:
extruder_stack = global_stack.extruders[position]
- container = quality_manager._createQualityChanges(quality_changes_quality_type, quality_changes_name,
- global_stack, extruder_stack)
+ intent_category = quality_changes_intent_category_per_extruder[position]
+ container = self._createNewQualityChanges(quality_changes_quality_type, intent_category, quality_changes_name, global_stack, extruder_stack)
container_info.container = container
+ self._container_registry.addContainer(container)
for key, value in container_info.parser["values"].items():
container_info.container.setProperty(key, "value", value)
self._machine_info.quality_changes_info.name = quality_changes_name
- def _clearStack(self, stack):
+ ## Helper class to create a new quality changes profile.
+ #
+ # This will then later be filled with the appropriate data.
+ # \param quality_type The quality type of the new profile.
+ # \param intent_category The intent category of the new profile.
+ # \param name The name for the profile. This will later be made unique so
+ # it doesn't need to be unique yet.
+ # \param global_stack The global stack showing the configuration that the
+ # profile should be created for.
+ # \param extruder_stack The extruder stack showing the configuration that
+ # the profile should be created for. If this is None, it will be created
+ # for the global stack.
+ def _createNewQualityChanges(self, quality_type: str, intent_category: Optional[str], name: str, global_stack: GlobalStack, extruder_stack: Optional[ExtruderStack]) -> InstanceContainer:
+ container_registry = CuraApplication.getInstance().getContainerRegistry()
+ base_id = global_stack.definition.getId() if extruder_stack is None else extruder_stack.getId()
+ new_id = base_id + "_" + name
+ new_id = new_id.lower().replace(" ", "_")
+ new_id = container_registry.uniqueName(new_id)
+
+ # Create a new quality_changes container for the quality.
+ quality_changes = InstanceContainer(new_id)
+ quality_changes.setName(name)
+ quality_changes.setMetaDataEntry("type", "quality_changes")
+ quality_changes.setMetaDataEntry("quality_type", quality_type)
+ if intent_category is not None:
+ quality_changes.setMetaDataEntry("intent_category", intent_category)
+
+ # If we are creating a container for an extruder, ensure we add that to the container.
+ if extruder_stack is not None:
+ quality_changes.setMetaDataEntry("position", extruder_stack.getMetaDataEntry("position"))
+
+ # If the machine specifies qualities should be filtered, ensure we match the current criteria.
+ machine_definition_id = ContainerTree.getInstance().machines[global_stack.definition.getId()].quality_definition
+ quality_changes.setDefinition(machine_definition_id)
+
+ quality_changes.setMetaDataEntry("setting_version", CuraApplication.getInstance().SettingVersion)
+ quality_changes.setDirty(True)
+ return quality_changes
+
+ @staticmethod
+ def _clearStack(stack):
application = CuraApplication.getInstance()
stack.definitionChanges.clear()
@@ -880,41 +932,30 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
extruder_stack.userChanges.setProperty(key, "value", value)
def _applyVariants(self, global_stack, extruder_stack_dict):
- application = CuraApplication.getInstance()
- variant_manager = application.getVariantManager()
+ machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
+ # Take the global variant from the machine info if available.
if self._machine_info.variant_info is not None:
- parser = self._machine_info.variant_info.parser
- variant_name = parser["general"]["name"]
-
- variant_type = VariantType.BUILD_PLATE
-
- node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
- if node is not None and node.getContainer() is not None:
- global_stack.variant = node.getContainer()
+ variant_name = self._machine_info.variant_info.parser["general"]["name"]
+ if variant_name in machine_node.variants:
+ global_stack.variant = machine_node.variants[variant_name].container
+ else:
+ Logger.log("w", "Could not find global variant '{0}'.".format(variant_name))
for position, extruder_stack in extruder_stack_dict.items():
if position not in self._machine_info.extruder_info_dict:
continue
extruder_info = self._machine_info.extruder_info_dict[position]
if extruder_info.variant_info is None:
- continue
- parser = extruder_info.variant_info.parser
-
- variant_name = parser["general"]["name"]
- variant_type = VariantType.NOZZLE
-
- node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
- if node is not None and node.getContainer() is not None:
- extruder_stack.variant = node.getContainer()
+ # If there is no variant_info, try to use the default variant. Otherwise, any available variant.
+ node = machine_node.variants.get(machine_node.preferred_variant_name, next(iter(machine_node.variants.values())))
+ else:
+ variant_name = extruder_info.variant_info.parser["general"]["name"]
+ node = ContainerTree.getInstance().machines[global_stack.definition.getId()].variants[variant_name]
+ extruder_stack.variant = node.container
def _applyMaterials(self, global_stack, extruder_stack_dict):
- application = CuraApplication.getInstance()
- material_manager = application.getMaterialManager()
-
- # Force update lookup tables first
- material_manager.initialize()
-
+ machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
for position, extruder_stack in extruder_stack_dict.items():
if position not in self._machine_info.extruder_info_dict:
continue
@@ -925,18 +966,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
root_material_id = extruder_info.root_material_id
root_material_id = self._old_new_materials.get(root_material_id, root_material_id)
- build_plate_id = global_stack.variant.getId()
-
- # get material diameter of this extruder
- machine_material_diameter = extruder_stack.getCompatibleMaterialDiameter()
- material_node = material_manager.getMaterialNode(global_stack.definition.getId(),
- extruder_stack.variant.getName(),
- build_plate_id,
- machine_material_diameter,
- root_material_id)
-
- if material_node is not None and material_node.getContainer() is not None:
- extruder_stack.material = material_node.getContainer() # type: InstanceContainer
+ material_node = machine_node.variants[extruder_stack.variant.getName()].materials[root_material_id]
+ extruder_stack.material = material_node.container # type: InstanceContainer
def _applyChangesToMachine(self, global_stack, extruder_stack_dict):
# Clear all first
@@ -952,10 +983,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# prepare the quality to select
self._quality_changes_to_apply = None
self._quality_type_to_apply = None
+ self._intent_category_to_apply = None
if self._machine_info.quality_changes_info is not None:
self._quality_changes_to_apply = self._machine_info.quality_changes_info.name
else:
self._quality_type_to_apply = self._machine_info.quality_type
+ self._intent_category_to_apply = self._machine_info.intent_category
# Set enabled/disabled for extruders
for position, extruder_stack in extruder_stack_dict.items():
@@ -966,34 +999,38 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
extruder_stack.setMetaDataEntry("enabled", "True")
extruder_stack.setMetaDataEntry("enabled", str(extruder_info.enabled))
+ # Set metadata fields that are missing from the global stack
+ for key, value in self._machine_info.metadata_dict.items():
+ if key not in global_stack.getMetaData():
+ global_stack.setMetaDataEntry(key, value)
+
def _updateActiveMachine(self, global_stack):
# Actually change the active machine.
machine_manager = Application.getInstance().getMachineManager()
- material_manager = Application.getInstance().getMaterialManager()
- quality_manager = Application.getInstance().getQualityManager()
-
- # Force update the lookup maps first
- material_manager.initialize()
- quality_manager.initialize()
+ container_tree = ContainerTree.getInstance()
machine_manager.setActiveMachine(global_stack.getId())
+ # Set metadata fields that are missing from the global stack
+ for key, value in self._machine_info.metadata_dict.items():
+ if key not in global_stack.getMetaData():
+ global_stack.setMetaDataEntry(key, value)
+
if self._quality_changes_to_apply:
- quality_changes_group_dict = quality_manager.getQualityChangesGroups(global_stack)
- if self._quality_changes_to_apply not in quality_changes_group_dict:
+ quality_changes_group_list = container_tree.getCurrentQualityChangesGroups()
+ quality_changes_group = next((qcg for qcg in quality_changes_group_list if qcg.name == self._quality_changes_to_apply), None)
+ if not quality_changes_group:
Logger.log("e", "Could not find quality_changes [%s]", self._quality_changes_to_apply)
return
- quality_changes_group = quality_changes_group_dict[self._quality_changes_to_apply]
machine_manager.setQualityChangesGroup(quality_changes_group, no_dialog = True)
else:
self._quality_type_to_apply = self._quality_type_to_apply.lower()
- quality_group_dict = quality_manager.getQualityGroups(global_stack)
+ quality_group_dict = container_tree.getCurrentQualityGroups()
if self._quality_type_to_apply in quality_group_dict:
quality_group = quality_group_dict[self._quality_type_to_apply]
else:
Logger.log("i", "Could not find quality type [%s], switch to default", self._quality_type_to_apply)
preferred_quality_type = global_stack.getMetaDataEntry("preferred_quality_type")
- quality_group_dict = quality_manager.getQualityGroups(global_stack)
quality_group = quality_group_dict.get(preferred_quality_type)
if quality_group is None:
Logger.log("e", "Could not get preferred quality type [%s]", preferred_quality_type)
@@ -1001,10 +1038,16 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if quality_group is not None:
machine_manager.setQualityGroup(quality_group, no_dialog = True)
+ # Also apply intent if available
+ available_intent_category_list = IntentManager.getInstance().currentAvailableIntentCategories()
+ if self._intent_category_to_apply is not None and self._intent_category_to_apply in available_intent_category_list:
+ machine_manager.setIntentByCategory(self._intent_category_to_apply)
+
# Notify everything/one that is to notify about changes.
global_stack.containersChanged.emit(global_stack.getTop())
- def _stripFileToId(self, file):
+ @staticmethod
+ def _stripFileToId(file):
mime_type = MimeTypeDatabase.getMimeTypeForFile(file)
file = mime_type.stripExtension(file)
return file.replace("Cura/", "")
@@ -1013,7 +1056,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
return self._container_registry.getContainerForMimeType(MimeTypeDatabase.getMimeType("application/x-ultimaker-material-profile"))
## Get the list of ID's of all containers in a container stack by partially parsing it's serialized data.
- def _getContainerIdListFromSerialized(self, serialized):
+ @staticmethod
+ def _getContainerIdListFromSerialized(serialized):
parser = ConfigParser(interpolation = None, empty_lines_in_values = False)
parser.read_string(serialized)
@@ -1034,12 +1078,20 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
return container_ids
- def _getMachineNameFromSerializedStack(self, serialized):
+ @staticmethod
+ def _getMachineNameFromSerializedStack(serialized):
parser = ConfigParser(interpolation = None, empty_lines_in_values = False)
parser.read_string(serialized)
return parser["general"].get("name", "")
- def _getMaterialLabelFromSerialized(self, serialized):
+ @staticmethod
+ def _getMetaDataDictFromSerializedStack(serialized: str) -> Dict[str, str]:
+ parser = ConfigParser(interpolation = None, empty_lines_in_values = False)
+ parser.read_string(serialized)
+ return dict(parser["metadata"])
+
+ @staticmethod
+ def _getMaterialLabelFromSerialized(serialized):
data = ET.fromstring(serialized)
metadata = data.iterfind("./um:metadata/um:name/um:label", {"um": "http://www.ultimaker.com/material"})
for entry in metadata:
diff --git a/plugins/3MFReader/WorkspaceDialog.py b/plugins/3MFReader/WorkspaceDialog.py
index 6e1cbb2019..3df7f1f570 100644
--- a/plugins/3MFReader/WorkspaceDialog.py
+++ b/plugins/3MFReader/WorkspaceDialog.py
@@ -41,8 +41,9 @@ class WorkspaceDialog(QObject):
self._num_user_settings = 0
self._active_mode = ""
self._quality_name = ""
- self._num_settings_overriden_by_quality_changes = 0
+ self._num_settings_overridden_by_quality_changes = 0
self._quality_type = ""
+ self._intent_name = ""
self._machine_name = ""
self._machine_type = ""
self._variant_type = ""
@@ -60,6 +61,7 @@ class WorkspaceDialog(QObject):
hasVisibleSettingsFieldChanged = pyqtSignal()
numSettingsOverridenByQualityChangesChanged = pyqtSignal()
qualityTypeChanged = pyqtSignal()
+ intentNameChanged = pyqtSignal()
machineNameChanged = pyqtSignal()
materialLabelsChanged = pyqtSignal()
objectsOnPlateChanged = pyqtSignal()
@@ -151,10 +153,10 @@ class WorkspaceDialog(QObject):
@pyqtProperty(int, notify=numSettingsOverridenByQualityChangesChanged)
def numSettingsOverridenByQualityChanges(self):
- return self._num_settings_overriden_by_quality_changes
+ return self._num_settings_overridden_by_quality_changes
- def setNumSettingsOverridenByQualityChanges(self, num_settings_overriden_by_quality_changes):
- self._num_settings_overriden_by_quality_changes = num_settings_overriden_by_quality_changes
+ def setNumSettingsOverriddenByQualityChanges(self, num_settings_overridden_by_quality_changes):
+ self._num_settings_overridden_by_quality_changes = num_settings_overridden_by_quality_changes
self.numSettingsOverridenByQualityChangesChanged.emit()
@pyqtProperty(str, notify=qualityNameChanged)
@@ -166,6 +168,15 @@ class WorkspaceDialog(QObject):
self._quality_name = quality_name
self.qualityNameChanged.emit()
+ @pyqtProperty(str, notify = intentNameChanged)
+ def intentName(self) -> str:
+ return self._intent_name
+
+ def setIntentName(self, intent_name: str) -> None:
+ if self._intent_name != intent_name:
+ self._intent_name = intent_name
+ self.intentNameChanged.emit()
+
@pyqtProperty(str, notify=activeModeChanged)
def activeMode(self):
return self._active_mode
diff --git a/plugins/3MFReader/WorkspaceDialog.qml b/plugins/3MFReader/WorkspaceDialog.qml
index 58d881c915..d0fd3d0846 100644
--- a/plugins/3MFReader/WorkspaceDialog.qml
+++ b/plugins/3MFReader/WorkspaceDialog.qml
@@ -1,10 +1,10 @@
// Copyright (c) 2016 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.1
-import QtQuick.Controls 1.1
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
+import QtQuick 2.10
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.3
+import QtQuick.Window 2.2
import UM 1.1 as UM
@@ -13,8 +13,8 @@ UM.Dialog
id: base
title: catalog.i18nc("@title:window", "Open Project")
- minimumWidth: 500 * screenScaleFactor
- minimumHeight: 450 * screenScaleFactor
+ minimumWidth: UM.Theme.getSize("popup_dialog").width
+ minimumHeight: UM.Theme.getSize("popup_dialog").height
width: minimumWidth
height: minimumHeight
@@ -24,7 +24,7 @@ UM.Dialog
onClosing: manager.notifyClosed()
onVisibleChanged:
{
- if(visible)
+ if (visible)
{
machineResolveComboBox.currentIndex = 0
qualityChangesResolveComboBox.currentIndex = 0
@@ -55,8 +55,8 @@ UM.Dialog
// See http://stackoverflow.com/questions/7659442/listelement-fields-as-properties
Component.onCompleted:
{
- append({"key": "override", "label": catalog.i18nc("@action:ComboBox option", "Update existing")});
- append({"key": "new", "label": catalog.i18nc("@action:ComboBox option", "Create new")});
+ append({"key": "override", "label": catalog.i18nc("@action:ComboBox Update/override existing profile", "Update existing")});
+ append({"key": "new", "label": catalog.i18nc("@action:ComboBox Save settings in a new profile", "Create new")});
}
}
@@ -223,6 +223,21 @@ UM.Dialog
}
}
Row
+ {
+ width: parent.width
+ height: childrenRect.height
+ Label
+ {
+ text: catalog.i18nc("@action:label", "Intent")
+ width: (parent.width / 3) | 0
+ }
+ Label
+ {
+ text: manager.intentName
+ width: (parent.width / 3) | 0
+ }
+ }
+ Row
{
width: parent.width
height: manager.numUserSettings != 0 ? childrenRect.height : 0
diff --git a/plugins/3MFReader/__init__.py b/plugins/3MFReader/__init__.py
index ce94bbe69c..d68338c35f 100644
--- a/plugins/3MFReader/__init__.py
+++ b/plugins/3MFReader/__init__.py
@@ -12,7 +12,6 @@ except ImportError:
from . import ThreeMFWorkspaceReader
from UM.i18n import i18nCatalog
-from UM.Platform import Platform
catalog = i18nCatalog("cura")
diff --git a/plugins/3MFReader/plugin.json b/plugins/3MFReader/plugin.json
index 5af21a7033..e366a5da72 100644
--- a/plugins/3MFReader/plugin.json
+++ b/plugins/3MFReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for reading 3MF files.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/3MFWriter/plugin.json b/plugins/3MFWriter/plugin.json
index 3820ebd2e7..5c72072447 100644
--- a/plugins/3MFWriter/plugin.json
+++ b/plugins/3MFWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for writing 3MF files.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/AMFReader/AMFReader.py b/plugins/AMFReader/AMFReader.py
new file mode 100644
index 0000000000..6c5ee91e87
--- /dev/null
+++ b/plugins/AMFReader/AMFReader.py
@@ -0,0 +1,173 @@
+# Copyright (c) 2019 fieldOfView, Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+# This AMF parser is based on the AMF parser in legacy cura:
+# https://github.com/daid/LegacyCura/blob/ad7641e059048c7dcb25da1f47c0a7e95e7f4f7c/Cura/util/meshLoaders/amf.py
+from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType
+from cura.CuraApplication import CuraApplication
+from UM.Logger import Logger
+
+from UM.Mesh.MeshData import MeshData, calculateNormalsFromIndexedVertices
+from UM.Mesh.MeshReader import MeshReader
+
+from cura.Scene.CuraSceneNode import CuraSceneNode
+from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
+from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
+from cura.Scene.ConvexHullDecorator import ConvexHullDecorator
+from UM.Scene.GroupDecorator import GroupDecorator
+
+import numpy
+import trimesh
+import os.path
+import zipfile
+
+MYPY = False
+try:
+ if not MYPY:
+ import xml.etree.cElementTree as ET
+except ImportError:
+ import xml.etree.ElementTree as ET
+
+from typing import Dict
+
+
+class AMFReader(MeshReader):
+ def __init__(self) -> None:
+ super().__init__()
+ self._supported_extensions = [".amf"]
+ self._namespaces = {} # type: Dict[str, str]
+
+ MimeTypeDatabase.addMimeType(
+ MimeType(
+ name = "application/x-amf",
+ comment = "AMF",
+ suffixes = ["amf"]
+ )
+ )
+
+ # Main entry point
+ # Reads the file, returns a SceneNode (possibly with nested ones), or None
+ def _read(self, file_name):
+ base_name = os.path.basename(file_name)
+ try:
+ zipped_file = zipfile.ZipFile(file_name)
+ xml_document = zipped_file.read(zipped_file.namelist()[0])
+ zipped_file.close()
+ except zipfile.BadZipfile:
+ raw_file = open(file_name, "r")
+ xml_document = raw_file.read()
+ raw_file.close()
+
+ try:
+ amf_document = ET.fromstring(xml_document)
+ except ET.ParseError:
+ Logger.log("e", "Could not parse XML in file %s" % base_name)
+ return None
+
+ if "unit" in amf_document.attrib:
+ unit = amf_document.attrib["unit"].lower()
+ else:
+ unit = "millimeter"
+ if unit == "millimeter":
+ scale = 1.0
+ elif unit == "meter":
+ scale = 1000.0
+ elif unit == "inch":
+ scale = 25.4
+ elif unit == "feet":
+ scale = 304.8
+ elif unit == "micron":
+ scale = 0.001
+ else:
+ Logger.log("w", "Unknown unit in amf: %s. Using mm instead." % unit)
+ scale = 1.0
+
+ nodes = []
+ for amf_object in amf_document.iter("object"):
+ for amf_mesh in amf_object.iter("mesh"):
+ amf_mesh_vertices = []
+ for vertices in amf_mesh.iter("vertices"):
+ for vertex in vertices.iter("vertex"):
+ for coordinates in vertex.iter("coordinates"):
+ v = [0.0, 0.0, 0.0]
+ for t in coordinates:
+ if t.tag == "x":
+ v[0] = float(t.text) * scale
+ elif t.tag == "y":
+ v[2] = -float(t.text) * scale
+ elif t.tag == "z":
+ v[1] = float(t.text) * scale
+ amf_mesh_vertices.append(v)
+ if not amf_mesh_vertices:
+ continue
+
+ indices = []
+ for volume in amf_mesh.iter("volume"):
+ for triangle in volume.iter("triangle"):
+ f = [0, 0, 0]
+ for t in triangle:
+ if t.tag == "v1":
+ f[0] = int(t.text)
+ elif t.tag == "v2":
+ f[1] = int(t.text)
+ elif t.tag == "v3":
+ f[2] = int(t.text)
+ indices.append(f)
+
+ mesh = trimesh.base.Trimesh(vertices = numpy.array(amf_mesh_vertices, dtype = numpy.float32), faces = numpy.array(indices, dtype = numpy.int32))
+ mesh.merge_vertices()
+ mesh.remove_unreferenced_vertices()
+ mesh.fix_normals()
+ mesh_data = self._toMeshData(mesh)
+
+ new_node = CuraSceneNode()
+ new_node.setSelectable(True)
+ new_node.setMeshData(mesh_data)
+ new_node.setName(base_name if len(nodes) == 0 else "%s %d" % (base_name, len(nodes)))
+ new_node.addDecorator(BuildPlateDecorator(CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate))
+ new_node.addDecorator(SliceableObjectDecorator())
+
+ nodes.append(new_node)
+
+ if not nodes:
+ Logger.log("e", "No meshes in file %s" % base_name)
+ return None
+
+ if len(nodes) == 1:
+ return nodes[0]
+
+ # Add all scenenodes to a group so they stay together
+ group_node = CuraSceneNode()
+ group_node.addDecorator(GroupDecorator())
+ group_node.addDecorator(ConvexHullDecorator())
+ group_node.addDecorator(BuildPlateDecorator(CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate))
+
+ for node in nodes:
+ node.setParent(group_node)
+
+ return group_node
+
+ def _toMeshData(self, tri_node: trimesh.base.Trimesh) -> MeshData:
+ tri_faces = tri_node.faces
+ tri_vertices = tri_node.vertices
+
+ indices = []
+ vertices = []
+
+ index_count = 0
+ face_count = 0
+ for tri_face in tri_faces:
+ face = []
+ for tri_index in tri_face:
+ vertices.append(tri_vertices[tri_index])
+ face.append(index_count)
+ index_count += 1
+ indices.append(face)
+ face_count += 1
+
+ vertices = numpy.asarray(vertices, dtype = numpy.float32)
+ indices = numpy.asarray(indices, dtype = numpy.int32)
+ normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count)
+
+ mesh_data = MeshData(vertices = vertices, indices = indices, normals = normals)
+ return mesh_data
diff --git a/plugins/AMFReader/__init__.py b/plugins/AMFReader/__init__.py
new file mode 100644
index 0000000000..c974a92d11
--- /dev/null
+++ b/plugins/AMFReader/__init__.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2019 fieldOfView
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from . import AMFReader
+
+from UM.i18n import i18nCatalog
+i18n_catalog = i18nCatalog("uranium")
+
+
+def getMetaData():
+ return {
+ "mesh_reader": [
+ {
+ "extension": "amf",
+ "description": i18n_catalog.i18nc("@item:inlistbox", "AMF File")
+ }
+ ]
+ }
+
+def register(app):
+ return {"mesh_reader": AMFReader.AMFReader()}
diff --git a/plugins/AMFReader/plugin.json b/plugins/AMFReader/plugin.json
new file mode 100644
index 0000000000..5e5b0f211b
--- /dev/null
+++ b/plugins/AMFReader/plugin.json
@@ -0,0 +1,7 @@
+{
+ "name": "AMF Reader",
+ "author": "fieldOfView",
+ "version": "1.0.0",
+ "description": "Provides support for reading AMF files.",
+ "api": "7.0.0"
+}
diff --git a/plugins/ChangeLogPlugin/ChangeLog.py b/plugins/ChangeLogPlugin/ChangeLog.py
deleted file mode 100644
index eeec5edf9b..0000000000
--- a/plugins/ChangeLogPlugin/ChangeLog.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from UM.i18n import i18nCatalog
-from UM.Extension import Extension
-from UM.Application import Application
-from UM.PluginRegistry import PluginRegistry
-from UM.Version import Version
-
-from PyQt5.QtCore import pyqtSlot, QObject
-
-import os.path
-import collections
-
-catalog = i18nCatalog("cura")
-
-class ChangeLog(Extension, QObject,):
- def __init__(self, parent = None):
- QObject.__init__(self, parent)
- Extension.__init__(self)
- self._changelog_window = None
- self._changelog_context = None
- version_string = Application.getInstance().getVersion()
- if version_string is not "master":
- self._current_app_version = Version(version_string)
- else:
- self._current_app_version = None
-
- self._change_logs = None
- Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
- Application.getInstance().getPreferences().addPreference("general/latest_version_changelog_shown", "2.0.0") #First version of CURA with uranium
- self.setMenuName(catalog.i18nc("@item:inmenu", "Changelog"))
- self.addMenuItem(catalog.i18nc("@item:inmenu", "Show Changelog"), self.showChangelog)
-
- def getChangeLogs(self):
- if not self._change_logs:
- self.loadChangeLogs()
- return self._change_logs
-
- @pyqtSlot(result = str)
- def getChangeLogString(self):
- logs = self.getChangeLogs()
- result = ""
- for version in logs:
- result += "
" + str(version) + "
"
- result += ""
- for change in logs[version]:
- if str(change) != "":
- result += "" + str(change) + " "
- for line in logs[version][change]:
- result += str(line) + " "
- result += " "
-
- pass
- return result
-
- def loadChangeLogs(self):
- self._change_logs = collections.OrderedDict()
- with open(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.txt"), "r", encoding = "utf-8") as f:
- open_version = None
- open_header = "" # Initialise to an empty header in case there is no "*" in the first line of the changelog
- for line in f:
- line = line.replace("\n","")
- if "[" in line and "]" in line:
- line = line.replace("[","")
- line = line.replace("]","")
- open_version = Version(line)
- open_header = ""
- self._change_logs[open_version] = collections.OrderedDict()
- elif line.startswith("*"):
- open_header = line.replace("*","")
- self._change_logs[open_version][open_header] = []
- elif line != "":
- if open_header not in self._change_logs[open_version]:
- self._change_logs[open_version][open_header] = []
- self._change_logs[open_version][open_header].append(line)
-
- def _onEngineCreated(self):
- if not self._current_app_version:
- return #We're on dev branch.
-
- if Application.getInstance().getPreferences().getValue("general/latest_version_changelog_shown") == "master":
- latest_version_shown = Version("0.0.0")
- else:
- latest_version_shown = Version(Application.getInstance().getPreferences().getValue("general/latest_version_changelog_shown"))
-
- Application.getInstance().getPreferences().setValue("general/latest_version_changelog_shown", Application.getInstance().getVersion())
-
- # Do not show the changelog when there is no global container stack
- # This implies we are running Cura for the first time.
- if not Application.getInstance().getGlobalContainerStack():
- return
-
- if self._current_app_version > latest_version_shown:
- self.showChangelog()
-
- def showChangelog(self):
- if not self._changelog_window:
- self.createChangelogWindow()
-
- self._changelog_window.show()
-
- def hideChangelog(self):
- if self._changelog_window:
- self._changelog_window.hide()
-
- def createChangelogWindow(self):
- path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.qml")
- self._changelog_window = Application.getInstance().createQmlComponent(path, {"manager": self})
diff --git a/plugins/ChangeLogPlugin/ChangeLog.qml b/plugins/ChangeLogPlugin/ChangeLog.qml
deleted file mode 100644
index 512687f15a..0000000000
--- a/plugins/ChangeLogPlugin/ChangeLog.qml
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2015 Ultimaker B.V.
-// Cura is released under the terms of the LGPLv3 or higher.
-
-import QtQuick 2.1
-import QtQuick.Controls 1.3
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
-
-import UM 1.1 as UM
-
-UM.Dialog
-{
- id: base
- minimumWidth: (UM.Theme.getSize("modal_window_minimum").width * 0.75) | 0
- minimumHeight: (UM.Theme.getSize("modal_window_minimum").height * 0.75) | 0
- width: minimumWidth
- height: minimumHeight
- title: catalog.i18nc("@label", "Changelog")
-
- TextArea
- {
- anchors.fill: parent
- text: manager.getChangeLogString()
- readOnly: true;
- textFormat: TextEdit.RichText
- }
-
- rightButtons: [
- Button
- {
- UM.I18nCatalog
- {
- id: catalog
- name: "cura"
- }
-
- text: catalog.i18nc("@action:button", "Close")
- onClicked: base.hide()
- }
- ]
-}
diff --git a/plugins/ChangeLogPlugin/__init__.py b/plugins/ChangeLogPlugin/__init__.py
deleted file mode 100644
index a5452b60c8..0000000000
--- a/plugins/ChangeLogPlugin/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (c) 2015 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from . import ChangeLog
-
-
-def getMetaData():
- return {}
-
-def register(app):
- return {"extension": ChangeLog.ChangeLog()}
diff --git a/plugins/ChangeLogPlugin/plugin.json b/plugins/ChangeLogPlugin/plugin.json
deleted file mode 100644
index 92041d1543..0000000000
--- a/plugins/ChangeLogPlugin/plugin.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "Changelog",
- "author": "Ultimaker B.V.",
- "version": "1.0.1",
- "description": "Shows changes since latest checked version.",
- "api": "6.0",
- "i18n-catalog": "cura"
-}
diff --git a/plugins/CuraDrive/plugin.json b/plugins/CuraDrive/plugin.json
index d1cab39ca5..9b9b3e2c15 100644
--- a/plugins/CuraDrive/plugin.json
+++ b/plugins/CuraDrive/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"description": "Backup and restore your configuration.",
"version": "1.2.0",
- "api": 6,
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py
index 6a828e32d6..d8349ccc29 100644
--- a/plugins/CuraDrive/src/DriveApiService.py
+++ b/plugins/CuraDrive/src/DriveApiService.py
@@ -45,7 +45,7 @@ class DriveApiService:
"Authorization": "Bearer {}".format(access_token)
})
except requests.exceptions.ConnectionError:
- Logger.log("w", "Unable to connect with the server.")
+ Logger.logException("w", "Unable to connect with the server.")
return []
# HTTP status 300s mean redirection. 400s and 500s are errors.
@@ -54,7 +54,13 @@ class DriveApiService:
Logger.log("w", "Could not get backups list from remote: %s", backup_list_request.text)
Message(catalog.i18nc("@info:backup_status", "There was an error listing your backups."), title = catalog.i18nc("@info:title", "Backup")).show()
return []
- return backup_list_request.json()["data"]
+
+ backup_list_response = backup_list_request.json()
+ if "data" not in backup_list_response:
+ Logger.log("w", "Could not get backups from remote, actual response body was: %s", str(backup_list_response))
+ return []
+
+ return backup_list_response["data"]
def createBackup(self) -> None:
self.creatingStateChanged.emit(is_creating = True)
@@ -92,7 +98,12 @@ class DriveApiService:
# If there is no download URL, we can't restore the backup.
return self._emitRestoreError()
- download_package = requests.get(download_url, stream = True)
+ try:
+ download_package = requests.get(download_url, stream = True)
+ except requests.exceptions.ConnectionError:
+ Logger.logException("e", "Unable to connect with the server")
+ return self._emitRestoreError()
+
if download_package.status_code >= 300:
# Something went wrong when attempting to download the backup.
Logger.log("w", "Could not download backup from url %s: %s", download_url, download_package.text)
@@ -136,9 +147,14 @@ class DriveApiService:
Logger.log("w", "Could not get access token.")
return False
- delete_backup = requests.delete("{}/{}".format(self.BACKUP_URL, backup_id), headers = {
- "Authorization": "Bearer {}".format(access_token)
- })
+ try:
+ delete_backup = requests.delete("{}/{}".format(self.BACKUP_URL, backup_id), headers = {
+ "Authorization": "Bearer {}".format(access_token)
+ })
+ except requests.exceptions.ConnectionError:
+ Logger.logException("e", "Unable to connect with the server")
+ return False
+
if delete_backup.status_code >= 300:
Logger.log("w", "Could not delete backup: %s", delete_backup.text)
return False
@@ -153,15 +169,19 @@ class DriveApiService:
if not access_token:
Logger.log("w", "Could not get access token.")
return None
-
- backup_upload_request = requests.put(self.BACKUP_URL, json = {
- "data": {
- "backup_size": backup_size,
- "metadata": backup_metadata
- }
- }, headers = {
- "Authorization": "Bearer {}".format(access_token)
- })
+ try:
+ backup_upload_request = requests.put(
+ self.BACKUP_URL,
+ json = {"data": {"backup_size": backup_size,
+ "metadata": backup_metadata
+ }
+ },
+ headers = {
+ "Authorization": "Bearer {}".format(access_token)
+ })
+ except requests.exceptions.ConnectionError:
+ Logger.logException("e", "Unable to connect with the server")
+ return None
# Any status code of 300 or above indicates an error.
if backup_upload_request.status_code >= 300:
diff --git a/plugins/CuraDrive/src/qml/main.qml b/plugins/CuraDrive/src/qml/main.qml
index 48bf3b6ea4..796a31e1d3 100644
--- a/plugins/CuraDrive/src/qml/main.qml
+++ b/plugins/CuraDrive/src/qml/main.qml
@@ -18,6 +18,7 @@ Window
minimumHeight: Math.round(UM.Theme.getSize("modal_window_minimum").height)
maximumWidth: Math.round(minimumWidth * 1.2)
maximumHeight: Math.round(minimumHeight * 1.2)
+ modality: Qt.ApplicationModal
width: minimumWidth
height: minimumHeight
color: UM.Theme.getColor("main_background")
diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py
index d5531a2773..1437153f32 100755
--- a/plugins/CuraEngineBackend/CuraEngineBackend.py
+++ b/plugins/CuraEngineBackend/CuraEngineBackend.py
@@ -15,14 +15,12 @@ from UM.Signal import Signal
from UM.Logger import Logger
from UM.Message import Message
from UM.PluginRegistry import PluginRegistry
-from UM.Resources import Resources
from UM.Platform import Platform
from UM.Qt.Duration import DurationFormat
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Settings.Interfaces import DefinitionContainerInterface
from UM.Settings.SettingInstance import SettingInstance #For typing.
from UM.Tool import Tool #For typing.
-from UM.Mesh.MeshData import MeshData #For typing.
from cura.CuraApplication import CuraApplication
from cura.Settings.ExtruderManager import ExtruderManager
@@ -209,7 +207,7 @@ class CuraEngineBackend(QObject, Backend):
self._createSocket()
if self._process_layers_job is not None: # We were processing layers. Stop that, the layers are going to change soon.
- Logger.log("d", "Aborting process layers job...")
+ Logger.log("i", "Aborting process layers job...")
self._process_layers_job.abort()
self._process_layers_job = None
@@ -224,7 +222,7 @@ class CuraEngineBackend(QObject, Backend):
## Perform a slice of the scene.
def slice(self) -> None:
- Logger.log("d", "Starting to slice...")
+ Logger.log("i", "Starting to slice...")
self._slice_start_time = time()
if not self._build_plates_to_be_sliced:
self.processingProgress.emit(1.0)
@@ -371,7 +369,7 @@ class CuraEngineBackend(QObject, Backend):
elif job.getResult() == StartJobResult.ObjectSettingError:
errors = {}
- for node in DepthFirstIterator(self._application.getController().getScene().getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+ for node in DepthFirstIterator(self._application.getController().getScene().getRoot()):
stack = node.callDecoration("getStack")
if not stack:
continue
@@ -402,7 +400,7 @@ class CuraEngineBackend(QObject, Backend):
self.setState(BackendState.NotStarted)
if job.getResult() == StartJobResult.ObjectsWithDisabledExtruder:
- self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice because there are objects associated with disabled Extruder %s." % job.getMessage()),
+ self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice because there are objects associated with disabled Extruder %s.") % job.getMessage(),
title = catalog.i18nc("@info:title", "Unable to slice"))
self._error_message.show()
self.setState(BackendState.Error)
@@ -440,7 +438,7 @@ class CuraEngineBackend(QObject, Backend):
if not self._application.getPreferences().getValue("general/auto_slice"):
enable_timer = False
- for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+ for node in DepthFirstIterator(self._scene.getRoot()):
if node.callDecoration("isBlockSlicing"):
enable_timer = False
self.setState(BackendState.Disabled)
@@ -462,7 +460,7 @@ class CuraEngineBackend(QObject, Backend):
## Return a dict with number of objects per build plate
def _numObjectsPerBuildPlate(self) -> Dict[int, int]:
num_objects = defaultdict(int) #type: Dict[int, int]
- for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+ for node in DepthFirstIterator(self._scene.getRoot()):
# Only count sliceable objects
if node.callDecoration("isSliceable"):
build_plate_number = node.callDecoration("getBuildPlateNumber")
@@ -476,7 +474,7 @@ class CuraEngineBackend(QObject, Backend):
#
# \param source The scene node that was changed.
def _onSceneChanged(self, source: SceneNode) -> None:
- if not isinstance(source, SceneNode):
+ if not source.callDecoration("isSliceable"):
return
# This case checks if the source node is a node that contains GCode. In this case the
@@ -519,9 +517,6 @@ class CuraEngineBackend(QObject, Backend):
self._build_plates_to_be_sliced.append(build_plate_number)
self.printDurationMessage.emit(source_build_plate_number, {}, [])
self.processingProgress.emit(0.0)
- self.setState(BackendState.NotStarted)
- # if not self._use_timer:
- # With manually having to slice, we want to clear the old invalid layer data.
self._clearLayerData(build_plate_changed)
self._invokeSlice()
@@ -548,15 +543,25 @@ class CuraEngineBackend(QObject, Backend):
if error.getErrorCode() == Arcus.ErrorCode.BindFailedError and self._start_slice_job is not None:
self._start_slice_job.setIsCancelled(False)
+ # Check if there's any slicable object in the scene.
+ def hasSlicableObject(self) -> bool:
+ has_slicable = False
+ for node in DepthFirstIterator(self._scene.getRoot()):
+ if node.callDecoration("isSliceable"):
+ has_slicable = True
+ break
+ return has_slicable
+
## Remove old layer data (if any)
def _clearLayerData(self, build_plate_numbers: Set = None) -> None:
# Clear out any old gcode
self._scene.gcode_dict = {} # type: ignore
- for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+ for node in DepthFirstIterator(self._scene.getRoot()):
if node.callDecoration("getLayerData"):
if not build_plate_numbers or node.callDecoration("getBuildPlateNumber") in build_plate_numbers:
- node.getParent().removeChild(node)
+ # We can asume that all nodes have a parent as we're looping through the scene (and filter out root)
+ cast(SceneNode, node.getParent()).removeChild(node)
def markSliceAll(self) -> None:
for build_plate_number in range(self._application.getMultiBuildPlateModel().maxBuildPlate + 1):
@@ -565,10 +570,14 @@ class CuraEngineBackend(QObject, Backend):
## Convenient function: mark everything to slice, emit state and clear layer data
def needsSlicing(self) -> None:
+ # CURA-6604: If there's no slicable object, do not (try to) trigger slice, which will clear all the current
+ # gcode. This can break Gcode file loading if it tries to remove it afterwards.
+ if not self.hasSlicableObject():
+ return
+ self.determineAutoSlicing()
self.stopSlicing()
self.markSliceAll()
self.processingProgress.emit(0.0)
- self.setState(BackendState.NotStarted)
if not self._use_timer:
# With manually having to slice, we want to clear the old invalid layer data.
self._clearLayerData()
@@ -636,7 +645,10 @@ class CuraEngineBackend(QObject, Backend):
self.setState(BackendState.Done)
self.processingProgress.emit(1.0)
- gcode_list = self._scene.gcode_dict[self._start_slice_job_build_plate] #type: ignore #Because we generate this attribute dynamically.
+ try:
+ gcode_list = self._scene.gcode_dict[self._start_slice_job_build_plate] #type: ignore #Because we generate this attribute dynamically.
+ except KeyError: # Can occur if the g-code has been cleared while a slice message is still arriving from the other end.
+ gcode_list = []
for index, line in enumerate(gcode_list):
replaced = line.replace("{print_time}", str(self._application.getPrintInformation().currentPrintTime.getDisplayString(DurationFormat.Format.ISO8601)))
replaced = replaced.replace("{filament_amount}", str(self._application.getPrintInformation().materialLengths))
@@ -675,14 +687,20 @@ class CuraEngineBackend(QObject, Backend):
#
# \param message The protobuf message containing g-code, encoded as UTF-8.
def _onGCodeLayerMessage(self, message: Arcus.PythonMessage) -> None:
- self._scene.gcode_dict[self._start_slice_job_build_plate].append(message.data.decode("utf-8", "replace")) #type: ignore #Because we generate this attribute dynamically.
+ try:
+ self._scene.gcode_dict[self._start_slice_job_build_plate].append(message.data.decode("utf-8", "replace")) #type: ignore #Because we generate this attribute dynamically.
+ except KeyError: # Can occur if the g-code has been cleared while a slice message is still arriving from the other end.
+ pass # Throw the message away.
## Called when a g-code prefix message is received from the engine.
#
# \param message The protobuf message containing the g-code prefix,
# encoded as UTF-8.
def _onGCodePrefixMessage(self, message: Arcus.PythonMessage) -> None:
- self._scene.gcode_dict[self._start_slice_job_build_plate].insert(0, message.data.decode("utf-8", "replace")) #type: ignore #Because we generate this attribute dynamically.
+ try:
+ self._scene.gcode_dict[self._start_slice_job_build_plate].insert(0, message.data.decode("utf-8", "replace")) #type: ignore #Because we generate this attribute dynamically.
+ except KeyError: # Can occur if the g-code has been cleared while a slice message is still arriving from the other end.
+ pass # Throw the message away.
## Creates a new socket connection.
def _createSocket(self, protocol_file: str = None) -> None:
@@ -737,6 +755,7 @@ class CuraEngineBackend(QObject, Backend):
"support_interface": message.time_support_interface,
"support": message.time_support,
"skirt": message.time_skirt,
+ "prime_tower": message.time_prime_tower,
"travel": message.time_travel,
"retract": message.time_retract,
"none": message.time_none
@@ -815,9 +834,8 @@ class CuraEngineBackend(QObject, Backend):
if self._global_container_stack:
self._global_container_stack.propertyChanged.disconnect(self._onSettingChanged)
self._global_container_stack.containersChanged.disconnect(self._onChanged)
- extruders = list(self._global_container_stack.extruders.values())
- for extruder in extruders:
+ for extruder in self._global_container_stack.extruderList:
extruder.propertyChanged.disconnect(self._onSettingChanged)
extruder.containersChanged.disconnect(self._onChanged)
@@ -826,8 +844,8 @@ class CuraEngineBackend(QObject, Backend):
if self._global_container_stack:
self._global_container_stack.propertyChanged.connect(self._onSettingChanged) # Note: Only starts slicing when the value changed.
self._global_container_stack.containersChanged.connect(self._onChanged)
- extruders = list(self._global_container_stack.extruders.values())
- for extruder in extruders:
+
+ for extruder in self._global_container_stack.extruderList:
extruder.propertyChanged.connect(self._onSettingChanged)
extruder.containersChanged.connect(self._onChanged)
self._onChanged()
diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py
index 3cc23130ea..32d60eb68b 100644
--- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py
+++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py
@@ -1,4 +1,4 @@
-#Copyright (c) 2017 Ultimaker B.V.
+#Copyright (c) 2019 Ultimaker B.V.
#Cura is released under the terms of the LGPLv3 or higher.
import gc
@@ -24,7 +24,7 @@ from cura import LayerPolygon
import numpy
from time import time
-from cura.Settings.ExtrudersModel import ExtrudersModel
+from cura.Machines.Models.ExtrudersModel import ExtrudersModel
catalog = i18nCatalog("cura")
@@ -136,23 +136,23 @@ class ProcessSlicedLayersJob(Job):
extruder = polygon.extruder
- line_types = numpy.fromstring(polygon.line_type, dtype="u1") # Convert bytearray to numpy array
+ line_types = numpy.fromstring(polygon.line_type, dtype = "u1") # Convert bytearray to numpy array
line_types = line_types.reshape((-1,1))
- points = numpy.fromstring(polygon.points, dtype="f4") # Convert bytearray to numpy array
+ points = numpy.fromstring(polygon.points, dtype = "f4") # Convert bytearray to numpy array
if polygon.point_type == 0: # Point2D
points = points.reshape((-1,2)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly.
else: # Point3D
points = points.reshape((-1,3))
- line_widths = numpy.fromstring(polygon.line_width, dtype="f4") # Convert bytearray to numpy array
+ line_widths = numpy.fromstring(polygon.line_width, dtype = "f4") # Convert bytearray to numpy array
line_widths = line_widths.reshape((-1,1)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly.
- line_thicknesses = numpy.fromstring(polygon.line_thickness, dtype="f4") # Convert bytearray to numpy array
+ line_thicknesses = numpy.fromstring(polygon.line_thickness, dtype = "f4") # Convert bytearray to numpy array
line_thicknesses = line_thicknesses.reshape((-1,1)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly.
- line_feedrates = numpy.fromstring(polygon.line_feedrate, dtype="f4") # Convert bytearray to numpy array
+ line_feedrates = numpy.fromstring(polygon.line_feedrate, dtype = "f4") # Convert bytearray to numpy array
line_feedrates = line_feedrates.reshape((-1,1)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly.
# Create a new 3D-array, copy the 2D points over and insert the right height.
@@ -194,7 +194,7 @@ class ProcessSlicedLayersJob(Job):
manager = ExtruderManager.getInstance()
extruders = manager.getActiveExtruderStacks()
if extruders:
- material_color_map = numpy.zeros((len(extruders), 4), dtype=numpy.float32)
+ material_color_map = numpy.zeros((len(extruders), 4), dtype = numpy.float32)
for extruder in extruders:
position = int(extruder.getMetaDataEntry("position", default = "0"))
try:
@@ -206,8 +206,8 @@ class ProcessSlicedLayersJob(Job):
material_color_map[position, :] = color
else:
# Single extruder via global stack.
- material_color_map = numpy.zeros((1, 4), dtype=numpy.float32)
- color_code = global_container_stack.material.getMetaDataEntry("color_code", default="#e0e000")
+ material_color_map = numpy.zeros((1, 4), dtype = numpy.float32)
+ color_code = global_container_stack.material.getMetaDataEntry("color_code", default = "#e0e000")
color = colorCodeToRGBA(color_code)
material_color_map[0, :] = color
diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py
index d3882a1209..43d54d8b12 100644
--- a/plugins/CuraEngineBackend/StartSliceJob.py
+++ b/plugins/CuraEngineBackend/StartSliceJob.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import numpy
@@ -11,6 +11,7 @@ import Arcus #For typing.
from UM.Job import Job
from UM.Logger import Logger
+from UM.Scene.SceneNode import SceneNode
from UM.Settings.ContainerStack import ContainerStack #For typing.
from UM.Settings.SettingRelation import SettingRelation #For typing.
@@ -71,7 +72,7 @@ class GcodeStartEndFormatter(Formatter):
value = default_value_str
# "-1" is global stack, and if the setting value exists in the global stack, use it as the fallback value.
if key in kwargs["-1"]:
- value = kwargs["-1"]
+ value = kwargs["-1"][key]
if str(extruder_nr) in kwargs and key in kwargs[str(extruder_nr)]:
value = kwargs[str(extruder_nr)][key]
@@ -105,9 +106,14 @@ class StartSliceJob(Job):
if stack is None:
return False
+ # if there are no per-object settings we don't need to check the other settings here
+ stack_top = stack.getTop()
+ if stack_top is None or not stack_top.getAllKeys():
+ return False
+
for key in stack.getAllKeys():
validation_state = stack.getProperty(key, "validationState")
- if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
+ if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError, ValidatorState.Invalid):
Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state)
return True
Job.yieldThread()
@@ -133,6 +139,14 @@ class StartSliceJob(Job):
self.setResult(StartJobResult.BuildPlateError)
return
+ # Wait for error checker to be done.
+ while CuraApplication.getInstance().getMachineErrorChecker().needToWaitForResult:
+ time.sleep(0.1)
+
+ if CuraApplication.getInstance().getMachineErrorChecker().hasError:
+ self.setResult(StartJobResult.SettingError)
+ return
+
# Don't slice if the buildplate or the nozzle type is incompatible with the materials
if not CuraApplication.getInstance().getMachineManager().variantBuildplateCompatible and \
not CuraApplication.getInstance().getMachineManager().variantBuildplateUsable:
@@ -150,7 +164,7 @@ class StartSliceJob(Job):
# Don't slice if there is a per object setting with an error value.
- for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+ for node in DepthFirstIterator(self._scene.getRoot()):
if not isinstance(node, CuraSceneNode) or not node.isSelectable():
continue
@@ -160,15 +174,16 @@ class StartSliceJob(Job):
with self._scene.getSceneLock():
# Remove old layer data.
- for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+ for node in DepthFirstIterator(self._scene.getRoot()):
if node.callDecoration("getLayerData") and node.callDecoration("getBuildPlateNumber") == self._build_plate_number:
- node.getParent().removeChild(node)
+ # Singe we walk through all nodes in the scene, they always have a parent.
+ cast(SceneNode, node.getParent()).removeChild(node)
break
# Get the objects in their groups to print.
object_groups = []
if stack.getProperty("print_sequence", "value") == "one_at_a_time":
- for node in OneAtATimeIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
+ for node in OneAtATimeIterator(self._scene.getRoot()):
temp_list = []
# Node can't be printed, so don't bother sending it.
@@ -183,7 +198,8 @@ class StartSliceJob(Job):
children = node.getAllChildren()
children.append(node)
for child_node in children:
- if child_node.getMeshData() and child_node.getMeshData().getVertices() is not None:
+ mesh_data = child_node.getMeshData()
+ if mesh_data and mesh_data.getVertices() is not None:
temp_list.append(child_node)
if temp_list:
@@ -194,12 +210,10 @@ class StartSliceJob(Job):
else:
temp_list = []
has_printing_mesh = False
- for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
- if node.callDecoration("isSliceable") and node.getMeshData() and node.getMeshData().getVertices() is not None:
- per_object_stack = node.callDecoration("getStack")
- is_non_printing_mesh = False
- if per_object_stack:
- is_non_printing_mesh = any(per_object_stack.getProperty(key, "value") for key in NON_PRINTING_MESH_SETTINGS)
+ for node in DepthFirstIterator(self._scene.getRoot()):
+ mesh_data = node.getMeshData()
+ if node.callDecoration("isSliceable") and mesh_data and mesh_data.getVertices() is not None:
+ is_non_printing_mesh = bool(node.callDecoration("isNonPrintingMesh"))
# Find a reason not to add the node
if node.callDecoration("getBuildPlateNumber") != self._build_plate_number:
@@ -213,7 +227,7 @@ class StartSliceJob(Job):
Job.yieldThread()
- #If the list doesn't have any model with suitable settings then clean the list
+ # If the list doesn't have any model with suitable settings then clean the list
# otherwise CuraEngine will crash
if not has_printing_mesh:
temp_list.clear()
@@ -259,18 +273,19 @@ class StartSliceJob(Job):
self._buildGlobalInheritsStackMessage(stack)
# Build messages for extruder stacks
- # Send the extruder settings in the order of extruder positions. Somehow, if you send e.g. extruder 3 first,
- # then CuraEngine can slice with the wrong settings. This I think should be fixed in CuraEngine as well.
- extruder_stack_list = sorted(list(global_stack.extruders.items()), key = lambda item: int(item[0]))
- for _, extruder_stack in extruder_stack_list:
+ for extruder_stack in global_stack.extruderList:
self._buildExtruderMessage(extruder_stack)
for group in filtered_object_groups:
group_message = self._slice_message.addRepeatedMessage("object_lists")
- if group[0].getParent() is not None and group[0].getParent().callDecoration("isGroup"):
- self._handlePerObjectSettings(group[0].getParent(), group_message)
+ parent = group[0].getParent()
+ if parent is not None and parent.callDecoration("isGroup"):
+ self._handlePerObjectSettings(cast(CuraSceneNode, parent), group_message)
+
for object in group:
mesh_data = object.getMeshData()
+ if mesh_data is None:
+ continue
rot_scale = object.getWorldTransformation().getTransposed().getData()[0:3, 0:3]
translate = object.getWorldTransformation().getData()[:3, 3]
@@ -294,7 +309,7 @@ class StartSliceJob(Job):
obj.vertices = flat_verts
- self._handlePerObjectSettings(object, obj)
+ self._handlePerObjectSettings(cast(CuraSceneNode, object), obj)
Job.yieldThread()
@@ -323,9 +338,10 @@ class StartSliceJob(Job):
value = stack.getProperty(key, "value")
result[key] = value
Job.yieldThread()
-
+
result["print_bed_temperature"] = result["material_bed_temperature"] # Renamed settings.
result["print_temperature"] = result["material_print_temperature"]
+ result["travel_speed"] = result["speed_travel"]
result["time"] = time.strftime("%H:%M:%S") #Some extra settings.
result["date"] = time.strftime("%d-%m-%Y")
result["day"] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][int(time.strftime("%w"))]
@@ -336,25 +352,29 @@ class StartSliceJob(Job):
return result
+ def _cacheAllExtruderSettings(self):
+ global_stack = cast(ContainerStack, CuraApplication.getInstance().getGlobalContainerStack())
+
+ # NB: keys must be strings for the string formatter
+ self._all_extruders_settings = {
+ "-1": self._buildReplacementTokens(global_stack)
+ }
+ for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
+ extruder_nr = extruder_stack.getProperty("extruder_nr", "value")
+ self._all_extruders_settings[str(extruder_nr)] = self._buildReplacementTokens(extruder_stack)
+
## Replace setting tokens in a piece of g-code.
# \param value A piece of g-code to replace tokens in.
# \param default_extruder_nr Stack nr to use when no stack nr is specified, defaults to the global stack
def _expandGcodeTokens(self, value: str, default_extruder_nr: int = -1) -> str:
if not self._all_extruders_settings:
- global_stack = cast(ContainerStack, CuraApplication.getInstance().getGlobalContainerStack())
-
- # NB: keys must be strings for the string formatter
- self._all_extruders_settings = {
- "-1": self._buildReplacementTokens(global_stack)
- }
-
- for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
- extruder_nr = extruder_stack.getProperty("extruder_nr", "value")
- self._all_extruders_settings[str(extruder_nr)] = self._buildReplacementTokens(extruder_stack)
+ self._cacheAllExtruderSettings()
try:
# any setting can be used as a token
fmt = GcodeStartEndFormatter(default_extruder_nr = default_extruder_nr)
+ if self._all_extruders_settings is None:
+ return ""
settings = self._all_extruders_settings.copy()
settings["default_extruder_nr"] = default_extruder_nr
return str(fmt.format(value, **settings))
@@ -366,8 +386,14 @@ class StartSliceJob(Job):
def _buildExtruderMessage(self, stack: ContainerStack) -> None:
message = self._slice_message.addRepeatedMessage("extruders")
message.id = int(stack.getMetaDataEntry("position"))
+ if not self._all_extruders_settings:
+ self._cacheAllExtruderSettings()
- settings = self._buildReplacementTokens(stack)
+ if self._all_extruders_settings is None:
+ return
+
+ extruder_nr = stack.getProperty("extruder_nr", "value")
+ settings = self._all_extruders_settings[str(extruder_nr)].copy()
# Also send the material GUID. This is a setting in fdmprinter, but we have no interface for it.
settings["material_guid"] = stack.material.getMetaDataEntry("GUID", "")
@@ -391,7 +417,13 @@ class StartSliceJob(Job):
# The settings are taken from the global stack. This does not include any
# per-extruder settings or per-object settings.
def _buildGlobalSettingsMessage(self, stack: ContainerStack) -> None:
- settings = self._buildReplacementTokens(stack)
+ if not self._all_extruders_settings:
+ self._cacheAllExtruderSettings()
+
+ if self._all_extruders_settings is None:
+ return
+
+ settings = self._all_extruders_settings["-1"].copy()
# Pre-compute material material_bed_temp_prepend and material_print_temp_prepend
start_gcode = settings["machine_start_gcode"]
diff --git a/plugins/CuraEngineBackend/plugin.json b/plugins/CuraEngineBackend/plugin.json
index 28f0e294e7..5482e3699e 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": "6.0",
+ "api": "7.0",
"version": "1.0.1",
"i18n-catalog": "cura"
}
diff --git a/plugins/CuraProfileReader/CuraProfileReader.py b/plugins/CuraProfileReader/CuraProfileReader.py
index 11e58dac6d..d4e5d393b2 100644
--- a/plugins/CuraProfileReader/CuraProfileReader.py
+++ b/plugins/CuraProfileReader/CuraProfileReader.py
@@ -1,11 +1,14 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-import configparser
-from UM.PluginRegistry import PluginRegistry
+import configparser
+from typing import List, Optional, Tuple
+
from UM.Logger import Logger
from UM.Settings.ContainerFormatError import ContainerFormatError
from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make.
+from cura.CuraApplication import CuraApplication
+from cura.Machines.ContainerTree import ContainerTree
from cura.ReaderWriters.ProfileReader import ProfileReader
import zipfile
@@ -17,39 +20,43 @@ import zipfile
class CuraProfileReader(ProfileReader):
## Initialises the cura profile reader.
# This does nothing since the only other function is basically stateless.
- def __init__(self):
+ def __init__(self) -> None:
super().__init__()
## Reads a cura profile from a file and returns it.
#
# \param file_name The file to read the cura profile from.
- # \return The cura profile that was in the file, if any. If the file could
- # not be read or didn't contain a valid profile, \code None \endcode is
+ # \return The cura profiles that were in the file, if any. If the file
+ # could not be read or didn't contain a valid profile, ``None`` is
# returned.
- def read(self, file_name):
+ def read(self, file_name: str) -> List[Optional[InstanceContainer]]:
try:
with zipfile.ZipFile(file_name, "r") as archive:
- results = []
+ results = [] # type: List[Optional[InstanceContainer]]
for profile_id in archive.namelist():
with archive.open(profile_id) as f:
serialized = f.read()
- profile = self._loadProfile(serialized.decode("utf-8"), profile_id)
- if profile is not None:
- results.append(profile)
+ upgraded_profiles = self._upgradeProfile(serialized.decode("utf-8"), profile_id) #After upgrading it may split into multiple profiles.
+ for upgraded_profile in upgraded_profiles:
+ serialization, new_id = upgraded_profile
+ profile = self._loadProfile(serialization, new_id)
+ if profile is not None:
+ results.append(profile)
return results
except zipfile.BadZipFile:
# It must be an older profile from Cura 2.1.
with open(file_name, encoding = "utf-8") as fhandle:
- serialized = fhandle.read()
- return [self._loadProfile(serialized, profile_id) for serialized, profile_id in self._upgradeProfile(serialized, file_name)]
+ serialized_bytes = fhandle.read()
+ return [self._loadProfile(serialized, profile_id) for serialized, profile_id in self._upgradeProfile(serialized_bytes, file_name)]
## Convert a profile from an old Cura to this Cura if needed.
#
- # \param serialized \type{str} The profile data to convert in the serialized on-disk format.
- # \param profile_id \type{str} The name of the profile.
- # \return \type{List[Tuple[str,str]]} List of serialized profile strings and matching profile names.
- def _upgradeProfile(self, serialized, profile_id):
+ # \param serialized The profile data to convert in the serialized on-disk
+ # format.
+ # \param profile_id The name of the profile.
+ # \return List of serialized profile strings and matching profile names.
+ def _upgradeProfile(self, serialized: str, profile_id: str) -> List[Tuple[str, str]]:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized)
@@ -61,48 +68,67 @@ class CuraProfileReader(ProfileReader):
return []
version = int(parser["general"]["version"])
+ setting_version = int(parser["metadata"].get("setting_version", "0"))
if InstanceContainer.Version != version:
name = parser["general"]["name"]
- return self._upgradeProfileVersion(serialized, name, version)
+ return self._upgradeProfileVersion(serialized, name, version, setting_version)
else:
return [(serialized, profile_id)]
## Load a profile from a serialized string.
#
- # \param serialized \type{str} The profile data to read.
- # \param profile_id \type{str} The name of the profile.
- # \return \type{InstanceContainer|None}
- def _loadProfile(self, serialized, profile_id):
+ # \param serialized The profile data to read.
+ # \param profile_id The name of the profile.
+ # \return The profile that was stored in the string.
+ def _loadProfile(self, serialized: str, profile_id: str) -> Optional[InstanceContainer]:
# Create an empty profile.
profile = InstanceContainer(profile_id)
profile.setMetaDataEntry("type", "quality_changes")
try:
- profile.deserialize(serialized)
+ profile.deserialize(serialized, file_name = profile_id)
except ContainerFormatError as e:
Logger.log("e", "Error in the format of a container: %s", str(e))
return None
except Exception as e:
Logger.log("e", "Error while trying to parse profile: %s", str(e))
return None
+
+ global_stack = CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return None
+
+ active_quality_definition = ContainerTree.getInstance().machines[global_stack.definition.getId()].quality_definition
+ if profile.getMetaDataEntry("definition") != active_quality_definition:
+ profile.setMetaDataEntry("definition", active_quality_definition)
return profile
## Upgrade a serialized profile to the current profile format.
#
- # \param serialized \type{str} The profile data to convert.
- # \param profile_id \type{str} The name of the profile.
- # \param source_version \type{int} The profile version of 'serialized'.
- # \return \type{List[Tuple[str,str]]} List of serialized profile strings and matching profile names.
- def _upgradeProfileVersion(self, serialized, profile_id, source_version):
- converter_plugins = PluginRegistry.getInstance().getAllMetaData(filter={"version_upgrade": {} }, active_only=True)
+ # \param serialized The profile data to convert.
+ # \param profile_id The name of the profile.
+ # \param source_version The profile version of 'serialized'.
+ # \return List of serialized profile strings and matching profile names.
+ def _upgradeProfileVersion(self, serialized: str, profile_id: str, main_version: int, setting_version: int) -> List[Tuple[str, str]]:
+ source_version = main_version * 1000000 + setting_version
- source_format = ("profile", source_version)
- profile_convert_funcs = [plugin["version_upgrade"][source_format][2] for plugin in converter_plugins
- if source_format in plugin["version_upgrade"] and plugin["version_upgrade"][source_format][1] == InstanceContainer.Version]
-
- if not profile_convert_funcs:
+ from UM.VersionUpgradeManager import VersionUpgradeManager
+ results = VersionUpgradeManager.getInstance().updateFilesData("quality_changes", source_version, [serialized], [profile_id])
+ if results is None:
return []
- filenames, outputs = profile_convert_funcs[0](serialized, profile_id)
- if filenames is None and outputs is None:
+ serialized = results.files_data[0]
+
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+ if "general" not in parser:
+ Logger.log("w", "Missing required section 'general'.")
return []
- return list(zip(outputs, filenames))
+
+ new_source_version = results.version
+ if int(new_source_version / 1000000) != InstanceContainer.Version or new_source_version % 1000000 != CuraApplication.SettingVersion:
+ Logger.log("e", "Failed to upgrade profile [%s]", profile_id)
+
+ if int(parser["general"]["version"]) != InstanceContainer.Version:
+ Logger.log("e", "Failed to upgrade profile [%s]", profile_id)
+ return []
+ return [(serialized, profile_id)]
diff --git a/plugins/CuraProfileReader/plugin.json b/plugins/CuraProfileReader/plugin.json
index 169fb43360..e1309b2d46 100644
--- a/plugins/CuraProfileReader/plugin.json
+++ b/plugins/CuraProfileReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for importing Cura profiles.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/CuraProfileWriter/plugin.json b/plugins/CuraProfileWriter/plugin.json
index 9627c754d7..180376f266 100644
--- a/plugins/CuraProfileWriter/plugin.json
+++ b/plugins/CuraProfileWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for exporting Cura profiles.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog":"cura"
}
diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py
index a1460cca3f..f286662bc4 100644
--- a/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py
+++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py
@@ -10,6 +10,9 @@ from UM.Version import Version
import urllib.request
from urllib.error import URLError
from typing import Dict, Optional
+import ssl
+
+import certifi
from .FirmwareUpdateCheckerLookup import FirmwareUpdateCheckerLookup, getSettingsKeyForMachine
from .FirmwareUpdateCheckerMessage import FirmwareUpdateCheckerMessage
@@ -39,8 +42,12 @@ class FirmwareUpdateCheckerJob(Job):
result = self.STRING_ZERO_VERSION
try:
+ # CURA-6698 Create an SSL context and use certifi CA certificates for verification.
+ context = ssl.SSLContext(protocol = ssl.PROTOCOL_TLSv1_2)
+ context.load_verify_locations(cafile = certifi.where())
+
request = urllib.request.Request(url, headers = self._headers)
- response = urllib.request.urlopen(request)
+ response = urllib.request.urlopen(request, context = context)
result = response.read().decode("utf-8")
except URLError:
Logger.log("w", "Could not reach '{0}', if this URL is old, consider removal.".format(url))
@@ -104,7 +111,7 @@ class FirmwareUpdateCheckerJob(Job):
# because the new version of Cura will be release before the firmware and we don't want to
# notify the user when no new firmware version is available.
if (checked_version != "") and (checked_version != current_version):
- Logger.log("i", "SHOWING FIRMWARE UPDATE MESSAGE")
+ Logger.log("i", "Showing firmware update message for new version: {version}".format(version = current_version))
message = FirmwareUpdateCheckerMessage(machine_id, self._machine_name,
self._lookups.getRedirectUserUrl())
message.actionTriggered.connect(self._callback)
@@ -113,7 +120,7 @@ class FirmwareUpdateCheckerJob(Job):
Logger.log("i", "No machine with name {0} in list of firmware to check.".format(self._machine_name))
except Exception as e:
- Logger.log("w", "Failed to check for new version: %s", e)
+ Logger.logException("w", "Failed to check for new version: %s", e)
if not self.silent:
Message(i18n_catalog.i18nc("@info", "Could not access update information.")).show()
return
diff --git a/plugins/FirmwareUpdateChecker/plugin.json b/plugins/FirmwareUpdateChecker/plugin.json
index 6c55d77fd8..34e26fb146 100644
--- a/plugins/FirmwareUpdateChecker/plugin.json
+++ b/plugins/FirmwareUpdateChecker/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Checks for firmware updates.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/FirmwareUpdater/plugin.json b/plugins/FirmwareUpdater/plugin.json
index c1034e5e42..2546263064 100644
--- a/plugins/FirmwareUpdater/plugin.json
+++ b/plugins/FirmwareUpdater/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides a machine actions for updating firmware.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeGzReader/GCodeGzReader.py b/plugins/GCodeGzReader/GCodeGzReader.py
index d075e4e3b0..a528b494e9 100644
--- a/plugins/GCodeGzReader/GCodeGzReader.py
+++ b/plugins/GCodeGzReader/GCodeGzReader.py
@@ -27,6 +27,6 @@ class GCodeGzReader(MeshReader):
file_data = file.read()
uncompressed_gcode = gzip.decompress(file_data).decode("utf-8")
PluginRegistry.getInstance().getPluginObject("GCodeReader").preReadFromStream(uncompressed_gcode)
- result = PluginRegistry.getInstance().getPluginObject("GCodeReader").readFromStream(uncompressed_gcode)
+ result = PluginRegistry.getInstance().getPluginObject("GCodeReader").readFromStream(uncompressed_gcode, file_name)
return result
diff --git a/plugins/GCodeGzReader/plugin.json b/plugins/GCodeGzReader/plugin.json
index d4f281682f..b3d52b1627 100644
--- a/plugins/GCodeGzReader/plugin.json
+++ b/plugins/GCodeGzReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Reads g-code from a compressed archive.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeGzWriter/plugin.json b/plugins/GCodeGzWriter/plugin.json
index b0e6f8d605..de59d1eda8 100644
--- a/plugins/GCodeGzWriter/plugin.json
+++ b/plugins/GCodeGzWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Writes g-code to a compressed archive.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeProfileReader/plugin.json b/plugins/GCodeProfileReader/plugin.json
index af1c2d1827..162c31ce35 100644
--- a/plugins/GCodeProfileReader/plugin.json
+++ b/plugins/GCodeProfileReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for importing profiles from g-code files.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeReader/FlavorParser.py b/plugins/GCodeReader/FlavorParser.py
index f8618712a1..d05338ae4d 100644
--- a/plugins/GCodeReader/FlavorParser.py
+++ b/plugins/GCodeReader/FlavorParser.py
@@ -1,31 +1,33 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+import math
+import re
+from typing import Dict, List, NamedTuple, Optional, Union, Set
+
+import numpy
+
from UM.Backend import Backend
from UM.Job import Job
from UM.Logger import Logger
from UM.Math.Vector import Vector
from UM.Message import Message
-from cura.Scene.CuraSceneNode import CuraSceneNode
from UM.i18n import i18nCatalog
-catalog = i18nCatalog("cura")
-
from cura.CuraApplication import CuraApplication
from cura.LayerDataBuilder import LayerDataBuilder
from cura.LayerDataDecorator import LayerDataDecorator
from cura.LayerPolygon import LayerPolygon
+from cura.Scene.CuraSceneNode import CuraSceneNode
from cura.Scene.GCodeListDecorator import GCodeListDecorator
from cura.Settings.ExtruderManager import ExtruderManager
-import numpy
-import math
-import re
-from typing import Dict, List, NamedTuple, Optional, Union
+catalog = i18nCatalog("cura")
PositionOptional = NamedTuple("Position", [("x", Optional[float]), ("y", Optional[float]), ("z", Optional[float]), ("f", Optional[float]), ("e", Optional[float])])
Position = NamedTuple("Position", [("x", float), ("y", float), ("z", float), ("f", float), ("e", List[float])])
+
## This parser is intended to interpret the common firmware codes among all the
# different flavors
class FlavorParser:
@@ -33,9 +35,11 @@ class FlavorParser:
def __init__(self) -> None:
CuraApplication.getInstance().hideMessageSignal.connect(self._onHideMessage)
self._cancelled = False
- self._message = None
+ self._message = None # type: Optional[Message]
self._layer_number = 0
self._extruder_number = 0
+ # All extruder numbers that have been seen
+ self._extruders_seen = {0} # type: Set[int]
self._clearValues()
self._scene_node = None
# X, Y, Z position, F feedrate and E extruder values are stored
@@ -64,7 +68,7 @@ class FlavorParser:
if n < 0:
return None
n += len(code)
- pattern = re.compile("[;\s]")
+ pattern = re.compile("[;\\s]")
match = pattern.search(line, n)
m = match.start() if match is not None else -1
try:
@@ -290,7 +294,12 @@ class FlavorParser:
extruder.getProperty("machine_nozzle_offset_y", "value")]
return result
- def processGCodeStream(self, stream: str) -> Optional[CuraSceneNode]:
+ #
+ # CURA-6643
+ # This function needs the filename so it can be set to the SceneNode. Otherwise, if you load a GCode file and press
+ # F5, that gcode SceneNode will be removed because it doesn't have a file to be reloaded from.
+ #
+ def processGCodeStream(self, stream: str, filename: str) -> Optional["CuraSceneNode"]:
Logger.log("d", "Preparing to load GCode")
self._cancelled = False
# We obtain the filament diameter from the selected extruder to calculate line widths
@@ -368,6 +377,8 @@ class FlavorParser:
self._layer_type = LayerPolygon.InfillType
elif type == "SUPPORT-INTERFACE":
self._layer_type = LayerPolygon.SupportInterfaceType
+ elif type == "PRIME-TOWER":
+ self._layer_type = LayerPolygon.PrimeTowerType
else:
Logger.log("w", "Encountered a unknown type (%s) while parsing g-code.", type)
@@ -414,6 +425,7 @@ class FlavorParser:
if line.startswith("T"):
T = self._getInt(line, "T")
if T is not None:
+ self._extruders_seen.add(T)
self._createPolygon(self._current_layer_thickness, current_path, self._extruder_offsets.get(self._extruder_number, [0, 0]))
current_path.clear()
@@ -425,7 +437,8 @@ class FlavorParser:
if line.startswith("M"):
M = self._getInt(line, "M")
- self.processMCode(M, line, current_position, current_path)
+ if M is not None:
+ self.processMCode(M, line, current_position, current_path)
# "Flush" leftovers. Last layer paths are still stored
if len(current_path) > 1:
@@ -448,6 +461,7 @@ class FlavorParser:
scene_node.addDecorator(decorator)
gcode_list_decorator = GCodeListDecorator()
+ gcode_list_decorator.setGcodeFileName(filename)
gcode_list_decorator.setGCodeList(gcode_list)
scene_node.addDecorator(gcode_list_decorator)
@@ -462,10 +476,9 @@ class FlavorParser:
if self._layer_number == 0:
Logger.log("w", "File doesn't contain any valid layers")
- settings = CuraApplication.getInstance().getGlobalContainerStack()
- if not settings.getProperty("machine_center_is_zero", "value"):
- machine_width = settings.getProperty("machine_width", "value")
- machine_depth = settings.getProperty("machine_depth", "value")
+ if not global_stack.getProperty("machine_center_is_zero", "value"):
+ machine_width = global_stack.getProperty("machine_width", "value")
+ machine_depth = global_stack.getProperty("machine_depth", "value")
scene_node.setPosition(Vector(-machine_width / 2, 0, machine_depth / 2))
Logger.log("d", "GCode loading finished")
diff --git a/plugins/GCodeReader/GCodeReader.py b/plugins/GCodeReader/GCodeReader.py
index 1bc22a3e62..21be026cc6 100755
--- a/plugins/GCodeReader/GCodeReader.py
+++ b/plugins/GCodeReader/GCodeReader.py
@@ -2,6 +2,8 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+from typing import Optional, Union, List, TYPE_CHECKING
+
from UM.FileHandler.FileReader import FileReader
from UM.Mesh.MeshReader import MeshReader
from UM.i18n import i18nCatalog
@@ -9,10 +11,13 @@ from UM.Application import Application
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType
catalog = i18nCatalog("cura")
+
+from .FlavorParser import FlavorParser
from . import MarlinFlavorParser, RepRapFlavorParser
-
-
+if TYPE_CHECKING:
+ from UM.Scene.SceneNode import SceneNode
+ from cura.Scene.CuraSceneNode import CuraSceneNode
# Class for loading and parsing G-code files
@@ -33,7 +38,7 @@ class GCodeReader(MeshReader):
)
self._supported_extensions = [".gcode", ".g"]
- self._flavor_reader = None
+ self._flavor_reader = None # type: Optional[FlavorParser]
Application.getInstance().getPreferences().addPreference("gcodereader/show_caution", True)
@@ -57,10 +62,16 @@ class GCodeReader(MeshReader):
file_data = file.read()
return self.preReadFromStream(file_data, args, kwargs)
- def readFromStream(self, stream):
- return self._flavor_reader.processGCodeStream(stream)
+ def readFromStream(self, stream: str, filename: str) -> Optional["CuraSceneNode"]:
+ if self._flavor_reader is None:
+ return None
+ return self._flavor_reader.processGCodeStream(stream, filename)
- def _read(self, file_name):
+ def _read(self, file_name: str) -> Union["SceneNode", List["SceneNode"]]:
with open(file_name, "r", encoding = "utf-8") as file:
file_data = file.read()
- return self.readFromStream(file_data)
+ result = [] # type: List[SceneNode]
+ node = self.readFromStream(file_data, file_name)
+ if node is not None:
+ result.append(node)
+ return result
diff --git a/plugins/GCodeReader/plugin.json b/plugins/GCodeReader/plugin.json
index bbc94fa917..e34fefbdff 100644
--- a/plugins/GCodeReader/plugin.json
+++ b/plugins/GCodeReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Victor Larchenko, Ultimaker",
"version": "1.0.1",
"description": "Allows loading and displaying G-code files.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py
index 3e5bf59e73..792b2aff10 100644
--- a/plugins/GCodeWriter/GCodeWriter.py
+++ b/plugins/GCodeWriter/GCodeWriter.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2017 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import re # For escaping characters in the settings.
@@ -9,8 +9,7 @@ from UM.Mesh.MeshWriter import MeshWriter
from UM.Logger import Logger
from UM.Application import Application
from UM.Settings.InstanceContainer import InstanceContainer
-
-from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
+from cura.Machines.ContainerTree import ContainerTree
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
@@ -117,17 +116,24 @@ class GCodeWriter(MeshWriter):
# \return A serialised string of the settings.
def _serialiseSettings(self, stack):
container_registry = self._application.getContainerRegistry()
- quality_manager = self._application.getQualityManager()
prefix = self._setting_keyword + str(GCodeWriter.version) + " " # The prefix to put before each line.
prefix_length = len(prefix)
quality_type = stack.quality.getMetaDataEntry("quality_type")
container_with_profile = stack.qualityChanges
+ machine_definition_id_for_quality = ContainerTree.getInstance().machines[stack.definition.getId()].quality_definition
if container_with_profile.getId() == "empty_quality_changes":
# If the global quality changes is empty, create a new one
quality_name = container_registry.uniqueName(stack.quality.getName())
- container_with_profile = quality_manager._createQualityChanges(quality_type, quality_name, stack, None)
+ quality_id = container_registry.uniqueName((stack.definition.getId() + "_" + quality_name).lower().replace(" ", "_"))
+ container_with_profile = InstanceContainer(quality_id)
+ container_with_profile.setName(quality_name)
+ container_with_profile.setMetaDataEntry("type", "quality_changes")
+ container_with_profile.setMetaDataEntry("quality_type", quality_type)
+ if stack.getMetaDataEntry("position") is not None: # For extruder stacks, the quality changes should include an intent category.
+ container_with_profile.setMetaDataEntry("intent_category", stack.intent.getMetaDataEntry("intent_category", "default"))
+ container_with_profile.setDefinition(machine_definition_id_for_quality)
flat_global_container = self._createFlattenedContainerInstance(stack.userChanges, container_with_profile)
# If the quality changes is not set, we need to set type manually
@@ -139,7 +145,6 @@ class GCodeWriter(MeshWriter):
flat_global_container.setMetaDataEntry("quality_type", stack.quality.getMetaDataEntry("quality_type", "normal"))
# Get the machine definition ID for quality profiles
- machine_definition_id_for_quality = getMachineDefinitionIDForQualitySearch(stack.definition)
flat_global_container.setMetaDataEntry("definition", machine_definition_id_for_quality)
serialized = flat_global_container.serialize()
@@ -151,7 +156,12 @@ class GCodeWriter(MeshWriter):
if extruder_quality.getId() == "empty_quality_changes":
# Same story, if quality changes is empty, create a new one
quality_name = container_registry.uniqueName(stack.quality.getName())
- extruder_quality = quality_manager._createQualityChanges(quality_type, quality_name, stack, None)
+ quality_id = container_registry.uniqueName((stack.definition.getId() + "_" + quality_name).lower().replace(" ", "_"))
+ extruder_quality = InstanceContainer(quality_id)
+ extruder_quality.setName(quality_name)
+ extruder_quality.setMetaDataEntry("type", "quality_changes")
+ extruder_quality.setMetaDataEntry("quality_type", quality_type)
+ extruder_quality.setDefinition(machine_definition_id_for_quality)
flat_extruder_quality = self._createFlattenedContainerInstance(extruder.userChanges, extruder_quality)
# If the quality changes is not set, we need to set type manually
diff --git a/plugins/GCodeWriter/plugin.json b/plugins/GCodeWriter/plugin.json
index f3a95ddb78..457652bf3f 100644
--- a/plugins/GCodeWriter/plugin.json
+++ b/plugins/GCodeWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Writes g-code to a file.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/ImageReader/ConfigUI.qml b/plugins/ImageReader/ConfigUI.qml
index b9ff2e4453..0429fae4e1 100644
--- a/plugins/ImageReader/ConfigUI.qml
+++ b/plugins/ImageReader/ConfigUI.qml
@@ -123,7 +123,7 @@ UM.Dialog
UM.TooltipArea {
Layout.fillWidth:true
height: childrenRect.height
- text: catalog.i18nc("@info:tooltip","By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh.")
+ text: catalog.i18nc("@info:tooltip","For lithophanes dark pixels should correspond to thicker locations in order to block more light coming through. For height maps lighter pixels signify higher terrain, so lighter pixels should correspond to thicker locations in the generated 3D model.")
Row {
width: parent.width
@@ -134,15 +134,61 @@ UM.Dialog
anchors.verticalCenter: parent.verticalCenter
}
ComboBox {
- id: image_color_invert
- objectName: "Image_Color_Invert"
- model: [ catalog.i18nc("@item:inlistbox","Lighter is higher"), catalog.i18nc("@item:inlistbox","Darker is higher") ]
+ id: lighter_is_higher
+ objectName: "Lighter_Is_Higher"
+ model: [ catalog.i18nc("@item:inlistbox","Darker is higher"), catalog.i18nc("@item:inlistbox","Lighter is higher") ]
width: 180 * screenScaleFactor
onCurrentIndexChanged: { manager.onImageColorInvertChanged(currentIndex) }
}
}
}
+ UM.TooltipArea {
+ Layout.fillWidth:true
+ height: childrenRect.height
+ text: catalog.i18nc("@info:tooltip","For lithophanes a simple logarithmic model for translucency is available. For height maps the pixel values correspond to heights linearly.")
+ Row {
+ width: parent.width
+
+ Label {
+ text: "Color Model"
+ width: 150 * screenScaleFactor
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ ComboBox {
+ id: color_model
+ objectName: "ColorModel"
+ model: [ catalog.i18nc("@item:inlistbox","Linear"), catalog.i18nc("@item:inlistbox","Translucency") ]
+ width: 180 * screenScaleFactor
+ onCurrentIndexChanged: { manager.onColorModelChanged(currentIndex) }
+ }
+ }
+ }
+
+ UM.TooltipArea {
+ Layout.fillWidth:true
+ height: childrenRect.height
+ text: catalog.i18nc("@info:tooltip","The percentage of light penetrating a print with a thickness of 1 millimeter. Lowering this value increases the contrast in dark regions and decreases the contrast in light regions of the image.")
+ visible: color_model.currentText == catalog.i18nc("@item:inlistbox","Translucency")
+ Row {
+ width: parent.width
+
+ Label {
+ text: catalog.i18nc("@action:label", "1mm Transmittance (%)")
+ width: 150 * screenScaleFactor
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ TextField {
+ id: transmittance
+ objectName: "Transmittance"
+ focus: true
+ validator: RegExpValidator {regExp: /^[1-9]\d{0,2}([\,|\.]\d*)?$/}
+ width: 180 * screenScaleFactor
+ onTextChanged: { manager.onTransmittanceChanged(text) }
+ }
+ }
+ }
+
UM.TooltipArea {
Layout.fillWidth:true
height: childrenRect.height
diff --git a/plugins/ImageReader/ImageReader.py b/plugins/ImageReader/ImageReader.py
index 5195b61595..d6c2827d16 100644
--- a/plugins/ImageReader/ImageReader.py
+++ b/plugins/ImageReader/ImageReader.py
@@ -3,6 +3,8 @@
import numpy
+import math
+
from PyQt5.QtGui import QImage, qRed, qGreen, qBlue
from PyQt5.QtCore import Qt
@@ -46,9 +48,9 @@ class ImageReader(MeshReader):
def _read(self, file_name):
size = max(self._ui.getWidth(), self._ui.getDepth())
- return self._generateSceneNode(file_name, size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512, self._ui.image_color_invert)
+ return self._generateSceneNode(file_name, size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512, self._ui.lighter_is_higher, self._ui.use_transparency_model, self._ui.transmittance_1mm)
- def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size, image_color_invert):
+ def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size, lighter_is_higher, use_transparency_model, transmittance_1mm):
scene_node = SceneNode()
mesh = MeshBuilder()
@@ -99,12 +101,14 @@ class ImageReader(MeshReader):
for x in range(0, width):
for y in range(0, height):
qrgb = img.pixel(x, y)
- avg = float(qRed(qrgb) + qGreen(qrgb) + qBlue(qrgb)) / (3 * 255)
- height_data[y, x] = avg
+ if use_transparency_model:
+ height_data[y, x] = (0.299 * math.pow(qRed(qrgb) / 255.0, 2.2) + 0.587 * math.pow(qGreen(qrgb) / 255.0, 2.2) + 0.114 * math.pow(qBlue(qrgb) / 255.0, 2.2))
+ else:
+ height_data[y, x] = (0.212655 * qRed(qrgb) + 0.715158 * qGreen(qrgb) + 0.072187 * qBlue(qrgb)) / 255 # fast computation ignoring gamma and degamma
Job.yieldThread()
- if image_color_invert:
+ if lighter_is_higher == use_transparency_model:
height_data = 1 - height_data
for _ in range(0, blur_iterations):
@@ -124,8 +128,15 @@ class ImageReader(MeshReader):
Job.yieldThread()
- height_data *= scale_vector.y
- height_data += base_height
+ if use_transparency_model:
+ divisor = 1.0 / math.log(transmittance_1mm / 100.0) # log-base doesn't matter here. Precompute this value for faster computation of each pixel.
+ min_luminance = (transmittance_1mm / 100.0) ** (peak_height - base_height)
+ for (y, x) in numpy.ndindex(height_data.shape):
+ mapped_luminance = min_luminance + (1.0 - min_luminance) * height_data[y, x]
+ height_data[y, x] = base_height + divisor * math.log(mapped_luminance) # use same base as a couple lines above this
+ else:
+ height_data *= scale_vector.y
+ height_data += base_height
heightmap_face_count = 2 * height_minus_one * width_minus_one
total_face_count = heightmap_face_count + (width_minus_one * 2) * (height_minus_one * 2) + 2
diff --git a/plugins/ImageReader/ImageReaderUI.py b/plugins/ImageReader/ImageReaderUI.py
index cb45afa4ad..a61fabb742 100644
--- a/plugins/ImageReader/ImageReaderUI.py
+++ b/plugins/ImageReader/ImageReaderUI.py
@@ -30,10 +30,12 @@ class ImageReaderUI(QObject):
self._width = self.default_width
self._depth = self.default_depth
- self.base_height = 1
- self.peak_height = 10
+ self.base_height = 0.4
+ self.peak_height = 2.5
self.smoothing = 1
- self.image_color_invert = False;
+ self.lighter_is_higher = False;
+ self.use_transparency_model = True;
+ self.transmittance_1mm = 50.0; # based on pearl PLA
self._ui_lock = threading.Lock()
self._cancelled = False
@@ -75,6 +77,7 @@ class ImageReaderUI(QObject):
self._ui_view.findChild(QObject, "Base_Height").setProperty("text", str(self.base_height))
self._ui_view.findChild(QObject, "Peak_Height").setProperty("text", str(self.peak_height))
+ self._ui_view.findChild(QObject, "Transmittance").setProperty("text", str(self.transmittance_1mm))
self._ui_view.findChild(QObject, "Smoothing").setProperty("value", self.smoothing)
def _createConfigUI(self):
@@ -143,4 +146,12 @@ class ImageReaderUI(QObject):
@pyqtSlot(int)
def onImageColorInvertChanged(self, value):
- self.image_color_invert = (value == 1)
+ self.lighter_is_higher = (value == 1)
+
+ @pyqtSlot(int)
+ def onColorModelChanged(self, value):
+ self.use_transparency_model = (value == 0)
+
+ @pyqtSlot(int)
+ def onTransmittanceChanged(self, value):
+ self.transmittance_1mm = value
diff --git a/plugins/ImageReader/plugin.json b/plugins/ImageReader/plugin.json
index d966537d99..a5f03a540d 100644
--- a/plugins/ImageReader/plugin.json
+++ b/plugins/ImageReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Enables ability to generate printable geometry from 2D image files.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py
index 013bab6f11..87b26eb4ec 100644
--- a/plugins/LegacyProfileReader/LegacyProfileReader.py
+++ b/plugins/LegacyProfileReader/LegacyProfileReader.py
@@ -157,7 +157,7 @@ class LegacyProfileReader(ProfileReader):
data = stream.getvalue()
profile = InstanceContainer(profile_id)
- profile.deserialize(data) # Also performs the version upgrade.
+ profile.deserialize(data, file_name) # Also performs the version upgrade.
profile.setDirty(True)
#We need to return one extruder stack and one global stack.
diff --git a/plugins/LegacyProfileReader/plugin.json b/plugins/LegacyProfileReader/plugin.json
index 2f5264ad37..f4f18becbf 100644
--- a/plugins/LegacyProfileReader/plugin.json
+++ b/plugins/LegacyProfileReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for importing profiles from legacy Cura versions.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py
index 480a61f301..cd0f681828 100644
--- a/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py
+++ b/plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py
@@ -5,6 +5,8 @@ import configparser # An input for some functions we're testing.
import os.path # To find the integration test .ini files.
import pytest # To register tests with.
import unittest.mock # To mock the application, plug-in and container registry out.
+import sys
+sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
import UM.Application # To mock the application out.
import UM.PluginRegistry # To mock the plug-in registry out.
@@ -12,11 +14,14 @@ import UM.Settings.ContainerRegistry # To mock the container registry out.
import UM.Settings.InstanceContainer # To intercept the serialised data from the read() function.
import LegacyProfileReader as LegacyProfileReaderModule # To get the directory of the module.
-from LegacyProfileReader import LegacyProfileReader # The module we're testing.
+
@pytest.fixture
def legacy_profile_reader():
- return LegacyProfileReader()
+ try:
+ return LegacyProfileReaderModule.LegacyProfileReader()
+ except TypeError:
+ return LegacyProfileReaderModule.LegacyProfileReader.LegacyProfileReader()
test_prepareDefaultsData = [
{
@@ -157,7 +162,7 @@ def test_read(legacy_profile_reader, file_name):
plugin_registry.getPluginPath = unittest.mock.MagicMock(return_value = os.path.dirname(LegacyProfileReaderModule.__file__))
# Mock out the resulting InstanceContainer so that we can intercept the data before it's passed through the version upgrader.
- def deserialize(self, data): # Intercepts the serialised data that we'd perform the version upgrade from when deserializing.
+ def deserialize(self, data, filename): # Intercepts the serialised data that we'd perform the version upgrade from when deserializing.
global intercepted_data
intercepted_data = data
@@ -187,4 +192,4 @@ def test_read(legacy_profile_reader, file_name):
assert parser["metadata"]["type"] == "quality_changes"
assert parser["metadata"]["quality_type"] == "normal"
assert parser["metadata"]["position"] == "0"
- assert parser["metadata"]["setting_version"] == "5" # Yes, before we upgraded.
\ No newline at end of file
+ assert parser["metadata"]["setting_version"] == "5" # Yes, before we upgraded.
diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py
index afd7aac86d..28535024a7 100755
--- a/plugins/MachineSettingsAction/MachineSettingsAction.py
+++ b/plugins/MachineSettingsAction/MachineSettingsAction.py
@@ -1,16 +1,24 @@
-# Copyright (c) 2017 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from PyQt5.QtCore import pyqtProperty, pyqtSignal
+from typing import Optional, TYPE_CHECKING
+
+from PyQt5.QtCore import pyqtProperty
import UM.i18n
from UM.FlameProfiler import pyqtSlot
-from UM.Application import Application
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.DefinitionContainer import DefinitionContainer
+from UM.Util import parseBool
+import cura.CuraApplication # Imported like this to prevent circular dependencies.
from cura.MachineAction import MachineAction
+from cura.Machines.ContainerTree import ContainerTree # To re-build the machine node when hasMaterials changes.
from cura.Settings.CuraStackBuilder import CuraStackBuilder
+from cura.Settings.cura_empty_instance_containers import isEmptyContainer
+
+if TYPE_CHECKING:
+ from PyQt5.QtCore import QObject
catalog = UM.i18n.i18nCatalog("cura")
@@ -18,139 +26,118 @@ catalog = UM.i18n.i18nCatalog("cura")
## This action allows for certain settings that are "machine only") to be modified.
# It automatically detects machine definitions that it knows how to change and attaches itself to those.
class MachineSettingsAction(MachineAction):
- def __init__(self, parent = None):
+ def __init__(self, parent: Optional["QObject"] = None) -> None:
super().__init__("MachineSettingsAction", catalog.i18nc("@action", "Machine Settings"))
self._qml_url = "MachineSettingsAction.qml"
- self._application = Application.getInstance()
-
- self._global_container_stack = None
+ from cura.CuraApplication import CuraApplication
+ self._application = CuraApplication.getInstance()
from cura.Settings.CuraContainerStack import _ContainerIndexes
- self._container_index = _ContainerIndexes.DefinitionChanges
+ self._store_container_index = _ContainerIndexes.DefinitionChanges
self._container_registry = ContainerRegistry.getInstance()
self._container_registry.containerAdded.connect(self._onContainerAdded)
- self._container_registry.containerRemoved.connect(self._onContainerRemoved)
- self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
+ # The machine settings dialog blocks auto-slicing when it's shown, and re-enables it when it's finished.
self._backend = self._application.getBackend()
+ self.onFinished.connect(self._onFinished)
- self._empty_definition_container_id_list = []
+ # If the g-code flavour changes between UltiGCode and another flavour, we need to update the container tree.
+ self._application.globalContainerStackChanged.connect(self._updateHasMaterialsInContainerTree)
- def _isEmptyDefinitionChanges(self, container_id: str):
- if not self._empty_definition_container_id_list:
- self._empty_definition_container_id_list = [self._application.empty_container.getId(),
- self._application.empty_definition_changes_container.getId()]
- return container_id in self._empty_definition_container_id_list
+ # Which container index in a stack to store machine setting changes.
+ @pyqtProperty(int, constant = True)
+ def storeContainerIndex(self) -> int:
+ return self._store_container_index
def _onContainerAdded(self, container):
# Add this action as a supported action to all machine definitions
if isinstance(container, DefinitionContainer) and container.getMetaDataEntry("type") == "machine":
self._application.getMachineActionManager().addSupportedAction(container.getId(), self.getKey())
- def _onContainerRemoved(self, container):
- # Remove definition_changes containers when a stack is removed
- if container.getMetaDataEntry("type") in ["machine", "extruder_train"]:
- definition_changes_id = container.definitionChanges.getId()
- if self._isEmptyDefinitionChanges(definition_changes_id):
- return
+ ## Triggered when the global container stack changes or when the g-code
+ # flavour setting is changed.
+ def _updateHasMaterialsInContainerTree(self) -> None:
+ global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
+ if global_stack is None:
+ return
+ machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
+
+ if machine_node.has_materials != parseBool(global_stack.getMetaDataEntry("has_materials")): # May have changed due to the g-code flavour.
+ machine_node.has_materials = parseBool(global_stack.getMetaDataEntry("has_materials"))
+ machine_node._loadAll()
def _reset(self):
- if not self._global_container_stack:
+ global_stack = self._application.getMachineManager().activeMachine
+ if not global_stack:
return
# Make sure there is a definition_changes container to store the machine settings
- definition_changes_id = self._global_container_stack.definitionChanges.getId()
- if self._isEmptyDefinitionChanges(definition_changes_id):
- CuraStackBuilder.createDefinitionChangesContainer(self._global_container_stack,
- self._global_container_stack.getName() + "_settings")
-
- # Notify the UI in which container to store the machine settings data
- from cura.Settings.CuraContainerStack import _ContainerIndexes
-
- container_index = _ContainerIndexes.DefinitionChanges
- if container_index != self._container_index:
- self._container_index = container_index
- self.containerIndexChanged.emit()
+ definition_changes_id = global_stack.definitionChanges.getId()
+ if isEmptyContainer(definition_changes_id):
+ CuraStackBuilder.createDefinitionChangesContainer(global_stack,
+ global_stack.getName() + "_settings")
# Disable auto-slicing while the MachineAction is showing
if self._backend: # This sometimes triggers before backend is loaded.
self._backend.disableTimer()
- @pyqtSlot()
- def onFinishAction(self):
- # Restore autoslicing when the machineaction is dismissed
+ def _onFinished(self):
+ # Restore auto-slicing when the machine action is dismissed
if self._backend and self._backend.determineAutoSlicing():
+ self._backend.enableTimer()
self._backend.tickle()
- containerIndexChanged = pyqtSignal()
-
- @pyqtProperty(int, notify = containerIndexChanged)
- def containerIndex(self):
- return self._container_index
-
- def _onGlobalContainerChanged(self):
- self._global_container_stack = Application.getInstance().getGlobalContainerStack()
-
- # This additional emit is needed because we cannot connect a UM.Signal directly to a pyqtSignal
- self.globalContainerChanged.emit()
-
- globalContainerChanged = pyqtSignal()
-
- @pyqtProperty(int, notify = globalContainerChanged)
- def definedExtruderCount(self):
- if not self._global_container_stack:
- return 0
-
- return len(self._global_container_stack.getMetaDataEntry("machine_extruder_trains"))
-
@pyqtSlot(int)
- def setMachineExtruderCount(self, extruder_count):
+ def setMachineExtruderCount(self, extruder_count: int) -> None:
# Note: this method was in this class before, but since it's quite generic and other plugins also need it
# it was moved to the machine manager instead. Now this method just calls the machine manager.
self._application.getMachineManager().setActiveMachineExtruderCount(extruder_count)
@pyqtSlot()
- def forceUpdate(self):
+ def forceUpdate(self) -> None:
# Force rebuilding the build volume by reloading the global container stack.
# This is a bit of a hack, but it seems quick enough.
- self._application.globalContainerStackChanged.emit()
+ self._application.getMachineManager().globalContainerChanged.emit()
@pyqtSlot()
- def updateHasMaterialsMetadata(self):
+ def updateHasMaterialsMetadata(self) -> None:
+ global_stack = self._application.getMachineManager().activeMachine
+
# Updates the has_materials metadata flag after switching gcode flavor
- if not self._global_container_stack:
+ if not global_stack:
return
- definition = self._global_container_stack.getBottom()
- if definition.getProperty("machine_gcode_flavor", "value") != "UltiGCode" or definition.getMetaDataEntry("has_materials", False):
+ definition = global_stack.getDefinition()
+ if definition.getProperty("machine_gcode_flavor", "value") != "UltiGCode" or parseBool(definition.getMetaDataEntry("has_materials", False)):
# In other words: only continue for the UM2 (extended), but not for the UM2+
return
machine_manager = self._application.getMachineManager()
- material_manager = self._application.getMaterialManager()
- extruder_positions = list(self._global_container_stack.extruders.keys())
- has_materials = self._global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
+ has_materials = global_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
- material_node = None
if has_materials:
- self._global_container_stack.setMetaDataEntry("has_materials", True)
+ global_stack.setMetaDataEntry("has_materials", True)
else:
# The metadata entry is stored in an ini, and ini files are parsed as strings only.
# Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
- if "has_materials" in self._global_container_stack.getMetaData():
- self._global_container_stack.removeMetaDataEntry("has_materials")
+ if "has_materials" in global_stack.getMetaData():
+ global_stack.removeMetaDataEntry("has_materials")
+
+ self._updateHasMaterialsInContainerTree()
# set materials
- for position in extruder_positions:
- if has_materials:
- material_node = material_manager.getDefaultMaterial(self._global_container_stack, position, None)
- machine_manager.setMaterial(position, material_node)
+ machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
+ for position, extruder in enumerate(global_stack.extruderList):
+ #Find out what material we need to default to.
+ approximate_diameter = round(extruder.getProperty("material_diameter", "value"))
+ material_node = machine_node.variants[extruder.variant.getName()].preferredMaterial(approximate_diameter)
+ machine_manager.setMaterial(str(position), material_node)
self._application.globalContainerStackChanged.emit()
@pyqtSlot(int)
- def updateMaterialForDiameter(self, extruder_position: int):
+ def updateMaterialForDiameter(self, extruder_position: int) -> None:
# Updates the material container to a material that matches the material diameter set for the printer
self._application.getMachineManager().updateMaterialWithVariant(str(extruder_position))
diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml
index ef8fda224a..56b4d3e3b6 100644
--- a/plugins/MachineSettingsAction/MachineSettingsAction.qml
+++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml
@@ -1,939 +1,119 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
-import QtQuick.Controls 1.1
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.3
-import UM 1.2 as UM
-import Cura 1.0 as Cura
+import UM 1.3 as UM
+import Cura 1.1 as Cura
+//
+// This component contains the content for the "Welcome" page of the welcome on-boarding process.
+//
Cura.MachineAction
{
- id: base
- property var extrudersModel: Cura.ExtrudersModel{} // Do not retrieve the Model from a backend. Otherwise the tabs
- // in tabView will not removed/updated. Probably QML bug
- property int extruderTabsCount: 0
+ UM.I18nCatalog { id: catalog; name: "cura" }
- property var activeMachineId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.id : ""
+ anchors.fill: parent
+ property var extrudersModel: Cura.ExtrudersModel {}
+
+ // If we create a TabButton for "Printer" and use Repeater for extruders, for some reason, once the component
+ // finishes it will automatically change "currentIndex = 1", and it is VERY difficult to change "currentIndex = 0"
+ // after that. Using a model and a Repeater to create both "Printer" and extruder TabButtons seem to solve this
+ // problem.
Connections
{
- target: base.extrudersModel
- onModelChanged:
- {
- var extruderCount = base.extrudersModel.count;
- base.extruderTabsCount = extruderCount;
- }
+ target: extrudersModel
+ onItemsChanged: tabNameModel.update()
}
- Connections
+ ListModel
{
- target: dialog ? dialog : null
- ignoreUnknownSignals: true
- // Any which way this action dialog is dismissed, make sure it is properly finished
- onNextClicked: finishAction()
- onBackClicked: finishAction()
- onAccepted: finishAction()
- onRejected: finishAction()
- onClosing: finishAction()
- }
+ id: tabNameModel
- function finishAction()
- {
- forceActiveFocus();
- manager.onFinishAction();
- }
+ Component.onCompleted: update()
- anchors.fill: parent;
- Item
- {
- id: machineSettingsAction
- anchors.fill: parent;
-
- UM.I18nCatalog { id: catalog; name: "cura"; }
-
- Label
+ function update()
{
- id: pageTitle
- width: parent.width
- text: catalog.i18nc("@title", "Machine Settings")
- wrapMode: Text.WordWrap
- font.pointSize: 18;
- }
-
- TabView
- {
- id: settingsTabs
- height: parent.height - y
- width: parent.width
- anchors.left: parent.left
- anchors.top: pageTitle.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
-
- property real columnWidth: Math.round((width - 3 * UM.Theme.getSize("default_margin").width) / 2)
- property real labelColumnWidth: Math.round(columnWidth / 2)
-
- Tab
+ clear()
+ append({ name: catalog.i18nc("@title:tab", "Printer") })
+ for (var i = 0; i < extrudersModel.count; i++)
{
- title: catalog.i18nc("@title:tab", "Printer");
- anchors.margins: UM.Theme.getSize("default_margin").width
-
- Column
- {
- spacing: UM.Theme.getSize("default_margin").height
-
- Row
- {
- width: parent.width
- spacing: UM.Theme.getSize("default_margin").height
-
- Column
- {
- width: settingsTabs.columnWidth
- spacing: UM.Theme.getSize("default_lining").height
-
- Label
- {
- text: catalog.i18nc("@label", "Printer Settings")
- font.bold: true
- }
-
- Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
-
- Loader
- {
- id: buildAreaWidthField
- sourceComponent: numericTextFieldWithUnit
- property string settingKey: "machine_width"
- property string label: catalog.i18nc("@label", "X (Width)")
- property string unit: catalog.i18nc("@label", "mm")
- property bool forceUpdateOnChange: true
- }
-
- Loader
- {
- id: buildAreaDepthField
- sourceComponent: numericTextFieldWithUnit
- property string settingKey: "machine_depth"
- property string label: catalog.i18nc("@label", "Y (Depth)")
- property string unit: catalog.i18nc("@label", "mm")
- property bool forceUpdateOnChange: true
- }
-
- Loader
- {
- id: buildAreaHeightField
- sourceComponent: numericTextFieldWithUnit
- property string settingKey: "machine_height"
- property string label: catalog.i18nc("@label", "Z (Height)")
- property string unit: catalog.i18nc("@label", "mm")
- property bool forceUpdateOnChange: true
- }
-
- Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
-
- Loader
- {
- id: shapeComboBox
- sourceComponent: comboBoxWithOptions
- property string settingKey: "machine_shape"
- property string label: catalog.i18nc("@label", "Build plate shape")
- property bool forceUpdateOnChange: true
- }
-
- Loader
- {
- id: centerIsZeroCheckBox
- sourceComponent: simpleCheckBox
- property string settingKey: "machine_center_is_zero"
- property string label: catalog.i18nc("@option:check", "Origin at center")
- property bool forceUpdateOnChange: true
- }
- Loader
- {
- id: heatedBedCheckBox
- sourceComponent: simpleCheckBox
- property var settingKey: "machine_heated_bed"
- property string label: catalog.i18nc("@option:check", "Heated bed")
- property bool forceUpdateOnChange: true
- }
-
- Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
-
- Loader
- {
- id: gcodeFlavorComboBox
- sourceComponent: comboBoxWithOptions
- property string settingKey: "machine_gcode_flavor"
- property string label: catalog.i18nc("@label", "G-code flavor")
- property bool forceUpdateOnChange: true
- property var afterOnActivate: manager.updateHasMaterialsMetadata
- }
- }
-
- Column
- {
- width: settingsTabs.columnWidth
- spacing: UM.Theme.getSize("default_lining").height
-
- Label
- {
- text: catalog.i18nc("@label", "Printhead Settings")
- font.bold: true
- }
-
- Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
-
- Loader
- {
- id: printheadXMinField
- sourceComponent: headPolygonTextField
- property string label: catalog.i18nc("@label", "X min")
- property string tooltip: catalog.i18nc("@tooltip", "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\".")
- property string axis: "x"
- property string side: "min"
- }
-
- Loader
- {
- id: printheadYMinField
- sourceComponent: headPolygonTextField
- property string label: catalog.i18nc("@label", "Y min")
- property string tooltip: catalog.i18nc("@tooltip", "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\".")
- property string axis: "y"
- property string side: "min"
- }
-
- Loader
- {
- id: printheadXMaxField
- sourceComponent: headPolygonTextField
- property string label: catalog.i18nc("@label", "X max")
- property string tooltip: catalog.i18nc("@tooltip", "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\".")
- property string axis: "x"
- property string side: "max"
- }
-
- Loader
- {
- id: printheadYMaxField
- sourceComponent: headPolygonTextField
- property string label: catalog.i18nc("@label", "Y max")
- property string tooltip: catalog.i18nc("@tooltip", "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\".")
- property string axis: "y"
- property string side: "max"
- }
-
- Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
-
- Loader
- {
- id: gantryHeightField
- sourceComponent: numericTextFieldWithUnit
- property string settingKey: "gantry_height"
- property string label: catalog.i18nc("@label", "Gantry height")
- property string unit: catalog.i18nc("@label", "mm")
- property string tooltip: catalog.i18nc("@tooltip", "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\".")
- property bool forceUpdateOnChange: true
- }
-
- Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
-
- UM.TooltipArea
- {
- height: childrenRect.height
- width: childrenRect.width
- text: machineExtruderCountProvider.properties.description
- visible: extruderCountModel.count >= 2
-
- Row
- {
- spacing: UM.Theme.getSize("default_margin").width
-
- Label
- {
- text: catalog.i18nc("@label", "Number of Extruders")
- elide: Text.ElideRight
- width: Math.max(0, settingsTabs.labelColumnWidth)
- anchors.verticalCenter: extruderCountComboBox.verticalCenter
- }
- ComboBox
- {
- id: extruderCountComboBox
- model: ListModel
- {
- id: extruderCountModel
- Component.onCompleted:
- {
- for(var i = 0; i < manager.definedExtruderCount; i++)
- {
- extruderCountModel.append({text: String(i + 1), value: i});
- }
- }
- }
-
- Connections
- {
- target: manager
- onDefinedExtruderCountChanged:
- {
- extruderCountModel.clear();
- for(var i = 0; i < manager.definedExtruderCount; ++i)
- {
- extruderCountModel.append({text: String(i + 1), value: i});
- }
- }
- }
-
- currentIndex: machineExtruderCountProvider.properties.value - 1
- onActivated:
- {
- manager.setMachineExtruderCount(index + 1);
- }
- }
- }
- }
- }
- }
-
- Row
- {
- spacing: UM.Theme.getSize("default_margin").width
- anchors.left: parent.left
- anchors.right: parent.right
- height: parent.height - y
- Column
- {
- height: parent.height
- width: settingsTabs.columnWidth
- Label
- {
- text: catalog.i18nc("@label", "Start G-code")
- font.bold: true
- }
- Loader
- {
- id: machineStartGcodeField
- sourceComponent: gcodeTextArea
- property int areaWidth: parent.width
- property int areaHeight: parent.height - y
- property string settingKey: "machine_start_gcode"
- property string tooltip: catalog.i18nc("@tooltip", "G-code commands to be executed at the very start.")
- }
- }
-
- Column {
- height: parent.height
- width: settingsTabs.columnWidth
- Label
- {
- text: catalog.i18nc("@label", "End G-code")
- font.bold: true
- }
- Loader
- {
- id: machineEndGcodeField
- sourceComponent: gcodeTextArea
- property int areaWidth: parent.width
- property int areaHeight: parent.height - y
- property string settingKey: "machine_end_gcode"
- property string tooltip: catalog.i18nc("@tooltip", "G-code commands to be executed at the very end.")
- }
- }
- }
- }
+ const m = extrudersModel.getItem(i)
+ append({ name: m.name })
}
+ }
+ }
- onCurrentIndexChanged:
+ Cura.RoundedRectangle
+ {
+ anchors
+ {
+ top: tabBar.bottom
+ topMargin: -UM.Theme.getSize("default_lining").height
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ }
+ cornerSide: Cura.RoundedRectangle.Direction.Down
+ border.color: UM.Theme.getColor("lining")
+ border.width: UM.Theme.getSize("default_lining").width
+ radius: UM.Theme.getSize("default_radius").width
+ color: UM.Theme.getColor("main_background")
+ StackLayout
+ {
+ id: tabStack
+ anchors.fill: parent
+
+ currentIndex: tabBar.currentIndex
+
+ MachineSettingsPrinterTab
{
- if(currentIndex > 0)
- {
- contentItem.forceActiveFocus();
- }
+ id: printerTab
}
Repeater
{
- id: extruderTabsRepeater
- model: base.extruderTabsCount
-
- Tab
+ model: extrudersModel
+ delegate: MachineSettingsExtruderTab
{
- title: base.extrudersModel.getItem(index).name
- anchors.margins: UM.Theme.getSize("default_margin").width
-
- Column
- {
- spacing: UM.Theme.getSize("default_lining").width
-
- Label
- {
- text: catalog.i18nc("@label", "Nozzle Settings")
- font.bold: true
- }
-
- Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
-
- Loader
- {
- id: extruderNozzleSizeField
- visible: !Cura.MachineManager.hasVariants
- sourceComponent: numericTextFieldWithUnit
- property string settingKey: "machine_nozzle_size"
- property string label: catalog.i18nc("@label", "Nozzle size")
- property string unit: catalog.i18nc("@label", "mm")
- function afterOnEditingFinished()
- {
- // Somehow the machine_nozzle_size dependent settings are not updated otherwise
- Cura.MachineManager.forceUpdateAllSettings()
- }
- property bool isExtruderSetting: true
- }
-
- Loader
- {
- id: materialDiameterField
- visible: Cura.MachineManager.hasMaterials
- sourceComponent: numericTextFieldWithUnit
- property string settingKey: "material_diameter"
- property string label: catalog.i18nc("@label", "Compatible material diameter")
- property string unit: catalog.i18nc("@label", "mm")
- property string tooltip: catalog.i18nc("@tooltip", "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile.")
- function afterOnEditingFinished()
- {
- if (settingsTabs.currentIndex > 0)
- {
- manager.updateMaterialForDiameter(settingsTabs.currentIndex - 1)
- }
- }
- function setValueFunction(value)
- {
- if (settingsTabs.currentIndex > 0)
- {
- const extruderIndex = index.toString()
- Cura.MachineManager.activeMachine.extruders[extruderIndex].compatibleMaterialDiameter = value
- }
- }
- property bool isExtruderSetting: true
- }
-
- Loader
- {
- id: extruderOffsetXField
- sourceComponent: numericTextFieldWithUnit
- property string settingKey: "machine_nozzle_offset_x"
- property string label: catalog.i18nc("@label", "Nozzle offset X")
- property string unit: catalog.i18nc("@label", "mm")
- property bool isExtruderSetting: true
- property bool forceUpdateOnChange: true
- property bool allowNegative: true
- }
-
- Loader
- {
- id: extruderOffsetYField
- sourceComponent: numericTextFieldWithUnit
- property string settingKey: "machine_nozzle_offset_y"
- property string label: catalog.i18nc("@label", "Nozzle offset Y")
- property string unit: catalog.i18nc("@label", "mm")
- property bool isExtruderSetting: true
- property bool forceUpdateOnChange: true
- property bool allowNegative: true
- }
-
- Loader
- {
- id: extruderCoolingFanNumberField
- sourceComponent: numericTextFieldWithUnit
- property string settingKey: "machine_extruder_cooling_fan_number"
- property string label: catalog.i18nc("@label", "Cooling Fan Number")
- property string unit: catalog.i18nc("@label", "")
- property bool isExtruderSetting: true
- property bool forceUpdateOnChange: true
- property bool allowNegative: false
- }
-
- Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
-
- Row
- {
- spacing: UM.Theme.getSize("default_margin").width
- anchors.left: parent.left
- anchors.right: parent.right
- height: parent.height - y
- Column
- {
- height: parent.height
- width: settingsTabs.columnWidth
- Label
- {
- text: catalog.i18nc("@label", "Extruder Start G-code")
- font.bold: true
- }
- Loader
- {
- id: extruderStartGcodeField
- sourceComponent: gcodeTextArea
- property int areaWidth: parent.width
- property int areaHeight: parent.height - y
- property string settingKey: "machine_extruder_start_code"
- property bool isExtruderSetting: true
- }
- }
- Column {
- height: parent.height
- width: settingsTabs.columnWidth
- Label
- {
- text: catalog.i18nc("@label", "Extruder End G-code")
- font.bold: true
- }
- Loader
- {
- id: extruderEndGcodeField
- sourceComponent: gcodeTextArea
- property int areaWidth: parent.width
- property int areaHeight: parent.height - y
- property string settingKey: "machine_extruder_end_code"
- property bool isExtruderSetting: true
- }
- }
- }
- }
+ id: discoverTab
+ extruderPosition: model.index
+ extruderStackId: model.id
}
}
}
}
- Component
+ Label
{
- id: simpleCheckBox
- UM.TooltipArea
+ id: machineNameLabel
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.leftMargin: UM.Theme.getSize("default_margin").width
+ text: Cura.MachineManager.activeMachine.name
+ horizontalAlignment: Text.AlignHCenter
+ font: UM.Theme.getFont("large_bold")
+ color: UM.Theme.getColor("text")
+ renderType: Text.NativeRendering
+ }
+
+ UM.TabRow
+ {
+ id: tabBar
+ anchors.top: machineNameLabel.bottom
+ anchors.topMargin: UM.Theme.getSize("default_margin").height
+ width: parent.width
+ Repeater
{
- height: checkBox.height
- width: checkBox.width
- text: _tooltip
-
- property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false: isExtruderSetting
- property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false: forceUpdateOnChange
- property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip
-
- UM.SettingPropertyProvider
+ model: tabNameModel
+ delegate: UM.TabRowButton
{
- id: propertyProvider
-
- containerStackId: {
- if(_isExtruderSetting)
- {
- if(settingsTabs.currentIndex > 0)
- {
- return Cura.ExtruderManager.extruderIds[String(settingsTabs.currentIndex - 1)];
- }
- return "";
- }
- return base.activeMachineId
- }
- key: settingKey
- watchedProperties: [ "value", "description" ]
- storeIndex: manager.containerIndex
- }
-
- CheckBox
- {
- id: checkBox
- text: label
- checked: String(propertyProvider.properties.value).toLowerCase() != 'false'
- onClicked:
- {
- propertyProvider.setPropertyValue("value", checked);
- if(_forceUpdateOnChange)
- {
- manager.forceUpdate();
- }
- }
+ text: model.name
}
}
}
-
- Component
- {
- id: numericTextFieldWithUnit
- UM.TooltipArea
- {
- height: childrenRect.height
- width: childrenRect.width
- text: _tooltip
-
- property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false: isExtruderSetting
- property bool _allowNegative: (typeof(allowNegative) === 'undefined') ? false : allowNegative
- property var _afterOnEditingFinished: (typeof(afterOnEditingFinished) === 'undefined') ? undefined : afterOnEditingFinished
- property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false : forceUpdateOnChange
- property string _label: (typeof(label) === 'undefined') ? "" : label
- property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip
- property var _setValueFunction: (typeof(setValueFunction) === 'undefined') ? undefined : setValueFunction
-
- UM.SettingPropertyProvider
- {
- id: propertyProvider
-
- containerStackId: {
- if(_isExtruderSetting)
- {
- if(settingsTabs.currentIndex > 0)
- {
- return Cura.ExtruderManager.extruderIds[String(settingsTabs.currentIndex - 1)];
- }
- return "";
- }
- return base.activeMachineId
- }
- key: settingKey
- watchedProperties: [ "value", "description" ]
- storeIndex: manager.containerIndex
- }
-
- Row
- {
- spacing: UM.Theme.getSize("default_margin").width
-
- Label
- {
- text: _label
- visible: _label != ""
- elide: Text.ElideRight
- width: Math.max(0, settingsTabs.labelColumnWidth)
- anchors.verticalCenter: textFieldWithUnit.verticalCenter
- }
-
- Item
- {
- width: textField.width
- height: textField.height
-
- id: textFieldWithUnit
- TextField
- {
- id: textField
- text: {
- const value = propertyProvider.properties.value;
- return value ? value : "";
- }
- validator: RegExpValidator { regExp: _allowNegative ? /-?[0-9\.,]{0,6}/ : /[0-9\.,]{0,6}/ }
- onEditingFinished:
- {
- if (propertyProvider && text != propertyProvider.properties.value)
- {
- // For some properties like the extruder-compatible material diameter, they need to
- // trigger many updates, such as the available materials, the current material may
- // need to be switched, etc. Although setting the diameter can be done directly via
- // the provider, all the updates that need to be triggered then need to depend on
- // the metadata update, a signal that can be fired way too often. The update functions
- // can have if-checks to filter out the irrelevant updates, but still it incurs unnecessary
- // overhead.
- // The ExtruderStack class has a dedicated function for this call "setCompatibleMaterialDiameter()",
- // and it triggers the diameter update signals only when it is needed. Here it is optionally
- // choose to use setCompatibleMaterialDiameter() or other more specific functions that
- // are available.
- if (_setValueFunction !== undefined)
- {
- _setValueFunction(text)
- }
- else
- {
- propertyProvider.setPropertyValue("value", text)
- }
- if(_forceUpdateOnChange)
- {
- manager.forceUpdate()
- }
- if(_afterOnEditingFinished)
- {
- _afterOnEditingFinished()
- }
- }
- }
- }
-
- Label
- {
- text: unit
- anchors.right: textField.right
- anchors.rightMargin: y - textField.y
- anchors.verticalCenter: textField.verticalCenter
- }
- }
- }
- }
- }
-
- Component
- {
- id: comboBoxWithOptions
- UM.TooltipArea
- {
- height: childrenRect.height
- width: childrenRect.width
- text: _tooltip
-
- property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false : isExtruderSetting
- property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false : forceUpdateOnChange
- property var _afterOnActivate: (typeof(afterOnActivate) === 'undefined') ? undefined : afterOnActivate
- property string _label: (typeof(label) === 'undefined') ? "" : label
- property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip
-
- UM.SettingPropertyProvider
- {
- id: propertyProvider
-
- containerStackId: {
- if(_isExtruderSetting)
- {
- if(settingsTabs.currentIndex > 0)
- {
- return Cura.ExtruderManager.extruderIds[String(settingsTabs.currentIndex - 1)];
- }
- return "";
- }
- return base.activeMachineId
- }
- key: settingKey
- watchedProperties: [ "value", "options", "description" ]
- storeIndex: manager.containerIndex
- }
-
- Row
- {
- spacing: UM.Theme.getSize("default_margin").width
-
- Label
- {
- text: _label
- visible: _label != ""
- elide: Text.ElideRight
- width: Math.max(0, settingsTabs.labelColumnWidth)
- anchors.verticalCenter: comboBox.verticalCenter
- }
- ComboBox
- {
- id: comboBox
- model: ListModel
- {
- id: optionsModel
- Component.onCompleted:
- {
- // Options come in as a string-representation of an OrderedDict
- var options = propertyProvider.properties.options.match(/^OrderedDict\(\[\((.*)\)\]\)$/);
- if(options)
- {
- options = options[1].split("), (")
- for(var i = 0; i < options.length; i++)
- {
- var option = options[i].substring(1, options[i].length - 1).split("', '")
- optionsModel.append({text: option[1], value: option[0]});
- }
- }
- }
- }
- currentIndex:
- {
- var currentValue = propertyProvider.properties.value;
- var index = 0;
- for(var i = 0; i < optionsModel.count; i++)
- {
- if(optionsModel.get(i).value == currentValue) {
- index = i;
- break;
- }
- }
- return index
- }
- onActivated:
- {
- if(propertyProvider.properties.value != optionsModel.get(index).value)
- {
- propertyProvider.setPropertyValue("value", optionsModel.get(index).value);
- if(_forceUpdateOnChange)
- {
- manager.forceUpdate();
- }
- if(_afterOnActivate)
- {
- _afterOnActivate();
- }
- }
- }
- }
- }
- }
- }
-
- Component
- {
- id: gcodeTextArea
-
- UM.TooltipArea
- {
- height: gcodeArea.height
- width: gcodeArea.width
- text: _tooltip
-
- property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false : isExtruderSetting
- property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip
-
- UM.SettingPropertyProvider
- {
- id: propertyProvider
-
- containerStackId: {
- if(_isExtruderSetting)
- {
- if(settingsTabs.currentIndex > 0)
- {
- return Cura.ExtruderManager.extruderIds[String(settingsTabs.currentIndex - 1)];
- }
- return "";
- }
- return base.activeMachineId
- }
- key: settingKey
- watchedProperties: [ "value", "description" ]
- storeIndex: manager.containerIndex
- }
-
- TextArea
- {
- id: gcodeArea
- width: areaWidth
- height: areaHeight
- font: UM.Theme.getFont("fixed")
- text: (propertyProvider.properties.value) ? propertyProvider.properties.value : ""
- onActiveFocusChanged:
- {
- if(!activeFocus)
- {
- propertyProvider.setPropertyValue("value", gcodeArea.text)
- }
- }
- Component.onCompleted:
- {
- wrapMode = TextEdit.NoWrap;
- }
- }
- }
- }
-
- Component
- {
- id: headPolygonTextField
- UM.TooltipArea
- {
- height: textField.height
- width: textField.width
- text: tooltip
-
- property string _label: (typeof(label) === 'undefined') ? "" : label
-
- Row
- {
- spacing: UM.Theme.getSize("default_margin").width
-
- Label
- {
- text: _label
- visible: _label != ""
- elide: Text.ElideRight
- width: Math.max(0, settingsTabs.labelColumnWidth)
- anchors.verticalCenter: textFieldWithUnit.verticalCenter
- }
-
- Item
- {
- id: textFieldWithUnit
- width: textField.width
- height: textField.height
-
- TextField
- {
- id: textField
- text:
- {
- var polygon = JSON.parse(machineHeadPolygonProvider.properties.value);
- var item = (axis == "x") ? 0 : 1
- var result = polygon[0][item];
- for(var i = 1; i < polygon.length; i++) {
- if (side == "min") {
- result = Math.min(result, polygon[i][item]);
- } else {
- result = Math.max(result, polygon[i][item]);
- }
- }
- result = Math.abs(result);
- printHeadPolygon[axis][side] = result;
- return result;
- }
- validator: RegExpValidator { regExp: /[0-9\.,]{0,6}/ }
- onEditingFinished:
- {
- printHeadPolygon[axis][side] = parseFloat(textField.text.replace(',','.'));
- var polygon = [];
- polygon.push([-printHeadPolygon["x"]["min"], printHeadPolygon["y"]["max"]]);
- polygon.push([-printHeadPolygon["x"]["min"],-printHeadPolygon["y"]["min"]]);
- polygon.push([ printHeadPolygon["x"]["max"], printHeadPolygon["y"]["max"]]);
- polygon.push([ printHeadPolygon["x"]["max"],-printHeadPolygon["y"]["min"]]);
- var polygon_string = JSON.stringify(polygon);
- if(polygon_string != machineHeadPolygonProvider.properties.value)
- {
- machineHeadPolygonProvider.setPropertyValue("value", polygon_string);
- manager.forceUpdate();
- }
- }
- }
-
- Label
- {
- text: catalog.i18nc("@label", "mm")
- anchors.right: textField.right
- anchors.rightMargin: y - textField.y
- anchors.verticalCenter: textField.verticalCenter
- }
- }
- }
- }
- }
-
- property var printHeadPolygon:
- {
- "x": {
- "min": 0,
- "max": 0,
- },
- "y": {
- "min": 0,
- "max": 0,
- },
- }
-
-
- UM.SettingPropertyProvider
- {
- id: machineExtruderCountProvider
-
- containerStackId: base.activeMachineId
- key: "machine_extruder_count"
- watchedProperties: [ "value", "description" ]
- storeIndex: manager.containerIndex
- }
-
- UM.SettingPropertyProvider
- {
- id: machineHeadPolygonProvider
-
- containerStackId: base.activeMachineId
- key: "machine_head_with_fans_polygon"
- watchedProperties: [ "value" ]
- storeIndex: manager.containerIndex
- }
}
diff --git a/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml b/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml
new file mode 100644
index 0000000000..2ceabf87d0
--- /dev/null
+++ b/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml
@@ -0,0 +1,182 @@
+// Copyright (c) 2019 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+
+import UM 1.3 as UM
+import Cura 1.1 as Cura
+
+
+//
+// This component contains the content for the "Welcome" page of the welcome on-boarding process.
+//
+Item
+{
+ id: base
+ UM.I18nCatalog { id: catalog; name: "cura" }
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+
+ property int labelWidth: 210 * screenScaleFactor
+ property int controlWidth: (UM.Theme.getSize("setting_control").width * 3 / 4) | 0
+ property var labelFont: UM.Theme.getFont("default")
+
+ property int columnWidth: ((parent.width - 2 * UM.Theme.getSize("default_margin").width) / 2) | 0
+ property int columnSpacing: 3 * screenScaleFactor
+ property int propertyStoreIndex: manager ? manager.storeContainerIndex : 1 // definition_changes
+
+ property string extruderStackId: ""
+ property int extruderPosition: 0
+ property var forceUpdateFunction: manager.forceUpdate
+
+ function updateMaterialDiameter()
+ {
+ manager.updateMaterialForDiameter(extruderPosition)
+ }
+
+ Item
+ {
+ id: upperBlock
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: UM.Theme.getSize("default_margin").width
+
+ height: childrenRect.height
+
+ // =======================================
+ // Left-side column "Nozzle Settings"
+ // =======================================
+ Column
+ {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ width: parent.width * 2 / 3
+
+ spacing: base.columnSpacing
+
+ Label // Title Label
+ {
+ text: catalog.i18nc("@title:label", "Nozzle Settings")
+ font: UM.Theme.getFont("medium_bold")
+ renderType: Text.NativeRendering
+ }
+
+ Cura.NumericTextFieldWithUnit // "Nozzle size"
+ {
+ id: extruderNozzleSizeField
+ visible: !Cura.MachineManager.activeMachine.hasVariants
+ containerStackId: base.extruderStackId
+ settingKey: "machine_nozzle_size"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Nozzle size")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.NumericTextFieldWithUnit // "Compatible material diameter"
+ {
+ id: extruderCompatibleMaterialDiameterField
+ containerStackId: base.extruderStackId
+ settingKey: "material_diameter"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Compatible material diameter")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ // Other modules won't automatically respond after the user changes the value, so we need to force it.
+ afterOnEditingFinishedFunction: updateMaterialDiameter
+ }
+
+ Cura.NumericTextFieldWithUnit // "Nozzle offset X"
+ {
+ id: extruderNozzleOffsetXField
+ containerStackId: base.extruderStackId
+ settingKey: "machine_nozzle_offset_x"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Nozzle offset X")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+ allowNegativeValue: true
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.NumericTextFieldWithUnit // "Nozzle offset Y"
+ {
+ id: extruderNozzleOffsetYField
+ containerStackId: base.extruderStackId
+ settingKey: "machine_nozzle_offset_y"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Nozzle offset Y")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+ allowNegativeValue: true
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.NumericTextFieldWithUnit // "Cooling Fan Number"
+ {
+ id: extruderNozzleCoolingFanNumberField
+ containerStackId: base.extruderStackId
+ settingKey: "machine_extruder_cooling_fan_number"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Cooling Fan Number")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: ""
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+ }
+ }
+
+ Item // Extruder Start and End G-code
+ {
+ id: lowerBlock
+ anchors.top: upperBlock.bottom
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: UM.Theme.getSize("default_margin").width
+
+ Cura.GcodeTextArea // "Extruder Start G-code"
+ {
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: UM.Theme.getSize("default_margin").height
+ anchors.left: parent.left
+ width: base.columnWidth - UM.Theme.getSize("default_margin").width
+
+ labelText: catalog.i18nc("@title:label", "Extruder Start G-code")
+ containerStackId: base.extruderStackId
+ settingKey: "machine_extruder_start_code"
+ settingStoreIndex: propertyStoreIndex
+ }
+
+ Cura.GcodeTextArea // "Extruder End G-code"
+ {
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: UM.Theme.getSize("default_margin").height
+ anchors.right: parent.right
+ width: base.columnWidth - UM.Theme.getSize("default_margin").width
+
+ labelText: catalog.i18nc("@title:label", "Extruder End G-code")
+ containerStackId: base.extruderStackId
+ settingKey: "machine_extruder_end_code"
+ settingStoreIndex: propertyStoreIndex
+ }
+ }
+}
diff --git a/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml b/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml
new file mode 100644
index 0000000000..3780d6447b
--- /dev/null
+++ b/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml
@@ -0,0 +1,384 @@
+// Copyright (c) 2019 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.3
+
+import UM 1.3 as UM
+import Cura 1.1 as Cura
+
+
+//
+// This the content in the "Printer" tab in the Machine Settings dialog.
+//
+Item
+{
+ id: base
+ UM.I18nCatalog { id: catalog; name: "cura" }
+
+ property int columnWidth: ((parent.width - 2 * UM.Theme.getSize("default_margin").width) / 2) | 0
+ property int columnSpacing: 3 * screenScaleFactor
+ property int propertyStoreIndex: manager ? manager.storeContainerIndex : 1 // definition_changes
+
+ property int labelWidth: (columnWidth * 2 / 3 - UM.Theme.getSize("default_margin").width * 2) | 0
+ property int controlWidth: (columnWidth / 3) | 0
+ property var labelFont: UM.Theme.getFont("default")
+
+ property string machineStackId: Cura.MachineManager.activeMachine.id
+
+ property var forceUpdateFunction: manager.forceUpdate
+
+ RowLayout
+ {
+ id: upperBlock
+ anchors
+ {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ margins: UM.Theme.getSize("default_margin").width
+ }
+ spacing: UM.Theme.getSize("default_margin").width
+
+ // =======================================
+ // Left-side column for "Printer Settings"
+ // =======================================
+ Column
+ {
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignTop
+
+ spacing: base.columnSpacing
+
+ Label // Title Label
+ {
+ text: catalog.i18nc("@title:label", "Printer Settings")
+ font: UM.Theme.getFont("medium_bold")
+ color: UM.Theme.getColor("text")
+ renderType: Text.NativeRendering
+ width: parent.width
+ elide: Text.ElideRight
+ }
+
+ Cura.NumericTextFieldWithUnit // "X (Width)"
+ {
+ id: machineXWidthField
+ containerStackId: machineStackId
+ settingKey: "machine_width"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "X (Width)")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.NumericTextFieldWithUnit // "Y (Depth)"
+ {
+ id: machineYDepthField
+ containerStackId: machineStackId
+ settingKey: "machine_depth"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Y (Depth)")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.NumericTextFieldWithUnit // "Z (Height)"
+ {
+ id: machineZHeightField
+ containerStackId: machineStackId
+ settingKey: "machine_height"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Z (Height)")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.ComboBoxWithOptions // "Build plate shape"
+ {
+ id: buildPlateShapeComboBox
+ containerStackId: machineStackId
+ settingKey: "machine_shape"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Build plate shape")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.SimpleCheckBox // "Origin at center"
+ {
+ id: originAtCenterCheckBox
+ containerStackId: machineStackId
+ settingKey: "machine_center_is_zero"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Origin at center")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.SimpleCheckBox // "Heated bed"
+ {
+ id: heatedBedCheckBox
+ containerStackId: machineStackId
+ settingKey: "machine_heated_bed"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Heated bed")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.SimpleCheckBox // "Heated build volume"
+ {
+ id: heatedVolumeCheckBox
+ containerStackId: machineStackId
+ settingKey: "machine_heated_build_volume"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Heated build volume")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.ComboBoxWithOptions // "G-code flavor"
+ {
+ id: gcodeFlavorComboBox
+ containerStackId: machineStackId
+ settingKey: "machine_gcode_flavor"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "G-code flavor")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ // FIXME(Lipu): better document this.
+ // This has something to do with UM2 and UM2+ regarding "has_material" and the gcode flavor settings.
+ // I don't remember exactly what.
+ afterOnEditingFinishedFunction: manager.updateHasMaterialsMetadata
+ }
+ }
+
+ // =======================================
+ // Right-side column for "Printhead Settings"
+ // =======================================
+ Column
+ {
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignTop
+
+ spacing: base.columnSpacing
+
+ Label // Title Label
+ {
+ text: catalog.i18nc("@title:label", "Printhead Settings")
+ font: UM.Theme.getFont("medium_bold")
+ color: UM.Theme.getColor("text")
+ renderType: Text.NativeRendering
+ width: parent.width
+ elide: Text.ElideRight
+ }
+
+ Cura.PrintHeadMinMaxTextField // "X min"
+ {
+ id: machineXMinField
+
+ settingStoreIndex: propertyStoreIndex
+
+ labelText: catalog.i18nc("@label", "X min")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+
+ axisName: "x"
+ axisMinOrMax: "min"
+ allowNegativeValue: true
+ allowPositiveValue: false
+
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.PrintHeadMinMaxTextField // "Y min"
+ {
+ id: machineYMinField
+
+ settingStoreIndex: propertyStoreIndex
+
+ labelText: catalog.i18nc("@label", "Y min")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+
+ axisName: "y"
+ axisMinOrMax: "min"
+ allowNegativeValue: true
+ allowPositiveValue: false
+
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.PrintHeadMinMaxTextField // "X max"
+ {
+ id: machineXMaxField
+
+ settingStoreIndex: propertyStoreIndex
+
+ labelText: catalog.i18nc("@label", "X max")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+
+ axisName: "x"
+ axisMinOrMax: "max"
+ allowNegativeValue: false
+ allowPositiveValue: true
+
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.PrintHeadMinMaxTextField // "Y max"
+ {
+ id: machineYMaxField
+
+ containerStackId: machineStackId
+ settingKey: "machine_head_with_fans_polygon"
+ settingStoreIndex: propertyStoreIndex
+
+ labelText: catalog.i18nc("@label", "Y max")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+
+ axisName: "y"
+ axisMinOrMax: "max"
+ allowNegativeValue: false
+ allowPositiveValue: true
+
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.NumericTextFieldWithUnit // "Gantry Height"
+ {
+ id: machineGantryHeightField
+ containerStackId: machineStackId
+ settingKey: "gantry_height"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Gantry Height")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ unitText: catalog.i18nc("@label", "mm")
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+
+ Cura.ComboBoxWithOptions // "Number of Extruders"
+ {
+ id: numberOfExtrudersComboBox
+ containerStackId: machineStackId
+ settingKey: "machine_extruder_count"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Number of Extruders")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ controlWidth: base.controlWidth
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ // FIXME(Lipu): better document this.
+ // This has something to do with UM2 and UM2+ regarding "has_material" and the gcode flavor settings.
+ // I don't remember exactly what.
+ afterOnEditingFinishedFunction: manager.updateHasMaterialsMetadata
+ setValueFunction: manager.setMachineExtruderCount
+
+ optionModel: ListModel
+ {
+ id: extruderCountModel
+
+ Component.onCompleted:
+ {
+ update()
+ }
+
+ function update()
+ {
+ clear()
+ for (var i = 1; i <= Cura.MachineManager.activeMachine.maxExtruderCount; i++)
+ {
+ // Use String as value. JavaScript only has Number. PropertyProvider.setPropertyValue()
+ // takes a QVariant as value, and Number gets translated into a float. This will cause problem
+ // for integer settings such as "Number of Extruders".
+ append({ text: String(i), value: String(i) })
+ }
+ }
+ }
+
+ Connections
+ {
+ target: Cura.MachineManager
+ onGlobalContainerChanged: extruderCountModel.update()
+ }
+ }
+
+ Cura.SimpleCheckBox // "Shared Heater"
+ {
+ id: sharedHeaterCheckBox
+ containerStackId: machineStackId
+ settingKey: "machine_extruders_share_heater"
+ settingStoreIndex: propertyStoreIndex
+ labelText: catalog.i18nc("@label", "Shared Heater")
+ labelFont: base.labelFont
+ labelWidth: base.labelWidth
+ forceUpdateOnChangeFunction: forceUpdateFunction
+ }
+ }
+ }
+
+ RowLayout // Start and End G-code
+ {
+ id: lowerBlock
+ spacing: UM.Theme.getSize("default_margin").width
+ anchors
+ {
+ top: upperBlock.bottom
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ margins: UM.Theme.getSize("default_margin").width
+ }
+
+ Cura.GcodeTextArea // "Start G-code"
+ {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ labelText: catalog.i18nc("@title:label", "Start G-code")
+ containerStackId: machineStackId
+ settingKey: "machine_start_gcode"
+ settingStoreIndex: propertyStoreIndex
+ }
+
+ Cura.GcodeTextArea // "End G-code"
+ {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ labelText: catalog.i18nc("@title:label", "End G-code")
+ containerStackId: machineStackId
+ settingKey: "machine_end_gcode"
+ settingStoreIndex: propertyStoreIndex
+ }
+ }
+}
diff --git a/plugins/MachineSettingsAction/plugin.json b/plugins/MachineSettingsAction/plugin.json
index d734c1adf5..cc1e5fb01e 100644
--- a/plugins/MachineSettingsAction/plugin.json
+++ b/plugins/MachineSettingsAction/plugin.json
@@ -3,6 +3,6 @@
"author": "fieldOfView",
"version": "1.0.1",
"description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/ModelChecker/ModelChecker.py b/plugins/ModelChecker/ModelChecker.py
index d2c2eefac2..0afed28f19 100644
--- a/plugins/ModelChecker/ModelChecker.py
+++ b/plugins/ModelChecker/ModelChecker.py
@@ -3,12 +3,13 @@
import os
-from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, pyqtProperty
+from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, pyqtProperty, QTimer
from UM.Application import Application
from UM.Extension import Extension
from UM.Logger import Logger
from UM.Message import Message
+from UM.Scene.Camera import Camera
from UM.i18n import i18nCatalog
from UM.PluginRegistry import PluginRegistry
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
@@ -29,13 +30,22 @@ class ModelChecker(QObject, Extension):
lifetime = 0,
title = catalog.i18nc("@info:title", "3D Model Assistant"))
+ self._change_timer = QTimer()
+ self._change_timer.setInterval(200)
+ self._change_timer.setSingleShot(True)
+ self._change_timer.timeout.connect(self.onChanged)
+
Application.getInstance().initializationFinished.connect(self._pluginsInitialized)
Application.getInstance().getController().getScene().sceneChanged.connect(self._onChanged)
Application.getInstance().globalContainerStackChanged.connect(self._onChanged)
- ## Pass-through to allow UM.Signal to connect with a pyqtSignal.
def _onChanged(self, *args, **kwargs):
- self.onChanged.emit()
+ # Ignore camera updates.
+ if len(args) == 0:
+ self._change_timer.start()
+ return
+ if not isinstance(args[0], Camera):
+ self._change_timer.start()
## Called when plug-ins are initialized.
#
@@ -66,7 +76,9 @@ class ModelChecker(QObject, Extension):
# This function can be triggered in the middle of a machine change, so do not proceed if the machine change
# has not done yet.
- if str(node_extruder_position) not in global_container_stack.extruders:
+ try:
+ extruder = global_container_stack.extruderList[int(node_extruder_position)]
+ except IndexError:
Application.getInstance().callLater(lambda: self.onChanged.emit())
return False
@@ -121,9 +133,9 @@ class ModelChecker(QObject, Extension):
material_shrinkage = {}
# Get all shrinkage values of materials used
- for extruder_position, extruder in global_container_stack.extruders.items():
+ for extruder_position, extruder in enumerate(global_container_stack.extruderList):
shrinkage = extruder.material.getProperty("material_shrinkage_percentage", "value")
if shrinkage is None:
shrinkage = 0
- material_shrinkage[extruder_position] = shrinkage
+ material_shrinkage[str(extruder_position)] = shrinkage
return material_shrinkage
diff --git a/plugins/ModelChecker/plugin.json b/plugins/ModelChecker/plugin.json
index 59be5bbf0a..6437fb0802 100644
--- a/plugins/ModelChecker/plugin.json
+++ b/plugins/ModelChecker/plugin.json
@@ -2,7 +2,7 @@
"name": "Model Checker",
"author": "Ultimaker B.V.",
"version": "1.0.1",
- "api": "6.0",
+ "api": "7.0",
"description": "Checks models and print configuration for possible printing issues and give suggestions.",
"i18n-catalog": "cura"
}
diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml
index a73650ed6a..a70c10ff0f 100644
--- a/plugins/MonitorStage/MonitorMain.qml
+++ b/plugins/MonitorStage/MonitorMain.qml
@@ -11,13 +11,21 @@ Rectangle
{
id: viewportOverlay
- property bool isConnected: Cura.MachineManager.activeMachineHasActiveNetworkConnection || Cura.MachineManager.activeMachineHasActiveCloudConnection
- property bool isNetworkConfigurable: ["Ultimaker 3", "Ultimaker 3 Extended", "Ultimaker S5"].indexOf(Cura.MachineManager.activeMachineDefinitionName) > -1
+ property bool isConnected: Cura.MachineManager.activeMachineHasNetworkConnection || Cura.MachineManager.activeMachineHasCloudConnection
+ property bool isNetworkConfigurable:
+ {
+ if(Cura.MachineManager.activeMachine === null)
+ {
+ return false
+ }
+ return Cura.MachineManager.activeMachine.supportsNetworkConnection
+ }
+
property bool isNetworkConfigured:
{
// Readability:
var connectedTypes = [2, 3];
- var types = Cura.MachineManager.activeMachineConfiguredConnectionTypes
+ var types = Cura.MachineManager.activeMachine.configuredConnectionTypes
// Check if configured connection types includes either 2 or 3 (LAN or cloud)
for (var i = 0; i < types.length; i++)
@@ -89,7 +97,7 @@ Rectangle
horizontalCenter: parent.horizontalCenter
}
visible: isNetworkConfigured && !isConnected
- text: catalog.i18nc("@info", "Please make sure your printer has a connection:\n- Check if the printer is turned on.\n- Check if the printer is connected to the network.")
+ text: catalog.i18nc("@info", "Please make sure your printer has a connection:\n- Check if the printer is turned on.\n- Check if the printer is connected to the network.\n- Check if you are signed in to discover cloud-connected printers.")
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("monitor_text_primary")
wrapMode: Text.WordWrap
@@ -98,7 +106,6 @@ Rectangle
width: contentWidth
}
- // CASE 3: CAN NOT MONITOR
Label
{
id: noNetworkLabel
@@ -106,24 +113,8 @@ Rectangle
{
horizontalCenter: parent.horizontalCenter
}
- visible: !isNetworkConfigured
- text: catalog.i18nc("@info", "Please select a network connected printer to monitor.")
- font: UM.Theme.getFont("medium")
- color: UM.Theme.getColor("monitor_text_primary")
- wrapMode: Text.WordWrap
- width: contentWidth
- lineHeight: UM.Theme.getSize("monitor_text_line_large").height
- lineHeightMode: Text.FixedHeight
- }
- Label
- {
- id: noNetworkUltimakerLabel
- anchors
- {
- horizontalCenter: parent.horizontalCenter
- }
visible: !isNetworkConfigured && isNetworkConfigurable
- text: catalog.i18nc("@info", "Please connect your Ultimaker printer to your local network.")
+ text: catalog.i18nc("@info", "Please connect your printer to the network.")
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("monitor_text_primary")
wrapMode: Text.WordWrap
@@ -135,7 +126,7 @@ Rectangle
{
anchors
{
- left: noNetworkUltimakerLabel.left
+ left: noNetworkLabel.left
}
visible: !isNetworkConfigured && isNetworkConfigurable
height: UM.Theme.getSize("monitor_text_line").height
@@ -160,7 +151,7 @@ Rectangle
verticalCenter: externalLinkIcon.verticalCenter
}
color: UM.Theme.getColor("monitor_text_link")
- font: UM.Theme.getFont("medium") // 14pt, regular
+ font: UM.Theme.getFont("medium")
linkColor: UM.Theme.getColor("monitor_text_link")
text: catalog.i18nc("@label link to technical assistance", "View user manuals online")
renderType: Text.NativeRendering
@@ -170,15 +161,9 @@ Rectangle
anchors.fill: parent
hoverEnabled: true
onClicked: Qt.openUrlExternally("https://ultimaker.com/en/resources/manuals/ultimaker-3d-printers")
- onEntered:
- {
- manageQueueText.font.underline = true
- }
- onExited:
- {
- manageQueueText.font.underline = false
- }
+ onEntered: manageQueueText.font.underline = true
+ onExited: manageQueueText.font.underline = false
}
}
}
-}
\ No newline at end of file
+}
diff --git a/plugins/MonitorStage/MonitorStage.py b/plugins/MonitorStage/MonitorStage.py
index 69b7f20f4e..3d2a1c3f37 100644
--- a/plugins/MonitorStage/MonitorStage.py
+++ b/plugins/MonitorStage/MonitorStage.py
@@ -2,8 +2,6 @@
# Cura is released under the terms of the LGPLv3 or higher.
import os.path
from UM.Application import Application
-from UM.PluginRegistry import PluginRegistry
-from UM.Resources import Resources
from cura.Stages.CuraStage import CuraStage
diff --git a/plugins/MonitorStage/__init__.py b/plugins/MonitorStage/__init__.py
index 0468e6319b..a755268c79 100644
--- a/plugins/MonitorStage/__init__.py
+++ b/plugins/MonitorStage/__init__.py
@@ -12,7 +12,7 @@ def getMetaData():
return {
"stage": {
"name": i18n_catalog.i18nc("@item:inmenu", "Monitor"),
- "weight": 2
+ "weight": 30
}
}
diff --git a/plugins/MonitorStage/plugin.json b/plugins/MonitorStage/plugin.json
index 95e4b86f36..2274351527 100644
--- a/plugins/MonitorStage/plugin.json
+++ b/plugins/MonitorStage/plugin.json
@@ -1,8 +1,8 @@
-{
- "name": "Monitor Stage",
- "author": "Ultimaker B.V.",
- "version": "1.0.1",
- "description": "Provides a monitor stage in Cura.",
- "api": "6.0",
- "i18n-catalog": "cura"
+{
+ "name": "Monitor Stage",
+ "author": "Ultimaker B.V.",
+ "version": "1.0.1",
+ "description": "Provides a monitor stage in Cura.",
+ "api": "7.0",
+ "i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/PerObjectSettingsTool/PerObjectItem.qml b/plugins/PerObjectSettingsTool/PerObjectItem.qml
index 559ad2bf81..7c6ece12db 100644
--- a/plugins/PerObjectSettingsTool/PerObjectItem.qml
+++ b/plugins/PerObjectSettingsTool/PerObjectItem.qml
@@ -29,6 +29,17 @@ UM.TooltipArea
UM.ActiveTool.forceUpdate();
}
}
+
+ // When the user removes settings from the list addedSettingsModel, we need to recheck if the
+ // setting is visible or not to show a mark in the CheckBox.
+ Connections
+ {
+ target: addedSettingsModel
+ onVisibleCountChanged:
+ {
+ check.checked = addedSettingsModel.getVisible(model.key)
+ }
+ }
}
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py
index 3e1df1c7b8..61d0dbc0f0 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py
@@ -1,7 +1,7 @@
# Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal
+from PyQt5.QtCore import pyqtProperty
from UM.FlameProfiler import pyqtSlot
from UM.Application import Application
@@ -13,6 +13,7 @@ import UM.Settings.Models.SettingVisibilityHandler
from cura.Settings.ExtruderManager import ExtruderManager #To get global-inherits-stack setting values from different extruders.
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
+
## The per object setting visibility handler ensures that only setting
# definitions that have a matching instance Container are returned as visible.
class PerObjectSettingVisibilityHandler(UM.Settings.Models.SettingVisibilityHandler.SettingVisibilityHandler):
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
index 0e2bd88619..bb342d5045 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
@@ -4,22 +4,68 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
-import QtQuick.Window 2.2
import UM 1.2 as UM
import Cura 1.0 as Cura
import ".."
-Item {
- id: base;
- UM.I18nCatalog { id: catalog; name: "cura"; }
-
- width: childrenRect.width;
- height: childrenRect.height;
- property var all_categories_except_support: [ "machine_settings", "resolution", "shell", "infill", "material", "speed",
+Item
+{
+ id: base
+ width: childrenRect.width
+ height: childrenRect.height
+ property var allCategoriesExceptSupport: [ "machine_settings", "resolution", "shell", "infill", "material", "speed",
"travel", "cooling", "platform_adhesion", "dual", "meshfix", "blackmagic", "experimental"]
+ readonly property string normalMeshType: ""
+ readonly property string supportMeshType: "support_mesh"
+ readonly property string cuttingMeshType: "cutting_mesh"
+ readonly property string infillMeshType: "infill_mesh"
+ readonly property string antiOverhangMeshType: "anti_overhang_mesh"
+
+ property var currentMeshType: UM.ActiveTool.properties.getValue("MeshType")
+
+ // Update the view every time the currentMeshType changes
+ onCurrentMeshTypeChanged:
+ {
+ var type = currentMeshType
+
+ // set checked state of mesh type buttons
+ normalButton.checked = type === normalMeshType
+ supportMeshButton.checked = type === supportMeshType
+ overhangMeshButton.checked = type === infillMeshType || type === cuttingMeshType
+ antiOverhangMeshButton.checked = type === antiOverhangMeshType
+
+ // update active type label
+ for (var button in meshTypeButtons.children)
+ {
+ if (meshTypeButtons.children[button].checked){
+ meshTypeLabel.text = catalog.i18nc("@label", "Mesh Type") + ": " + meshTypeButtons.children[button].text
+ break
+ }
+ }
+ }
+
+ function setOverhangsMeshType()
+ {
+ if (infillOnlyCheckbox.checked)
+ {
+ setMeshType(infillMeshType)
+ }
+ else
+ {
+ setMeshType(cuttingMeshType)
+ }
+ }
+
+ function setMeshType(type)
+ {
+ UM.ActiveTool.setProperty("MeshType", type)
+ }
+
+ UM.I18nCatalog { id: catalog; name: "uranium"}
+
Column
{
id: items
@@ -28,123 +74,97 @@ Item {
spacing: UM.Theme.getSize("default_margin").height
- Row
+ Row // Mesh type buttons
{
+ id: meshTypeButtons
spacing: UM.Theme.getSize("default_margin").width
- Label
+ Button
{
- text: catalog.i18nc("@label","Mesh Type")
- font: UM.Theme.getFont("default")
- color: UM.Theme.getColor("text")
- height: UM.Theme.getSize("setting").height
- verticalAlignment: Text.AlignVCenter
+ id: normalButton
+ text: catalog.i18nc("@label", "Normal model")
+ iconSource: UM.Theme.getIcon("pos_normal");
+ property bool needBorder: true
+ checkable: true
+ onClicked: setMeshType(normalMeshType);
+ style: UM.Theme.styles.tool_button;
+ z: 4
}
- UM.SettingPropertyProvider
+ Button
{
- id: meshTypePropertyProvider
- containerStack: Cura.MachineManager.activeMachine
- watchedProperties: [ "enabled" ]
+ id: supportMeshButton
+ text: catalog.i18nc("@label", "Print as support")
+ iconSource: UM.Theme.getIcon("pos_print_as_support");
+ property bool needBorder: true
+ checkable:true
+ onClicked: setMeshType(supportMeshType)
+ style: UM.Theme.styles.tool_button;
+ z: 3
}
- ComboBox
+ Button
{
- id: meshTypeSelection
- style: UM.Theme.styles.combobox
- onActivated: {
- UM.ActiveTool.setProperty("MeshType", model.get(index).type)
- }
- model: ListModel
- {
- id: meshTypeModel
- Component.onCompleted: meshTypeSelection.populateModel()
- }
-
- function populateModel()
- {
- meshTypeModel.append({
- type: "",
- text: catalog.i18nc("@label", "Normal model")
- });
- meshTypePropertyProvider.key = "support_mesh";
- if(meshTypePropertyProvider.properties.enabled == "True")
- {
- meshTypeModel.append({
- type: "support_mesh",
- text: catalog.i18nc("@label", "Print as support")
- });
- }
- meshTypePropertyProvider.key = "anti_overhang_mesh";
- if(meshTypePropertyProvider.properties.enabled == "True")
- {
- meshTypeModel.append({
- type: "anti_overhang_mesh",
- text: catalog.i18nc("@label", "Don't support overlap with other models")
- });
- }
- meshTypePropertyProvider.key = "cutting_mesh";
- if(meshTypePropertyProvider.properties.enabled == "True")
- {
- meshTypeModel.append({
- type: "cutting_mesh",
- text: catalog.i18nc("@label", "Modify settings for overlap with other models")
- });
- }
- meshTypePropertyProvider.key = "infill_mesh";
- if(meshTypePropertyProvider.properties.enabled == "True")
- {
- meshTypeModel.append({
- type: "infill_mesh",
- text: catalog.i18nc("@label", "Modify settings for infill of other models")
- });
- }
-
- meshTypeSelection.updateCurrentIndex();
- }
-
- function updateCurrentIndex()
- {
- var mesh_type = UM.ActiveTool.properties.getValue("MeshType");
- meshTypeSelection.currentIndex = -1;
- for(var index=0; index < meshTypeSelection.model.count; index++)
- {
- if(meshTypeSelection.model.get(index).type == mesh_type)
- {
- meshTypeSelection.currentIndex = index;
- return;
- }
- }
- meshTypeSelection.currentIndex = 0;
- }
+ id: overhangMeshButton
+ text: catalog.i18nc("@label", "Modify settings for overlaps")
+ iconSource: UM.Theme.getIcon("pos_modify_overlaps");
+ property bool needBorder: true
+ checkable:true
+ onClicked: setMeshType(infillMeshType)
+ style: UM.Theme.styles.tool_button;
+ z: 2
}
- Connections
+ Button
{
- target: Cura.MachineManager
- onGlobalContainerChanged:
- {
- meshTypeSelection.model.clear();
- meshTypeSelection.populateModel();
- }
- }
-
- Connections
- {
- target: UM.Selection
- onSelectionChanged: meshTypeSelection.updateCurrentIndex()
+ id: antiOverhangMeshButton
+ text: catalog.i18nc("@label", "Don't support overlaps")
+ iconSource: UM.Theme.getIcon("pos_modify_dont_support_overlap");
+ property bool needBorder: true
+ checkable: true
+ onClicked: setMeshType(antiOverhangMeshType)
+ style: UM.Theme.styles.tool_button;
+ z: 1
}
}
- Column
+ Label
+ {
+ id: meshTypeLabel
+ font: UM.Theme.getFont("default")
+ color: UM.Theme.getColor("text")
+ height: UM.Theme.getSize("setting").height
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ CheckBox
+ {
+ id: infillOnlyCheckbox
+
+ text: catalog.i18nc("@action:checkbox", "Infill only");
+
+ style: UM.Theme.styles.checkbox;
+
+ visible: currentMeshType === infillMeshType || currentMeshType === cuttingMeshType
+ onClicked: setOverhangsMeshType()
+
+ Binding
+ {
+ target: infillOnlyCheckbox
+ property: "checked"
+ value: currentMeshType === infillMeshType
+ }
+ }
+
+ Column // Settings Dialog
{
// This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
// It kinda looks ugly otherwise (big panel, no content on it)
id: currentSettings
property int maximumHeight: 200 * screenScaleFactor
height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("default_lining").height), maximumHeight)
- visible: meshTypeSelection.model.get(meshTypeSelection.currentIndex).type != "anti_overhang_mesh"
+ visible: currentMeshType != "anti_overhang_mesh"
ScrollView
{
@@ -159,26 +179,26 @@ Item {
model: UM.SettingDefinitionsModel
{
- id: addedSettingsModel;
- containerId: Cura.MachineManager.activeDefinitionId
+ id: addedSettingsModel
+ containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
expanded: [ "*" ]
filter:
{
if (printSequencePropertyProvider.properties.value == "one_at_a_time")
{
- return {"settable_per_meshgroup": true};
+ return {"settable_per_meshgroup": true}
}
- return {"settable_per_mesh": true};
+ return {"settable_per_mesh": true}
}
exclude:
{
- var excluded_settings = [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ];
+ var excluded_settings = [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
- if(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type == "support_mesh")
+ if (currentMeshType == "support_mesh")
{
- excluded_settings = excluded_settings.concat(base.all_categories_except_support);
+ excluded_settings = excluded_settings.concat(base.allCategoriesExceptSupport)
}
- return excluded_settings;
+ return excluded_settings
}
visibilityHandler: Cura.PerObjectSettingVisibilityHandler
@@ -188,8 +208,9 @@ Item {
// For some reason the model object is updated after removing him from the memory and
// it happens only on Windows. For this reason, set the destroyed value manually.
- Component.onDestruction: {
- setDestroyed(true);
+ Component.onDestruction:
+ {
+ setDestroyed(true)
}
}
@@ -213,7 +234,8 @@ Item {
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
asynchronous: model.type != "enum" && model.type != "extruder"
- onLoaded: {
+ onLoaded:
+ {
settingLoader.item.showRevertButton = false
settingLoader.item.showInheritButton = false
settingLoader.item.showLinkedSettingIcon = false
@@ -299,7 +321,7 @@ Item {
target: inheritStackProvider
onPropertiesChanged:
{
- provider.forcePropertiesChanged();
+ provider.forcePropertiesChanged()
}
}
@@ -312,22 +334,22 @@ Item {
// so here we connect to the signal and update the those values.
if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined")
{
- const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId");
+ const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId")
if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId)
{
- addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId;
+ addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId
}
}
if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined")
{
- const containerId = UM.ActiveTool.properties.getValue("ContainerID");
+ const containerId = UM.ActiveTool.properties.getValue("ContainerID")
if (provider.containerStackId != containerId)
{
- provider.containerStackId = containerId;
+ provider.containerStackId = containerId
}
if (inheritStackProvider.containerStackId != containerId)
{
- inheritStackProvider.containerStackId = containerId;
+ inheritStackProvider.containerStackId = containerId
}
}
}
@@ -337,7 +359,7 @@ Item {
}
}
- Button
+ Cura.SecondaryButton
{
id: customiseSettingsButton;
height: UM.Theme.getSize("setting_control").height;
@@ -345,33 +367,12 @@ Item {
text: catalog.i18nc("@action:button", "Select settings");
- style: ButtonStyle
- {
- background: Rectangle
- {
- width: control.width;
- height: control.height;
- border.width: UM.Theme.getSize("default_lining").width;
- border.color: control.pressed ? UM.Theme.getColor("action_button_active_border") :
- control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border")
- color: control.pressed ? UM.Theme.getColor("action_button_active") :
- control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
- }
- label: Label
- {
- text: control.text;
- color: UM.Theme.getColor("setting_control_text");
- font: UM.Theme.getFont("default")
- anchors.centerIn: parent
- }
- }
-
onClicked:
{
settingPickDialog.visible = true;
- if (meshTypeSelection.model.get(meshTypeSelection.currentIndex).type == "support_mesh")
+ if (currentMeshType == "support_mesh")
{
- settingPickDialog.additional_excluded_settings = base.all_categories_except_support;
+ settingPickDialog.additional_excluded_settings = base.allCategoriesExceptSupport;
}
else
{
@@ -379,138 +380,12 @@ Item {
}
}
}
+
}
-
- UM.Dialog {
+ SettingPickDialog
+ {
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)
- {
- // Set skip setting, it will prevent from resetting selected mesh_type
- contents.model.visibilityHandler.addSkipResetSetting(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type)
- listview.model.forceUpdate()
-
- 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;
- }
-
- listview.model.filter = new_filter;
- }
-
- TextField {
- id: filterInput
-
- anchors {
- top: parent.top
- left: parent.left
- right: toggleShowAll.left
- rightMargin: UM.Theme.getSize("default_margin").width
- }
-
- placeholderText: catalog.i18nc("@label:textbox", "Filter...");
-
- onTextChanged: settingPickDialog.updateFilter()
- }
-
- CheckBox
- {
- 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;
- }
- }
-
- ScrollView
- {
- id: scrollView
-
- anchors
- {
- top: filterInput.bottom;
- left: parent.left;
- right: parent.right;
- bottom: parent.bottom;
- }
- ListView
- {
- id:listview
- model: UM.SettingDefinitionsModel
- {
- id: definitionsModel;
- containerId: Cura.MachineManager.activeDefinitionId
- 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)
- {
- case "category":
- return "PerObjectCategory.qml"
- default:
- return "PerObjectItem.qml"
- }
- }
- }
- Component.onCompleted: settingPickDialog.updateFilter()
- }
- }
-
- rightButtons: [
- Button {
- text: catalog.i18nc("@action:button", "Close");
- onClicked: {
- settingPickDialog.visible = false;
- }
- }
- ]
}
UM.SettingPropertyProvider
@@ -533,25 +408,25 @@ Item {
storeIndex: 0
}
- SystemPalette { id: palette; }
+ SystemPalette { id: palette }
Component
{
- id: settingTextField;
+ id: settingTextField
Cura.SettingTextField { }
}
Component
{
- id: settingComboBox;
+ id: settingComboBox
Cura.SettingComboBox { }
}
Component
{
- id: settingExtruder;
+ id: settingExtruder
Cura.SettingExtruder { }
}
@@ -565,22 +440,23 @@ Item {
Component
{
- id: settingCheckBox;
+ id: settingCheckBox
Cura.SettingCheckBox { }
}
Component
{
- id: settingCategory;
+ id: settingCategory
Cura.SettingCategory { }
}
Component
{
- id: settingUnknown;
+ id: settingUnknown
Cura.SettingUnknown { }
}
+
}
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py
index baa700165c..b2eb925a6d 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py
@@ -1,6 +1,6 @@
# Copyright (c) 2016 Ultimaker B.V.
# Uranium is released under the terms of the LGPLv3 or higher.
-
+from UM.Logger import Logger
from UM.Tool import Tool
from UM.Scene.Selection import Selection
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
@@ -20,15 +20,11 @@ class PerObjectSettingsTool(Tool):
self.setExposedProperties("SelectedObjectId", "ContainerID", "SelectedActiveExtruder", "MeshType")
- self._advanced_mode = False
self._multi_extrusion = False
self._single_model_selected = False
Selection.selectionChanged.connect(self.propertyChanged)
- Application.getInstance().getPreferences().preferenceChanged.connect(self._onPreferenceChanged)
- self._onPreferenceChanged("cura/active_mode")
-
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
self._onGlobalContainerChanged()
Selection.selectionChanged.connect(self._updateEnabled)
@@ -70,8 +66,16 @@ class PerObjectSettingsTool(Tool):
selected_object.addDecorator(SettingOverrideDecorator())
selected_object.callDecoration("setActiveExtruder", extruder_stack_id)
- def setMeshType(self, mesh_type):
+ ## Returns True when the mesh_type was changed, False when current mesh_type == mesh_type
+ def setMeshType(self, mesh_type: str) -> bool:
+ if self.getMeshType() == mesh_type:
+ return False
+
selected_object = Selection.getSelectedObject(0)
+ if selected_object is None:
+ Logger.log("w", "Tried setting the mesh type of the selected object, but no object was selected")
+ return False
+
stack = selected_object.callDecoration("getStack") #Don't try to get the active extruder since it may be None anyway.
if not stack:
selected_object.addDecorator(SettingOverrideDecorator())
@@ -90,6 +94,9 @@ class PerObjectSettingsTool(Tool):
new_instance.resetState() # Ensure that the state is not seen as a user state.
settings.addInstance(new_instance)
+ self.propertyChanged.emit()
+ return True
+
def getMeshType(self):
selected_object = Selection.getSelectedObject(0)
stack = selected_object.callDecoration("getStack") #Don't try to get the active extruder since it may be None anyway.
@@ -103,11 +110,6 @@ class PerObjectSettingsTool(Tool):
return ""
- def _onPreferenceChanged(self, preference):
- if preference == "cura/active_mode":
- self._advanced_mode = Application.getInstance().getPreferences().getValue(preference) == 1
- self._updateEnabled()
-
def _onGlobalContainerChanged(self):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
@@ -140,4 +142,4 @@ class PerObjectSettingsTool(Tool):
self._single_model_selected = False # Group is selected, so tool needs to be disabled
else:
self._single_model_selected = True
- Application.getInstance().getController().toolEnabledChanged.emit(self._plugin_id, self._advanced_mode and self._single_model_selected)
+ Application.getInstance().getController().toolEnabledChanged.emit(self._plugin_id, self._single_model_selected)
diff --git a/plugins/PerObjectSettingsTool/SettingPickDialog.qml b/plugins/PerObjectSettingsTool/SettingPickDialog.qml
new file mode 100644
index 0000000000..92e22f26bc
--- /dev/null
+++ b/plugins/PerObjectSettingsTool/SettingPickDialog.qml
@@ -0,0 +1,139 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2
+
+import UM 1.2 as UM
+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:
+ {
+ // 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()
+
+ 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
+ }
+
+ listview.model.filter = new_filter
+ }
+
+ TextField {
+ id: filterInput
+
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: toggleShowAll.left
+ rightMargin: UM.Theme.getSize("default_margin").width
+ }
+
+ placeholderText: catalog.i18nc("@label:textbox", "Filter...")
+
+ onTextChanged: settingPickDialog.updateFilter()
+ }
+
+ CheckBox
+ {
+ 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
+ }
+ }
+
+ ScrollView
+ {
+ id: scrollView
+
+ anchors
+ {
+ 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:
+ {
+ 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)
+ {
+ case "category":
+ return "PerObjectCategory.qml"
+ default:
+ return "PerObjectItem.qml"
+ }
+ }
+ }
+ Component.onCompleted: settingPickDialog.updateFilter()
+ }
+ }
+
+ rightButtons: [
+ Button {
+ text: catalog.i18nc("@action:button", "Close")
+ onClicked: {
+ settingPickDialog.visible = false
+ }
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/plugins/PerObjectSettingsTool/plugin.json b/plugins/PerObjectSettingsTool/plugin.json
index f272abf06a..b30acfd52e 100644
--- a/plugins/PerObjectSettingsTool/plugin.json
+++ b/plugins/PerObjectSettingsTool/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides the Per Model Settings.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/PerObjectSettingsTool/tool_icon.svg b/plugins/PerObjectSettingsTool/tool_icon.svg
index 4b15eb453f..41e49cae07 100644
--- a/plugins/PerObjectSettingsTool/tool_icon.svg
+++ b/plugins/PerObjectSettingsTool/tool_icon.svg
@@ -1,3 +1,22 @@
-
+
+
\ No newline at end of file
diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
index 78f9cc0516..376ab291c4 100644
--- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py
+++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
@@ -162,7 +162,7 @@ class PostProcessingPlugin(QObject, Extension):
loaded_script = importlib.util.module_from_spec(spec)
if spec.loader is None:
continue
- spec.loader.exec_module(loaded_script)
+ spec.loader.exec_module(loaded_script) # type: ignore
sys.modules[script_name] = loaded_script #TODO: This could be a security risk. Overwrite any module with a user-provided name?
loaded_class = getattr(loaded_script, script_name)
@@ -219,6 +219,7 @@ class PostProcessingPlugin(QObject, Extension):
self._script_list.clear()
if not new_stack.getMetaDataEntry("post_processing_scripts"): # Missing or empty.
self.scriptListChanged.emit() # Even emit this if it didn't change. We want it to write the empty list to the stack's metadata.
+ self.setSelectedScriptIndex(-1)
return
self._script_list.clear()
diff --git a/plugins/PostProcessingPlugin/plugin.json b/plugins/PostProcessingPlugin/plugin.json
index 1e73133c53..6a2b84933e 100644
--- a/plugins/PostProcessingPlugin/plugin.json
+++ b/plugins/PostProcessingPlugin/plugin.json
@@ -2,7 +2,7 @@
"name": "Post Processing",
"author": "Ultimaker",
"version": "2.2.1",
- "api": "6.0",
+ "api": "7.0",
"description": "Extension that allows for user created scripts for post processing",
"catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
index be9f93c0f6..cdbb4a79ef 100644
--- a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
+++ b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
@@ -100,8 +100,8 @@ class ChangeAtZ(Script):
},
"d_twLayers":
{
- "label": "No. Layers",
- "description": "No. of layers used to change",
+ "label": "Layer Spread",
+ "description": "The change will be gradual over this many layers. Enter 1 to make the change immediate.",
"unit": "",
"type": "int",
"default_value": 1,
@@ -330,7 +330,7 @@ class ChangeAtZ(Script):
"extruderOne": self.getSettingValueByKey("i2_extruderOne"),
"extruderTwo": self.getSettingValueByKey("i4_extruderTwo"),
"fanSpeed": self.getSettingValueByKey("j2_fanSpeed")}
- old = {"speed": -1, "flowrate": -1, "flowrateOne": -1, "flowrateTwo": -1, "platformTemp": -1, "extruderOne": -1,
+ old = {"speed": -1, "flowrate": 100, "flowrateOne": -1, "flowrateTwo": -1, "platformTemp": -1, "extruderOne": -1,
"extruderTwo": -1, "bedTemp": -1, "fanSpeed": -1, "state": -1}
twLayers = self.getSettingValueByKey("d_twLayers")
if self.getSettingValueByKey("c_behavior") == "single_layer":
@@ -367,6 +367,8 @@ class ChangeAtZ(Script):
modified_gcode = ""
lines = active_layer.split("\n")
for line in lines:
+ if line.strip() == "":
+ continue
if ";Generated with Cura_SteamEngine" in line:
TWinstances += 1
modified_gcode += ";ChangeAtZ instances: %d\n" % TWinstances
@@ -410,6 +412,8 @@ class ChangeAtZ(Script):
tmp_extruder = self.getValue(line, "T", None)
if tmp_extruder == None: #check if extruder is specified
old["flowrate"] = self.getValue(line, "S", old["flowrate"])
+ if old["flowrate"] == -1:
+ old["flowrate"] = 100.0
elif tmp_extruder == 0: #first extruder
old["flowrateOne"] = self.getValue(line, "S", old["flowrateOne"])
elif tmp_extruder == 1: #second extruder
@@ -481,9 +485,9 @@ class ChangeAtZ(Script):
state = 2
done_layers = 0
if targetL_i > -100000:
- modified_gcode += ";ChangeAtZ V%s: reset below Layer %d\n" % (self.version,targetL_i)
+ modified_gcode += ";ChangeAtZ V%s: reset below Layer %d\n" % (self.version, targetL_i)
else:
- modified_gcode += ";ChangeAtZ V%s: reset below %1.2f mm\n" % (self.version,targetZ)
+ modified_gcode += ";ChangeAtZ V%s: reset below %1.2f mm\n" % (self.version, targetZ)
if IsUM2 and oldValueUnknown: #executes on UM2 with Ultigcode and machine setting
modified_gcode += "M606 S%d;recalls saved settings\n" % (TWinstances-1)
else: #executes on RepRap, UM2 with Ultigcode and Cura setting
diff --git a/plugins/PostProcessingPlugin/scripts/DisplayFilenameAndLayerOnLCD.py b/plugins/PostProcessingPlugin/scripts/DisplayFilenameAndLayerOnLCD.py
index 9fd9e08d7d..001beecd3b 100644
--- a/plugins/PostProcessingPlugin/scripts/DisplayFilenameAndLayerOnLCD.py
+++ b/plugins/PostProcessingPlugin/scripts/DisplayFilenameAndLayerOnLCD.py
@@ -1,10 +1,13 @@
# Cura PostProcessingPlugin
# Author: Amanda de Castilho
# Date: August 28, 2018
+# Modified: November 16, 2018 by Joshua Pope-Lewis
-# Description: This plugin inserts a line at the start of each layer,
-# M117 - displays the filename and layer height to the LCD
-# Alternatively, user can override the filename to display alt text + layer height
+# Description: This plugin shows custom messages about your print on the Status bar...
+# Please look at the 3 options
+# - Scolling (SCROLL_LONG_FILENAMES) if enabled in Marlin and you arent printing a small item select this option.
+# - Name: By default it will use the name generated by Cura (EG: TT_Test_Cube) - Type a custom name in here
+# - Max Layer: Enabling this will show how many layers are in the entire print (EG: Layer 1 of 265!)
from ..Script import Script
from UM.Application import Application
@@ -15,35 +18,72 @@ class DisplayFilenameAndLayerOnLCD(Script):
def getSettingDataString(self):
return """{
- "name": "Display filename and layer on LCD",
+ "name": "Display Filename And Layer On LCD",
"key": "DisplayFilenameAndLayerOnLCD",
"metadata": {},
"version": 2,
"settings":
{
+ "scroll":
+ {
+ "label": "Scroll enabled/Small layers?",
+ "description": "If SCROLL_LONG_FILENAMES is enabled select this setting however, if the model is small disable this setting!",
+ "type": "bool",
+ "default_value": false
+ },
"name":
{
- "label": "text to display:",
+ "label": "Text to display:",
"description": "By default the current filename will be displayed on the LCD. Enter text here to override the filename and display something else.",
"type": "str",
"default_value": ""
+ },
+ "startNum":
+ {
+ "label": "Initial layer number:",
+ "description": "Choose which number you prefer for the initial layer, 0 or 1",
+ "type": "int",
+ "default_value": 0,
+ "minimum_value": 0,
+ "maximum_value": 1
+ },
+ "maxlayer":
+ {
+ "label": "Display max layer?:",
+ "description": "Display how many layers are in the entire print on status bar?",
+ "type": "bool",
+ "default_value": true
}
}
}"""
def execute(self, data):
+ max_layer = 0
if self.getSettingValueByKey("name") != "":
name = self.getSettingValueByKey("name")
else:
- name = Application.getInstance().getPrintInformation().jobName
- lcd_text = "M117 " + name + " layer: "
- i = 0
+ name = Application.getInstance().getPrintInformation().jobName
+ if not self.getSettingValueByKey("scroll"):
+ if self.getSettingValueByKey("maxlayer"):
+ lcd_text = "M117 Layer "
+ else:
+ lcd_text = "M117 Printing Layer "
+ else:
+ lcd_text = "M117 Printing " + name + " - Layer "
+ i = self.getSettingValueByKey("startNum")
for layer in data:
- display_text = lcd_text + str(i)
+ display_text = lcd_text + str(i) + " " + name
layer_index = data.index(layer)
lines = layer.split("\n")
for line in lines:
+ if line.startswith(";LAYER_COUNT:"):
+ max_layer = line
+ max_layer = max_layer.split(":")[1]
if line.startswith(";LAYER:"):
+ if self.getSettingValueByKey("maxlayer"):
+ display_text = display_text + " of " + max_layer
+ else:
+ display_text = display_text + "!"
line_index = lines.index(line)
lines.insert(line_index + 1, display_text)
i += 1
diff --git a/plugins/PostProcessingPlugin/scripts/DisplayRemainingTimeOnLCD.py b/plugins/PostProcessingPlugin/scripts/DisplayRemainingTimeOnLCD.py
new file mode 100644
index 0000000000..7d9af10925
--- /dev/null
+++ b/plugins/PostProcessingPlugin/scripts/DisplayRemainingTimeOnLCD.py
@@ -0,0 +1,94 @@
+# Cura PostProcessingPlugin
+# Author: Mathias Lyngklip Kjeldgaard
+# Date: July 31, 2019
+# Modified: November 26, 2019
+
+# Description: This plugin displayes the remaining time on the LCD of the printer
+# using the estimated print-time generated by Cura.
+
+
+
+
+from ..Script import Script
+
+import re
+import datetime
+
+
+class DisplayRemainingTimeOnLCD(Script):
+
+ def __init__(self):
+ super().__init__()
+
+
+ def getSettingDataString(self):
+ return """{
+ "name":"Display Remaining Time on LCD",
+ "key":"DisplayRemainingTimeOnLCD",
+ "metadata": {},
+ "version": 2,
+ "settings":
+ {
+ "TurnOn":
+ {
+ "label": "Enable",
+ "description": "When enabled, It will write Time Left: HHMMSS on the display. This is updated every layer.",
+ "type": "bool",
+ "default_value": false
+ }
+ }
+ }"""
+
+ def execute(self, data):
+ if self.getSettingValueByKey("TurnOn"):
+ total_time = 0
+ total_time_string = ""
+ for layer in data:
+ layer_index = data.index(layer)
+ lines = layer.split("\n")
+ for line in lines:
+ if line.startswith(";TIME:"):
+ # At this point, we have found a line in the GCODE with ";TIME:"
+ # which is the indication of total_time. Looks like: ";TIME:1337", where
+ # 1337 is the total print time in seconds.
+ line_index = lines.index(line) # We take a hold of that line
+ split_string = re.split(":", line) # Then we split it, so we can get the number
+
+ string_with_numbers = "{}".format(split_string[1]) # Here we insert that number from the
+ # list into a string.
+ total_time = int(string_with_numbers) # Only to contert it to a int.
+
+ m, s = divmod(total_time, 60) # Math to calculate
+ h, m = divmod(m, 60) # hours, minutes and seconds.
+ total_time_string = "{:d}h{:02d}m{:02d}s".format(h, m, s) # Now we put it into the string
+ lines[line_index] = "M117 Time Left {}".format(total_time_string) # And print that string instead of the original one
+
+
+
+
+ elif line.startswith(";TIME_ELAPSED:"):
+
+ # As we didnt find the total time (";TIME:"), we have found a elapsed time mark
+ # This time represents the time the printer have printed. So with some math;
+ # totalTime - printTime = RemainingTime.
+ line_index = lines.index(line) # We get a hold of the line
+ list_split = re.split(":", line) # Again, we split at ":" so we can get the number
+ string_with_numbers = "{}".format(list_split[1]) # Then we put that number from the list, into a string
+
+ current_time = float(string_with_numbers) # This time we convert to a float, as the line looks something like:
+ # ;TIME_ELAPSED:1234.6789
+ # which is total time in seconds
+
+ time_left = total_time - current_time # Here we calculate remaining time
+ m1, s1 = divmod(time_left, 60) # And some math to get the total time in seconds into
+ h1, m1 = divmod(m1, 60) # the right format. (HH,MM,SS)
+ current_time_string = "{:d}h{:2d}m{:2d}s".format(int(h1), int(m1), int(s1)) # Here we create the string holding our time
+ lines[line_index] = "M117 Time Left {}".format(current_time_string) # And now insert that into the GCODE
+
+
+ # Here we are OUT of the second for-loop
+ # Which means we have found and replaces all the occurences.
+ # Which also means we are ready to join the lines for that section of the GCODE file.
+ final_lines = "\n".join(lines)
+ data[layer_index] = final_lines
+ return data
diff --git a/plugins/PostProcessingPlugin/scripts/FilamentChange.py b/plugins/PostProcessingPlugin/scripts/FilamentChange.py
index febb93be4c..943ca30f2e 100644
--- a/plugins/PostProcessingPlugin/scripts/FilamentChange.py
+++ b/plugins/PostProcessingPlugin/scripts/FilamentChange.py
@@ -1,9 +1,7 @@
# Copyright (c) 2019 Ultimaker B.V.
# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
-from typing import Optional, Tuple
-
-from UM.Logger import Logger
+from typing import List
from ..Script import Script
class FilamentChange(Script):
@@ -65,9 +63,10 @@ class FilamentChange(Script):
}
}"""
- def execute(self, data: list):
-
- """data is a list. Each index contains a layer"""
+ ## Inserts the filament change g-code at specific layer numbers.
+ # \param data A list of layers of g-code.
+ # \return A similar list, with filament change commands inserted.
+ def execute(self, data: List[str]):
layer_nums = self.getSettingValueByKey("layer_number")
initial_retract = self.getSettingValueByKey("initial_retract")
later_retract = self.getSettingValueByKey("later_retract")
@@ -88,32 +87,16 @@ class FilamentChange(Script):
if y_pos is not None:
color_change = color_change + (" Y%.2f" % y_pos)
- color_change = color_change + " ; Generated by FilamentChange plugin"
+ color_change = color_change + " ; Generated by FilamentChange plugin\n"
layer_targets = layer_nums.split(",")
if len(layer_targets) > 0:
for layer_num in layer_targets:
- layer_num = int(layer_num.strip())
- if layer_num <= len(data):
- index, layer_data = self._searchLayerData(data, layer_num - 1)
- if layer_data is None:
- Logger.log("e", "Could not found the layer")
- continue
- lines = layer_data.split("\n")
- lines.insert(2, color_change)
- final_line = "\n".join(lines)
- data[index] = final_line
+ try:
+ layer_num = int(layer_num.strip()) + 1 #Needs +1 because the 1st layer is reserved for start g-code.
+ except ValueError: #Layer number is not an integer.
+ continue
+ if 0 < layer_num < len(data):
+ data[layer_num] = color_change + data[layer_num]
- return data
-
- ## This method returns the data corresponding with the indicated layer number, looking in the gcode for
- # the occurrence of this layer number.
- def _searchLayerData(self, data: list, layer_num: int) -> Tuple[int, Optional[str]]:
- for index, layer_data in enumerate(data):
- first_line = layer_data.split("\n")[0]
- # The first line should contain the layer number at the beginning.
- if first_line[:len(self._layer_keyword)] == self._layer_keyword:
- # If found the layer that we are looking for, then return the data
- if first_line[len(self._layer_keyword):] == str(layer_num):
- return index, layer_data
- return 0, None
\ No newline at end of file
+ return data
\ No newline at end of file
diff --git a/plugins/PostProcessingPlugin/scripts/InsertAtLayerChange.py b/plugins/PostProcessingPlugin/scripts/InsertAtLayerChange.py
new file mode 100644
index 0000000000..c21993aad1
--- /dev/null
+++ b/plugins/PostProcessingPlugin/scripts/InsertAtLayerChange.py
@@ -0,0 +1,50 @@
+# Created by Wayne Porter
+
+from ..Script import Script
+
+class InsertAtLayerChange(Script):
+ def __init__(self):
+ super().__init__()
+
+ def getSettingDataString(self):
+ return """{
+ "name": "Insert at layer change",
+ "key": "InsertAtLayerChange",
+ "metadata": {},
+ "version": 2,
+ "settings":
+ {
+ "insert_location":
+ {
+ "label": "When to insert",
+ "description": "Whether to insert code before or after layer change.",
+ "type": "enum",
+ "options": {"before": "Before", "after": "After"},
+ "default_value": "before"
+ },
+ "gcode_to_add":
+ {
+ "label": "GCODE to insert.",
+ "description": "GCODE to add before or after layer change.",
+ "type": "str",
+ "default_value": ""
+ }
+ }
+ }"""
+
+ def execute(self, data):
+ gcode_to_add = self.getSettingValueByKey("gcode_to_add") + "\n"
+ for layer in data:
+ # Check that a layer is being printed
+ lines = layer.split("\n")
+ for line in lines:
+ if ";LAYER:" in line:
+ index = data.index(layer)
+ if self.getSettingValueByKey("insert_location") == "before":
+ layer = gcode_to_add + layer
+ else:
+ layer = layer + gcode_to_add
+
+ data[index] = layer
+ break
+ return data
diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py
index 8b50a88b7f..17b4de88dd 100644
--- a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py
+++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py
@@ -1,15 +1,18 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from ..Script import Script
from UM.Application import Application #To get the current printer's settings.
+from UM.Logger import Logger
+
+from typing import List, Tuple
class PauseAtHeight(Script):
- def __init__(self):
+ def __init__(self) -> None:
super().__init__()
- def getSettingDataString(self):
+ def getSettingDataString(self) -> str:
return """{
"name": "Pause at height",
"key": "PauseAtHeight",
@@ -105,19 +108,24 @@ class PauseAtHeight(Script):
"standby_temperature":
{
"label": "Standby Temperature",
- "description": "Change the temperature during the pause",
+ "description": "Change the temperature during the pause.",
"unit": "°C",
"type": "int",
"default_value": 0
+ },
+ "display_text":
+ {
+ "label": "Display Text",
+ "description": "Text that should appear on the display while paused. If left empty, there will not be any message.",
+ "type": "str",
+ "default_value": ""
}
}
}"""
- def getNextXY(self, layer: str):
- """
- Get the X and Y values for a layer (will be used to get X and Y of
- the layer after the pause
- """
+ ## Get the X and Y values for a layer (will be used to get X and Y of the
+ # layer after the pause).
+ def getNextXY(self, layer: str) -> Tuple[float, float]:
lines = layer.split("\n")
for line in lines:
if self.getValue(line, "X") is not None and self.getValue(line, "Y") is not None:
@@ -126,8 +134,10 @@ class PauseAtHeight(Script):
return x, y
return 0, 0
- def execute(self, data: list):
- """data is a list. Each index contains a layer"""
+ ## Inserts the pause commands.
+ # \param data: List of layers.
+ # \return New list of layers.
+ def execute(self, data: List[str]) -> List[str]:
pause_at = self.getSettingValueByKey("pause_at")
pause_height = self.getSettingValueByKey("pause_height")
pause_layer = self.getSettingValueByKey("pause_layer")
@@ -143,6 +153,7 @@ class PauseAtHeight(Script):
firmware_retract = Application.getInstance().getGlobalContainerStack().getProperty("machine_firmware_retract", "value")
control_temperatures = Application.getInstance().getGlobalContainerStack().getProperty("machine_nozzle_temp_enabled", "value")
initial_layer_height = Application.getInstance().getGlobalContainerStack().getProperty("layer_height_0", "value")
+ display_text = self.getSettingValueByKey("display_text")
is_griffin = False
@@ -151,6 +162,9 @@ class PauseAtHeight(Script):
# use offset to calculate the current height: = -
layer_0_z = 0
current_z = 0
+ current_height = 0
+ current_layer = 0
+ current_extrusion_f = 0
got_first_g_cmd_on_layer_0 = False
current_t = 0 #Tracks the current extruder for tracking the target temperature.
target_temperature = {} #Tracks the current target temperature for each extruder.
@@ -184,6 +198,10 @@ class PauseAtHeight(Script):
if not layers_started:
continue
+ # Look for the feed rate of an extrusion instruction
+ if self.getValue(line, "F") is not None and self.getValue(line, "E") is not None:
+ current_extrusion_f = self.getValue(line, "F")
+
# If a Z instruction is in the line, read the current Z
if self.getValue(line, "Z") is not None:
current_z = self.getValue(line, "Z")
@@ -201,7 +219,7 @@ class PauseAtHeight(Script):
current_height = current_z - layer_0_z
if current_height < pause_height:
- break # Try the next layer.
+ continue # Scan the enitre layer, z-changes are not always on the same/first line.
# Pause at layer
else:
@@ -247,8 +265,8 @@ class PauseAtHeight(Script):
# the nozzle)
x, y = self.getNextXY(layer)
prev_lines = prev_layer.split("\n")
- for line in prev_lines:
- new_e = self.getValue(line, 'E', current_e)
+ for lin in prev_lines:
+ new_e = self.getValue(lin, "E", current_e)
if new_e != current_e:
current_e = new_e
break
@@ -264,7 +282,7 @@ class PauseAtHeight(Script):
if not is_griffin:
# Retraction
- prepend_gcode += self.putValue(M = 83) + "\n"
+ prepend_gcode += self.putValue(M = 83) + " ; switch to relative E values for any needed retraction\n"
if retraction_amount != 0:
if firmware_retract: #Can't set the distance directly to what the user wants. We have to choose ourselves.
retraction_count = 1 if control_temperatures else 3 #Retract more if we don't control the temperature.
@@ -274,25 +292,28 @@ class PauseAtHeight(Script):
prepend_gcode += self.putValue(G = 1, E = -retraction_amount, F = retraction_speed * 60) + "\n"
# Move the head away
- prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + "\n"
+ prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + " ; move up a millimeter to get out of the way\n"
# This line should be ok
prepend_gcode += self.putValue(G = 1, X = park_x, Y = park_y, F = 9000) + "\n"
if current_z < 15:
- prepend_gcode += self.putValue(G = 1, Z = 15, F = 300) + "\n"
+ prepend_gcode += self.putValue(G = 1, Z = 15, F = 300) + " ; too close to bed--move to at least 15mm\n"
if control_temperatures:
# Set extruder standby temperature
- prepend_gcode += self.putValue(M = 104, S = standby_temperature) + "; standby temperature\n"
+ prepend_gcode += self.putValue(M = 104, S = standby_temperature) + " ; standby temperature\n"
+
+ if display_text:
+ prepend_gcode += "M117 " + display_text + "\n"
# Wait till the user continues printing
- prepend_gcode += self.putValue(M = 0) + ";Do the actual pause\n"
+ prepend_gcode += self.putValue(M = 0) + " ; Do the actual pause\n"
if not is_griffin:
if control_temperatures:
# Set extruder resume temperature
- prepend_gcode += self.putValue(M = 109, S = int(target_temperature.get(current_t, 0))) + "; resume temperature\n"
+ prepend_gcode += self.putValue(M = 109, S = int(target_temperature.get(current_t, 0))) + " ; resume temperature\n"
# Push the filament back,
if retraction_amount != 0:
@@ -308,8 +329,10 @@ class PauseAtHeight(Script):
prepend_gcode += self.putValue(G = 1, E = -retraction_amount, F = retraction_speed * 60) + "\n"
# Move the head back
- prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + "\n"
+ if current_z < 15:
+ prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + "\n"
prepend_gcode += self.putValue(G = 1, X = x, Y = y, F = 9000) + "\n"
+ prepend_gcode += self.putValue(G = 1, Z = current_z, F = 300) + " ; move back down to resume height\n"
if retraction_amount != 0:
if firmware_retract: #Can't set the distance directly to what the user wants. We have to choose ourselves.
retraction_count = 1 if control_temperatures else 3 #Retract more if we don't control the temperature.
@@ -317,8 +340,13 @@ class PauseAtHeight(Script):
prepend_gcode += self.putValue(G = 11) + "\n"
else:
prepend_gcode += self.putValue(G = 1, E = retraction_amount, F = retraction_speed * 60) + "\n"
- prepend_gcode += self.putValue(G = 1, F = 9000) + "\n"
- prepend_gcode += self.putValue(M = 82) + "\n"
+
+ if current_extrusion_f != 0:
+ prepend_gcode += self.putValue(G = 1, F = current_extrusion_f) + " ; restore extrusion feedrate\n"
+ else:
+ Logger.log("w", "No previous feedrate found in gcode, feedrate for next layer(s) might be incorrect")
+
+ prepend_gcode += self.putValue(M = 82) + " ; switch back to absolute E values\n"
# reset extrude value to pre pause value
prepend_gcode += self.putValue(G = 92, E = current_e) + "\n"
diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeightforRepetier.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeightforRepetier.py
index f6c93d9ae6..0353574289 100644
--- a/plugins/PostProcessingPlugin/scripts/PauseAtHeightforRepetier.py
+++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeightforRepetier.py
@@ -1,3 +1,4 @@
+from UM.Logger import Logger
from ..Script import Script
class PauseAtHeightforRepetier(Script):
def __init__(self):
@@ -73,6 +74,7 @@ class PauseAtHeightforRepetier(Script):
def execute(self, data):
x = 0.
y = 0.
+ current_extrusion_f = 0
current_z = 0.
pause_z = self.getSettingValueByKey("pause_height")
retraction_amount = self.getSettingValueByKey("retraction_amount")
@@ -94,9 +96,11 @@ class PauseAtHeightforRepetier(Script):
if self.getValue(line, 'G') == 1 or self.getValue(line, 'G') == 0:
current_z = self.getValue(line, 'Z')
+ if self.getValue(line, 'F') is not None and self.getValue(line, 'E') is not None:
+ current_extrusion_f = self.getValue(line, 'F', current_extrusion_f)
x = self.getValue(line, 'X', x)
y = self.getValue(line, 'Y', y)
- if current_z != None:
+ if current_z is not None:
if current_z >= pause_z:
index = data.index(layer)
@@ -150,7 +154,12 @@ class PauseAtHeightforRepetier(Script):
prepend_gcode +="G1 X%f Y%f F9000\n" % (x, y)
if retraction_amount != 0:
prepend_gcode +="G1 E%f F6000\n" % (retraction_amount)
- prepend_gcode +="G1 F9000\n"
+
+ if current_extrusion_f != 0:
+ prepend_gcode += self.putValue(G=1, F=current_extrusion_f) + " ; restore extrusion feedrate\n"
+ else:
+ Logger.log("w", "No previous feedrate found in gcode, feedrate for next layer(s) might be incorrect")
+
prepend_gcode +="M82\n"
# reset extrude value to pre pause value
diff --git a/plugins/PostProcessingPlugin/scripts/RetractContinue.py b/plugins/PostProcessingPlugin/scripts/RetractContinue.py
new file mode 100644
index 0000000000..b0af9cd95e
--- /dev/null
+++ b/plugins/PostProcessingPlugin/scripts/RetractContinue.py
@@ -0,0 +1,75 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
+
+import math
+
+from ..Script import Script
+
+## Continues retracting during all travel moves.
+class RetractContinue(Script):
+ def getSettingDataString(self):
+ return """{
+ "name": "Retract Continue",
+ "key": "RetractContinue",
+ "metadata": {},
+ "version": 2,
+ "settings":
+ {
+ "extra_retraction_speed":
+ {
+ "label": "Extra Retraction Ratio",
+ "description": "How much does it retract during the travel move, by ratio of the travel length.",
+ "type": "float",
+ "default_value": 0.05
+ }
+ }
+ }"""
+
+ def execute(self, data):
+ current_e = 0
+ current_x = 0
+ current_y = 0
+ extra_retraction_speed = self.getSettingValueByKey("extra_retraction_speed")
+
+ for layer_number, layer in enumerate(data):
+ lines = layer.split("\n")
+ for line_number, line in enumerate(lines):
+ if self.getValue(line, "G") in {0, 1}: # Track X,Y location.
+ current_x = self.getValue(line, "X", current_x)
+ current_y = self.getValue(line, "Y", current_y)
+ if self.getValue(line, "G") == 1:
+ if self.getValue(line, "E"):
+ new_e = self.getValue(line, "E")
+ if new_e >= current_e: # Not a retraction.
+ continue
+ # A retracted travel move may consist of multiple commands, due to combing.
+ # This continues retracting over all of these moves and only unretracts at the end.
+ delta_line = 1
+ dx = current_x # Track the difference in X for this move only to compute the length of the travel.
+ dy = current_y
+ while line_number + delta_line < len(lines) and self.getValue(lines[line_number + delta_line], "G") != 1:
+ travel_move = lines[line_number + delta_line]
+ if self.getValue(travel_move, "G") != 0:
+ delta_line += 1
+ continue
+ travel_x = self.getValue(travel_move, "X", dx)
+ travel_y = self.getValue(travel_move, "Y", dy)
+ f = self.getValue(travel_move, "F", "no f")
+ length = math.sqrt((travel_x - dx) * (travel_x - dx) + (travel_y - dy) * (travel_y - dy)) # Length of the travel move.
+ new_e -= length * extra_retraction_speed # New retraction is by ratio of this travel move.
+ if f == "no f":
+ new_travel_move = "G1 X{travel_x} Y{travel_y} E{new_e}".format(travel_x = travel_x, travel_y = travel_y, new_e = new_e)
+ else:
+ new_travel_move = "G1 F{f} X{travel_x} Y{travel_y} E{new_e}".format(f = f, travel_x = travel_x, travel_y = travel_y, new_e = new_e)
+ lines[line_number + delta_line] = new_travel_move
+
+ delta_line += 1
+ dx = travel_x
+ dy = travel_y
+
+ current_e = new_e
+
+ new_layer = "\n".join(lines)
+ data[layer_number] = new_layer
+
+ return data
\ No newline at end of file
diff --git a/plugins/PostProcessingPlugin/scripts/Stretch.py b/plugins/PostProcessingPlugin/scripts/Stretch.py
index 9757296041..20eef60ef2 100644
--- a/plugins/PostProcessingPlugin/scripts/Stretch.py
+++ b/plugins/PostProcessingPlugin/scripts/Stretch.py
@@ -128,9 +128,26 @@ class Stretcher():
onestep = GCodeStep(0, in_relative_movement)
onestep.copyPosFrom(current)
elif _getValue(line, "G") == 1:
+ last_x = current.step_x
+ last_y = current.step_y
+ last_z = current.step_z
+ last_e = current.step_e
current.readStep(line)
- onestep = GCodeStep(1, in_relative_movement)
- onestep.copyPosFrom(current)
+ if (current.step_x == last_x and current.step_y == last_y and
+ current.step_z == last_z and current.step_e != last_e
+ ):
+ # It's an extruder only move. Preserve it rather than process it as an
+ # extruded move. Otherwise, the stretched output might contain slight
+ # motion in X and Y in addition to E. This can cause problems with
+ # firmwares that implement pressure advance.
+ onestep = GCodeStep(-1, in_relative_movement)
+ onestep.copyPosFrom(current)
+ # Rather than copy the original line, write a new one with consistent
+ # extruder coordinates
+ onestep.comment = "G1 F{} E{}".format(onestep.step_f, onestep.step_e)
+ else:
+ onestep = GCodeStep(1, in_relative_movement)
+ onestep.copyPosFrom(current)
# end of relative movement
elif _getValue(line, "G") == 90:
@@ -145,6 +162,7 @@ class Stretcher():
current.readStep(line)
onestep = GCodeStep(-1, in_relative_movement)
onestep.copyPosFrom(current)
+ onestep.comment = line
else:
onestep = GCodeStep(-1, in_relative_movement)
onestep.copyPosFrom(current)
diff --git a/plugins/PostProcessingPlugin/scripts/TimeLapse.py b/plugins/PostProcessingPlugin/scripts/TimeLapse.py
new file mode 100644
index 0000000000..53e55a9454
--- /dev/null
+++ b/plugins/PostProcessingPlugin/scripts/TimeLapse.py
@@ -0,0 +1,95 @@
+# Created by Wayne Porter
+
+from ..Script import Script
+
+class TimeLapse(Script):
+ def __init__(self):
+ super().__init__()
+
+ def getSettingDataString(self):
+ return """{
+ "name": "Time Lapse",
+ "key": "TimeLapse",
+ "metadata": {},
+ "version": 2,
+ "settings":
+ {
+ "trigger_command":
+ {
+ "label": "Trigger camera command",
+ "description": "Gcode command used to trigger camera.",
+ "type": "str",
+ "default_value": "M240"
+ },
+ "pause_length":
+ {
+ "label": "Pause length",
+ "description": "How long to wait (in ms) after camera was triggered.",
+ "type": "int",
+ "default_value": 700,
+ "minimum_value": 0,
+ "unit": "ms"
+ },
+ "park_print_head":
+ {
+ "label": "Park Print Head",
+ "description": "Park the print head out of the way. Assumes absolute positioning.",
+ "type": "bool",
+ "default_value": true
+ },
+ "head_park_x":
+ {
+ "label": "Park Print Head X",
+ "description": "What X location does the head move to for photo.",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 0,
+ "enabled": "park_print_head"
+ },
+ "head_park_y":
+ {
+ "label": "Park Print Head Y",
+ "description": "What Y location does the head move to for photo.",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 190,
+ "enabled": "park_print_head"
+ },
+ "park_feed_rate":
+ {
+ "label": "Park Feed Rate",
+ "description": "How fast does the head move to the park coordinates.",
+ "unit": "mm/s",
+ "type": "float",
+ "default_value": 9000,
+ "enabled": "park_print_head"
+ }
+ }
+ }"""
+
+ def execute(self, data):
+ feed_rate = self.getSettingValueByKey("park_feed_rate")
+ park_print_head = self.getSettingValueByKey("park_print_head")
+ x_park = self.getSettingValueByKey("head_park_x")
+ y_park = self.getSettingValueByKey("head_park_y")
+ trigger_command = self.getSettingValueByKey("trigger_command")
+ pause_length = self.getSettingValueByKey("pause_length")
+ gcode_to_append = ";TimeLapse Begin\n"
+
+ if park_print_head:
+ gcode_to_append += self.putValue(G = 1, F = feed_rate, X = x_park, Y = y_park) + " ;Park print head\n"
+ gcode_to_append += self.putValue(M = 400) + " ;Wait for moves to finish\n"
+ gcode_to_append += trigger_command + " ;Snap Photo\n"
+ gcode_to_append += self.putValue(G = 4, P = pause_length) + " ;Wait for camera\n"
+ gcode_to_append += ";TimeLapse End\n"
+ for layer in data:
+ # Check that a layer is being printed
+ lines = layer.split("\n")
+ for line in lines:
+ if ";LAYER:" in line:
+ index = data.index(layer)
+ layer += gcode_to_append
+
+ data[index] = layer
+ break
+ return data
diff --git a/plugins/PostProcessingPlugin/scripts/UsePreviousProbeMeasurements.py b/plugins/PostProcessingPlugin/scripts/UsePreviousProbeMeasurements.py
new file mode 100644
index 0000000000..271cb57100
--- /dev/null
+++ b/plugins/PostProcessingPlugin/scripts/UsePreviousProbeMeasurements.py
@@ -0,0 +1,46 @@
+# Cura PostProcessingPlugin
+# Author: Amanda de Castilho
+# Date: January 5,2019
+
+# Description: This plugin overrides probing command and inserts code to ensure
+# previous probe measurements are loaded and bed leveling enabled
+# (searches for G29 and replaces it with M501 & M420 S1)
+# *** Assumes G29 is in the start code, will do nothing if it isn't ***
+
+from ..Script import Script
+
+class UsePreviousProbeMeasurements(Script):
+ def __init__(self):
+ super().__init__()
+
+ def getSettingDataString(self):
+ return """{
+ "name": "Use Previous Probe Measurements",
+ "key": "UsePreviousProbeMeasurements",
+ "metadata": {},
+ "version": 2,
+ "settings":
+ {
+ "use_previous_measurements":
+ {
+ "label": "Use last measurement?",
+ "description": "Selecting this will remove the G29 probing command and instead ensure previous measurements are loaded and enabled",
+ "type": "bool",
+ "default_value": false
+ }
+ }
+ }"""
+
+ def execute(self, data):
+ text = "M501 ;load bed level data\nM420 S1 ;enable bed leveling"
+ if self.getSettingValueByKey("use_previous_measurements"):
+ for layer in data:
+ layer_index = data.index(layer)
+ lines = layer.split("\n")
+ for line in lines:
+ if line.startswith("G29"):
+ line_index = lines.index(line)
+ lines[line_index] = text
+ final_lines = "\n".join(lines)
+ data[layer_index] = final_lines
+ return data
diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml
index b62d65254d..87d7c5f35c 100644
--- a/plugins/PrepareStage/PrepareMenu.qml
+++ b/plugins/PrepareStage/PrepareMenu.qml
@@ -20,11 +20,19 @@ Item
name: "cura"
}
+ anchors
+ {
+ left: parent.left
+ right: parent.right
+ leftMargin: UM.Theme.getSize("wide_margin").width
+ rightMargin: UM.Theme.getSize("wide_margin").width
+ }
+
// Item to ensure that all of the buttons are nicely centered.
Item
{
anchors.horizontalCenter: parent.horizontalCenter
- width: openFileButton.width + itemRow.width + UM.Theme.getSize("default_margin").width
+ width: parent.width - 2 * UM.Theme.getSize("wide_margin").width
height: parent.height
RowLayout
@@ -32,9 +40,9 @@ Item
id: itemRow
anchors.left: openFileButton.right
+ anchors.right: parent.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
- width: Math.round(0.9 * prepareMenu.width)
height: parent.height
spacing: 0
@@ -58,6 +66,7 @@ Item
Cura.ConfigurationMenu
{
+ id: printerSetup
Layout.fillHeight: true
Layout.fillWidth: true
Layout.preferredWidth: itemRow.width - machineSelection.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width
diff --git a/plugins/PrepareStage/__init__.py b/plugins/PrepareStage/__init__.py
index f085d788f9..8e86ff303d 100644
--- a/plugins/PrepareStage/__init__.py
+++ b/plugins/PrepareStage/__init__.py
@@ -10,7 +10,7 @@ def getMetaData():
return {
"stage": {
"name": i18n_catalog.i18nc("@item:inmenu", "Prepare"),
- "weight": 0
+ "weight": 10
}
}
diff --git a/plugins/PrepareStage/plugin.json b/plugins/PrepareStage/plugin.json
index dc5c68ce16..e65c62ef49 100644
--- a/plugins/PrepareStage/plugin.json
+++ b/plugins/PrepareStage/plugin.json
@@ -1,8 +1,8 @@
-{
- "name": "Prepare Stage",
- "author": "Ultimaker B.V.",
- "version": "1.0.1",
- "description": "Provides a prepare stage in Cura.",
- "api": "6.0",
- "i18n-catalog": "cura"
+{
+ "name": "Prepare Stage",
+ "author": "Ultimaker B.V.",
+ "version": "1.0.1",
+ "description": "Provides a prepare stage in Cura.",
+ "api": "7.0",
+ "i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/PreviewStage/PreviewMain.qml b/plugins/PreviewStage/PreviewMain.qml
index 6b5ce2436b..2926f0d012 100644
--- a/plugins/PreviewStage/PreviewMain.qml
+++ b/plugins/PreviewStage/PreviewMain.qml
@@ -11,12 +11,34 @@ import Cura 1.0 as Cura
Item
{
+
+ // An Item whose bounds are guaranteed to be safe for overlays to be placed.
+ // Defaults to parent, ie. the entire available area
+ property var safeArea: parent
+
+ // Subtract the actionPanel from the safe area. This way the view won't draw interface elements under/over it
+ Item
+ {
+ id: childSafeArea
+ x: safeArea.x - parent.x
+ y: safeArea.y - parent.y
+ width: actionPanelWidget.x - x
+ height: actionPanelWidget.y - y
+ }
+
Loader
{
id: previewMain
anchors.fill: parent
source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : ""
+
+ onLoaded:
+ {
+ if (previewMain.item.safeArea !== undefined){
+ previewMain.item.safeArea = Qt.binding(function() { return childSafeArea });
+ }
+ }
}
Cura.ActionPanelWidget
diff --git a/plugins/PreviewStage/PreviewMenu.qml b/plugins/PreviewStage/PreviewMenu.qml
index 62f814aac9..ff1ccff75f 100644
--- a/plugins/PreviewStage/PreviewMenu.qml
+++ b/plugins/PreviewStage/PreviewMenu.qml
@@ -20,15 +20,21 @@ Item
name: "cura"
}
+ anchors
+ {
+ left: parent.left
+ right: parent.right
+ leftMargin: UM.Theme.getSize("wide_margin").width
+ rightMargin: UM.Theme.getSize("wide_margin").width
+ }
+
Row
{
id: stageMenuRow
- anchors.centerIn: parent
- height: parent.height
- width: childrenRect.width
- // We want this row to have a preferred with equals to the 85% of the parent
- property int preferredWidth: Math.round(0.85 * previewMenu.width)
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: parent.width - 2 * UM.Theme.getSize("wide_margin").width
+ height: parent.height
Cura.ViewsSelector
{
@@ -49,12 +55,12 @@ Item
color: UM.Theme.getColor("lining")
}
- // This component will grow freely up to complete the preferredWidth of the row.
+ // This component will grow freely up to complete the width of the row.
Loader
{
id: viewPanel
height: parent.height
- width: source != "" ? (stageMenuRow.preferredWidth - viewsSelector.width - printSetupSelectorItem.width - 2 * UM.Theme.getSize("default_lining").width) : 0
+ width: source != "" ? (previewMenu.width - viewsSelector.width - printSetupSelectorItem.width - 2 * (UM.Theme.getSize("wide_margin").width + UM.Theme.getSize("default_lining").width)) : 0
source: UM.Controller.activeView != null && UM.Controller.activeView.stageMenuComponent != null ? UM.Controller.activeView.stageMenuComponent : ""
}
diff --git a/plugins/PreviewStage/__init__.py b/plugins/PreviewStage/__init__.py
index 424f573e4a..cb32f583ee 100644
--- a/plugins/PreviewStage/__init__.py
+++ b/plugins/PreviewStage/__init__.py
@@ -11,7 +11,7 @@ def getMetaData():
return {
"stage": {
"name": i18n_catalog.i18nc("@item:inmenu", "Preview"),
- "weight": 1
+ "weight": 20
}
}
diff --git a/plugins/PreviewStage/plugin.json b/plugins/PreviewStage/plugin.json
index e1e4288bae..1c21e682ee 100644
--- a/plugins/PreviewStage/plugin.json
+++ b/plugins/PreviewStage/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides a preview stage in Cura.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py b/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py
index 51b6a70b7a..c89bd31e21 100644
--- a/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py
+++ b/plugins/RemovableDriveOutputDevice/WindowsRemovableDrivePlugin.py
@@ -48,9 +48,13 @@ class WindowsRemovableDrivePlugin(RemovableDrivePlugin.RemovableDrivePlugin):
drives = {}
bitmask = ctypes.windll.kernel32.GetLogicalDrives()
- # Check possible drive letters, from A to Z
+ # Check possible drive letters, from C to Z
# Note: using ascii_uppercase because we do not want this to change with locale!
- for letter in string.ascii_uppercase:
+ # Skip A and B, since those drives are typically reserved for floppy disks.
+ # Those drives can theoretically be reassigned but it's safer to not check them for removable drives.
+ # Windows will also behave weirdly even with some of its internal functions if you do this (e.g. search indexing doesn't search it).
+ # Users that have removable drives in A or B will just have to save to file and select the drive there.
+ for letter in string.ascii_uppercase[2:]:
drive = "{0}:/".format(letter)
# Do we really want to skip A and B?
diff --git a/plugins/RemovableDriveOutputDevice/plugin.json b/plugins/RemovableDriveOutputDevice/plugin.json
index 5523d6b1c1..c794257e3a 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.1",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml
index 88f298d1f5..d6de45df9b 100644
--- a/plugins/SimulationView/LayerSlider.qml
+++ b/plugins/SimulationView/LayerSlider.qml
@@ -155,25 +155,19 @@ Item
}
onPositionChanged: parent.onHandleDragged()
- onPressed: sliderRoot.setActiveHandle(rangeHandle)
+ onPressed:
+ {
+ sliderRoot.setActiveHandle(rangeHandle)
+ sliderRoot.forceActiveFocus()
+ }
}
- SimulationSliderLabel
- {
- id: rangleHandleLabel
+ }
- height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
- x: parent.x - width - UM.Theme.getSize("default_margin").width
- anchors.verticalCenter: parent.verticalCenter
- target: Qt.point(sliderRoot.width, y + height / 2)
- visible: sliderRoot.activeHandle == parent
-
- // custom properties
- maximumValue: sliderRoot.maximumValue
- value: sliderRoot.upperValue
- busy: UM.SimulationView.busy
- setValue: rangeHandle.setValueManually // connect callback functions
- }
+ onHeightChanged : {
+ // After a height change, the pixel-position of the handles is out of sync with the property value
+ setLowerValue(lowerValue)
+ setUpperValue(upperValue)
}
// Upper handle
@@ -270,11 +264,12 @@ Item
{
id: upperHandleLabel
- height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
- x: parent.x - parent.width - width
- anchors.verticalCenter: parent.verticalCenter
- target: Qt.point(sliderRoot.width, y + height / 2)
- visible: sliderRoot.activeHandle == parent
+ height: sliderRoot.handleSize
+ anchors.bottom: parent.top
+ anchors.bottomMargin: UM.Theme.getSize("narrow_margin").height
+ anchors.horizontalCenter: parent.horizontalCenter
+ target: Qt.point(parent.width / 2, parent.top)
+ visible: sliderRoot.activeHandle == parent || sliderRoot.activeHandle == rangeHandle
// custom properties
maximumValue: sliderRoot.maximumValue
@@ -333,7 +328,6 @@ Item
// set the slider position based on the lower value
function setValue(value)
{
-
// Normalize values between range, since using arrow keys will create out-of-the-range values
value = sliderRoot.normalizeValue(value)
@@ -380,11 +374,12 @@ Item
{
id: lowerHandleLabel
- height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
- x: parent.x - parent.width - width
- anchors.verticalCenter: parent.verticalCenter
- target: Qt.point(sliderRoot.width + width, y + height / 2)
- visible: sliderRoot.activeHandle == parent
+ height: sliderRoot.handleSize
+ anchors.top: parent.bottom
+ anchors.topMargin: UM.Theme.getSize("narrow_margin").height
+ anchors.horizontalCenter: parent.horizontalCenter
+ target: Qt.point(parent.width / 2, parent.bottom)
+ visible: sliderRoot.activeHandle == parent || sliderRoot.activeHandle == rangeHandle
// custom properties
maximumValue: sliderRoot.maximumValue
@@ -393,4 +388,4 @@ Item
setValue: lowerHandle.setValueManually // connect callback functions
}
}
-}
\ No newline at end of file
+}
diff --git a/plugins/SimulationView/NozzleNode.py b/plugins/SimulationView/NozzleNode.py
index 8a29871775..11b788c128 100644
--- a/plugins/SimulationView/NozzleNode.py
+++ b/plugins/SimulationView/NozzleNode.py
@@ -3,7 +3,6 @@
from UM.Application import Application
from UM.Math.Color import Color
-from UM.Math.Vector import Vector
from UM.PluginRegistry import PluginRegistry
from UM.Scene.SceneNode import SceneNode
from UM.View.GL.OpenGL import OpenGL
diff --git a/plugins/SimulationView/PathSlider.qml b/plugins/SimulationView/PathSlider.qml
index c7a43c6407..facdbb6a53 100644
--- a/plugins/SimulationView/PathSlider.qml
+++ b/plugins/SimulationView/PathSlider.qml
@@ -56,6 +56,11 @@ Item
return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue)
}
+ onWidthChanged : {
+ // After a width change, the pixel-position of the handle is out of sync with the property value
+ setHandleValue(handleValue)
+ }
+
// slider track
Rectangle
{
diff --git a/plugins/SimulationView/SimulationSliderLabel.qml b/plugins/SimulationView/SimulationSliderLabel.qml
index 06c6a51b44..c1fb0f4de9 100644
--- a/plugins/SimulationView/SimulationSliderLabel.qml
+++ b/plugins/SimulationView/SimulationSliderLabel.qml
@@ -1,7 +1,6 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-
-import QtQuick 2.2
+import QtQuick 2.5
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.1
@@ -20,9 +19,9 @@ UM.PointingRectangle {
property int startFrom: 1
target: Qt.point(parent.width, y + height / 2)
- arrowSize: UM.Theme.getSize("default_arrow").width
+ arrowSize: UM.Theme.getSize("button_tooltip_arrow").height
height: parent.height
- width: valueLabel.width + UM.Theme.getSize("default_margin").width
+ width: valueLabel.width
visible: false
color: UM.Theme.getColor("tool_panel_background")
@@ -40,26 +39,35 @@ UM.PointingRectangle {
anchors.fill: parent
}
+ TextMetrics {
+ id: maxValueMetrics
+ font: valueLabel.font
+ text: maximumValue + 1 // layers are 0 based, add 1 for display value
+
+ }
+
TextField {
id: valueLabel
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
+ alignWhenCentered: false
}
- width: ((maximumValue + 1).toString().length + 1) * 10 * screenScaleFactor
+ width: maxValueMetrics.width + UM.Theme.getSize("default_margin").width
text: sliderLabelRoot.value + startFrom // the current handle value, add 1 because layers is an array
- horizontalAlignment: TextInput.AlignRight
+ horizontalAlignment: TextInput.AlignHCenter
// key bindings, work when label is currenctly focused (active handle in LayerSlider)
Keys.onUpPressed: sliderLabelRoot.setValue(sliderLabelRoot.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
Keys.onDownPressed: sliderLabelRoot.setValue(sliderLabelRoot.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
style: TextFieldStyle {
- textColor: UM.Theme.getColor("setting_control_text")
+ textColor: UM.Theme.getColor("text")
font: UM.Theme.getFont("default")
- background: Item { }
+ renderType: Text.NativeRendering
+ background: Item { }
}
onEditingFinished: {
diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py
index 3b2db2efac..6d6f19c57c 100644
--- a/plugins/SimulationView/SimulationView.py
+++ b/plugins/SimulationView/SimulationView.py
@@ -48,7 +48,7 @@ if TYPE_CHECKING:
catalog = i18nCatalog("cura")
-## View used to display g-code paths.
+## The preview layer view. It is used to display g-code paths.
class SimulationView(CuraView):
# Must match SimulationViewMenuComponent.qml
LAYER_VIEW_TYPE_MATERIAL_TYPE = 0
@@ -83,9 +83,13 @@ class SimulationView(CuraView):
self._simulationview_composite_shader = None # type: Optional["ShaderProgram"]
self._old_composite_shader = None # type: Optional["ShaderProgram"]
+ self._max_feedrate = sys.float_info.min
+ self._min_feedrate = sys.float_info.max
+ self._max_thickness = sys.float_info.min
+ self._min_thickness = sys.float_info.max
+
self._global_container_stack = None # type: Optional[ContainerStack]
- self._proxy = SimulationViewProxy()
- self._controller.getScene().getRoot().childrenChanged.connect(self._onSceneChanged)
+ self._proxy = None
self._resetSettings()
self._legend_items = None
@@ -104,7 +108,6 @@ class SimulationView(CuraView):
Application.getInstance().getPreferences().addPreference("layerview/show_skin", True)
Application.getInstance().getPreferences().addPreference("layerview/show_infill", True)
- Application.getInstance().getPreferences().preferenceChanged.connect(self._onPreferencesChanged)
self._updateWithPreferences()
self._solid_layers = int(Application.getInstance().getPreferences().getValue("view/top_layer_count"))
@@ -180,8 +183,7 @@ class SimulationView(CuraView):
def _onSceneChanged(self, node: "SceneNode") -> None:
if node.getMeshData() is None:
- self.resetLayerData()
-
+ return
self.setActivity(False)
self.calculateMaxLayers()
self.calculateMaxPathsOnLayer(self._current_layer_num)
@@ -211,6 +213,8 @@ class SimulationView(CuraView):
def beginRendering(self) -> None:
scene = self.getController().getScene()
renderer = self.getRenderer()
+ if renderer is None:
+ return
if not self._ghost_shader:
self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
@@ -218,10 +222,10 @@ class SimulationView(CuraView):
if theme is not None:
self._ghost_shader.setUniformValue("u_color", Color(*theme.getColor("layerview_ghost").getRgb()))
- for node in DepthFirstIterator(scene.getRoot()): # type: ignore
+ for node in DepthFirstIterator(scene.getRoot()):
# We do not want to render ConvexHullNode as it conflicts with the bottom layers.
# However, it is somewhat relevant when the node is selected, so do render it then.
- if type(node) is ConvexHullNode and not Selection.isSelected(node.getWatchedNode()):
+ if type(node) is ConvexHullNode and not Selection.isSelected(cast(ConvexHullNode, node).getWatchedNode()):
continue
if not node.render(renderer):
@@ -384,7 +388,7 @@ class SimulationView(CuraView):
self._max_thickness = max(float(p.lineThicknesses.max()), self._max_thickness)
try:
self._min_thickness = min(float(p.lineThicknesses[numpy.nonzero(p.lineThicknesses)].min()), self._min_thickness)
- except:
+ except ValueError:
# Sometimes, when importing a GCode the line thicknesses are zero and so the minimum (avoiding
# the zero) can't be calculated
Logger.log("i", "Min thickness can't be calculated because all the values are zero")
@@ -441,6 +445,8 @@ class SimulationView(CuraView):
## Hackish way to ensure the proxy is already created, which ensures that the layerview.qml is already created
# as this caused some issues.
def getProxy(self, engine, script_engine):
+ if self._proxy is None:
+ self._proxy = SimulationViewProxy(self)
return self._proxy
def endRendering(self) -> None:
@@ -460,6 +466,13 @@ class SimulationView(CuraView):
return True
if event.type == Event.ViewActivateEvent:
+ # Start listening to changes.
+ Application.getInstance().getPreferences().preferenceChanged.connect(self._onPreferencesChanged)
+ self._controller.getScene().getRoot().childrenChanged.connect(self._onSceneChanged)
+
+ self.calculateMaxLayers()
+ self.calculateMaxPathsOnLayer(self._current_layer_num)
+
# FIX: on Max OS X, somehow QOpenGLContext.currentContext() can become None during View switching.
# This can happen when you do the following steps:
# 1. Start Cura
@@ -479,7 +492,11 @@ class SimulationView(CuraView):
# Make sure the SimulationPass is created
layer_pass = self.getSimulationPass()
- self.getRenderer().addRenderPass(layer_pass)
+ renderer = self.getRenderer()
+ if renderer is None:
+ return False
+
+ renderer.addRenderPass(layer_pass)
# Make sure the NozzleNode is add to the root
nozzle = self.getNozzleNode()
@@ -498,7 +515,7 @@ class SimulationView(CuraView):
self._simulationview_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))
if not self._composite_pass:
- self._composite_pass = cast(CompositePass, self.getRenderer().getRenderPass("composite"))
+ self._composite_pass = cast(CompositePass, renderer.getRenderPass("composite"))
self._old_layer_bindings = self._composite_pass.getLayerBindings()[:] # make a copy so we can restore to it later
self._composite_pass.getLayerBindings().append("simulationview")
@@ -506,13 +523,21 @@ class SimulationView(CuraView):
self._composite_pass.setCompositeShader(self._simulationview_composite_shader)
elif event.type == Event.ViewDeactivateEvent:
+ self._controller.getScene().getRoot().childrenChanged.disconnect(self._onSceneChanged)
+ Application.getInstance().getPreferences().preferenceChanged.disconnect(self._onPreferencesChanged)
self._wireprint_warning_message.hide()
Application.getInstance().globalContainerStackChanged.disconnect(self._onGlobalStackChanged)
if self._global_container_stack:
self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged)
if self._nozzle_node:
self._nozzle_node.setParent(None)
- self.getRenderer().removeRenderPass(self._layer_pass)
+
+ renderer = self.getRenderer()
+ if renderer is None:
+ return False
+
+ if self._layer_pass is not None:
+ renderer.removeRenderPass(self._layer_pass)
if self._composite_pass:
self._composite_pass.setLayerBindings(cast(List[str], self._old_layer_bindings))
self._composite_pass.setCompositeShader(cast(ShaderProgram, self._old_composite_shader))
@@ -572,14 +597,14 @@ class SimulationView(CuraView):
self._current_layer_jumps = job.getResult().get("jumps")
self._controller.getScene().sceneChanged.emit(self._controller.getScene().getRoot())
- self._top_layers_job = None # type: Optional["_CreateTopLayersJob"]
+ self._top_layers_job = None
def _updateWithPreferences(self) -> None:
self._solid_layers = int(Application.getInstance().getPreferences().getValue("view/top_layer_count"))
self._only_show_top_layers = bool(Application.getInstance().getPreferences().getValue("view/only_show_top_layers"))
self._compatibility_mode = self._evaluateCompatibilityMode()
- self.setSimulationViewType(int(float(Application.getInstance().getPreferences().getValue("layerview/layer_view_type"))));
+ self.setSimulationViewType(int(float(Application.getInstance().getPreferences().getValue("layerview/layer_view_type"))))
for extruder_nr, extruder_opacity in enumerate(Application.getInstance().getPreferences().getValue("layerview/extruder_opacities").split("|")):
try:
diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml
index 58901652d3..bfd8799673 100644
--- a/plugins/SimulationView/SimulationViewMainComponent.qml
+++ b/plugins/SimulationView/SimulationViewMainComponent.qml
@@ -11,19 +11,39 @@ import Cura 1.0 as Cura
Item
{
- property bool is_simulation_playing: false
+ // An Item whose bounds are guaranteed to be safe for overlays to be placed.
+ // Defaults to parent, ie. the entire available area
+ // eg. the layer slider will not be placed in this area.
+ property var safeArea: parent
+
+
+ property bool isSimulationPlaying: false
+ readonly property real layerSliderSafeYMin: safeArea.y
+ readonly property real layerSliderSafeYMax: safeArea.y + safeArea.height
+ readonly property real pathSliderSafeXMin: safeArea.x + playButton.width
+ readonly property real pathSliderSafeXMax: safeArea.x + safeArea.width
+
visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity
+ // A slider which lets users trace a single layer (XY movements)
PathSlider
{
id: pathSlider
+
+ readonly property real preferredWidth: UM.Theme.getSize("slider_layerview_size").height // not a typo, should be as long as layerview slider
+ readonly property real margin: UM.Theme.getSize("default_margin").width
+ readonly property real pathSliderSafeWidth: pathSliderSafeXMax - pathSliderSafeXMin
+
height: UM.Theme.getSize("slider_handle").width
- width: UM.Theme.getSize("slider_layerview_size").height
+ width: preferredWidth + margin * 2 < pathSliderSafeWidth ? preferredWidth : pathSliderSafeWidth - margin * 2
+
anchors.bottom: parent.bottom
- anchors.bottomMargin: UM.Theme.getSize("default_margin").height
+ anchors.bottomMargin: margin
anchors.horizontalCenter: parent.horizontalCenter
+ anchors.horizontalCenterOffset: -(parent.width - pathSliderSafeXMax - pathSliderSafeXMin) / 2 // center between parent top and layerSliderSafeYMax
+
visible: !UM.SimulationView.compatibilityMode
@@ -58,7 +78,7 @@ Item
UM.SimpleButton
{
id: playButton
- iconSource: !is_simulation_playing ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg"
+ iconSource: !isSimulationPlaying ? "./resources/simulation_resume.svg": "./resources/simulation_pause.svg"
width: UM.Theme.getSize("small_button").width
height: UM.Theme.getSize("small_button").height
hoverColor: UM.Theme.getColor("slider_handle_active")
@@ -88,7 +108,7 @@ Item
onClicked:
{
- if(is_simulation_playing)
+ if(isSimulationPlaying)
{
pauseSimulation()
}
@@ -102,7 +122,7 @@ Item
{
UM.SimulationView.setSimulationRunning(false)
simulationTimer.stop()
- is_simulation_playing = false
+ isSimulationPlaying = false
layerSlider.manuallyChanged = true
pathSlider.manuallyChanged = true
}
@@ -131,7 +151,7 @@ Item
// When the user plays the simulation, if the path slider is at the end of this layer, we start
// the simulation at the beginning of the current layer.
- if (!is_simulation_playing)
+ if (!isSimulationPlaying)
{
if (currentPath >= numPaths)
{
@@ -166,22 +186,30 @@ Item
}
// The status must be set here instead of in the resumeSimulation function otherwise it won't work
// correctly, because part of the logic is in this trigger function.
- is_simulation_playing = true
+ isSimulationPlaying = true
}
}
+ // Scrolls trough Z layers
LayerSlider
{
+ property var preferredHeight: UM.Theme.getSize("slider_layerview_size").height
+ property double heightMargin: UM.Theme.getSize("default_margin").height * 3 // extra margin to accomodate layer number tooltips
+ property double layerSliderSafeHeight: layerSliderSafeYMax - layerSliderSafeYMin
+
id: layerSlider
width: UM.Theme.getSize("slider_handle").width
- height: UM.Theme.getSize("slider_layerview_size").height
+ height: preferredHeight + heightMargin * 2 < layerSliderSafeHeight ? preferredHeight : layerSliderSafeHeight - heightMargin * 2
anchors
{
right: parent.right
verticalCenter: parent.verticalCenter
+ verticalCenterOffset: -(parent.height - layerSliderSafeYMax - layerSliderSafeYMin) / 2 // center between parent top and layerSliderSafeYMax
rightMargin: UM.Theme.getSize("default_margin").width
+ bottomMargin: heightMargin
+ topMargin: heightMargin
}
// Custom properties
diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml
index 957d8170cf..b94cf029f0 100644
--- a/plugins/SimulationView/SimulationViewMenuComponent.qml
+++ b/plugins/SimulationView/SimulationViewMenuComponent.qml
@@ -15,6 +15,8 @@ Cura.ExpandableComponent
{
id: base
+ dragPreferencesNamePrefix: "view/colorscheme"
+
contentHeaderTitle: catalog.i18nc("@label", "Color scheme")
Connections
@@ -177,7 +179,6 @@ Cura.ExpandableComponent
height: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
width: parent.width
visible: !UM.SimulationView.compatibilityMode
- enabled: index < 4
onClicked:
{
diff --git a/plugins/SimulationView/SimulationViewProxy.py b/plugins/SimulationView/SimulationViewProxy.py
index a84b151983..58a004cc31 100644
--- a/plugins/SimulationView/SimulationViewProxy.py
+++ b/plugins/SimulationView/SimulationViewProxy.py
@@ -1,21 +1,24 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+from typing import TYPE_CHECKING
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty
from UM.FlameProfiler import pyqtSlot
from UM.Application import Application
-import SimulationView
+if TYPE_CHECKING:
+ from .SimulationView import SimulationView
class SimulationViewProxy(QObject):
- def __init__(self, parent=None):
+ def __init__(self, simulation_view: "SimulationView", parent=None):
super().__init__(parent)
+ self._simulation_view = simulation_view
self._current_layer = 0
self._controller = Application.getInstance().getController()
self._controller.activeViewChanged.connect(self._onActiveViewChanged)
- self._onActiveViewChanged()
self.is_simulationView_selected = False
+ self._onActiveViewChanged()
currentLayerChanged = pyqtSignal()
currentPathChanged = pyqtSignal()
@@ -28,182 +31,112 @@ class SimulationViewProxy(QObject):
@pyqtProperty(bool, notify=activityChanged)
def layerActivity(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getActivity()
- return False
+ return self._simulation_view.getActivity()
@pyqtProperty(int, notify=maxLayersChanged)
def numLayers(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getMaxLayers()
- return 0
+ return self._simulation_view.getMaxLayers()
@pyqtProperty(int, notify=currentLayerChanged)
def currentLayer(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getCurrentLayer()
- return 0
+ return self._simulation_view.getCurrentLayer()
@pyqtProperty(int, notify=currentLayerChanged)
def minimumLayer(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getMinimumLayer()
- return 0
+ return self._simulation_view.getMinimumLayer()
@pyqtProperty(int, notify=maxPathsChanged)
def numPaths(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getMaxPaths()
- return 0
+ return self._simulation_view.getMaxPaths()
@pyqtProperty(int, notify=currentPathChanged)
def currentPath(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getCurrentPath()
- return 0
+ return self._simulation_view.getCurrentPath()
@pyqtProperty(int, notify=currentPathChanged)
def minimumPath(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getMinimumPath()
- return 0
+ return self._simulation_view.getMinimumPath()
@pyqtProperty(bool, notify=busyChanged)
def busy(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.isBusy()
- return False
+ return self._simulation_view.isBusy()
@pyqtProperty(bool, notify=preferencesChanged)
def compatibilityMode(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getCompatibilityMode()
- return False
+ return self._simulation_view.getCompatibilityMode()
+
+ @pyqtProperty(int, notify=globalStackChanged)
+ def extruderCount(self):
+ return self._simulation_view.getExtruderCount()
@pyqtSlot(int)
def setCurrentLayer(self, layer_num):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setLayer(layer_num)
+ self._simulation_view.setLayer(layer_num)
@pyqtSlot(int)
def setMinimumLayer(self, layer_num):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setMinimumLayer(layer_num)
+ self._simulation_view.setMinimumLayer(layer_num)
@pyqtSlot(int)
def setCurrentPath(self, path_num):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setPath(path_num)
+ self._simulation_view.setPath(path_num)
@pyqtSlot(int)
def setMinimumPath(self, path_num):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setMinimumPath(path_num)
+ self._simulation_view.setMinimumPath(path_num)
@pyqtSlot(int)
def setSimulationViewType(self, layer_view_type):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setSimulationViewType(layer_view_type)
+ self._simulation_view.setSimulationViewType(layer_view_type)
@pyqtSlot(result=int)
def getSimulationViewType(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getSimulationViewType()
- return 0
+ return self._simulation_view.getSimulationViewType()
@pyqtSlot(bool)
def setSimulationRunning(self, running):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setSimulationRunning(running)
+ self._simulation_view.setSimulationRunning(running)
@pyqtSlot(result=bool)
def getSimulationRunning(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.isSimulationRunning()
- return False
+ return self._simulation_view.isSimulationRunning()
@pyqtSlot(result=float)
def getMinFeedrate(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getMinFeedrate()
- return 0
+ return self._simulation_view.getMinFeedrate()
@pyqtSlot(result=float)
def getMaxFeedrate(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getMaxFeedrate()
- return 0
+ return self._simulation_view.getMaxFeedrate()
@pyqtSlot(result=float)
def getMinThickness(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getMinThickness()
- return 0
+ return self._simulation_view.getMinThickness()
@pyqtSlot(result=float)
def getMaxThickness(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getMaxThickness()
- return 0
+ return self._simulation_view.getMaxThickness()
# Opacity 0..1
@pyqtSlot(int, float)
def setExtruderOpacity(self, extruder_nr, opacity):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setExtruderOpacity(extruder_nr, opacity)
+ self._simulation_view.setExtruderOpacity(extruder_nr, opacity)
@pyqtSlot(int)
def setShowTravelMoves(self, show):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setShowTravelMoves(show)
+ self._simulation_view.setShowTravelMoves(show)
@pyqtSlot(int)
def setShowHelpers(self, show):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setShowHelpers(show)
+ self._simulation_view.setShowHelpers(show)
@pyqtSlot(int)
def setShowSkin(self, show):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setShowSkin(show)
+ self._simulation_view.setShowSkin(show)
@pyqtSlot(int)
def setShowInfill(self, show):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- active_view.setShowInfill(show)
-
- @pyqtProperty(int, notify=globalStackChanged)
- def extruderCount(self):
- active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- return active_view.getExtruderCount()
- return 0
+ self._simulation_view.setShowInfill(show)
def _layerActivityChanged(self):
self.activityChanged.emit()
@@ -236,24 +169,25 @@ class SimulationViewProxy(QObject):
def _onActiveViewChanged(self):
active_view = self._controller.getActiveView()
- if isinstance(active_view, SimulationView.SimulationView.SimulationView):
- # remove other connection if once the SimulationView was created.
- if self.is_simulationView_selected:
- active_view.currentLayerNumChanged.disconnect(self._onLayerChanged)
- active_view.currentPathNumChanged.disconnect(self._onPathChanged)
- active_view.maxLayersChanged.disconnect(self._onMaxLayersChanged)
- active_view.maxPathsChanged.disconnect(self._onMaxPathsChanged)
- active_view.busyChanged.disconnect(self._onBusyChanged)
- active_view.activityChanged.disconnect(self._onActivityChanged)
- active_view.globalStackChanged.disconnect(self._onGlobalStackChanged)
- active_view.preferencesChanged.disconnect(self._onPreferencesChanged)
-
+ if active_view == self._simulation_view:
+ self._simulation_view.currentLayerNumChanged.connect(self._onLayerChanged)
+ self._simulation_view.currentPathNumChanged.connect(self._onPathChanged)
+ self._simulation_view.maxLayersChanged.connect(self._onMaxLayersChanged)
+ self._simulation_view.maxPathsChanged.connect(self._onMaxPathsChanged)
+ self._simulation_view.busyChanged.connect(self._onBusyChanged)
+ self._simulation_view.activityChanged.connect(self._onActivityChanged)
+ self._simulation_view.globalStackChanged.connect(self._onGlobalStackChanged)
+ self._simulation_view.preferencesChanged.connect(self._onPreferencesChanged)
self.is_simulationView_selected = True
- active_view.currentLayerNumChanged.connect(self._onLayerChanged)
- active_view.currentPathNumChanged.connect(self._onPathChanged)
- active_view.maxLayersChanged.connect(self._onMaxLayersChanged)
- active_view.maxPathsChanged.connect(self._onMaxPathsChanged)
- active_view.busyChanged.connect(self._onBusyChanged)
- active_view.activityChanged.connect(self._onActivityChanged)
- active_view.globalStackChanged.connect(self._onGlobalStackChanged)
- active_view.preferencesChanged.connect(self._onPreferencesChanged)
+ elif self.is_simulationView_selected:
+ # Disconnect all of em again.
+ self.is_simulationView_selected = False
+ self._simulation_view.currentLayerNumChanged.disconnect(self._onLayerChanged)
+ self._simulation_view.currentPathNumChanged.disconnect(self._onPathChanged)
+ self._simulation_view.maxLayersChanged.disconnect(self._onMaxLayersChanged)
+ self._simulation_view.maxPathsChanged.disconnect(self._onMaxPathsChanged)
+ self._simulation_view.busyChanged.disconnect(self._onBusyChanged)
+ self._simulation_view.activityChanged.disconnect(self._onActivityChanged)
+ self._simulation_view.globalStackChanged.disconnect(self._onGlobalStackChanged)
+ self._simulation_view.preferencesChanged.disconnect(self._onPreferencesChanged)
+
diff --git a/plugins/SimulationView/layers.shader b/plugins/SimulationView/layers.shader
index 69c7c61ee5..11b049c9fe 100644
--- a/plugins/SimulationView/layers.shader
+++ b/plugins/SimulationView/layers.shader
@@ -1,6 +1,9 @@
[shaders]
vertex =
- uniform highp mat4 u_modelViewProjectionMatrix;
+ uniform highp mat4 u_modelMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
+
uniform lowp float u_active_extruder;
uniform lowp float u_shade_factor;
uniform highp int u_layer_view_type;
@@ -16,7 +19,7 @@ vertex =
void main()
{
- gl_Position = u_modelViewProjectionMatrix * a_vertex;
+ gl_Position = u_projectionMatrix * u_viewMatrix * u_modelMatrix * a_vertex;
// shade the color depending on the extruder index
v_color = a_color;
// 8 and 9 are travel moves
@@ -76,7 +79,10 @@ fragment =
vertex41core =
#version 410
- uniform highp mat4 u_modelViewProjectionMatrix;
+ uniform highp mat4 u_modelMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
+
uniform lowp float u_active_extruder;
uniform lowp float u_shade_factor;
uniform highp int u_layer_view_type;
@@ -92,7 +98,7 @@ vertex41core =
void main()
{
- gl_Position = u_modelViewProjectionMatrix * a_vertex;
+ gl_Position = u_projectionMatrix * u_viewMatrix * u_modelMatrix * a_vertex;
v_color = a_color;
if ((a_line_type != 8) && (a_line_type != 9)) {
v_color = (a_extruder == u_active_extruder) ? v_color : vec4(u_shade_factor * v_color.rgb, v_color.a);
@@ -154,7 +160,9 @@ u_show_skin = 1
u_show_infill = 1
[bindings]
-u_modelViewProjectionMatrix = model_view_projection_matrix
+u_modelMatrix = model_matrix
+u_viewMatrix = view_matrix
+u_projectionMatrix = projection_matrix
[attributes]
a_vertex = vertex
diff --git a/plugins/SimulationView/layers3d.shader b/plugins/SimulationView/layers3d.shader
index a277606509..ecd96c3f68 100644
--- a/plugins/SimulationView/layers3d.shader
+++ b/plugins/SimulationView/layers3d.shader
@@ -1,10 +1,10 @@
[shaders]
vertex41core =
#version 410
- uniform highp mat4 u_modelViewProjectionMatrix;
-
uniform highp mat4 u_modelMatrix;
- uniform highp mat4 u_viewProjectionMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
+
uniform lowp float u_active_extruder;
uniform lowp float u_max_feedrate;
uniform lowp float u_min_feedrate;
@@ -104,7 +104,10 @@ vertex41core =
geometry41core =
#version 410
- uniform highp mat4 u_viewProjectionMatrix;
+ uniform highp mat4 u_modelMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
+
uniform int u_show_travel_moves;
uniform int u_show_helpers;
uniform int u_show_skin;
@@ -136,6 +139,8 @@ geometry41core =
void main()
{
+ highp mat4 viewProjectionMatrix = u_projectionMatrix * u_viewMatrix;
+
vec4 g_vertex_delta;
vec3 g_vertex_normal_horz; // horizontal and vertical in respect to layers
vec4 g_vertex_offset_horz; // vec4 to match gl_in[x].gl_Position
@@ -183,65 +188,83 @@ geometry41core =
g_vertex_offset_vert = vec4(g_vertex_normal_vert * size_y, 0.0);
if ((v_line_type[0] == 8) || (v_line_type[0] == 9)) {
+ vec4 va_head = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head + g_vertex_offset_vert);
+ vec4 va_up = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert);
+ vec4 va_down = viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert);
+ vec4 vb_head = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head + g_vertex_offset_vert);
+ vec4 vb_down = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert);
+ vec4 vb_up = viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert);
+
// Travels: flat plane with pointy ends
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head + g_vertex_offset_vert));
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_up);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_head);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_down);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_up);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_down);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_up);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_head);
//And reverse so that the line is also visible from the back side.
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_up);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_down);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_up);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_down);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_head);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_up);
EndPrimitive();
} else {
+ vec4 va_m_horz = viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz);
+ vec4 vb_m_horz = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz);
+ vec4 va_p_vert = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert);
+ vec4 vb_p_vert = viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert);
+ vec4 va_p_horz = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz);
+ vec4 vb_p_horz = viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz);
+ vec4 va_m_vert = viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert);
+ vec4 vb_m_vert = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert);
+ vec4 va_head = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head);
+ vec4 vb_head = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head);
+
// All normal lines are rendered as 3d tubes.
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz));
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz));
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, va_m_horz);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, vb_m_horz);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_p_vert);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_p_vert);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, va_p_horz);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, vb_p_horz);
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, va_m_vert);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, vb_m_vert);
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, va_m_horz);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, vb_m_horz);
EndPrimitive();
// left side
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz));
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, va_m_horz);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_p_vert);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, va_head);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, va_p_horz);
EndPrimitive();
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz));
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head));
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz));
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, va_p_horz);
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, va_m_vert);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, va_head);
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, va_m_horz);
EndPrimitive();
// right side
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz));
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, vb_p_horz);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_p_vert);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, vb_head);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, vb_m_horz);
EndPrimitive();
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz));
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, vb_m_horz);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, vb_m_vert);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, vb_head);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, vb_p_horz);
EndPrimitive();
}
@@ -301,9 +324,9 @@ u_min_thickness = 0
u_max_thickness = 1
[bindings]
-u_modelViewProjectionMatrix = model_view_projection_matrix
u_modelMatrix = model_matrix
-u_viewProjectionMatrix = view_projection_matrix
+u_viewMatrix = view_matrix
+u_projectionMatrix = projection_matrix
u_normalMatrix = normal_matrix
u_lightPosition = light_0_position
diff --git a/plugins/SimulationView/layers3d_shadow.shader b/plugins/SimulationView/layers3d_shadow.shader
index 15136fcf3f..b2ed7f8c12 100644
--- a/plugins/SimulationView/layers3d_shadow.shader
+++ b/plugins/SimulationView/layers3d_shadow.shader
@@ -1,10 +1,10 @@
[shaders]
vertex41core =
#version 410
- uniform highp mat4 u_modelViewProjectionMatrix;
-
uniform highp mat4 u_modelMatrix;
- uniform highp mat4 u_viewProjectionMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
+
uniform lowp float u_active_extruder;
uniform lowp vec4 u_extruder_opacity; // currently only for max 4 extruders, others always visible
@@ -58,7 +58,10 @@ vertex41core =
geometry41core =
#version 410
- uniform highp mat4 u_viewProjectionMatrix;
+ uniform highp mat4 u_modelMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
+
uniform int u_show_travel_moves;
uniform int u_show_helpers;
uniform int u_show_skin;
@@ -90,6 +93,8 @@ geometry41core =
void main()
{
+ highp mat4 viewProjectionMatrix = u_projectionMatrix * u_viewMatrix;
+
vec4 g_vertex_delta;
vec3 g_vertex_normal_horz; // horizontal and vertical in respect to layers
vec4 g_vertex_offset_horz; // vec4 to match gl_in[x].gl_Position
@@ -137,65 +142,83 @@ geometry41core =
g_vertex_offset_vert = vec4(g_vertex_normal_vert * size_y, 0.0);
if ((v_line_type[0] == 8) || (v_line_type[0] == 9)) {
+ vec4 va_head = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head + g_vertex_offset_vert);
+ vec4 va_up = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert);
+ vec4 va_down = viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert);
+ vec4 vb_head = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head + g_vertex_offset_vert);
+ vec4 vb_down = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert);
+ vec4 vb_up = viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert);
+
// Travels: flat plane with pointy ends
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head + g_vertex_offset_vert));
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_up);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_head);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_down);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_up);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_down);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_up);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_head);
//And reverse so that the line is also visible from the back side.
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert));
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_up);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_down);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_up);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_down);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_head);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_up);
EndPrimitive();
} else {
+ vec4 va_m_horz = viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz);
+ vec4 vb_m_horz = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz);
+ vec4 va_p_vert = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert);
+ vec4 vb_p_vert = viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert);
+ vec4 va_p_horz = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz);
+ vec4 vb_p_horz = viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz);
+ vec4 va_m_vert = viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert);
+ vec4 vb_m_vert = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert);
+ vec4 va_head = viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head);
+ vec4 vb_head = viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head);
+
// All normal lines are rendered as 3d tubes.
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz));
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz));
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, va_m_horz);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, vb_m_horz);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_p_vert);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_p_vert);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, va_p_horz);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, vb_p_horz);
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, va_m_vert);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, vb_m_vert);
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, va_m_horz);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, vb_m_horz);
EndPrimitive();
// left side
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz));
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, va_m_horz);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, va_p_vert);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, va_head);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, va_p_horz);
EndPrimitive();
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz));
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert));
- myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head));
- myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz));
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, va_p_horz);
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, va_m_vert);
+ myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, va_head);
+ myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, va_m_horz);
EndPrimitive();
// right side
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz));
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, vb_p_horz);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, vb_p_vert);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, vb_head);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, vb_m_horz);
EndPrimitive();
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert));
- myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head));
- myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz));
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, vb_m_horz);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, vb_m_vert);
+ myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, vb_head);
+ myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, vb_p_horz);
EndPrimitive();
}
@@ -246,9 +269,9 @@ u_show_skin = 1
u_show_infill = 1
[bindings]
-u_modelViewProjectionMatrix = model_view_projection_matrix
u_modelMatrix = model_matrix
-u_viewProjectionMatrix = view_projection_matrix
+u_viewMatrix = view_matrix
+u_projectionMatrix = projection_matrix
u_normalMatrix = normal_matrix
u_lightPosition = light_0_position
diff --git a/plugins/SimulationView/layers_shadow.shader b/plugins/SimulationView/layers_shadow.shader
index 6149cc1703..8f500536a5 100644
--- a/plugins/SimulationView/layers_shadow.shader
+++ b/plugins/SimulationView/layers_shadow.shader
@@ -1,6 +1,9 @@
[shaders]
vertex =
- uniform highp mat4 u_modelViewProjectionMatrix;
+ uniform highp mat4 u_modelMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
+
uniform lowp float u_active_extruder;
uniform lowp float u_shade_factor;
uniform highp int u_layer_view_type;
@@ -16,7 +19,7 @@ vertex =
void main()
{
- gl_Position = u_modelViewProjectionMatrix * a_vertex;
+ gl_Position = u_projectionMatrix * u_viewMatrix * u_modelMatrix * a_vertex;
// shade the color depending on the extruder index
v_color = vec4(0.4, 0.4, 0.4, 0.9); // default color for not current layer;
// 8 and 9 are travel moves
@@ -80,7 +83,10 @@ fragment =
vertex41core =
#version 410
- uniform highp mat4 u_modelViewProjectionMatrix;
+ uniform highp mat4 u_modelMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
+
uniform lowp float u_active_extruder;
uniform lowp float u_shade_factor;
uniform highp int u_layer_view_type;
@@ -96,7 +102,7 @@ vertex41core =
void main()
{
- gl_Position = u_modelViewProjectionMatrix * a_vertex;
+ gl_Position = u_projectionMatrix * u_viewMatrix * u_modelMatrix * a_vertex;
v_color = vec4(0.4, 0.4, 0.4, 0.9); // default color for not current layer
// if ((a_line_type != 8) && (a_line_type != 9)) {
// v_color = (a_extruder == u_active_extruder) ? v_color : vec4(u_shade_factor * v_color.rgb, v_color.a);
@@ -159,7 +165,9 @@ u_show_skin = 1
u_show_infill = 1
[bindings]
-u_modelViewProjectionMatrix = model_view_projection_matrix
+u_modelMatrix = model_matrix
+u_viewMatrix = view_matrix
+u_projectionMatrix = projection_matrix
[attributes]
a_vertex = vertex
diff --git a/plugins/SimulationView/plugin.json b/plugins/SimulationView/plugin.json
index 3ccf91b9e6..e444f1fa2e 100644
--- a/plugins/SimulationView/plugin.json
+++ b/plugins/SimulationView/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides the Simulation view.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/SliceInfoPlugin/MoreInfoWindow.qml b/plugins/SliceInfoPlugin/MoreInfoWindow.qml
index 985ebe94a2..50276ec25c 100644
--- a/plugins/SliceInfoPlugin/MoreInfoWindow.qml
+++ b/plugins/SliceInfoPlugin/MoreInfoWindow.qml
@@ -1,150 +1,156 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.7
+import QtQuick 2.10
+import QtQuick.Controls 2.3
import QtQuick.Window 2.2
-import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
import UM 1.3 as UM
-import Cura 1.0 as Cura
+import Cura 1.1 as Cura
-UM.Dialog
+Window
{
+ UM.I18nCatalog { id: catalog; name: "cura" }
+
id: baseDialog
title: catalog.i18nc("@title:window", "More information on anonymous data collection")
visible: false
+ modality: Qt.ApplicationModal
+
minimumWidth: 500 * screenScaleFactor
minimumHeight: 400 * screenScaleFactor
width: minimumWidth
height: minimumHeight
- property bool allowSendData: true // for saving the user's choice
+ color: UM.Theme.getColor("main_background")
- onAccepted: manager.setSendSliceInfo(allowSendData)
+ property bool allowSendData: true // for saving the user's choice
onVisibilityChanged:
{
if (visible)
{
- baseDialog.allowSendData = UM.Preferences.getValue("info/send_slice_info");
+ baseDialog.allowSendData = UM.Preferences.getValue("info/send_slice_info")
if (baseDialog.allowSendData)
{
- allowSendButton.checked = true;
+ allowSendButton.checked = true
}
else
{
- dontSendButton.checked = true;
+ dontSendButton.checked = true
}
}
}
+ // Main content area
Item
{
- id: textRow
- anchors
- {
- top: parent.top
- bottom: radioButtonsRow.top
- bottomMargin: UM.Theme.getSize("default_margin").height
- left: parent.left
- right: parent.right
- }
+ anchors.fill: parent
+ anchors.margins: UM.Theme.getSize("default_margin").width
- Label
+ Item // Text part
{
- id: headerText
+ id: textRow
anchors
{
top: parent.top
- left: parent.left
- right: parent.right
- }
-
- text: catalog.i18nc("@text:window", "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent.")
- wrapMode: Text.WordWrap
- }
-
- TextArea
- {
- id: exampleData
- anchors
- {
- top: headerText.bottom
- topMargin: UM.Theme.getSize("default_margin").height
- bottom: parent.bottom
+ bottom: radioButtonsRow.top
bottomMargin: UM.Theme.getSize("default_margin").height
left: parent.left
right: parent.right
}
- text: manager.getExampleData()
- readOnly: true
- textFormat: TextEdit.PlainText
- }
- }
-
- Column
- {
- id: radioButtonsRow
- width: parent.width
- anchors.bottom: buttonRow.top
- anchors.bottomMargin: UM.Theme.getSize("default_margin").height
-
- ExclusiveGroup { id: group }
-
- RadioButton
- {
- id: dontSendButton
- text: catalog.i18nc("@text:window", "I don't want to send these data")
- exclusiveGroup: group
- onClicked:
+ Label
{
- baseDialog.allowSendData = !checked;
+ id: headerText
+ anchors
+ {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ }
+ text: catalog.i18nc("@text:window", "Ultimaker Cura collects anonymous data in order to improve the print quality and user experience. Below is an example of all the data that is shared:")
+ wrapMode: Text.WordWrap
+ renderType: Text.NativeRendering
}
- }
- RadioButton
- {
- id: allowSendButton
- text: catalog.i18nc("@text:window", "Allow sending these data to Ultimaker and help us improve Cura")
- exclusiveGroup: group
- onClicked:
+
+ Cura.ScrollableTextArea
{
- baseDialog.allowSendData = checked;
- }
- }
- }
+ anchors
+ {
+ top: headerText.bottom
+ topMargin: UM.Theme.getSize("default_margin").height
+ bottom: parent.bottom
+ bottomMargin: UM.Theme.getSize("default_margin").height
+ left: parent.left
+ right: parent.right
+ }
- Item
- {
- id: buttonRow
- anchors.bottom: parent.bottom
- width: parent.width
- anchors.bottomMargin: UM.Theme.getSize("default_margin").height
-
- UM.I18nCatalog { id: catalog; name: "cura" }
-
- Button
- {
- anchors.right: parent.right
- text: catalog.i18nc("@action:button", "OK")
- onClicked:
- {
- baseDialog.accepted()
- baseDialog.hide()
+ textArea.text: manager.getExampleData()
+ textArea.textFormat: Text.RichText
+ textArea.wrapMode: Text.Wrap
+ textArea.readOnly: true
}
}
- Button
+ Column // Radio buttons for agree and disagree
{
+ id: radioButtonsRow
anchors.left: parent.left
- text: catalog.i18nc("@action:button", "Cancel")
- onClicked:
+ anchors.right: parent.right
+ anchors.bottom: buttonRow.top
+ anchors.bottomMargin: UM.Theme.getSize("default_margin").height
+
+ Cura.RadioButton
{
- baseDialog.rejected()
- baseDialog.hide()
+ id: dontSendButton
+ text: catalog.i18nc("@text:window", "I don't want to send anonymous data")
+ onClicked:
+ {
+ baseDialog.allowSendData = !checked
+ }
+ }
+ Cura.RadioButton
+ {
+ id: allowSendButton
+ text: catalog.i18nc("@text:window", "Allow sending anonymous data")
+ onClicked:
+ {
+ baseDialog.allowSendData = checked
+ }
+ }
+ }
+
+ Item // Bottom buttons
+ {
+ id: buttonRow
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ height: childrenRect.height
+
+ Cura.PrimaryButton
+ {
+ anchors.right: parent.right
+ text: catalog.i18nc("@action:button", "OK")
+ onClicked:
+ {
+ manager.setSendSliceInfo(allowSendData)
+ baseDialog.hide()
+ }
+ }
+
+ Cura.SecondaryButton
+ {
+ anchors.left: parent.left
+ text: catalog.i18nc("@action:button", "Cancel")
+ onClicked:
+ {
+ baseDialog.hide()
+ }
}
}
}
diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py
index 5149b6a6a6..af8a8b9853 100755
--- a/plugins/SliceInfoPlugin/SliceInfo.py
+++ b/plugins/SliceInfoPlugin/SliceInfo.py
@@ -18,6 +18,8 @@ from UM.Logger import Logger
from UM.PluginRegistry import PluginRegistry
from UM.Qt.Duration import DurationFormat
+from cura import ApplicationMetadata
+
from .SliceInfoJob import SliceInfoJob
@@ -48,20 +50,6 @@ class SliceInfo(QObject, Extension):
def _onAppInitialized(self):
# DO NOT read any preferences values in the constructor because at the time plugins are created, no version
# upgrade has been performed yet because version upgrades are plugins too!
- if not self._application.getPreferences().getValue("info/asked_send_slice_info"):
- self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymized usage statistics."),
- lifetime = 0,
- dismissable = False,
- title = catalog.i18nc("@info:title", "Collecting Data"))
-
- self.send_slice_info_message.addAction("MoreInfo", name = catalog.i18nc("@action:button", "More info"), icon = None,
- description = catalog.i18nc("@action:tooltip", "See more information on what data Cura sends."), button_style = Message.ActionButtonStyle.LINK)
-
- self.send_slice_info_message.addAction("Dismiss", name = catalog.i18nc("@action:button", "Allow"), icon = None,
- description = catalog.i18nc("@action:tooltip", "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."))
- self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered)
- self.send_slice_info_message.show()
-
if self._more_info_dialog is None:
self._more_info_dialog = self._createDialog("MoreInfoWindow.qml")
@@ -76,7 +64,7 @@ class SliceInfo(QObject, Extension):
def showMoreInfoDialog(self):
if self._more_info_dialog is None:
self._more_info_dialog = self._createDialog("MoreInfoWindow.qml")
- self._more_info_dialog.open()
+ self._more_info_dialog.show()
def _createDialog(self, qml_name):
Logger.log("d", "Creating dialog [%s]", qml_name)
@@ -91,7 +79,7 @@ class SliceInfo(QObject, Extension):
if not plugin_path:
Logger.log("e", "Could not get plugin path!", self.getPluginId())
return None
- file_path = os.path.join(plugin_path, "example_data.json")
+ file_path = os.path.join(plugin_path, "example_data.html")
if file_path:
with open(file_path, "r", encoding = "utf-8") as f:
self._example_data_content = f.read()
@@ -133,6 +121,7 @@ class SliceInfo(QObject, Extension):
data["time_stamp"] = time.time()
data["schema_version"] = 0
data["cura_version"] = application.getVersion()
+ data["cura_build_type"] = ApplicationMetadata.CuraBuildType
active_mode = Application.getInstance().getPreferences().getValue("cura/active_mode")
if active_mode == 0:
@@ -140,6 +129,10 @@ class SliceInfo(QObject, Extension):
else:
data["active_mode"] = "custom"
+ data["camera_view"] = application.getPreferences().getValue("general/camera_perspective_mode")
+ if data["camera_view"] == "orthographic":
+ data["camera_view"] = "orthogonal" #The database still only recognises the old name "orthogonal".
+
definition_changes = global_stack.definitionChanges
machine_settings_changed_by_user = False
if definition_changes.getId() != "empty":
@@ -184,6 +177,7 @@ class SliceInfo(QObject, Extension):
extruder_dict["extruder_settings"] = extruder_settings
data["extruders"].append(extruder_dict)
+ data["intent_category"] = global_stack.getIntentCategory()
data["quality_profile"] = global_stack.quality.getMetaData().get("quality_type")
data["user_modified_setting_keys"] = self._getUserModifiedSettingKeys()
@@ -195,6 +189,8 @@ class SliceInfo(QObject, Extension):
model = dict()
model["hash"] = node.getMeshData().getHash()
bounding_box = node.getBoundingBox()
+ if not bounding_box:
+ continue
model["bounding_box"] = {"minimum": {"x": bounding_box.minimum.x,
"y": bounding_box.minimum.y,
"z": bounding_box.minimum.z},
diff --git a/plugins/SliceInfoPlugin/SliceInfoJob.py b/plugins/SliceInfoPlugin/SliceInfoJob.py
index a5667c1c13..50d6b560f1 100644
--- a/plugins/SliceInfoPlugin/SliceInfoJob.py
+++ b/plugins/SliceInfoPlugin/SliceInfoJob.py
@@ -8,6 +8,8 @@ import ssl
import urllib.request
import urllib.error
+import certifi
+
class SliceInfoJob(Job):
def __init__(self, url, data):
@@ -20,11 +22,14 @@ class SliceInfoJob(Job):
Logger.log("e", "URL or DATA for sending slice info was not set!")
return
- # Submit data
- kwoptions = {"data" : self._data, "timeout" : 5}
+ # CURA-6698 Create an SSL context and use certifi CA certificates for verification.
+ context = ssl.SSLContext(protocol = ssl.PROTOCOL_TLSv1_2)
+ context.load_verify_locations(cafile = certifi.where())
- if Platform.isOSX():
- kwoptions["context"] = ssl._create_unverified_context()
+ # Submit data
+ kwoptions = {"data": self._data,
+ "timeout": 5,
+ "context": context}
Logger.log("i", "Sending anonymous slice info to [%s]...", self._url)
@@ -35,4 +40,4 @@ class SliceInfoJob(Job):
except urllib.error.HTTPError:
Logger.logException("e", "An HTTP error occurred while trying to send slice information")
except Exception: # We don't want any exception to cause problems
- Logger.logException("e", "An exception occurred while trying to send slice information")
\ No newline at end of file
+ Logger.logException("e", "An exception occurred while trying to send slice information")
diff --git a/plugins/SliceInfoPlugin/example_data.html b/plugins/SliceInfoPlugin/example_data.html
new file mode 100644
index 0000000000..103eb55a6a
--- /dev/null
+++ b/plugins/SliceInfoPlugin/example_data.html
@@ -0,0 +1,65 @@
+
+
+ Cura Version: 4.0
+ Operating System: Windows 10
+ Language: en_US
+ Machine Type: Ultimaker S5
+ Intent Profile: Default
+ Quality Profile: Fast
+ Using Custom Settings: No
+
+
Extruder 1:
+
+
Material Type: PLA
+
Print Core: AA 0.4
+
Material Used: 1240 mm
+
+
+
Extruder 2:
+
+
Material Type: PVA
+
Print Core: BB 0.4
+
Material Used: 432 mm
+
+
+
Print Settings:
+
+
Layer Height: 0.15
+
Wall Line Count: 3
+
Enable Retraction: no
+
Infill Density: 20%
+
Infill Pattern: triangles
+
Gradual Infill Steps: 0
+
Printing Temperature: 220 °C
+
Generate Support: yes
+
Support Extruder: 1
+
Build Plate Adhesion Type: brim
+
Enable Prime Tower: yes
+
Print Sequence: All at once
+
...
+
+
+
Model Information:
+
+
+ Model 1
+
+
Hash: b72789b9b...
+
Transformation: [transformation matrix]
+
Bounding Box: [minimum x, y, z; maximum x, y, z]
+
Is Helper Mesh: no
+
Helper Mesh Type: support mesh
+
+
+
+
+
Print Times:
+
+
Infill: 61200 sec.
+
Support: 25480 sec.
+
Travel: 6224 sec.
+
Walls: 10225 sec.
+
Total: 103129 sec.
+
+
+
diff --git a/plugins/SliceInfoPlugin/example_data.json b/plugins/SliceInfoPlugin/example_data.json
deleted file mode 100644
index 5fc4175e60..0000000000
--- a/plugins/SliceInfoPlugin/example_data.json
+++ /dev/null
@@ -1,114 +0,0 @@
-{
- "time_stamp": 1523973715.486928,
- "schema_version": 0,
- "cura_version": "3.3",
- "active_mode": "custom",
- "machine_settings_changed_by_user": true,
- "language": "en_US",
- "os": {
- "type": "Linux",
- "version": "#43~16.04.1-Ubuntu SMP Wed Mar 14 17:48:43 UTC 2018"
- },
- "active_machine": {
- "definition_id": "ultimaker3",
- "manufacturer": "Ultimaker B.V."
- },
- "extruders": [
- {
- "active": true,
- "material": {
- "GUID": "506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9",
- "type": "PLA",
- "brand": "Generic"
- },
- "material_used": 0.84,
- "variant": "AA 0.4",
- "nozzle_size": 0.4,
- "extruder_settings": {
- "wall_line_count": 3,
- "retraction_enable": true,
- "infill_sparse_density": 30,
- "infill_pattern": "triangles",
- "gradual_infill_steps": 0,
- "default_material_print_temperature": 200,
- "material_print_temperature": 200
- }
- },
- {
- "active": false,
- "material": {
- "GUID": "86a89ceb-4159-47f6-ab97-e9953803d70f",
- "type": "PVA",
- "brand": "Generic"
- },
- "material_used": 0.5,
- "variant": "BB 0.4",
- "nozzle_size": 0.4,
- "extruder_settings": {
- "wall_line_count": 3,
- "retraction_enable": true,
- "infill_sparse_density": 20,
- "infill_pattern": "triangles",
- "gradual_infill_steps": 0,
- "default_material_print_temperature": 215,
- "material_print_temperature": 220
- }
- }
- ],
- "quality_profile": "fast",
- "user_modified_setting_keys": ["layer_height", "wall_line_width", "infill_sparse_density"],
- "models": [
- {
- "hash": "b72789b9beb5366dff20b1cf501020c3d4d4df7dc2295ecd0fddd0a6436df070",
- "bounding_box": {
- "minimum": {
- "x": -10.0,
- "y": 0.0,
- "z": -5.0
- },
- "maximum": {
- "x": 9.999999046325684,
- "y": 40.0,
- "z": 5.0
- }
- },
- "transformation": {
- "data": "[[ 1. 0. 0. 0.] [ 0. 1. 0. 20.] [ 0. 0. 1. 0.] [ 0. 0. 0. 1.]]"
- },
- "extruder": 0,
- "model_settings": {
- "support_enabled": true,
- "support_extruder_nr": 1,
- "infill_mesh": false,
- "cutting_mesh": false,
- "support_mesh": false,
- "anti_overhang_mesh": false,
- "wall_line_count": 3,
- "retraction_enable": true,
- "infill_sparse_density": 30,
- "infill_pattern": "triangles",
- "gradual_infill_steps": 0
- }
- }
- ],
- "print_times": {
- "travel": 187,
- "support": 825,
- "infill": 351,
- "total": 7234
- },
- "print_settings": {
- "layer_height": 0.15,
- "support_enabled": true,
- "support_extruder_nr": 1,
- "adhesion_type": "brim",
- "wall_line_count": 3,
- "retraction_enable": true,
- "prime_tower_enable": true,
- "infill_sparse_density": 20,
- "infill_pattern": "triangles",
- "gradual_infill_steps": 0,
- "print_sequence": "all_at_once"
- },
- "output_to": "LocalFileOutputDevice"
-}
diff --git a/plugins/SliceInfoPlugin/plugin.json b/plugins/SliceInfoPlugin/plugin.json
index 8ff0e194fb..8975f52591 100644
--- a/plugins/SliceInfoPlugin/plugin.json
+++ b/plugins/SliceInfoPlugin/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Submits anonymous slice info. Can be disabled through preferences.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py
index 797d6dabec..61954f5bca 100644
--- a/plugins/SolidView/SolidView.py
+++ b/plugins/SolidView/SolidView.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from UM.View.View import View
@@ -7,7 +7,6 @@ from UM.Scene.Selection import Selection
from UM.Resources import Resources
from UM.Application import Application
from UM.View.RenderBatch import RenderBatch
-from UM.Settings.Validator import ValidatorState
from UM.Math.Color import Color
from UM.View.GL.OpenGL import OpenGL
@@ -20,9 +19,9 @@ import math
class SolidView(View):
def __init__(self):
super().__init__()
-
- Application.getInstance().getPreferences().addPreference("view/show_overhang", True)
-
+ application = Application.getInstance()
+ application.getPreferences().addPreference("view/show_overhang", True)
+ application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
self._enabled_shader = None
self._disabled_shader = None
self._non_printing_shader = None
@@ -30,6 +29,41 @@ class SolidView(View):
self._extruders_model = None
self._theme = None
+ self._support_angle = 90
+
+ self._global_stack = None
+
+ Application.getInstance().engineCreatedSignal.connect(self._onGlobalContainerChanged)
+
+ def _onGlobalContainerChanged(self) -> None:
+ if self._global_stack:
+ try:
+ self._global_stack.propertyChanged.disconnect(self._onPropertyChanged)
+ except TypeError:
+ pass
+ for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
+ extruder_stack.propertyChanged.disconnect(self._onPropertyChanged)
+
+ self._global_stack = Application.getInstance().getGlobalContainerStack()
+ if self._global_stack:
+ self._global_stack.propertyChanged.connect(self._onPropertyChanged)
+ for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
+ extruder_stack.propertyChanged.connect(self._onPropertyChanged)
+ self._onPropertyChanged("support_angle", "value") # Force an re-evaluation
+
+ def _onPropertyChanged(self, key: str, property_name: str) -> None:
+ if key != "support_angle" or property_name != "value":
+ return
+ # As the rendering is called a *lot* we really, dont want to re-evaluate the property every time. So we store em!
+ global_container_stack = Application.getInstance().getGlobalContainerStack()
+ if global_container_stack:
+ support_extruder_nr = int(global_container_stack.getExtruderPositionValueWithDefault("support_extruder_nr"))
+ try:
+ support_angle_stack = global_container_stack.extruderList[support_extruder_nr]
+ except IndexError:
+ pass
+ else:
+ self._support_angle = support_angle_stack.getProperty("support_angle", "value")
def beginRendering(self):
scene = self.getController().getScene()
@@ -63,15 +97,10 @@ class SolidView(View):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
- support_extruder_nr = global_container_stack.getExtruderPositionValueWithDefault("support_extruder_nr")
- support_angle_stack = Application.getInstance().getExtruderManager().getExtruderStack(support_extruder_nr)
-
- if support_angle_stack is not None and Application.getInstance().getPreferences().getValue("view/show_overhang"):
- angle = support_angle_stack.getProperty("support_angle", "value")
+ if Application.getInstance().getPreferences().getValue("view/show_overhang"):
# Make sure the overhang angle is valid before passing it to the shader
- # Note: if the overhang angle is set to its default value, it does not need to get validated (validationState = None)
- if angle is not None and global_container_stack.getProperty("support_angle", "validationState") in [None, ValidatorState.Valid]:
- self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle)))
+ if self._support_angle is not None and self._support_angle >= 0 and self._support_angle <= 90:
+ self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - self._support_angle)))
else:
self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) #Overhang angle of 0 causes no area at all to be marked as overhang.
else:
@@ -113,6 +142,10 @@ class SolidView(View):
shade_factor * int(material_color[5:7], 16) / 255,
1.0
]
+
+ # Color the currently selected face-id. (Disable for now.)
+ #face = Selection.getHoverFace()
+ uniforms["hover_face"] = -1 #if not face or node != face[0] else face[1]
except ValueError:
pass
diff --git a/plugins/SolidView/plugin.json b/plugins/SolidView/plugin.json
index b3f62221c5..716f2d8d89 100644
--- a/plugins/SolidView/plugin.json
+++ b/plugins/SolidView/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides a normal solid mesh view.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/SupportEraser/SupportEraser.py b/plugins/SupportEraser/SupportEraser.py
index 0683c48635..35f597dcc5 100644
--- a/plugins/SupportEraser/SupportEraser.py
+++ b/plugins/SupportEraser/SupportEraser.py
@@ -98,8 +98,10 @@ class SupportEraser(Tool):
node.setName("Eraser")
node.setSelectable(True)
+ node.setCalculateBoundingBox(True)
mesh = self._createCube(10)
node.setMeshData(mesh.build())
+ node.calculateBoundingBoxMesh()
active_build_plate = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
node.addDecorator(BuildPlateDecorator(active_build_plate))
diff --git a/plugins/SupportEraser/plugin.json b/plugins/SupportEraser/plugin.json
index fa6d6d230e..888c3df50d 100644
--- a/plugins/SupportEraser/plugin.json
+++ b/plugins/SupportEraser/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Creates an eraser mesh to block the printing of support in certain places",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/SupportEraser/tool_icon.svg b/plugins/SupportEraser/tool_icon.svg
index a0f8a3e3c3..fee69e0715 100644
--- a/plugins/SupportEraser/tool_icon.svg
+++ b/plugins/SupportEraser/tool_icon.svg
@@ -1,11 +1,14 @@
-
\ No newline at end of file
diff --git a/plugins/Toolbox/plugin.json b/plugins/Toolbox/plugin.json
index 61dc0429f5..0b967e1645 100644
--- a/plugins/Toolbox/plugin.json
+++ b/plugins/Toolbox/plugin.json
@@ -2,6 +2,6 @@
"name": "Toolbox",
"author": "Ultimaker B.V.",
"version": "1.0.1",
- "api": "6.0",
+ "api": "7.0",
"description": "Find, manage and install new Cura packages."
}
diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml
index d15d98eed7..d6d862b5f6 100644
--- a/plugins/Toolbox/resources/qml/Toolbox.qml
+++ b/plugins/Toolbox/resources/qml/Toolbox.qml
@@ -1,11 +1,17 @@
// Copyright (c) 2018 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
+// Main window for the Toolbox
+
import QtQuick 2.2
import QtQuick.Dialogs 1.1
import QtQuick.Window 2.2
import UM 1.1 as UM
+import "./pages"
+import "./dialogs"
+import "./components"
+
Window
{
id: base
@@ -14,8 +20,8 @@ Window
modality: Qt.ApplicationModal
flags: Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint
- width: Math.floor(720 * screenScaleFactor)
- height: Math.floor(640 * screenScaleFactor)
+ width: UM.Theme.getSize("large_popup_dialog").width
+ height: UM.Theme.getSize("large_popup_dialog").height
minimumWidth: width
maximumWidth: minimumWidth
minimumHeight: height
@@ -29,9 +35,16 @@ Window
Item
{
anchors.fill: parent
+
+ WelcomePage
+ {
+ visible: toolbox.viewPage === "welcome"
+ }
+
ToolboxHeader
{
id: header
+ visible: toolbox.viewPage !== "welcome"
}
Item
@@ -48,32 +61,32 @@ Window
ToolboxLoadingPage
{
id: viewLoading
- visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "loading"
+ visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "loading"
}
ToolboxErrorPage
{
id: viewErrored
- visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "errored"
+ visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "errored"
}
ToolboxDownloadsPage
{
id: viewDownloads
- visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "overview"
+ visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "overview"
}
ToolboxDetailPage
{
id: viewDetail
- visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "detail"
+ visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "detail"
}
ToolboxAuthorPage
{
id: viewAuthor
- visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "author"
+ visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "author"
}
ToolboxInstalledPage
{
id: installedPluginList
- visible: toolbox.viewCategory == "installed"
+ visible: toolbox.viewCategory === "installed"
}
}
diff --git a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml b/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml
deleted file mode 100644
index 4d4ae92e73..0000000000
--- a/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2018 Ultimaker B.V.
-// Toolbox is released under the terms of the LGPLv3 or higher.
-
-import QtQuick 2.2
-import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
-import UM 1.1 as UM
-import Cura 1.0 as Cura
-
-
-Item
-{
- id: base
-
- property var active: false
- property var complete: false
-
- property var readyLabel: catalog.i18nc("@action:button", "Install")
- property var activeLabel: catalog.i18nc("@action:button", "Cancel")
- property var completeLabel: catalog.i18nc("@action:button", "Installed")
-
- signal readyAction() // Action when button is ready and clicked (likely install)
- signal activeAction() // Action when button is active and clicked (likely cancel)
- signal completeAction() // Action when button is complete and clicked (likely go to installed)
-
- width: UM.Theme.getSize("toolbox_action_button").width
- height: UM.Theme.getSize("toolbox_action_button").height
-
- Cura.PrimaryButton
- {
- id: button
- width: UM.Theme.getSize("toolbox_action_button").width
- height: UM.Theme.getSize("toolbox_action_button").height
- fixedWidthMode: true
- text:
- {
- if (complete)
- {
- return completeLabel
- }
- else if (active)
- {
- return activeLabel
- }
- else
- {
- return readyLabel
- }
- }
- onClicked:
- {
- if (complete)
- {
- completeAction()
- }
- else if (active)
- {
- activeAction()
- }
- else
- {
- readyAction()
- }
- }
- busy: active
- }
-}
diff --git a/plugins/Toolbox/resources/qml/RatingWidget.qml b/plugins/Toolbox/resources/qml/components/RatingWidget.qml
similarity index 100%
rename from plugins/Toolbox/resources/qml/RatingWidget.qml
rename to plugins/Toolbox/resources/qml/components/RatingWidget.qml
diff --git a/plugins/Toolbox/resources/qml/SmallRatingWidget.qml b/plugins/Toolbox/resources/qml/components/SmallRatingWidget.qml
similarity index 100%
rename from plugins/Toolbox/resources/qml/SmallRatingWidget.qml
rename to plugins/Toolbox/resources/qml/components/SmallRatingWidget.qml
diff --git a/plugins/Toolbox/resources/qml/ToolboxActionButtonStyle.qml b/plugins/Toolbox/resources/qml/components/ToolboxActionButtonStyle.qml
similarity index 100%
rename from plugins/Toolbox/resources/qml/ToolboxActionButtonStyle.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxActionButtonStyle.qml
diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/components/ToolboxBackColumn.qml
similarity index 100%
rename from plugins/Toolbox/resources/qml/ToolboxBackColumn.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxBackColumn.qml
diff --git a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml b/plugins/Toolbox/resources/qml/components/ToolboxCompatibilityChart.qml
similarity index 73%
rename from plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxCompatibilityChart.qml
index db4e8c628f..ae9241f0ab 100644
--- a/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxCompatibilityChart.qml
@@ -1,9 +1,9 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
+
import UM 1.1 as UM
Item
@@ -11,48 +11,17 @@ Item
id: base
property var packageData
- property var technicalDataSheetUrl:
- {
- var link = undefined
- if ("Technical Data Sheet" in packageData.links)
- {
- // HACK: This is the way the old API (used in 3.6-beta) used to do it. For safety it's still here,
- // but it can be removed over time.
- link = packageData.links["Technical Data Sheet"]
- }
- else if ("technicalDataSheet" in packageData.links)
- {
- link = packageData.links["technicalDataSheet"]
- }
- return link
- }
- property var safetyDataSheetUrl:
- {
- var sds_name = "safetyDataSheet"
- return (sds_name in packageData.links) ? packageData.links[sds_name] : undefined
- }
- property var printingGuidelinesUrl:
- {
- var pg_name = "printingGuidelines"
- return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined
- }
+ property var technicalDataSheetUrl: packageData.links.technicalDataSheet
+ property var safetyDataSheetUrl: packageData.links.safetyDataSheet
+ property var printingGuidelinesUrl: packageData.links.printingGuidelines
+ property var materialWebsiteUrl: packageData.links.website
- property var materialWebsiteUrl:
- {
- var pg_name = "website"
- return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined
- }
- anchors.topMargin: UM.Theme.getSize("default_margin").height
- height: visible ? childrenRect.height : 0
+ height: childrenRect.height
+ onVisibleChanged: packageData.type === "material" && (compatibilityItem.visible || dataSheetLinks.visible)
- visible: packageData.type == "material" &&
- (packageData.has_configs || technicalDataSheetUrl !== undefined ||
- safetyDataSheetUrl !== undefined || printingGuidelinesUrl !== undefined ||
- materialWebsiteUrl !== undefined)
-
- Item
+ Column
{
- id: combatibilityItem
+ id: compatibilityItem
visible: packageData.has_configs
width: parent.width
// This is a bit of a hack, but the whole QML is pretty messy right now. This needs a big overhaul.
@@ -61,7 +30,6 @@ Item
Label
{
id: heading
- anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
text: catalog.i18nc("@label", "Compatibility")
wrapMode: Text.WordWrap
@@ -73,8 +41,6 @@ Item
TableView
{
id: table
- anchors.top: heading.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
frameVisible: false
@@ -155,32 +121,32 @@ Item
TableViewColumn
{
role: "machine"
- title: "Machine"
+ title: catalog.i18nc("@label:table_header", "Machine")
width: Math.floor(table.width * 0.25)
delegate: columnTextDelegate
}
TableViewColumn
{
role: "print_core"
- title: "Print Core"
+ title: "Print Core" //This term should not be translated.
width: Math.floor(table.width * 0.2)
}
TableViewColumn
{
role: "build_plate"
- title: "Build Plate"
+ title: catalog.i18nc("@label:table_header", "Build Plate")
width: Math.floor(table.width * 0.225)
}
TableViewColumn
{
role: "support_material"
- title: "Support"
+ title: catalog.i18nc("@label:table_header", "Support")
width: Math.floor(table.width * 0.225)
}
TableViewColumn
{
role: "quality"
- title: "Quality"
+ title: catalog.i18nc("@label:table_header", "Quality")
width: Math.floor(table.width * 0.1)
}
}
@@ -188,13 +154,14 @@ Item
Label
{
- id: data_sheet_links
- anchors.top: combatibilityItem.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height / 2
+ id: dataSheetLinks
+ anchors.top: compatibilityItem.bottom
+ anchors.topMargin: UM.Theme.getSize("narrow_margin").height
visible: base.technicalDataSheetUrl !== undefined ||
- base.safetyDataSheetUrl !== undefined || base.printingGuidelinesUrl !== undefined ||
- base.materialWebsiteUrl !== undefined
- height: visible ? contentHeight : 0
+ base.safetyDataSheetUrl !== undefined ||
+ base.printingGuidelinesUrl !== undefined ||
+ base.materialWebsiteUrl !== undefined
+
text:
{
var result = ""
diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/components/ToolboxDetailList.qml
similarity index 82%
rename from plugins/Toolbox/resources/qml/ToolboxDetailList.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxDetailList.qml
index 4e44ea7d0b..22c6b6045f 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxDetailList.qml
@@ -1,9 +1,8 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Toolbox 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 2.10
+import QtQuick.Controls 2.3
import UM 1.1 as UM
Item
@@ -11,10 +10,9 @@ Item
id: detailList
ScrollView
{
- frameVisible: false
+ clip: true
anchors.fill: detailList
- style: UM.Theme.styles.scrollview
- flickableItem.flickableDirection: Flickable.VerticalFlick
+
Column
{
anchors
diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/components/ToolboxDetailTile.qml
similarity index 72%
rename from plugins/Toolbox/resources/qml/ToolboxDetailTile.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxDetailTile.qml
index c7bb1f60ac..5badc6b66d 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxDetailTile.qml
@@ -1,30 +1,30 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
-import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
+import QtQuick.Controls 2.3
+
import UM 1.1 as UM
Item
{
id: tile
width: detailList.width - UM.Theme.getSize("wide_margin").width
- height: normalData.height + compatibilityChart.height + 4 * UM.Theme.getSize("default_margin").height
- Item
+ height: normalData.height + 2 * UM.Theme.getSize("wide_margin").height
+ Column
{
id: normalData
- height: childrenRect.height
+
anchors
{
+ top: parent.top
left: parent.left
right: controls.left
- rightMargin: UM.Theme.getSize("default_margin").width * 2 + UM.Theme.getSize("toolbox_loader").width
- top: parent.top
+ rightMargin: UM.Theme.getSize("wide_margin").width
}
+
Label
{
- id: packageName
width: parent.width
height: UM.Theme.getSize("toolbox_property_label").height
text: model.name
@@ -33,9 +33,9 @@ Item
font: UM.Theme.getFont("medium_bold")
renderType: Text.NativeRendering
}
+
Label
{
- anchors.top: packageName.bottom
width: parent.width
text: model.description
maximumLineCount: 25
@@ -45,6 +45,12 @@ Item
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
}
+
+ ToolboxCompatibilityChart
+ {
+ width: parent.width
+ packageData: model
+ }
}
ToolboxDetailTileActions
@@ -57,20 +63,12 @@ Item
packageData: model
}
- ToolboxCompatibilityChart
- {
- id: compatibilityChart
- anchors.top: normalData.bottom
- width: normalData.width
- packageData: model
- }
-
Rectangle
{
color: UM.Theme.getColor("lining")
width: tile.width
height: UM.Theme.getSize("default_lining").height
- anchors.top: compatibilityChart.bottom
+ anchors.top: normalData.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height + UM.Theme.getSize("wide_margin").height //Normal margin for spacing after chart, wide margin between items.
}
}
diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml b/plugins/Toolbox/resources/qml/components/ToolboxDetailTileActions.qml
similarity index 93%
rename from plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxDetailTileActions.qml
index 60fe095537..dfe91edbf6 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxDetailTileActions.qml
@@ -10,7 +10,7 @@ import Cura 1.1 as Cura
Column
{
property bool installed: toolbox.isInstalled(model.id)
- property bool canUpdate: toolbox.canUpdate(model.id)
+ property bool canUpdate: CuraApplication.getPackageManager().packagesWithUpdate.indexOf(model.id) != -1
property bool loginRequired: model.login_required && !Cura.API.account.isLoggedIn
property var packageData
@@ -35,11 +35,12 @@ Column
// Don't allow installing while another download is running
enabled: installed || (!(toolbox.isDownloading && toolbox.activePackage != model) && !loginRequired)
opacity: enabled ? 1.0 : 0.5
- visible: !updateButton.visible && !installed// Don't show when the update button is visible
+ visible: !updateButton.visible && !installed // Don't show when the update button is visible
}
Cura.SecondaryButton
{
+ id: installedButton
visible: installed
onClicked: toolbox.viewCategory = "installed"
text: catalog.i18nc("@action:button", "Installed")
@@ -112,11 +113,9 @@ Column
{
target: toolbox
onInstallChanged: installed = toolbox.isInstalled(model.id)
- onMetadataChanged: canUpdate = toolbox.canUpdate(model.id)
onFilterChanged:
{
installed = toolbox.isInstalled(model.id)
- canUpdate = toolbox.canUpdate(model.id)
}
}
}
diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/components/ToolboxDownloadsGrid.qml
similarity index 93%
rename from plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxDownloadsGrid.qml
index a9fcb39b28..6682281a31 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxDownloadsGrid.qml
@@ -2,9 +2,7 @@
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
-import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
-import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.3
import UM 1.1 as UM
Column
diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/components/ToolboxDownloadsGridTile.qml
similarity index 95%
rename from plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxDownloadsGridTile.qml
index a11c6ee963..78cdf1562a 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxDownloadsGridTile.qml
@@ -67,7 +67,7 @@ Item
width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width
height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width
fillMode: Image.PreserveAspectFit
- source: model.icon_url || "../images/logobot.svg"
+ source: model.icon_url || "../../images/logobot.svg"
mipmap: true
}
UM.RecolorImage
@@ -81,8 +81,8 @@ Item
}
sourceSize.height: height
visible: installedPackages != 0
- color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
- source: "../images/installed_check.svg"
+ color: (installedPackages >= packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
+ source: "../../images/installed_check.svg"
}
}
Item
diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/components/ToolboxDownloadsShowcase.qml
similarity index 95%
rename from plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxDownloadsShowcase.qml
index 795622cf82..72dd6f91a2 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxDownloadsShowcase.qml
@@ -14,7 +14,7 @@ Rectangle
Column
{
height: childrenRect.height + 2 * padding
- spacing: UM.Theme.getSize("toolbox_showcase_spacing").width
+ spacing: UM.Theme.getSize("default_margin").width
width: parent.width
padding: UM.Theme.getSize("wide_margin").height
Label
diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/components/ToolboxDownloadsShowcaseTile.qml
similarity index 95%
rename from plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxDownloadsShowcaseTile.qml
index 3699746b86..f6e32b2d84 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxDownloadsShowcaseTile.qml
@@ -23,7 +23,7 @@ Rectangle
height: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height
fillMode: Image.PreserveAspectFit
- source: model.icon_url || "../images/logobot.svg"
+ source: model.icon_url || "../../images/logobot.svg"
mipmap: true
anchors
{
@@ -61,8 +61,8 @@ Rectangle
right: parent.right
}
visible: installedPackages != 0
- color: (installedPackages == packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
- source: "../images/installed_check.svg"
+ color: (installedPackages >= packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
+ source: "../../images/installed_check.svg"
}
SmallRatingWidget
diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/components/ToolboxFooter.qml
similarity index 100%
rename from plugins/Toolbox/resources/qml/ToolboxFooter.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxFooter.qml
diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/components/ToolboxHeader.qml
similarity index 75%
rename from plugins/Toolbox/resources/qml/ToolboxHeader.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxHeader.qml
index 087402d564..491567eb5f 100644
--- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxHeader.qml
@@ -1,9 +1,11 @@
// Copyright (c) 2018 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
+import QtQuick 2.10
import QtQuick.Controls 1.4
-import UM 1.1 as UM
+
+import UM 1.4 as UM
+import Cura 1.0 as Cura
Item
{
@@ -50,6 +52,7 @@ Item
}
}
}
+
ToolboxTabButton
{
id: installedTabButton
@@ -62,7 +65,25 @@ Item
rightMargin: UM.Theme.getSize("default_margin").width
}
onClicked: toolbox.viewCategory = "installed"
+ width: UM.Theme.getSize("toolbox_header_tab").width + marketplaceNotificationIcon.width - UM.Theme.getSize("default_margin").width
}
+
+ Cura.NotificationIcon
+ {
+ id: marketplaceNotificationIcon
+
+ visible: CuraApplication.getPackageManager().packagesWithUpdate.length > 0
+
+ anchors.right: installedTabButton.right
+ anchors.verticalCenter: installedTabButton.verticalCenter
+
+ labelText:
+ {
+ const itemCount = CuraApplication.getPackageManager().packagesWithUpdate.length
+ return itemCount > 9 ? "9+" : itemCount
+ }
+ }
+
ToolboxShadow
{
anchors.top: bar.bottom
diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/components/ToolboxInstalledTile.qml
similarity index 96%
rename from plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxInstalledTile.qml
index f50c3f3ac6..f85a1056b7 100644
--- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxInstalledTile.qml
@@ -41,14 +41,13 @@ Item
Column
{
id: pluginInfo
- topPadding: Math.floor(UM.Theme.getSize("default_margin").height / 2)
+ topPadding: UM.Theme.getSize("narrow_margin").height
property var color: model.type === "plugin" && !isEnabled ? UM.Theme.getColor("lining") : UM.Theme.getColor("text")
width: Math.floor(tileRow.width - (authorInfo.width + pluginActions.width + 2 * tileRow.spacing + ((disableButton.visible) ? disableButton.width + tileRow.spacing : 0)))
Label
{
text: model.name
width: parent.width
- height: Math.floor(UM.Theme.getSize("toolbox_property_label").height)
wrapMode: Text.WordWrap
font: UM.Theme.getFont("large_bold")
color: pluginInfo.color
diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml b/plugins/Toolbox/resources/qml/components/ToolboxInstalledTileActions.qml
similarity index 96%
rename from plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxInstalledTileActions.qml
index 61af84fbe5..db30b1caf5 100644
--- a/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxInstalledTileActions.qml
@@ -10,7 +10,7 @@ import Cura 1.1 as Cura
Column
{
- property bool canUpdate: false
+ property bool canUpdate: CuraApplication.getPackageManager().packagesWithUpdate.indexOf(model.id) != -1
property bool canDowngrade: false
property bool loginRequired: model.login_required && !Cura.API.account.isLoggedIn
width: UM.Theme.getSize("toolbox_action_button").width
@@ -83,7 +83,6 @@ Column
target: toolbox
onMetadataChanged:
{
- canUpdate = toolbox.canUpdate(model.id)
canDowngrade = toolbox.canDowngrade(model.id)
}
}
diff --git a/plugins/Toolbox/resources/qml/components/ToolboxProgressButton.qml b/plugins/Toolbox/resources/qml/components/ToolboxProgressButton.qml
new file mode 100644
index 0000000000..40d6c1af47
--- /dev/null
+++ b/plugins/Toolbox/resources/qml/components/ToolboxProgressButton.qml
@@ -0,0 +1,60 @@
+// Copyright (c) 2019 Ultimaker B.V.
+// Toolbox is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+
+import UM 1.1 as UM
+import Cura 1.0 as Cura
+
+
+Cura.PrimaryButton
+{
+ id: button
+
+ property var active: false
+ property var complete: false
+
+ property var readyLabel: catalog.i18nc("@action:button", "Install")
+ property var activeLabel: catalog.i18nc("@action:button", "Cancel")
+ property var completeLabel: catalog.i18nc("@action:button", "Installed")
+
+ signal readyAction() // Action when button is ready and clicked (likely install)
+ signal activeAction() // Action when button is active and clicked (likely cancel)
+ signal completeAction() // Action when button is complete and clicked (likely go to installed)
+
+ width: UM.Theme.getSize("toolbox_action_button").width
+ height: UM.Theme.getSize("toolbox_action_button").height
+ fixedWidthMode: true
+ text:
+ {
+ if (complete)
+ {
+ return completeLabel
+ }
+ else if (active)
+ {
+ return activeLabel
+ }
+ else
+ {
+ return readyLabel
+ }
+ }
+ onClicked:
+ {
+ if (complete)
+ {
+ completeAction()
+ }
+ else if (active)
+ {
+ activeAction()
+ }
+ else
+ {
+ readyAction()
+ }
+ }
+ busy: active
+}
diff --git a/plugins/Toolbox/resources/qml/ToolboxShadow.qml b/plugins/Toolbox/resources/qml/components/ToolboxShadow.qml
similarity index 100%
rename from plugins/Toolbox/resources/qml/ToolboxShadow.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxShadow.qml
diff --git a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml b/plugins/Toolbox/resources/qml/components/ToolboxTabButton.qml
similarity index 50%
rename from plugins/Toolbox/resources/qml/ToolboxTabButton.qml
rename to plugins/Toolbox/resources/qml/components/ToolboxTabButton.qml
index 5e1aeaa636..7a7d2be48a 100644
--- a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml
+++ b/plugins/Toolbox/resources/qml/components/ToolboxTabButton.qml
@@ -9,14 +9,17 @@ Button
{
id: control
property bool active: false
- hoverEnabled: true
+
+ implicitWidth: UM.Theme.getSize("toolbox_header_tab").width
+ implicitHeight: UM.Theme.getSize("toolbox_header_tab").height
background: Item
{
- implicitWidth: UM.Theme.getSize("toolbox_header_tab").width
- implicitHeight: UM.Theme.getSize("toolbox_header_tab").height
+ id: backgroundItem
Rectangle
{
+ id: highlight
+
visible: control.active
color: UM.Theme.getColor("primary")
anchors.bottom: parent.bottom
@@ -24,28 +27,42 @@ Button
height: UM.Theme.getSize("toolbox_header_highlight").height
}
}
+
contentItem: Label
{
id: label
text: control.text
- color:
- {
- if(control.hovered)
- {
- return UM.Theme.getColor("toolbox_header_button_text_hovered");
- }
- if(control.active)
- {
- return UM.Theme.getColor("toolbox_header_button_text_active");
- }
- else
- {
- return UM.Theme.getColor("toolbox_header_button_text_inactive");
- }
- }
- font: control.enabled ? (control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")) : UM.Theme.getFont("default_italic")
+ color: UM.Theme.getColor("toolbox_header_button_text_inactive")
+ font: UM.Theme.getFont("medium")
+
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
+
renderType: Text.NativeRendering
}
+
+ states:
+ [
+ State
+ {
+ name: "disabled"
+ when: !control.enabled
+ PropertyChanges
+ {
+ target: label
+ font: UM.Theme.getFont("default_italic")
+ }
+ },
+ State
+ {
+ name: "active"
+ when: control.active
+ PropertyChanges
+ {
+ target: label
+ font: UM.Theme.getFont("medium_bold")
+ color: UM.Theme.getColor("action_button_text")
+ }
+ }
+ ]
}
\ No newline at end of file
diff --git a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml b/plugins/Toolbox/resources/qml/dialogs/ToolboxConfirmUninstallResetDialog.qml
similarity index 94%
rename from plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml
rename to plugins/Toolbox/resources/qml/dialogs/ToolboxConfirmUninstallResetDialog.qml
index e238132680..1b5e4d1d46 100644
--- a/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml
+++ b/plugins/Toolbox/resources/qml/dialogs/ToolboxConfirmUninstallResetDialog.qml
@@ -14,7 +14,7 @@ import Cura 1.0 as Cura
UM.Dialog
{
- // This dialog asks the user whether he/she wants to open a project file as a project or import models.
+ // This dialog asks the user to confirm he/she wants to uninstall materials/pprofiles which are currently in use
id: base
title: catalog.i18nc("@title:window", "Confirm uninstall") + toolbox.pluginToUninstall
@@ -26,7 +26,7 @@ UM.Dialog
minimumWidth: 450 * screenScaleFactor
minimumHeight: 150 * screenScaleFactor
- modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal
+ modality: Qt.WindowModal
Column
{
diff --git a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml b/plugins/Toolbox/resources/qml/dialogs/ToolboxLicenseDialog.qml
similarity index 90%
rename from plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml
rename to plugins/Toolbox/resources/qml/dialogs/ToolboxLicenseDialog.qml
index 40b22c268d..f7edde1fff 100644
--- a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml
+++ b/plugins/Toolbox/resources/qml/dialogs/ToolboxLicenseDialog.qml
@@ -30,7 +30,7 @@ UM.Dialog
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
- text: licenseDialog.pluginName + catalog.i18nc("@label", "This plugin contains a license.\nYou need to accept this license to install this plugin.\nDo you agree with the terms below?")
+ text: licenseDialog.pluginName + ": " + catalog.i18nc("@label", "This plugin contains a license.\nYou need to accept this license to install this plugin.\nDo you agree with the terms below?")
wrapMode: Text.Wrap
renderType: Text.NativeRendering
}
diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/pages/ToolboxAuthorPage.qml
similarity index 94%
rename from plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml
rename to plugins/Toolbox/resources/qml/pages/ToolboxAuthorPage.qml
index b653f1a73b..d1abe48de1 100644
--- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml
+++ b/plugins/Toolbox/resources/qml/pages/ToolboxAuthorPage.qml
@@ -6,6 +6,8 @@ import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.1 as UM
+import "../components"
+
Item
{
id: page
@@ -31,7 +33,7 @@ Item
width: UM.Theme.getSize("toolbox_thumbnail_medium").width
height: UM.Theme.getSize("toolbox_thumbnail_medium").height
fillMode: Image.PreserveAspectFit
- source: details.icon_url || "../images/logobot.svg"
+ source: details.icon_url || "../../images/logobot.svg"
mipmap: true
anchors
{
@@ -65,6 +67,7 @@ Item
{
id: description
text: details.description || ""
+ font: UM.Theme.getFont("default")
anchors
{
top: title.bottom
@@ -108,6 +111,8 @@ Item
top: description.bottom
left: properties.right
leftMargin: UM.Theme.getSize("default_margin").width
+ right: parent.right
+ rightMargin: UM.Theme.getSize("default_margin").width
topMargin: UM.Theme.getSize("default_margin").height
}
spacing: Math.floor(UM.Theme.getSize("narrow_margin").height)
@@ -122,6 +127,8 @@ Item
}
return ""
}
+ width: parent.width
+ elide: Text.ElideRight
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
linkColor: UM.Theme.getColor("text_link")
diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/pages/ToolboxDetailPage.qml
similarity index 98%
rename from plugins/Toolbox/resources/qml/ToolboxDetailPage.qml
rename to plugins/Toolbox/resources/qml/pages/ToolboxDetailPage.qml
index fef2732af9..6d34e23f42 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml
+++ b/plugins/Toolbox/resources/qml/pages/ToolboxDetailPage.qml
@@ -8,6 +8,8 @@ import UM 1.1 as UM
import Cura 1.1 as Cura
+import "../components"
+
Item
{
id: page
@@ -44,7 +46,7 @@ Item
{
anchors.fill: parent
fillMode: Image.PreserveAspectFit
- source: details === null ? "" : (details.icon_url || "../images/logobot.svg")
+ source: details === null ? "" : (details.icon_url || "../../images/logobot.svg")
mipmap: true
}
}
@@ -89,6 +91,7 @@ Item
Label
{
text: catalog.i18nc("@label", "Your rating") + ":"
+ visible: details.type == "plugin"
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_medium")
renderType: Text.NativeRendering
diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/pages/ToolboxDownloadsPage.qml
similarity index 53%
rename from plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml
rename to plugins/Toolbox/resources/qml/pages/ToolboxDownloadsPage.qml
index 3e0dda4f4a..9be8cbe2b9 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml
+++ b/plugins/Toolbox/resources/qml/pages/ToolboxDownloadsPage.qml
@@ -1,25 +1,24 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Toolbox 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 2.10
+import QtQuick.Controls 2.3
import UM 1.1 as UM
+import "../components"
+
ScrollView
{
- frameVisible: false
+ clip: true
width: parent.width
height: parent.height
- style: UM.Theme.styles.scrollview
-
- flickableItem.flickableDirection: Flickable.VerticalFlick
+ contentHeight: mainColumn.height
Column
{
+ id: mainColumn
width: base.width
spacing: UM.Theme.getSize("default_margin").height
- height: childrenRect.height
ToolboxDownloadsShowcase
{
@@ -31,14 +30,14 @@ 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.materialsAvailableModel : toolbox.pluginsAvailableModel
+ heading: toolbox.viewCategory === "material" ? catalog.i18nc("@label", "Community Contributions") : catalog.i18nc("@label", "Community Plugins")
+ model: toolbox.viewCategory === "material" ? toolbox.materialsAvailableModel : toolbox.pluginsAvailableModel
}
ToolboxDownloadsGrid
{
id: genericMaterials
- visible: toolbox.viewCategory == "material"
+ visible: toolbox.viewCategory === "material"
width: parent.width
heading: catalog.i18nc("@label", "Generic Materials")
model: toolbox.materialsGenericModel
diff --git a/plugins/Toolbox/resources/qml/ToolboxErrorPage.qml b/plugins/Toolbox/resources/qml/pages/ToolboxErrorPage.qml
similarity index 100%
rename from plugins/Toolbox/resources/qml/ToolboxErrorPage.qml
rename to plugins/Toolbox/resources/qml/pages/ToolboxErrorPage.qml
diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/pages/ToolboxInstalledPage.qml
similarity index 70%
rename from plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml
rename to plugins/Toolbox/resources/qml/pages/ToolboxInstalledPage.qml
index a85a69cbac..99590c712c 100644
--- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml
+++ b/plugins/Toolbox/resources/qml/pages/ToolboxInstalledPage.qml
@@ -1,49 +1,52 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
-import QtQuick.Dialogs 1.1
-import QtQuick.Window 2.2
-import QtQuick.Controls 1.4
-import QtQuick.Controls.Styles 1.4
+import QtQuick.Controls 2.3
import UM 1.1 as UM
+import "../components"
+
ScrollView
{
id: page
- frameVisible: false
+ clip: true
width: parent.width
height: parent.height
- style: UM.Theme.styles.scrollview
- flickableItem.flickableDirection: Flickable.VerticalFlick
Column
{
+ width: page.width
spacing: UM.Theme.getSize("default_margin").height
+ padding: UM.Theme.getSize("wide_margin").width
visible: toolbox.pluginsInstalledModel.items.length > 0
- height: childrenRect.height + 4 * UM.Theme.getSize("default_margin").height
-
- anchors
- {
- right: parent.right
- left: parent.left
- margins: UM.Theme.getSize("default_margin").width
- top: parent.top
- }
+ height: childrenRect.height + 2 * UM.Theme.getSize("wide_margin").height
Label
{
- width: page.width
+ anchors
+ {
+ left: parent.left
+ right: parent.right
+ margins: parent.padding
+ }
text: catalog.i18nc("@title:tab", "Plugins")
color: UM.Theme.getColor("text_medium")
font: UM.Theme.getFont("large")
renderType: Text.NativeRendering
}
+
Rectangle
{
+ anchors
+ {
+ left: parent.left
+ right: parent.right
+ margins: parent.padding
+ }
+ id: installedPlugins
color: "transparent"
- width: parent.width
height: childrenRect.height + UM.Theme.getSize("default_margin").width
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
@@ -64,8 +67,15 @@ ScrollView
}
}
}
+
Label
{
+ anchors
+ {
+ left: parent.left
+ right: parent.right
+ margins: parent.padding
+ }
text: catalog.i18nc("@title:tab", "Materials")
color: UM.Theme.getColor("text_medium")
font: UM.Theme.getFont("medium")
@@ -74,8 +84,14 @@ ScrollView
Rectangle
{
+ anchors
+ {
+ left: parent.left
+ right: parent.right
+ margins: parent.padding
+ }
+ id: installedMaterials
color: "transparent"
- width: parent.width
height: childrenRect.height + UM.Theme.getSize("default_margin").width
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
diff --git a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml b/plugins/Toolbox/resources/qml/pages/ToolboxLoadingPage.qml
similarity index 100%
rename from plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml
rename to plugins/Toolbox/resources/qml/pages/ToolboxLoadingPage.qml
diff --git a/plugins/Toolbox/resources/qml/pages/WelcomePage.qml b/plugins/Toolbox/resources/qml/pages/WelcomePage.qml
new file mode 100644
index 0000000000..cbfdf8f402
--- /dev/null
+++ b/plugins/Toolbox/resources/qml/pages/WelcomePage.qml
@@ -0,0 +1,53 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.7
+import QtQuick.Controls 2.1
+import QtQuick.Window 2.2
+
+import UM 1.3 as UM
+import Cura 1.1 as Cura
+
+Column
+{
+ id: welcomePage
+ spacing: UM.Theme.getSize("wide_margin").height
+ width: parent.width
+ height: childrenRect.height
+ anchors.centerIn: parent
+
+ Image
+ {
+ id: profileImage
+ fillMode: Image.PreserveAspectFit
+ source: "../../images/logobot.svg"
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: Math.round(parent.width / 4)
+ }
+
+ Label
+ {
+ id: welcomeTextLabel
+ text: catalog.i18nc("@description", "Get plugins and materials verified by Ultimaker")
+ width: Math.round(parent.width / 2)
+ font: UM.Theme.getFont("default")
+ color: UM.Theme.getColor("text")
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ wrapMode: Label.WordWrap
+ renderType: Text.NativeRendering
+ }
+
+ Cura.PrimaryButton
+ {
+ id: loginButton
+ width: UM.Theme.getSize("account_button").width
+ height: UM.Theme.getSize("account_button").height
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: catalog.i18nc("@button", "Sign in")
+ onClicked: Cura.API.account.login()
+ fixedWidthMode: true
+ }
+}
+
diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py
index 877f8256ee..7bfc58df04 100644
--- a/plugins/Toolbox/src/AuthorsModel.py
+++ b/plugins/Toolbox/src/AuthorsModel.py
@@ -53,7 +53,7 @@ class AuthorsModel(ListModel):
# Filter on all the key-word arguments.
for key, value in self._filter.items():
- if key is "package_types":
+ if key == "package_types":
key_filter = lambda item, value = value: value in item["package_types"] # type: ignore
elif "*" in value:
key_filter = lambda item, key = key, value = value: self._matchRegExp(item, key, value) # type: ignore
diff --git a/plugins/Toolbox/src/ConfigsModel.py b/plugins/Toolbox/src/ConfigsModel.py
index dd54d53d93..9ba65caaa4 100644
--- a/plugins/Toolbox/src/ConfigsModel.py
+++ b/plugins/Toolbox/src/ConfigsModel.py
@@ -1,11 +1,10 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-import re
-from typing import Dict
from PyQt5.QtCore import Qt, pyqtProperty
from UM.Qt.ListModel import ListModel
+
## Model that holds supported configurations (for material/quality packages).
class ConfigsModel(ListModel):
def __init__(self, parent = None):
diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py
index d94fdf6bb7..1cf87790bc 100644
--- a/plugins/Toolbox/src/PackagesModel.py
+++ b/plugins/Toolbox/src/PackagesModel.py
@@ -112,7 +112,7 @@ class PackagesModel(ListModel):
# Filter on all the key-word arguments.
for key, value in self._filter.items():
- if key is "tags":
+ if key == "tags":
key_filter = lambda item, v = value: v in item["tags"]
elif "*" in value:
key_filter = lambda candidate, k = key, v = value: self._matchRegExp(candidate, k, v)
diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py
index 7d8d359831..27197275b8 100644
--- a/plugins/Toolbox/src/Toolbox.py
+++ b/plugins/Toolbox/src/Toolbox.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Toolbox is released under the terms of the LGPLv3 or higher.
import json
@@ -19,6 +19,7 @@ from UM.Version import Version
from cura import ApplicationMetadata
from cura import UltimakerCloudAuthentication
from cura.CuraApplication import CuraApplication
+from cura.Machines.ContainerTree import ContainerTree
from .AuthorsModel import AuthorsModel
from .PackagesModel import PackagesModel
@@ -47,10 +48,9 @@ class Toolbox(QObject, Extension):
self._download_progress = 0 # type: float
self._is_downloading = False # type: bool
self._network_manager = None # type: Optional[QNetworkAccessManager]
- self._request_headers = [] # type: List[Tuple[bytes, bytes]]
+ self._request_headers = [] # type: List[Tuple[bytes, bytes]]
self._updateRequestHeader()
-
self._request_urls = {} # type: Dict[str, QUrl]
self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated
self._old_plugin_ids = set() # type: Set[str]
@@ -59,13 +59,15 @@ class Toolbox(QObject, Extension):
# The responses as given by the server parsed to a list.
self._server_response_data = {
"authors": [],
- "packages": []
+ "packages": [],
+ "updates": [],
} # type: Dict[str, List[Any]]
# Models:
self._models = {
"authors": AuthorsModel(self),
"packages": PackagesModel(self),
+ "updates": PackagesModel(self),
} # type: Dict[str, Union[AuthorsModel, PackagesModel]]
self._plugins_showcase_model = PackagesModel(self)
@@ -86,7 +88,7 @@ class Toolbox(QObject, Extension):
# View page defines which type of page layout to use. For example,
# possible values include "overview", "detail" or "author".
- self._view_page = "loading" # type: str
+ self._view_page = "welcome" # type: str
# Active package refers to which package is currently being downloaded,
# installed, or otherwise modified.
@@ -105,7 +107,7 @@ class Toolbox(QObject, Extension):
self._restart_dialog_message = "" # type: str
self._application.initializationFinished.connect(self._onAppInitialized)
- self._application.getCuraAPI().account.loginStateChanged.connect(self._updateRequestHeader)
+ self._application.getCuraAPI().account.accessTokenChanged.connect(self._updateRequestHeader)
# Signals:
# --------------------------------------------------------------------------
@@ -125,6 +127,16 @@ class Toolbox(QObject, Extension):
showLicenseDialog = pyqtSignal()
uninstallVariablesChanged = pyqtSignal()
+ ## Go back to the start state (welcome screen or loading if no login required)
+ def _restart(self):
+ self._updateRequestHeader()
+ # For an Essentials build, login is mandatory
+ if not self._application.getCuraAPI().account.isLoggedIn and ApplicationMetadata.IsEnterpriseVersion:
+ self.setViewPage("welcome")
+ else:
+ self.setViewPage("loading")
+ self._fetchPackageData()
+
def _updateRequestHeader(self):
self._request_headers = [
(b"User-Agent",
@@ -185,16 +197,27 @@ class Toolbox(QObject, Extension):
cloud_api_version = self._cloud_api_version,
sdk_version = self._sdk_version
)
+
+ # We need to construct a query like installed_packages=ID:VERSION&installed_packages=ID:VERSION, etc.
+ installed_package_ids_with_versions = [":".join(items) for items in
+ self._package_manager.getAllInstalledPackageIdsAndVersions()]
+ installed_packages_query = "&installed_packages=".join(installed_package_ids_with_versions)
+
self._request_urls = {
"authors": QUrl("{base_url}/authors".format(base_url = self._api_url)),
- "packages": QUrl("{base_url}/packages".format(base_url = self._api_url))
+ "packages": QUrl("{base_url}/packages".format(base_url = self._api_url)),
+ "updates": QUrl("{base_url}/packages/package-updates?installed_packages={query}".format(
+ base_url = self._api_url, query = installed_packages_query))
}
- @pyqtSlot()
- def browsePackages(self) -> None:
- # Create the network manager:
- # This was formerly its own function but really had no reason to be as
- # it was never called more than once ever.
+ self._application.getCuraAPI().account.loginStateChanged.connect(self._restart)
+
+ # On boot we check which packages have updates.
+ if CuraApplication.getInstance().getPreferences().getValue("info/automatic_update_check") and len(installed_package_ids_with_versions) > 0:
+ # Request the latest and greatest!
+ self._fetchPackageUpdates()
+
+ def _prepareNetworkManager(self):
if self._network_manager is not None:
self._network_manager.finished.disconnect(self._onRequestFinished)
self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccessibleChanged)
@@ -202,13 +225,22 @@ class Toolbox(QObject, Extension):
self._network_manager.finished.connect(self._onRequestFinished)
self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccessibleChanged)
+ def _fetchPackageUpdates(self):
+ self._prepareNetworkManager()
+ self._makeRequestByType("updates")
+
+ def _fetchPackageData(self):
+ self._prepareNetworkManager()
# Make remote requests:
self._makeRequestByType("packages")
self._makeRequestByType("authors")
-
# Gather installed packages:
self._updateInstalledModels()
+ # Displays the toolbox
+ @pyqtSlot()
+ def launch(self) -> None:
+
if not self._dialog:
self._dialog = self._createDialog("Toolbox.qml")
@@ -216,6 +248,8 @@ class Toolbox(QObject, Extension):
Logger.log("e", "Unexpected error trying to create the 'Marketplace' dialog.")
return
+ self._restart()
+
self._dialog.show()
# Apply enabled/disabled state to installed plugins
@@ -227,7 +261,7 @@ class Toolbox(QObject, Extension):
if not plugin_path:
return None
path = os.path.join(plugin_path, "resources", "qml", qml_name)
-
+
dialog = self._application.createQmlComponent(path, {"toolbox": self})
if not dialog:
raise Exception("Failed to create Marketplace dialog")
@@ -272,7 +306,7 @@ class Toolbox(QObject, Extension):
for plugin_id in old_plugin_ids:
# Neither the installed packages nor the packages that are scheduled to remove are old plugins
if plugin_id not in installed_package_ids and plugin_id not in scheduled_to_remove_package_ids:
- Logger.log("i", "Found a plugin that was installed with the old plugin browser: %s", plugin_id)
+ Logger.log("d", "Found a plugin that was installed with the old plugin browser: %s", plugin_id)
old_metadata = self._plugin_registry.getMetaData(plugin_id)
new_metadata = self._convertPluginMetadata(old_metadata)
@@ -321,7 +355,7 @@ class Toolbox(QObject, Extension):
self._package_used_qualities = package_used_qualities
# Ask change to default material / profile
if self._confirm_reset_dialog is None:
- self._confirm_reset_dialog = self._createDialog("ToolboxConfirmUninstallResetDialog.qml")
+ self._confirm_reset_dialog = self._createDialog("dialogs/ToolboxConfirmUninstallResetDialog.qml")
self.uninstallVariablesChanged.emit()
if self._confirm_reset_dialog is None:
Logger.log("e", "ToolboxConfirmUninstallResetDialog should have been initialized, but it is not. Not showing dialog and not uninstalling package.")
@@ -353,15 +387,22 @@ class Toolbox(QObject, Extension):
@pyqtSlot()
def resetMaterialsQualitiesAndUninstall(self) -> None:
application = CuraApplication.getInstance()
- material_manager = application.getMaterialManager()
- quality_manager = application.getQualityManager()
machine_manager = application.getMachineManager()
+ container_tree = ContainerTree.getInstance()
for global_stack, extruder_nr, container_id in self._package_used_materials:
- default_material_node = material_manager.getDefaultMaterial(global_stack, extruder_nr, global_stack.extruders[extruder_nr].variant.getName())
+ extruder = global_stack.extruderList[int(extruder_nr)]
+ approximate_diameter = extruder.getApproximateMaterialDiameter()
+ variant_node = container_tree.machines[global_stack.definition.getId()].variants[extruder.variant.getName()]
+ default_material_node = variant_node.preferredMaterial(approximate_diameter)
machine_manager.setMaterial(extruder_nr, default_material_node, global_stack = global_stack)
for global_stack, extruder_nr, container_id in self._package_used_qualities:
- default_quality_group = quality_manager.getDefaultQualityType(global_stack)
+ variant_names = [extruder.variant.getName() for extruder in global_stack.extruderList]
+ material_bases = [extruder.material.getMetaDataEntry("base_file") for extruder in global_stack.extruderList]
+ extruder_enabled = [extruder.isEnabled for extruder in global_stack.extruderList]
+ definition_id = global_stack.definition.getId()
+ machine_node = container_tree.machines[definition_id]
+ default_quality_group = machine_node.getQualityGroups(variant_names, material_bases, extruder_enabled)[machine_node.preferred_quality_type]
machine_manager.setQualityGroup(default_quality_group, global_stack = global_stack)
if self._package_id_to_uninstall is not None:
@@ -455,36 +496,6 @@ class Toolbox(QObject, Extension):
break
return remote_package
- # Checks
- # --------------------------------------------------------------------------
- @pyqtSlot(str, result = bool)
- def canUpdate(self, package_id: str) -> bool:
- local_package = self._package_manager.getInstalledPackageInfo(package_id)
- if local_package is None:
- local_package = self.getOldPluginPackageMetadata(package_id)
- if local_package is None:
- return False
-
- remote_package = self.getRemotePackage(package_id)
- if remote_package is None:
- return False
-
- local_version = Version(local_package["package_version"])
- remote_version = Version(remote_package["package_version"])
- can_upgrade = False
- if remote_version > local_version:
- can_upgrade = True
- # A package with the same version can be built to have different SDK versions. So, for a package with the same
- # version, we also need to check if the current one has a lower SDK version. If so, this package should also
- # be upgradable.
- elif remote_version == local_version:
- # First read sdk_version_semver. If that doesn't exist, read just sdk_version (old version system).
- remote_sdk_version = Version(remote_package.get("sdk_version_semver", remote_package.get("sdk_version", 0)))
- local_sdk_version = Version(local_package.get("sdk_version_semver", local_package.get("sdk_version", 0)))
- can_upgrade = local_sdk_version < remote_sdk_version
-
- return can_upgrade
-
@pyqtSlot(str, result = bool)
def canDowngrade(self, package_id: str) -> bool:
# If the currently installed version is higher than the bundled version (if present), the we can downgrade
@@ -550,7 +561,7 @@ class Toolbox(QObject, Extension):
# Make API Calls
# --------------------------------------------------------------------------
def _makeRequestByType(self, request_type: str) -> None:
- Logger.log("i", "Requesting %s metadata from server.", request_type)
+ Logger.log("d", "Requesting %s metadata from server.", request_type)
request = QNetworkRequest(self._request_urls[request_type])
for header_name, header_value in self._request_headers:
request.setRawHeader(header_name, header_value)
@@ -584,9 +595,15 @@ class Toolbox(QObject, Extension):
if self._download_reply:
try:
self._download_reply.downloadProgress.disconnect(self._onDownloadProgress)
- except TypeError: # Raised when the method is not connected to the signal yet.
+ except (TypeError, RuntimeError): # Raised when the method is not connected to the signal yet.
pass # Don't need to disconnect.
- self._download_reply.abort()
+ try:
+ self._download_reply.abort()
+ except RuntimeError:
+ # In some cases the garbage collector is a bit to agressive, which causes the dowload_reply
+ # to be deleted (especially if the machine has been put to sleep). As we don't know what exactly causes
+ # this (The issue probably lives in the bowels of (py)Qt somewhere), we can only catch and ignore it.
+ pass
self._download_reply = None
self._download_request = None
self.setDownloadProgress(0)
@@ -628,17 +645,22 @@ class Toolbox(QObject, Extension):
if not self._models[response_type]:
Logger.log("e", "Could not find the %s model.", response_type)
break
-
+
self._server_response_data[response_type] = json_data["data"]
self._models[response_type].setMetadata(self._server_response_data[response_type])
- if response_type is "packages":
+ if response_type == "packages":
self._models[response_type].setFilter({"type": "plugin"})
self.reBuildMaterialsModels()
self.reBuildPluginsModels()
- elif response_type is "authors":
+ self._notifyPackageManager()
+ elif response_type == "authors":
self._models[response_type].setFilter({"package_types": "material"})
self._models[response_type].setFilter({"tags": "generic"})
+ elif response_type == "updates":
+ # Tell the package manager that there's a new set of updates available.
+ packages = set([pkg["package_id"] for pkg in self._server_response_data[response_type]])
+ self._package_manager.setPackagesWithUpdate(packages)
self.metadataChanged.emit()
@@ -656,6 +678,11 @@ class Toolbox(QObject, Extension):
# Ignore any operation that is not a get operation
pass
+ # This function goes through all known remote versions of a package and notifies the package manager of this change
+ def _notifyPackageManager(self):
+ for package in self._server_response_data["packages"]:
+ self._package_manager.addAvailablePackageVersion(package["package_id"], Version(package["package_version"]))
+
def _onDownloadProgress(self, bytes_sent: int, bytes_total: int) -> None:
if bytes_total > 0:
new_progress = bytes_sent / bytes_total * 100
@@ -664,11 +691,15 @@ class Toolbox(QObject, Extension):
self.setIsDownloading(False)
self._download_reply = cast(QNetworkReply, self._download_reply)
self._download_reply.downloadProgress.disconnect(self._onDownloadProgress)
-
+
# Check if the download was sucessfull
if self._download_reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
- Logger.log("w", "Failed to download package. The following error was returned: %s", json.loads(bytes(self._download_reply.readAll()).decode("utf-8")))
- return
+ try:
+ Logger.log("w", "Failed to download package. The following error was returned: %s", json.loads(bytes(self._download_reply.readAll()).decode("utf-8")))
+ except json.decoder.JSONDecodeError:
+ Logger.logException("w", "Failed to download package and failed to parse a response from it")
+ finally:
+ return
# Must not delete the temporary file on Windows
self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curapackage", delete = False)
file_path = self._temp_plugin_file.name
diff --git a/plugins/TrimeshReader/TrimeshReader.py b/plugins/TrimeshReader/TrimeshReader.py
new file mode 100644
index 0000000000..91f8423579
--- /dev/null
+++ b/plugins/TrimeshReader/TrimeshReader.py
@@ -0,0 +1,161 @@
+# Copyright (c) 2019 Ultimaker B.V., fieldOfView
+# Cura is released under the terms of the LGPLv3 or higher.
+
+# The _toMeshData function is taken from the AMFReader class which was built by fieldOfView.
+
+from typing import Any, List, Union, TYPE_CHECKING
+import numpy # To create the mesh data.
+import os.path # To create the mesh name for the resulting mesh.
+import trimesh # To load the files into a Trimesh.
+
+from UM.Mesh.MeshData import MeshData, calculateNormalsFromIndexedVertices # To construct meshes from the Trimesh data.
+from UM.Mesh.MeshReader import MeshReader # The plug-in type we're extending.
+from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType # To add file types that we can open.
+from UM.Scene.GroupDecorator import GroupDecorator # Added to the parent node if we load multiple nodes at once.
+
+from cura.CuraApplication import CuraApplication
+from cura.Scene.BuildPlateDecorator import BuildPlateDecorator # Added to the resulting scene node.
+from cura.Scene.ConvexHullDecorator import ConvexHullDecorator # Added to group nodes if we load multiple nodes at once.
+from cura.Scene.CuraSceneNode import CuraSceneNode # To create a node in the scene after reading the file.
+from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator # Added to the resulting scene node.
+
+if TYPE_CHECKING:
+ from UM.Scene.SceneNode import SceneNode
+
+## Class that leverages Trimesh to import files.
+class TrimeshReader(MeshReader):
+ def __init__(self) -> None:
+ super().__init__()
+
+ self._supported_extensions = [".ctm", ".dae", ".gltf", ".glb", ".ply", ".zae"]
+ MimeTypeDatabase.addMimeType(
+ MimeType(
+ name = "application/x-ctm",
+ comment = "Open Compressed Triangle Mesh",
+ suffixes = ["ctm"]
+ )
+ )
+ MimeTypeDatabase.addMimeType(
+ MimeType(
+ name = "model/vnd.collada+xml",
+ comment = "COLLADA Digital Asset Exchange",
+ suffixes = ["dae"]
+ )
+ )
+ MimeTypeDatabase.addMimeType(
+ MimeType(
+ name = "model/gltf-binary",
+ comment = "glTF Binary",
+ suffixes = ["glb"]
+ )
+ )
+ MimeTypeDatabase.addMimeType(
+ MimeType(
+ name = "model/gltf+json",
+ comment = "glTF Embedded JSON",
+ suffixes = ["gltf"]
+ )
+ )
+ # Trimesh seems to have a bug when reading .off files.
+ #MimeTypeDatabase.addMimeType(
+ # MimeType(
+ # name = "application/x-off",
+ # comment = "Geomview Object File Format",
+ # suffixes = ["off"]
+ # )
+ #)
+ MimeTypeDatabase.addMimeType(
+ MimeType(
+ name = "application/x-ply", # Wikipedia lists the MIME type as "text/plain" but that won't do as it's not unique to PLY files.
+ comment = "Stanford Triangle Format",
+ suffixes = ["ply"]
+ )
+ )
+ MimeTypeDatabase.addMimeType(
+ MimeType(
+ name = "model/vnd.collada+xml+zip",
+ comment = "Compressed COLLADA Digital Asset Exchange",
+ suffixes = ["zae"]
+ )
+ )
+
+ ## Reads a file using Trimesh.
+ # \param file_name The file path. This is assumed to be one of the file
+ # types that Trimesh can read. It will not be checked again.
+ # \return A scene node that contains the file's contents.
+ def _read(self, file_name: str) -> Union["SceneNode", List["SceneNode"]]:
+ # CURA-6739
+ # GLTF files are essentially JSON files. If you directly give a file name to trimesh.load(), it will
+ # try to figure out the format, but for GLTF, it loads it as a binary file with flags "rb", and the json.load()
+ # doesn't like it. For some reason, this seems to happen with 3.5.7, but not 3.7.1. Below is a workaround to
+ # pass a file object that has been opened with "r" instead "rb" to load a GLTF file.
+ if file_name.lower().endswith(".gltf"):
+ mesh_or_scene = trimesh.load(open(file_name, "r", encoding = "utf-8"), file_type = "gltf")
+ else:
+ mesh_or_scene = trimesh.load(file_name)
+
+ meshes = [] # type: List[Union[trimesh.Trimesh, trimesh.Scene, Any]]
+ if isinstance(mesh_or_scene, trimesh.Trimesh):
+ meshes = [mesh_or_scene]
+ elif isinstance(mesh_or_scene, trimesh.Scene):
+ meshes = [mesh for mesh in mesh_or_scene.geometry.values()]
+
+ active_build_plate = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
+ nodes = [] # type: List[SceneNode]
+ for mesh in meshes:
+ if not isinstance(mesh, trimesh.Trimesh): # Trimesh can also receive point clouds, 2D paths, 3D paths or metadata. Skip those.
+ continue
+ mesh.merge_vertices()
+ mesh.remove_unreferenced_vertices()
+ mesh.fix_normals()
+ mesh_data = self._toMeshData(mesh)
+
+ file_base_name = os.path.basename(file_name)
+ new_node = CuraSceneNode()
+ new_node.setMeshData(mesh_data)
+ new_node.setSelectable(True)
+ new_node.setName(file_base_name if len(meshes) == 1 else "{file_base_name} {counter}".format(file_base_name = file_base_name, counter = str(len(nodes) + 1)))
+ new_node.addDecorator(BuildPlateDecorator(active_build_plate))
+ new_node.addDecorator(SliceableObjectDecorator())
+ nodes.append(new_node)
+
+ if len(nodes) == 1:
+ return nodes[0]
+ # Add all nodes to a group so they stay together.
+ group_node = CuraSceneNode()
+ group_node.addDecorator(GroupDecorator())
+ group_node.addDecorator(ConvexHullDecorator())
+ group_node.addDecorator(BuildPlateDecorator(active_build_plate))
+ for node in nodes:
+ node.setParent(group_node)
+ return group_node
+
+ ## Converts a Trimesh to Uranium's MeshData.
+ # \param tri_node A Trimesh containing the contents of a file that was
+ # just read.
+ # \return Mesh data from the Trimesh in a way that Uranium can understand
+ # it.
+ def _toMeshData(self, tri_node: trimesh.base.Trimesh) -> MeshData:
+ tri_faces = tri_node.faces
+ tri_vertices = tri_node.vertices
+
+ indices = []
+ vertices = []
+
+ index_count = 0
+ face_count = 0
+ for tri_face in tri_faces:
+ face = []
+ for tri_index in tri_face:
+ vertices.append(tri_vertices[tri_index])
+ face.append(index_count)
+ index_count += 1
+ indices.append(face)
+ face_count += 1
+
+ vertices = numpy.asarray(vertices, dtype = numpy.float32)
+ indices = numpy.asarray(indices, dtype = numpy.int32)
+ normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count)
+
+ mesh_data = MeshData(vertices = vertices, indices = indices, normals = normals)
+ return mesh_data
\ No newline at end of file
diff --git a/plugins/TrimeshReader/__init__.py b/plugins/TrimeshReader/__init__.py
new file mode 100644
index 0000000000..8a267a7bc0
--- /dev/null
+++ b/plugins/TrimeshReader/__init__.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2019 Ultimaker
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from . import TrimeshReader
+
+from UM.i18n import i18nCatalog
+i18n_catalog = i18nCatalog("uranium")
+
+
+def getMetaData():
+ return {
+ "mesh_reader": [
+ {
+ "extension": "ctm",
+ "description": i18n_catalog.i18nc("@item:inlistbox 'Open' is part of the name of this file format.", "Open Compressed Triangle Mesh")
+ },
+ {
+ "extension": "dae",
+ "description": i18n_catalog.i18nc("@item:inlistbox", "COLLADA Digital Asset Exchange")
+ },
+ {
+ "extension": "glb",
+ "description": i18n_catalog.i18nc("@item:inlistbox", "glTF Binary")
+ },
+ {
+ "extension": "gltf",
+ "description": i18n_catalog.i18nc("@item:inlistbox", "glTF Embedded JSON")
+ },
+ # Trimesh seems to have a bug when reading OFF files.
+ #{
+ # "extension": "off",
+ # "description": i18n_catalog.i18nc("@item:inlistbox", "Geomview Object File Format")
+ #},
+ {
+ "extension": "ply",
+ "description": i18n_catalog.i18nc("@item:inlistbox", "Stanford Triangle Format")
+ },
+ {
+ "extension": "zae",
+ "description": i18n_catalog.i18nc("@item:inlistbox", "Compressed COLLADA Digital Asset Exchange")
+ }
+ ]
+ }
+
+def register(app):
+ return {"mesh_reader": TrimeshReader.TrimeshReader()}
diff --git a/plugins/TrimeshReader/plugin.json b/plugins/TrimeshReader/plugin.json
new file mode 100644
index 0000000000..dbe937b01d
--- /dev/null
+++ b/plugins/TrimeshReader/plugin.json
@@ -0,0 +1,7 @@
+{
+ "name": "Trimesh Reader",
+ "author": "Ultimaker B.V.",
+ "version": "1.0.0",
+ "description": "Provides support for reading model files.",
+ "api": "7.0.0"
+}
diff --git a/plugins/UFPReader/UFPReader.py b/plugins/UFPReader/UFPReader.py
new file mode 100644
index 0000000000..71061f938b
--- /dev/null
+++ b/plugins/UFPReader/UFPReader.py
@@ -0,0 +1,42 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import TYPE_CHECKING
+
+from Charon.VirtualFile import VirtualFile
+
+from UM.Mesh.MeshReader import MeshReader
+from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
+from UM.PluginRegistry import PluginRegistry
+
+if TYPE_CHECKING:
+ from cura.Scene.CuraSceneNode import CuraSceneNode
+
+
+class UFPReader(MeshReader):
+
+ def __init__(self) -> None:
+ super().__init__()
+
+ MimeTypeDatabase.addMimeType(
+ MimeType(
+ name = "application/x-ufp",
+ comment = "Ultimaker Format Package",
+ suffixes = ["ufp"]
+ )
+ )
+ self._supported_extensions = [".ufp"]
+
+ def _read(self, file_name: str) -> "CuraSceneNode":
+ # Open the file
+ archive = VirtualFile()
+ archive.open(file_name)
+ # Get the gcode data from the file
+ gcode_data = archive.getData("/3D/model.gcode")
+ # Convert the bytes stream to string
+ gcode_stream = gcode_data["/3D/model.gcode"].decode("utf-8")
+
+ # Open the GCodeReader to parse the data
+ gcode_reader = PluginRegistry.getInstance().getPluginObject("GCodeReader") # type: ignore
+ gcode_reader.preReadFromStream(gcode_stream) # type: ignore
+ return gcode_reader.readFromStream(gcode_stream, file_name) # type: ignore
diff --git a/plugins/UFPReader/__init__.py b/plugins/UFPReader/__init__.py
new file mode 100644
index 0000000000..cfea4b9882
--- /dev/null
+++ b/plugins/UFPReader/__init__.py
@@ -0,0 +1,34 @@
+#Copyright (c) 2019 Ultimaker B.V.
+#Cura is released under the terms of the LGPLv3 or higher.
+
+import sys
+
+from UM.Logger import Logger
+try:
+ from . import UFPReader
+except ImportError:
+ Logger.log("w", "Could not import UFPReader; libCharon may be missing")
+
+from UM.i18n import i18nCatalog
+i18n_catalog = i18nCatalog("cura")
+
+
+def getMetaData():
+ return {
+ "mesh_reader": [
+ {
+ "mime_type": "application/x-ufp",
+ "extension": "ufp",
+ "description": i18n_catalog.i18nc("@item:inlistbox", "Ultimaker Format Package")
+ }
+ ]
+ }
+
+
+def register(app):
+ if "UFPReader.UFPReader" not in sys.modules:
+ return {}
+
+ app.addNonSliceableExtension(".ufp")
+ return {"mesh_reader": UFPReader.UFPReader()}
+
diff --git a/plugins/UFPReader/plugin.json b/plugins/UFPReader/plugin.json
new file mode 100644
index 0000000000..a88a9c3ab0
--- /dev/null
+++ b/plugins/UFPReader/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "UFP Reader",
+ "author": "Ultimaker B.V.",
+ "version": "1.0.0",
+ "description": "Provides support for reading Ultimaker Format Packages.",
+ "supported_sdk_versions": ["7.0.0"],
+ "i18n-catalog": "cura"
+}
\ No newline at end of file
diff --git a/plugins/UFPWriter/UFPWriter.py b/plugins/UFPWriter/UFPWriter.py
index c0db104c82..e085adfd47 100644
--- a/plugins/UFPWriter/UFPWriter.py
+++ b/plugins/UFPWriter/UFPWriter.py
@@ -1,4 +1,4 @@
-#Copyright (c) 2018 Ultimaker B.V.
+#Copyright (c) 2019 Ultimaker B.V.
#Cura is released under the terms of the LGPLv3 or higher.
from typing import cast
@@ -7,13 +7,13 @@ from Charon.VirtualFile import VirtualFile #To open UFP files.
from Charon.OpenMode import OpenMode #To indicate that we want to write to UFP files.
from io import StringIO #For converting g-code to bytes.
-from UM.Application import Application
from UM.Logger import Logger
from UM.Mesh.MeshWriter import MeshWriter #The writer we need to implement.
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType
from UM.PluginRegistry import PluginRegistry #To get the g-code writer.
from PyQt5.QtCore import QBuffer
+from cura.CuraApplication import CuraApplication
from cura.Snapshot import Snapshot
from cura.Utils.Threading import call_on_qt_thread
@@ -28,7 +28,7 @@ class UFPWriter(MeshWriter):
MimeTypeDatabase.addMimeType(
MimeType(
name = "application/x-ufp",
- comment = "Cura UFP File",
+ comment = "Ultimaker Format Package",
suffixes = ["ufp"]
)
)
@@ -38,7 +38,11 @@ class UFPWriter(MeshWriter):
def _createSnapshot(self, *args):
# must be called from the main thread because of OpenGL
Logger.log("d", "Creating thumbnail image...")
- self._snapshot = Snapshot.snapshot(width = 300, height = 300)
+ try:
+ self._snapshot = Snapshot.snapshot(width = 300, height = 300)
+ except Exception:
+ Logger.logException("w", "Failed to create snapshot image")
+ self._snapshot = None # Failing to create thumbnail should not fail creation of UFP
# 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
@@ -79,9 +83,9 @@ class UFPWriter(MeshWriter):
Logger.log("d", "Thumbnail not created, cannot save it")
# Store the material.
- application = Application.getInstance()
+ application = CuraApplication.getInstance()
machine_manager = application.getMachineManager()
- material_manager = application.getMaterialManager()
+ container_registry = application.getContainerRegistry()
global_stack = machine_manager.activeMachine
material_extension = "xml.fdm_material"
@@ -107,12 +111,12 @@ class UFPWriter(MeshWriter):
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)
+ material_root_query = container_registry.findContainers(id = material_root_id)
+ if not material_root_query:
+ Logger.log("e", "Cannot find material container with root id {root_id}".format(root_id = material_root_id))
return False
+ material_container = material_root_query[0]
- material_container = material_group.root_material_node.getContainer()
try:
serialized_material = material_container.serialize()
except NotImplementedError:
diff --git a/plugins/UFPWriter/plugin.json b/plugins/UFPWriter/plugin.json
index 288d6acf77..35fd18f05e 100644
--- a/plugins/UFPWriter/plugin.json
+++ b/plugins/UFPWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for writing Ultimaker Format Packages.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/UM3NetworkPrinting/__init__.py b/plugins/UM3NetworkPrinting/__init__.py
index 3da7795589..ea0f69639d 100644
--- a/plugins/UM3NetworkPrinting/__init__.py
+++ b/plugins/UM3NetworkPrinting/__init__.py
@@ -1,7 +1,7 @@
-# Copyright (c) 2017 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from .src import DiscoverUM3Action
from .src import UM3OutputDevicePlugin
+from .src import UltimakerNetworkedPrinterAction
def getMetaData():
@@ -11,5 +11,5 @@ def getMetaData():
def register(app):
return {
"output_device": UM3OutputDevicePlugin.UM3OutputDevicePlugin(),
- "machine_action": DiscoverUM3Action.DiscoverUM3Action()
+ "machine_action": UltimakerNetworkedPrinterAction.UltimakerNetworkedPrinterAction()
}
diff --git a/plugins/UM3NetworkPrinting/plugin.json b/plugins/UM3NetworkPrinting/plugin.json
index 088b4dae6a..193ba63d83 100644
--- a/plugins/UM3NetworkPrinting/plugin.json
+++ b/plugins/UM3NetworkPrinting/plugin.json
@@ -1,8 +1,8 @@
{
- "name": "UM3 Network Connection",
+ "name": "Ultimaker Network Connection",
"author": "Ultimaker B.V.",
- "description": "Manages network connections to Ultimaker 3 printers.",
- "version": "1.0.1",
- "api": "6.0",
+ "description": "Manages network connections to Ultimaker networked printers.",
+ "version": "2.0.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/UM3NetworkPrinting/resources/png/Ultimaker S3.png b/plugins/UM3NetworkPrinting/resources/png/Ultimaker S3.png
new file mode 100644
index 0000000000..b6ce6e1273
Binary files /dev/null and b/plugins/UM3NetworkPrinting/resources/png/Ultimaker S3.png differ
diff --git a/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml b/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml
index bf7690ac37..2e3d17ceb0 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
@@ -7,34 +7,39 @@ import QtQuick.Controls.Styles 1.3
import UM 1.3 as UM
import Cura 1.0 as Cura
-Rectangle {
+Rectangle
+{
id: base
property var enabled: true
- property var iconSource: null;
- color: UM.Theme.getColor("monitor_icon_primary")
- height: width;
- radius: Math.round(0.5 * width);
- width: 24 * screenScaleFactor;
+ property var iconSource: null
+ color: enabled ? UM.Theme.getColor("monitor_icon_primary") : UM.Theme.getColor("monitor_icon_disabled")
+ height: width
+ radius: Math.round(0.5 * width)
+ width: 24 * screenScaleFactor
- UM.RecolorImage {
- id: icon;
- anchors {
- horizontalCenter: parent.horizontalCenter;
- verticalCenter: parent.verticalCenter;
+ UM.RecolorImage
+ {
+ id: icon
+ anchors
+ {
+ horizontalCenter: parent.horizontalCenter
+ verticalCenter: parent.verticalCenter
}
- color: UM.Theme.getColor("monitor_icon_accent");
- height: width;
- source: iconSource;
- width: Math.round(parent.width / 2);
+ color: UM.Theme.getColor("monitor_icon_accent")
+ height: width
+ source: iconSource
+ width: Math.round(parent.width / 2)
}
- MouseArea {
- id: clickArea;
- anchors.fill: parent;
+ MouseArea
+ {
+ id: clickArea
+ anchors.fill: parent
hoverEnabled: base.enabled
- onClicked: {
+ onClicked:
+ {
if (base.enabled)
{
if (OutputDevice.activeCameraUrl != "")
@@ -48,4 +53,4 @@ Rectangle {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml
index 3883a7e285..59a0148550 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml
@@ -1,8 +1,8 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import UM 1.2 as UM
-import Cura 1.0 as Cura
+import Cura 1.5 as Cura
import QtQuick 2.2
import QtQuick.Controls 1.1
@@ -14,42 +14,22 @@ Cura.MachineAction
{
id: base
anchors.fill: parent;
+ property alias currentItemIndex: listview.currentIndex
property var selectedDevice: null
property bool completeProperties: true
+ // For validating IP addresses
+ property var networkingUtil: Cura.NetworkingUtil {}
+
function connectToPrinter()
{
- if(base.selectedDevice && base.completeProperties)
+ if (base.selectedDevice && base.completeProperties)
{
- var printerKey = base.selectedDevice.key
- var printerName = base.selectedDevice.name // TODO To change when the groups have a name
- if (manager.getStoredKey() != printerKey)
- {
- // Check if there is another instance with the same key
- if (!manager.existsKey(printerKey))
- {
- manager.associateActiveMachineWithPrinterDevice(base.selectedDevice)
- manager.setGroupName(printerName) // TODO To change when the groups have a name
- completed()
- }
- else
- {
- existingConnectionDialog.open()
- }
- }
+ manager.associateActiveMachineWithPrinterDevice(base.selectedDevice)
+ completed()
}
}
- MessageDialog
- {
- id: existingConnectionDialog
- title: catalog.i18nc("@window:title", "Existing Connection")
- icon: StandardIcon.Information
- text: catalog.i18nc("@message:text", "This printer/group is already added to Cura. Please select another printer/group.")
- standardButtons: StandardButton.Ok
- modality: Qt.ApplicationModal
- }
-
Column
{
anchors.fill: parent;
@@ -74,7 +54,7 @@ Cura.MachineAction
width: parent.width
wrapMode: Text.WordWrap
renderType: Text.NativeRendering
- text: catalog.i18nc("@label", "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n\nSelect your printer from the list below:")
+ text: catalog.i18nc("@label", "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.") + "\n\n" + catalog.i18nc("@label", "Select your printer from the list below:")
}
Row
@@ -147,21 +127,6 @@ Cura.MachineAction
{
id: listview
model: manager.foundDevices
- onModelChanged:
- {
- var selectedKey = manager.getLastManualEntryKey()
- // If there is no last manual entry key, then we select the stored key (if any)
- if (selectedKey == "")
- selectedKey = manager.getStoredKey()
- for(var i = 0; i < model.length; i++) {
- if(model[i].key == selectedKey)
- {
- currentIndex = i;
- return
- }
- }
- currentIndex = -1;
- }
width: parent.width
currentIndex: -1
onCurrentIndexChanged:
@@ -246,29 +211,10 @@ Cura.MachineAction
renderType: Text.NativeRendering
text:
{
- if(base.selectedDevice)
- {
- if (base.selectedDevice.printerType == "ultimaker3")
- {
- return "Ultimaker 3";
- }
- else if (base.selectedDevice.printerType == "ultimaker3_extended")
- {
- return "Ultimaker 3 Extended";
- }
- else if (base.selectedDevice.printerType == "ultimaker_s5")
- {
- return "Ultimaker S5";
- }
- else
- {
- return catalog.i18nc("@label", "Unknown") // We have no idea what type it is. Should not happen 'in the field'
- }
- }
- else
- {
- return ""
+ if (base.selectedDevice) {
+ return base.selectedDevice.printerTypeName
}
+ return ""
}
}
Label
@@ -342,6 +288,17 @@ Cura.MachineAction
}
}
+ MessageDialog
+ {
+ id: invalidIPAddressMessageDialog
+ x: parent ? (parent.x + (parent.width) / 2) : 0
+ y: parent ? (parent.y + (parent.height) / 2) : 0
+ title: catalog.i18nc("@title:window", "Invalid IP address")
+ text: catalog.i18nc("@text", "Please enter a valid IP address.")
+ icon: StandardIcon.Warning
+ standardButtons: StandardButton.Ok
+ }
+
UM.Dialog
{
id: manualPrinterDialog
@@ -371,7 +328,7 @@ Cura.MachineAction
Label
{
- text: catalog.i18nc("@alabel", "Enter the IP address or hostname of your printer on the network.")
+ text: catalog.i18nc("@label", "Enter the IP address of your printer on the network.")
width: parent.width
wrapMode: Text.WordWrap
renderType: Text.NativeRendering
@@ -404,6 +361,26 @@ Cura.MachineAction
text: catalog.i18nc("@action:button", "OK")
onClicked:
{
+ // Validate the input first
+ if (!networkingUtil.isValidIP(manualPrinterDialog.addressText))
+ {
+ invalidIPAddressMessageDialog.open()
+ return
+ }
+
+ // if the entered IP address has already been discovered, switch the current item to that item
+ // and do nothing else.
+ for (var i = 0; i < manager.foundDevices.length; i++)
+ {
+ var device = manager.foundDevices[i]
+ if (device.address == manualPrinterDialog.addressText)
+ {
+ currentItemIndex = i
+ manualPrinterDialog.hide()
+ return
+ }
+ }
+
manager.setManualDevice(manualPrinterDialog.printerKey, manualPrinterDialog.addressText)
manualPrinterDialog.hide()
}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml
index fae8280488..5257361367 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/ExpandableCard.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -87,4 +87,4 @@ Item
}
}
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/GenericPopUp.qml b/plugins/UM3NetworkPrinting/resources/qml/GenericPopUp.qml
index 74d9377f3e..61981dab2c 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/GenericPopUp.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/GenericPopUp.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml
index d1a0c207c5..5d08422877 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -35,7 +35,7 @@ Item
{
height: parent.height
width: 32 * screenScaleFactor // Ensure the icon is centered under the extruder icon (same width)
-
+
Rectangle
{
anchors.centerIn: parent
@@ -56,7 +56,7 @@ Item
visible: buildplate
}
}
-
+
Label
{
id: buildplateLabel
@@ -69,6 +69,7 @@ Item
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml
index 0d7a177dd3..08743ed777 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
@@ -23,7 +23,7 @@ Item
height: centerSection.height
width: maximumWidth
-
+
// Enable keyboard navigation
Keys.onLeftPressed: navigateTo(currentIndex - 1)
Keys.onRightPressed: navigateTo(currentIndex + 1)
@@ -131,7 +131,7 @@ Item
}
}
spacing: 60 * screenScaleFactor // TODO: Theme!
-
+
Repeater
{
model: printers
@@ -255,4 +255,4 @@ Item
currentIndex = i
}
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml
index 1718994d83..1fe766d9f7 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
@@ -30,6 +30,26 @@ UM.Dialog
OutputDevice.forceSendJob(printer.activePrintJob.key)
overrideConfirmationDialog.close()
}
+ visible:
+ {
+ // Don't show the button if we're missing a printer or print job
+ if (!printer || !printer.activePrintJob)
+ {
+ return false
+ }
+
+ // Check each required change...
+ for (var i = 0; i < printer.activePrintJob.configurationChanges.length; i++)
+ {
+ var change = printer.activePrintJob.configurationChanges[i]
+ // If that type of change is in the list of blocking changes, hide the button
+ if (!change.canOverride)
+ {
+ return false
+ }
+ }
+ return true
+ }
},
Button
{
@@ -52,6 +72,7 @@ UM.Dialog
bottomMargin: 56 * screenScaleFactor // TODO: Theme!
}
wrapMode: Text.WordWrap
+ renderType: Text.NativeRendering
text:
{
if (!printer || !printer.activePrintJob)
@@ -139,4 +160,4 @@ UM.Dialog
}
return translationText
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml
index 771bd4b8cf..34ca3c6df2 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
@@ -81,7 +81,7 @@ Item
enabled: visible && !(printJob.state == "pausing" || printJob.state == "resuming");
onClicked: {
if (printJob.state == "paused") {
- printJob.setState("print");
+ printJob.setState("resume");
popUp.close();
return;
}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenuButton.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenuButton.qml
index 3e4f1839b6..aa5d6de89b 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenuButton.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenuButton.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
@@ -11,21 +11,22 @@ Button
id: base
background: Rectangle
{
- color: UM.Theme.getColor("viewport_background") // TODO: Theme!
+ color: enabled ? UM.Theme.getColor("viewport_background") : "transparent"
height: base.height
opacity: base.down || base.hovered ? 1 : 0
radius: Math.round(0.5 * width)
width: base.width
}
contentItem: Label {
- color: UM.Theme.getColor("monitor_text_primary")
+ color: enabled ? UM.Theme.getColor("monitor_text_primary") : UM.Theme.getColor("monitor_text_disabled")
font.pixelSize: 32 * screenScaleFactor
horizontalAlignment: Text.AlignHCenter
text: base.text
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering;
}
height: width
hoverEnabled: enabled
text: "\u22EE" //Unicode Three stacked points.
width: 36 * screenScaleFactor // TODO: Theme!
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml
index 4079f23b0a..63caaab433 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorExtruderConfiguration.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -56,7 +56,7 @@ Item
Label
{
id: materialLabel
-
+
color: UM.Theme.getColor("monitor_text_primary")
elide: Text.ElideRight
font: UM.Theme.getFont("default") // 12pt, regular
@@ -66,6 +66,7 @@ Item
// FIXED-LINE-HEIGHT:
height: parent.height
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
}
@@ -85,7 +86,7 @@ Item
Label
{
id: printCoreLabel
-
+
color: UM.Theme.getColor("monitor_text_primary")
elide: Text.ElideRight
font: UM.Theme.getFont("default_bold") // 12pt, bold
@@ -95,6 +96,7 @@ Item
// FIXED-LINE-HEIGHT:
height: parent.height
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml
index c3e78317c5..876215d65d 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -48,5 +48,6 @@ Item
x: Math.round(size * 0.25)
y: Math.round(size * 0.15625)
visible: position >= 0
+ renderType: Text.NativeRendering
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorInfoBlurb.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorInfoBlurb.qml
index 21000b8bff..32e19c1cdb 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorInfoBlurb.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorInfoBlurb.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
@@ -40,6 +40,7 @@ Item
width: 240 * screenScaleFactor // TODO: Theme!
color: UM.Theme.getColor("monitor_tooltip_text")
font: UM.Theme.getFont("default")
+ renderType: Text.NativeRendering
}
}
}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorItem.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorItem.qml
index 41b3a93a7b..1ac72b8f8e 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorItem.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorItem.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -42,4 +42,4 @@ Component {
z: 1;
}
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml
index a23b8ab0d3..c01f778bba 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml
@@ -1,6 +1,5 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-
import QtQuick 2.2
import QtQuick.Controls 2.0
import UM 1.3 as UM
@@ -22,10 +21,6 @@ Item
// The print job which all other data is derived from
property var printJob: null
- // If the printer is a cloud printer or not. Other items base their enabled state off of this boolean. In the future
- // they might not need to though.
- property bool cloudConnection: Cura.MachineManager.activeMachineIsUsingCloudConnection
-
width: parent.width
height: childrenRect.height
@@ -51,7 +46,7 @@ Item
{
anchors.verticalCenter: parent.verticalCenter
height: 18 * screenScaleFactor // TODO: Theme!
- width: 216 * screenScaleFactor // TODO: Theme! (Should match column size)
+ width: UM.Theme.getSize("monitor_column").width
Rectangle
{
color: UM.Theme.getColor("monitor_skeleton_loading")
@@ -69,8 +64,10 @@ Item
visible: printJob
// FIXED-LINE-HEIGHT:
+ width: parent.width
height: parent.height
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
}
@@ -78,7 +75,8 @@ Item
{
anchors.verticalCenter: parent.verticalCenter
height: 18 * screenScaleFactor // TODO: Theme!
- width: 216 * screenScaleFactor // TODO: Theme! (Should match column size)
+ width: UM.Theme.getSize("monitor_column").width
+
Rectangle
{
color: UM.Theme.getColor("monitor_skeleton_loading")
@@ -87,6 +85,7 @@ Item
visible: !printJob
radius: 2 * screenScaleFactor // TODO: Theme!
}
+
Label
{
text: printJob ? OutputDevice.formatDuration(printJob.timeTotal) : ""
@@ -98,6 +97,7 @@ Item
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
}
@@ -143,6 +143,7 @@ Item
// FIXED-LINE-HEIGHT:
height: parent.height
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
Row
@@ -158,14 +159,9 @@ Item
spacing: 6 // TODO: Theme!
visible: printJob
- Repeater
+ MonitorPrinterPill
{
- id: compatiblePills
- delegate: MonitorPrinterPill
- {
- text: modelData
- }
- model: printJob ? printJob.compatibleMachineFamilies : []
+ text: printJob.configuration.printerType
}
}
}
@@ -185,13 +181,10 @@ Item
id: printerConfiguration
anchors.verticalCenter: parent.verticalCenter
buildplate: catalog.i18nc("@label", "Glass")
- configurations:
- [
- base.printJob.configuration.extruderConfigurations[0],
- base.printJob.configuration.extruderConfigurations[1]
- ]
+ configurations: base.printJob.configuration.extruderConfigurations
height: 72 * screenScaleFactor // TODO: Theme!
}
+
Label {
text: printJob && printJob.owner ? printJob.owner : ""
color: UM.Theme.getColor("monitor_text_primary")
@@ -202,6 +195,7 @@ Item
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
}
}
@@ -218,7 +212,7 @@ Item
}
width: 32 * screenScaleFactor // TODO: Theme!
height: 32 * screenScaleFactor // TODO: Theme!
- enabled: !cloudConnection
+ enabled: OutputDevice.supportsPrintJobActions
onClicked: enabled ? contextMenu.switchPopupState() : {}
visible:
{
@@ -248,10 +242,10 @@ Item
enabled: !contextMenuButton.enabled
}
- MonitorInfoBlurb
- {
- id: contextMenuDisabledInfo
- text: catalog.i18nc("@info", "These options are not available because you are monitoring a cloud printer.")
- target: contextMenuButton
- }
-}
\ No newline at end of file
+ MonitorInfoBlurb
+ {
+ id: contextMenuDisabledInfo
+ text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
+ target: contextMenuButton
+ }
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml
index a392571757..7492b4e8e4 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -41,7 +41,7 @@ Item
UM.RecolorImage
{
id: ultiBotImage
-
+
anchors.centerIn: printJobPreview
color: UM.Theme.getColor("monitor_placeholder_image")
height: printJobPreview.height
@@ -98,4 +98,4 @@ Item
visible: source != ""
width: 0.5 * printJobPreview.width
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml
index 2ba70268b2..0a478c8543 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
@@ -20,49 +20,38 @@ Item
property var printJob: null
width: childrenRect.width
- height: 18 * screenScaleFactor // TODO: Theme!
+ height: UM.Theme.getSize("monitor_text_line").height
- ProgressBar
+ UM.ProgressBar
{
id: progressBar
anchors
{
verticalCenter: parent.verticalCenter
+ left: parent.left
}
value: printJob ? printJob.progress : 0
- style: ProgressBarStyle
- {
- background: Rectangle
- {
- color: UM.Theme.getColor("monitor_progress_bar_empty")
- implicitHeight: visible ? 12 * screenScaleFactor : 0 // TODO: Theme!
- implicitWidth: 180 * screenScaleFactor // TODO: Theme!
- radius: 2 * screenScaleFactor // TODO: Theme!
- }
- progress: Rectangle
- {
- id: progressItem;
- color: printJob && printJob.isActive ? UM.Theme.getColor("monitor_progress_bar_fill") : UM.Theme.getColor("monitor_progress_bar_deactive")
- radius: 2 * screenScaleFactor // TODO: Theme!
- }
- }
+ width: UM.Theme.getSize("monitor_progress_bar").width
}
+
Label
{
id: percentLabel
anchors
{
left: progressBar.right
- leftMargin: 18 * screenScaleFactor // TODO: Theme!
+ leftMargin: UM.Theme.getSize("monitor_margin").width
+ verticalCenter: parent.verticalCenter
}
text: printJob ? Math.round(printJob.progress * 100) + "%" : "0%"
color: printJob && printJob.isActive ? UM.Theme.getColor("monitor_text_primary") : UM.Theme.getColor("monitor_text_disabled")
width: contentWidth
- font: UM.Theme.getFont("medium") // 14pt, regular
+ font: UM.Theme.getFont("default") // 12pt, regular
// FIXED-LINE-HEIGHT:
- height: 18 * screenScaleFactor // TODO: Theme!
+ height: UM.Theme.getSize("monitor_text_line").height
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
Label
{
@@ -70,50 +59,52 @@ Item
anchors
{
left: percentLabel.right
- leftMargin: 18 * screenScaleFactor // TODO: Theme!
+ leftMargin: UM.Theme.getSize("monitor_margin").width
+ verticalCenter: parent.verticalCenter
}
color: UM.Theme.getColor("monitor_text_primary")
- font: UM.Theme.getFont("medium") // 14pt, regular
+ font: UM.Theme.getFont("default")
text:
{
if (!printJob)
{
- return ""
+ return "";
}
switch (printJob.state)
{
case "wait_cleanup":
if (printJob.timeTotal > printJob.timeElapsed)
{
- return catalog.i18nc("@label:status", "Aborted")
+ return catalog.i18nc("@label:status", "Aborted");
}
- return catalog.i18nc("@label:status", "Finished")
+ return catalog.i18nc("@label:status", "Finished");
case "finished":
- return catalog.i18nc("@label:status", "Finished")
+ return catalog.i18nc("@label:status", "Finished");
case "sent_to_printer":
- return catalog.i18nc("@label:status", "Preparing...")
+ return catalog.i18nc("@label:status", "Preparing...");
case "pre_print":
- return catalog.i18nc("@label:status", "Preparing...")
+ return catalog.i18nc("@label:status", "Preparing...");
case "aborting": // NOTE: Doesn't exist but maybe should someday
- return catalog.i18nc("@label:status", "Aborting...")
+ return catalog.i18nc("@label:status", "Aborting...");
case "aborted": // NOTE: Unused, see above
- return catalog.i18nc("@label:status", "Aborted")
+ return catalog.i18nc("@label:status", "Aborted");
case "pausing":
- return catalog.i18nc("@label:status", "Pausing...")
+ return catalog.i18nc("@label:status", "Pausing...");
case "paused":
- return catalog.i18nc("@label:status", "Paused")
+ return catalog.i18nc("@label:status", "Paused");
case "resuming":
- return catalog.i18nc("@label:status", "Resuming...")
+ return catalog.i18nc("@label:status", "Resuming...");
case "queued":
- return catalog.i18nc("@label:status", "Action required")
+ return catalog.i18nc("@label:status", "Action required");
default:
- return catalog.i18nc("@label:status", "Finishes %1 at %2".arg(OutputDevice.getDateCompleted( printJob.timeRemaining )).arg(OutputDevice.getTimeCompleted( printJob.timeRemaining )))
+ return catalog.i18nc("@label:status", "Finishes %1 at %2".arg(OutputDevice.getDateCompleted(printJob.timeRemaining)).arg(OutputDevice.getTimeCompleted(printJob.timeRemaining)));
}
}
width: contentWidth
// FIXED-LINE-HEIGHT:
- height: 18 * screenScaleFactor // TODO: Theme!
+ height: UM.Theme.getSize("monitor_text_line").height
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml
index 8c63e1ef1a..9242abacdd 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.3
@@ -81,7 +81,7 @@ Item
mipmap: true
}
}
-
+
Item
{
@@ -90,7 +90,7 @@ Item
verticalCenter: parent.verticalCenter
}
width: 180 * screenScaleFactor // TODO: Theme!
- height: printerNameLabel.height + printerFamilyPill.height + 6 * screenScaleFactor // TODO: Theme!
+ height: childrenRect.height
Rectangle
{
@@ -99,7 +99,7 @@ Item
height: 18 * screenScaleFactor // TODO: Theme!
width: parent.width
radius: 2 * screenScaleFactor // TODO: Theme!
-
+
Label
{
text: printer && printer.name ? printer.name : ""
@@ -112,6 +112,7 @@ Item
// FIXED-LINE-HEIGHT:
height: parent.height
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
}
@@ -134,13 +135,61 @@ Item
}
text: printer ? printer.type : ""
}
+ Item
+ {
+ id: managePrinterLink
+ anchors {
+ top: printerFamilyPill.bottom
+ topMargin: 6 * screenScaleFactor
+ }
+ height: 18 * screenScaleFactor // TODO: Theme!
+ width: childrenRect.width
+
+ Label
+ {
+ id: managePrinterText
+ anchors.verticalCenter: managePrinterLink.verticalCenter
+ color: UM.Theme.getColor("monitor_text_link")
+ font: UM.Theme.getFont("default")
+ linkColor: UM.Theme.getColor("monitor_text_link")
+ text: catalog.i18nc("@label link to Connect and Cloud interfaces", "Manage printer")
+ renderType: Text.NativeRendering
+ }
+ UM.RecolorImage
+ {
+ id: externalLinkIcon
+ anchors
+ {
+ left: managePrinterText.right
+ leftMargin: 6 * screenScaleFactor
+ verticalCenter: managePrinterText.verticalCenter
+ }
+ color: UM.Theme.getColor("monitor_text_link")
+ source: UM.Theme.getIcon("external_link")
+ width: 12 * screenScaleFactor
+ height: 12 * screenScaleFactor
+ }
+ }
+ MouseArea
+ {
+ anchors.fill: managePrinterLink
+ onClicked: OutputDevice.openPrintJobControlPanel()
+ onEntered:
+ {
+ manageQueueText.font.underline = true
+ }
+ onExited:
+ {
+ manageQueueText.font.underline = false
+ }
+ }
}
MonitorPrinterConfiguration
{
id: printerConfiguration
anchors.verticalCenter: parent.verticalCenter
- buildplate: printer ? "Glass" : null // 'Glass' as a default
+ buildplate: printer ? catalog.i18nc("@label", "Glass") : null // 'Glass' as a default
configurations:
{
var configs = []
@@ -171,8 +220,7 @@ Item
}
width: 36 * screenScaleFactor // TODO: Theme!
height: 36 * screenScaleFactor // TODO: Theme!
- enabled: !cloudConnection
-
+ enabled: OutputDevice.supportsPrintJobActions
onClicked: enabled ? contextMenu.switchPopupState() : {}
visible:
{
@@ -205,7 +253,7 @@ Item
MonitorInfoBlurb
{
id: contextMenuDisabledInfo
- text: catalog.i18nc("@info", "These options are not available because you are monitoring a cloud printer.")
+ text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
target: contextMenuButton
}
@@ -243,7 +291,6 @@ Item
}
}
-
// Divider
Rectangle
{
@@ -315,6 +362,7 @@ Item
return ""
}
visible: text !== ""
+ renderType: Text.NativeRendering
}
Item
@@ -356,6 +404,7 @@ Item
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
Label
@@ -376,6 +425,7 @@ Item
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
}
@@ -403,6 +453,7 @@ Item
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
}
}
@@ -437,11 +488,31 @@ Item
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
height: 18 * screenScaleFactor // TODO: Theme!
+ renderType: Text.NativeRendering
}
implicitHeight: 32 * screenScaleFactor // TODO: Theme!
implicitWidth: 96 * screenScaleFactor // TODO: Theme!
visible: printer && printer.activePrintJob && printer.activePrintJob.configurationChanges.length > 0 && !printerStatus.visible
onClicked: base.enabled ? overrideConfirmationDialog.open() : {}
+ enabled: OutputDevice.supportsPrintJobActions
+ }
+
+ // For cloud printing, add this mouse area over the disabled details button to indicate that it's not available
+ MouseArea
+ {
+ id: detailsButtonDisabledButtonArea
+ anchors.fill: detailsButton
+ hoverEnabled: detailsButton.visible && !detailsButton.enabled
+ onEntered: overrideButtonDisabledInfo.open()
+ onExited: overrideButtonDisabledInfo.close()
+ enabled: !detailsButton.enabled
+ }
+
+ MonitorInfoBlurb
+ {
+ id: overrideButtonDisabledInfo
+ text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
+ target: detailsButton
}
}
@@ -450,4 +521,4 @@ Item
id: overrideConfirmationDialog
printer: base.printer
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml
index dbe085e18e..21d08a310c 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterConfiguration.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -55,4 +55,4 @@ Item
anchors.bottom: parent.bottom
buildplate: null
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml
index 2aeecd5a92..44aa1a1f8d 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterPill.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -11,20 +11,8 @@ import UM 1.2 as UM
*/
Item
{
- // The printer name
+ id: monitorPrinterPill
property var text: ""
- property var tagText: {
- switch(text) {
- case "Ultimaker 3":
- return "UM 3"
- case "Ultimaker 3 Extended":
- return "UM 3 EXT"
- case "Ultimaker S5":
- return "UM S5"
- default:
- return text
- }
- }
implicitHeight: 18 * screenScaleFactor // TODO: Theme!
implicitWidth: Math.max(printerNameLabel.contentWidth + 12 * screenScaleFactor, 36 * screenScaleFactor) // TODO: Theme!
@@ -40,8 +28,9 @@ Item
id: printerNameLabel
anchors.centerIn: parent
color: UM.Theme.getColor("monitor_text_primary")
- text: tagText
+ text: monitorPrinterPill.text
font.pointSize: 10 // TODO: Theme!
- visible: text !== ""
+ visible: monitorPrinterPill.text !== ""
+ renderType: Text.NativeRendering
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml
index c75bd4190f..ce692168c3 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -14,6 +14,10 @@ import Cura 1.0 as Cura
*/
Item
{
+ // If the printer is a cloud printer or not. Other items base their enabled state off of this boolean. In the future
+ // they might not need to though.
+ property bool cloudConnection: Cura.MachineManager.activeMachineIsUsingCloudConnection
+
Label
{
id: queuedLabel
@@ -25,6 +29,7 @@ Item
color: UM.Theme.getColor("monitor_text_primary")
font: UM.Theme.getFont("large")
text: catalog.i18nc("@label", "Queued")
+ renderType: Text.NativeRendering
}
Item
@@ -59,7 +64,7 @@ Item
color: UM.Theme.getColor("monitor_text_link")
font: UM.Theme.getFont("medium") // 14pt, regular
linkColor: UM.Theme.getColor("monitor_text_link")
- text: catalog.i18nc("@label link to connect manager", "Go to Cura Connect")
+ text: catalog.i18nc("@label link to connect manager", "Manage in browser")
renderType: Text.NativeRendering
}
}
@@ -67,8 +72,7 @@ Item
MouseArea
{
anchors.fill: manageQueueLabel
- hoverEnabled: true
- onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel()
+ onClicked: OutputDevice.openPrintJobControlPanel()
onEntered:
{
manageQueueText.font.underline = true
@@ -91,6 +95,21 @@ Item
}
spacing: 18 * screenScaleFactor // TODO: Theme!
+ Label
+ {
+ text: catalog.i18nc("@label", "There are no print jobs in the queue. Slice and send a job to add one.")
+ color: UM.Theme.getColor("monitor_text_primary")
+ elide: Text.ElideRight
+ font: UM.Theme.getFont("medium") // 14pt, regular
+ anchors.verticalCenter: parent.verticalCenter
+
+ // FIXED-LINE-HEIGHT:
+ height: 18 * screenScaleFactor // TODO: Theme!
+ verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
+ visible: printJobList.count === 0
+ }
+
Label
{
text: catalog.i18nc("@label", "Print jobs")
@@ -103,6 +122,8 @@ Item
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
+ visible: printJobList.count > 0
}
Label
@@ -112,11 +133,13 @@ Item
elide: Text.ElideRight
font: UM.Theme.getFont("medium") // 14pt, regular
anchors.verticalCenter: parent.verticalCenter
- width: 216 * screenScaleFactor // TODO: Theme! (Should match column size)
+ width: UM.Theme.getSize("monitor_column").width
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
+ visible: printJobList.count > 0
}
Label
@@ -126,11 +149,13 @@ Item
elide: Text.ElideRight
font: UM.Theme.getFont("medium") // 14pt, regular
anchors.verticalCenter: parent.verticalCenter
- width: 216 * screenScaleFactor // TODO: Theme! (Should match column size)
+ width: UM.Theme.getSize("monitor_column").width
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
+ visible: printJobList.count > 0
}
}
@@ -162,99 +187,13 @@ Item
}
model:
{
- // When printing over the cloud we don't recieve print jobs until there is one, so
- // unless there's at least one print job we'll be stuck with skeleton loading
- // indefinitely.
- if (Cura.MachineManager.activeMachineHasActiveCloudConnection)
+ if (OutputDevice.receivedData)
{
return OutputDevice.queuedPrintJobs
}
- return OutputDevice.receivedPrintJobs ? OutputDevice.queuedPrintJobs : [null,null]
+ return [null, null]
}
spacing: 6 // TODO: Theme!
}
}
-
- Rectangle
- {
- anchors
- {
- horizontalCenter: parent.horizontalCenter
- top: printJobQueueHeadings.bottom
- topMargin: 12 * screenScaleFactor // TODO: Theme!
- }
- height: 48 * screenScaleFactor // TODO: Theme!
- width: parent.width
- color: UM.Theme.getColor("monitor_card_background")
- border.color: UM.Theme.getColor("monitor_card_border")
- radius: 2 * screenScaleFactor // TODO: Theme!
-
- visible: printJobList.model.length == 0
-
- Row
- {
- anchors
- {
- left: parent.left
- leftMargin: 18 * screenScaleFactor // TODO: Theme!
- verticalCenter: parent.verticalCenter
- }
- spacing: 18 * screenScaleFactor // TODO: Theme!
- height: 18 * screenScaleFactor // TODO: Theme!
-
- Label
- {
- text: "All jobs are printed."
- color: UM.Theme.getColor("monitor_text_primary")
- font: UM.Theme.getFont("medium") // 14pt, regular
- }
-
- Item
- {
- id: viewPrintHistoryLabel
-
- height: 18 * screenScaleFactor // TODO: Theme!
- width: childrenRect.width
-
- UM.RecolorImage
- {
- id: printHistoryIcon
- anchors.verticalCenter: parent.verticalCenter
- color: UM.Theme.getColor("monitor_text_link")
- source: UM.Theme.getIcon("external_link")
- width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!)
- height: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!)
- }
- Label
- {
- id: viewPrintHistoryText
- anchors
- {
- left: printHistoryIcon.right
- leftMargin: 6 * screenScaleFactor // TODO: Theme!
- verticalCenter: printHistoryIcon.verticalCenter
- }
- color: UM.Theme.getColor("monitor_text_link")
- font: UM.Theme.getFont("medium") // 14pt, regular
- linkColor: UM.Theme.getColor("monitor_text_link")
- text: catalog.i18nc("@label link to connect manager", "View print history")
- renderType: Text.NativeRendering
- }
- MouseArea
- {
- anchors.fill: parent
- hoverEnabled: true
- onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel()
- onEntered:
- {
- viewPrintHistoryText.font.underline = true
- }
- onExited:
- {
- viewPrintHistoryText.font.underline = false
- }
- }
- }
- }
- }
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml
index 59cbda7172..47c45f8b11 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorStage.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -25,7 +25,7 @@ Component
}
width: maximumWidth
color: UM.Theme.getColor("monitor_stage_background")
-
+
// Enable keyboard navigation. NOTE: This is done here so that we can also potentially
// forward to the queue items in the future. (Deleting selected print job, etc.)
Keys.forwardTo: carousel
@@ -50,7 +50,14 @@ Component
MonitorCarousel
{
id: carousel
- printers: OutputDevice.receivedPrintJobs ? OutputDevice.printers : [null]
+ printers:
+ {
+ if (OutputDevice.receivedData)
+ {
+ return OutputDevice.printers
+ }
+ return [null]
+ }
}
}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenuItem.qml b/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenuItem.qml
index 67c82db320..78b94ce259 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenuItem.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenuItem.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@@ -16,8 +16,9 @@ Button {
text: parent.text
horizontalAlignment: Text.AlignLeft;
verticalAlignment: Text.AlignVCenter;
+ renderType: Text.NativeRendering;
}
height: visible ? 39 * screenScaleFactor : 0; // TODO: Theme!
hoverEnabled: true;
width: parent.width;
-}
\ No newline at end of file
+}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml b/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml
index c2590e99a8..6d9f375788 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml
@@ -1,52 +1,57 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-
import QtQuick 2.2
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import UM 1.1 as UM
UM.Dialog {
+
id: base;
+ title: catalog.i18nc("@title:window", "Print over network");
+ width: minimumWidth;
height: minimumHeight;
- leftButtons: [
- Button {
- enabled: true;
- onClicked: {
- base.visible = false;
- printerSelectionCombobox.currentIndex = 0;
- OutputDevice.cancelPrintSelection();
- }
- text: catalog.i18nc("@action:button","Cancel");
- }
- ]
maximumHeight: minimumHeight;
maximumWidth: minimumWidth;
minimumHeight: 140 * screenScaleFactor;
minimumWidth: 500 * screenScaleFactor;
modality: Qt.ApplicationModal;
- onVisibleChanged: {
- if (visible) {
- resetPrintersModel();
- } else {
- OutputDevice.cancelPrintSelection();
+
+ Component.onCompleted: {
+ populateComboBox()
+ }
+
+ // populates the combo box with the correct printer values
+ function populateComboBox() {
+ comboBoxPrintersModel.clear();
+ comboBoxPrintersModel.append({ name: "Automatic", key: "" }); // Connect will just do it's thing
+ for (var i in OutputDevice.printers) {
+ comboBoxPrintersModel.append({
+ name: OutputDevice.printers[i].name,
+ key: OutputDevice.printers[i].uniqueName
+ });
}
}
+
+ leftButtons: [
+ Button {
+ enabled: true;
+ onClicked: {
+ base.close();
+ }
+ text: catalog.i18nc("@action:button","Cancel");
+ }
+ ]
rightButtons: [
Button {
enabled: true;
onClicked: {
- base.visible = false;
- OutputDevice.selectPrinter(printerSelectionCombobox.model.get(printerSelectionCombobox.currentIndex).key);
- // reset to defaults
- printerSelectionCombobox.currentIndex = 0;
+ OutputDevice.selectTargetPrinter(printerComboBox.model.get(printerComboBox.currentIndex).key);
+ base.close();
}
text: catalog.i18nc("@action:button","Print");
}
]
- title: catalog.i18nc("@title:window", "Print over network");
- visible: true;
- width: minimumWidth;
Column {
id: printerSelection;
@@ -59,10 +64,6 @@ UM.Dialog {
}
height: 50 * screenScaleFactor;
- SystemPalette {
- id: palette;
- }
-
UM.I18nCatalog {
id: catalog;
name: "cura";
@@ -78,26 +79,18 @@ UM.Dialog {
height: 20 * screenScaleFactor;
text: catalog.i18nc("@label", "Printer selection");
wrapMode: Text.Wrap;
+ renderType: Text.NativeRendering;
}
ComboBox {
- id: printerSelectionCombobox;
+ id: printerComboBox;
Behavior on height { NumberAnimation { duration: 100 } }
height: 40 * screenScaleFactor;
model: ListModel {
- id: printersModel;
+ id: comboBoxPrintersModel;
}
textRole: "name";
width: parent.width;
}
}
-
- // Utils
- function resetPrintersModel() {
- printersModel.clear();
- printersModel.append({ name: "Automatic", key: ""});
- for (var index in OutputDevice.printers) {
- printersModel.append({name: OutputDevice.printers[index].name, key: OutputDevice.printers[index].key});
- }
- }
}
diff --git a/plugins/UM3NetworkPrinting/resources/qml/PrinterVideoStream.qml b/plugins/UM3NetworkPrinting/resources/qml/PrinterVideoStream.qml
index 77b481f6d8..cfbb30fdfb 100644
--- a/plugins/UM3NetworkPrinting/resources/qml/PrinterVideoStream.qml
+++ b/plugins/UM3NetworkPrinting/resources/qml/PrinterVideoStream.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
diff --git a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml b/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml
deleted file mode 100644
index c99ed1688e..0000000000
--- a/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2018 Ultimaker B.V.
-// Cura is released under the terms of the LGPLv3 or higher.
-
-import QtQuick 2.2
-import QtQuick.Controls 1.1
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
-import UM 1.2 as UM
-import Cura 1.0 as Cura
-
-Item {
- id: base;
- property string activeQualityDefinitionId: Cura.MachineManager.activeQualityDefinitionId;
- property bool isUM3: activeQualityDefinitionId == "ultimaker3" || activeQualityDefinitionId.match("ultimaker_") != null;
- property bool printerConnected: Cura.MachineManager.printerConnected;
- property bool printerAcceptsCommands:
- {
- if (printerConnected && Cura.MachineManager.printerOutputDevices[0])
- {
- return Cura.MachineManager.printerOutputDevices[0].acceptsCommands
- }
- return false
- }
- property bool authenticationRequested:
- {
- if (printerConnected && Cura.MachineManager.printerOutputDevices[0])
- {
- var device = Cura.MachineManager.printerOutputDevices[0]
- // AuthState.AuthenticationRequested or AuthState.AuthenticationReceived
- return device.authenticationState == 2 || device.authenticationState == 5
- }
- return false
- }
- property var materialNames:
- {
- if (printerConnected && Cura.MachineManager.printerOutputDevices[0])
- {
- return Cura.MachineManager.printerOutputDevices[0].materialNames
- }
- return null
- }
- property var hotendIds:
- {
- if (printerConnected && Cura.MachineManager.printerOutputDevices[0])
- {
- return Cura.MachineManager.printerOutputDevices[0].hotendIds
- }
- return null
- }
-
- UM.I18nCatalog {
- id: catalog;
- name: "cura";
- }
-
- Row {
- objectName: "networkPrinterConnectButton";
- spacing: UM.Theme.getSize("default_margin").width;
- visible: isUM3;
-
- Button {
- height: UM.Theme.getSize("save_button_save_to_button").height;
- onClicked: Cura.MachineManager.printerOutputDevices[0].requestAuthentication();
- style: UM.Theme.styles.print_setup_action_button;
- text: catalog.i18nc("@action:button", "Request Access");
- tooltip: catalog.i18nc("@info:tooltip", "Send access request to the printer");
- visible: printerConnected && !printerAcceptsCommands && !authenticationRequested;
- }
-
- Button {
- height: UM.Theme.getSize("save_button_save_to_button").height;
- onClicked: connectActionDialog.show();
- style: UM.Theme.styles.print_setup_action_button;
- text: catalog.i18nc("@action:button", "Connect");
- tooltip: catalog.i18nc("@info:tooltip", "Connect to a printer");
- visible: !printerConnected;
- }
- }
-
- UM.Dialog {
- id: connectActionDialog;
- rightButtons: Button {
- iconName: "dialog-close";
- onClicked: connectActionDialog.reject();
- text: catalog.i18nc("@action:button", "Close");
- }
-
- Loader {
- anchors.fill: parent;
- source: "DiscoverUM3Action.qml";
- }
- }
-}
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py
index adff94bbbc..ed8d22a478 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py
+++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import json
from json import JSONDecodeError
@@ -11,18 +11,19 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManage
from UM.Logger import Logger
from cura import UltimakerCloudAuthentication
from cura.API import Account
+
from .ToolPathUploader import ToolPathUploader
-from ..Models import BaseModel
-from .Models.CloudClusterResponse import CloudClusterResponse
-from .Models.CloudError import CloudError
-from .Models.CloudClusterStatus import CloudClusterStatus
-from .Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
-from .Models.CloudPrintResponse import CloudPrintResponse
-from .Models.CloudPrintJobResponse import CloudPrintJobResponse
+from ..Models.BaseModel import BaseModel
+from ..Models.Http.CloudClusterResponse import CloudClusterResponse
+from ..Models.Http.CloudError import CloudError
+from ..Models.Http.CloudClusterStatus import CloudClusterStatus
+from ..Models.Http.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
+from ..Models.Http.CloudPrintResponse import CloudPrintResponse
+from ..Models.Http.CloudPrintJobResponse import CloudPrintJobResponse
## The generic type variable used to document the methods below.
-CloudApiClientModel = TypeVar("CloudApiClientModel", bound = BaseModel)
+CloudApiClientModel = TypeVar("CloudApiClientModel", bound=BaseModel)
## The cloud API client is responsible for handling the requests and responses from the cloud.
@@ -34,6 +35,9 @@ class CloudApiClient:
CLUSTER_API_ROOT = "{}/connect/v1".format(ROOT_PATH)
CURA_API_ROOT = "{}/cura/v1".format(ROOT_PATH)
+ # In order to avoid garbage collection we keep the callbacks in this list.
+ _anti_gc_callbacks = [] # type: List[Callable[[], None]]
+
## Initializes a new cloud API client.
# \param account: The user's account object
# \param on_error: The callback to be called whenever we receive errors from the server.
@@ -43,8 +47,6 @@ class CloudApiClient:
self._account = account
self._on_error = on_error
self._upload = None # type: Optional[ToolPathUploader]
- # In order to avoid garbage collection we keep the callbacks in this list.
- self._anti_gc_callbacks = [] # type: List[Callable[[], None]]
## Gets the account used for the API.
@property
@@ -54,7 +56,7 @@ class CloudApiClient:
## Retrieves all the clusters for the user that is currently logged in.
# \param on_finished: The function to be called after the result is parsed.
def getClusters(self, on_finished: Callable[[List[CloudClusterResponse]], Any]) -> None:
- url = "{}/clusters".format(self.CLUSTER_API_ROOT)
+ url = "{}/clusters?status=active".format(self.CLUSTER_API_ROOT)
reply = self._manager.get(self._createEmptyRequest(url))
self._addCallback(reply, on_finished, CloudClusterResponse)
@@ -69,8 +71,8 @@ class CloudApiClient:
## Requests the cloud to register the upload of a print job mesh.
# \param request: The request object.
# \param on_finished: The function to be called after the result is parsed.
- def requestUpload(self, request: CloudPrintJobUploadRequest, on_finished: Callable[[CloudPrintJobResponse], Any]
- ) -> None:
+ def requestUpload(self, request: CloudPrintJobUploadRequest,
+ on_finished: Callable[[CloudPrintJobResponse], Any]) -> None:
url = "{}/jobs/upload".format(self.CURA_API_ROOT)
body = json.dumps({"data": request.toDict()})
reply = self._manager.put(self._createEmptyRequest(url), body.encode())
@@ -96,6 +98,16 @@ class CloudApiClient:
reply = self._manager.post(self._createEmptyRequest(url), b"")
self._addCallback(reply, on_finished, CloudPrintResponse)
+ ## Send a print job action to the cluster for the given print job.
+ # \param cluster_id: The ID of the cluster.
+ # \param cluster_job_id: The ID of the print job within the cluster.
+ # \param action: The name of the action to execute.
+ def doPrintJobAction(self, cluster_id: str, cluster_job_id: str, action: str,
+ data: Optional[Dict[str, Any]] = None) -> None:
+ body = json.dumps({"data": data}).encode() if data else b""
+ url = "{}/clusters/{}/print_jobs/{}/action/{}".format(self.CLUSTER_API_ROOT, cluster_id, cluster_job_id, action)
+ self._manager.post(self._createEmptyRequest(url), body)
+
## We override _createEmptyRequest in order to add the user credentials.
# \param url: The URL to request
# \param content_type: The type of the body contents.
@@ -156,12 +168,16 @@ class CloudApiClient:
reply: QNetworkReply,
on_finished: Union[Callable[[CloudApiClientModel], Any],
Callable[[List[CloudApiClientModel]], Any]],
- model: Type[CloudApiClientModel],
- ) -> None:
+ model: Type[CloudApiClientModel]) -> None:
def parse() -> None:
- status_code, response = self._parseReply(reply)
self._anti_gc_callbacks.remove(parse)
- return self._parseModels(response, on_finished, model)
+
+ # Don't try to parse the reply if we didn't get one
+ if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None:
+ return
+
+ status_code, response = self._parseReply(reply)
+ self._parseModels(response, on_finished, model)
self._anti_gc_callbacks.append(parse)
reply.finished.connect(parse)
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py
deleted file mode 100644
index bd56ef3185..0000000000
--- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputController.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
-
-from typing import TYPE_CHECKING
-if TYPE_CHECKING:
- from .CloudOutputDevice import CloudOutputDevice
-
-
-class CloudOutputController(PrinterOutputController):
- def __init__(self, output_device: "CloudOutputDevice") -> None:
- super().__init__(output_device)
-
- # The cloud connection only supports fetching the printer and queue status and adding a job to the queue.
- # To let the UI know this we mark all features below as False.
- self.can_pause = False
- self.can_abort = False
- self.can_pre_heat_bed = False
- self.can_pre_heat_hotends = False
- self.can_send_raw_gcode = False
- self.can_control_manually = False
- self.can_update_firmware = False
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py
index 7b5add276a..b544490cfb 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py
+++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py
@@ -1,37 +1,34 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-import os
-
from time import time
-from typing import Dict, List, Optional, Set, cast
+from typing import List, Optional, cast
from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot
+from PyQt5.QtGui import QDesktopServices
from UM import i18nCatalog
from UM.Backend.Backend import BackendState
from UM.FileHandler.FileHandler import FileHandler
from UM.Logger import Logger
-from UM.Message import Message
-from UM.Qt.Duration import Duration, DurationFormat
from UM.Scene.SceneNode import SceneNode
+from UM.Version import Version
from cura.CuraApplication import CuraApplication
-from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice
-from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
-from cura.PrinterOutputDevice import ConnectionType
+from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState
+from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
-from .CloudOutputController import CloudOutputController
-from ..MeshFormatHandler import MeshFormatHandler
-from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel
-from .CloudProgressMessage import CloudProgressMessage
from .CloudApiClient import CloudApiClient
-from .Models.CloudClusterResponse import CloudClusterResponse
-from .Models.CloudClusterStatus import CloudClusterStatus
-from .Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
-from .Models.CloudPrintResponse import CloudPrintResponse
-from .Models.CloudPrintJobResponse import CloudPrintJobResponse
-from .Models.CloudClusterPrinterStatus import CloudClusterPrinterStatus
-from .Models.CloudClusterPrintJobStatus import CloudClusterPrintJobStatus
-from .Utils import findChanges, formatDateCompleted, formatTimeCompleted
+from ..ExportFileJob import ExportFileJob
+from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOutputDevice
+from ..Messages.PrintJobUploadBlockedMessage import PrintJobUploadBlockedMessage
+from ..Messages.PrintJobUploadErrorMessage import PrintJobUploadErrorMessage
+from ..Messages.PrintJobUploadSuccessMessage import PrintJobUploadSuccessMessage
+from ..Models.Http.CloudClusterResponse import CloudClusterResponse
+from ..Models.Http.CloudClusterStatus import CloudClusterStatus
+from ..Models.Http.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
+from ..Models.Http.CloudPrintResponse import CloudPrintResponse
+from ..Models.Http.CloudPrintJobResponse import CloudPrintJobResponse
+from ..Models.Http.ClusterPrinterStatus import ClusterPrinterStatus
+from ..Models.Http.ClusterPrintJobStatus import ClusterPrintJobStatus
I18N_CATALOG = i18nCatalog("cura")
@@ -41,20 +38,22 @@ I18N_CATALOG = i18nCatalog("cura")
# Currently it only supports viewing the printer and print job status and adding a new job to the queue.
# As such, those methods have been implemented here.
# Note that this device represents a single remote cluster, not a list of multiple clusters.
-class CloudOutputDevice(NetworkedPrinterOutputDevice):
+class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
- # The interval with which the remote clusters are checked
+ # The interval with which the remote cluster is checked.
+ # We can do this relatively often as this API call is quite fast.
CHECK_CLUSTER_INTERVAL = 10.0 # seconds
- # Signal triggered when the print jobs in the queue were changed.
- printJobsChanged = pyqtSignal()
+ # Override the network response timeout in seconds after which we consider the device offline.
+ # For cloud this needs to be higher because the interval at which we check the status is higher as well.
+ NETWORK_RESPONSE_CONSIDER_OFFLINE = 15.0 # seconds
- # Signal triggered when the selected printer in the UI should be changed.
- activePrinterChanged = pyqtSignal()
+ # The minimum version of firmware that support print job actions over cloud.
+ PRINT_JOB_ACTIONS_MIN_VERSION = Version("5.3.0")
# Notify can only use signals that are defined by the class that they are in, not inherited ones.
# Therefore we create a private signal used to trigger the printersChanged signal.
- _clusterPrintersChanged = pyqtSignal()
+ _cloudClusterPrintersChanged = pyqtSignal()
## Creates a new cloud output device
# \param api_client: The client that will run the API calls
@@ -66,46 +65,36 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
# Because the cloud connection does not off all of these, we manually construct this version here.
# An example of why this is needed is the selection of the compatible file type when exporting the tool path.
properties = {
- b"address": b"",
- b"name": cluster.host_name.encode() if cluster.host_name else b"",
+ b"address": cluster.host_internal_ip.encode() if cluster.host_internal_ip else b"",
+ b"name": cluster.friendly_name.encode() if cluster.friendly_name else b"",
b"firmware_version": cluster.host_version.encode() if cluster.host_version else b"",
- b"printer_type": b""
+ b"printer_type": cluster.printer_type.encode() if cluster.printer_type else b"",
+ b"cluster_size": b"1" # cloud devices are always clusters of at least one
}
- super().__init__(device_id = cluster.cluster_id, address = "",
- connection_type = ConnectionType.CloudConnection, properties = properties, parent = parent)
- self._api = api_client
- self._cluster = cluster
+ super().__init__(
+ device_id=cluster.cluster_id,
+ address="",
+ connection_type=ConnectionType.CloudConnection,
+ properties=properties,
+ parent=parent
+ )
+ self._api = api_client
+ self._account = api_client.account
+ self._cluster = cluster
+ self.setAuthenticationState(AuthState.NotAuthenticated)
self._setInterfaceElements()
- self._account = api_client.account
-
- # We use the Cura Connect monitor tab to get most functionality right away.
- self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
- "../../resources/qml/MonitorStage.qml")
-
# Trigger the printersChanged signal when the private signal is triggered.
- self.printersChanged.connect(self._clusterPrintersChanged)
-
- # We keep track of which printer is visible in the monitor page.
- self._active_printer = None # type: Optional[PrinterOutputModel]
-
- # Properties to populate later on with received cloud data.
- self._print_jobs = [] # type: List[UM3PrintJobOutputModel]
- self._number_of_extruders = 2 # All networked printers are dual-extrusion Ultimaker machines.
-
- # We only allow a single upload at a time.
- self._progress = CloudProgressMessage()
+ self.printersChanged.connect(self._cloudClusterPrintersChanged)
# Keep server string of the last generated time to avoid updating models more than once for the same response
- self._received_printers = None # type: Optional[List[CloudClusterPrinterStatus]]
- self._received_print_jobs = None # type: Optional[List[CloudClusterPrintJobStatus]]
-
- # A set of the user's job IDs that have finished
- self._finished_jobs = set() # type: Set[str]
+ self._received_printers = None # type: Optional[List[ClusterPrinterStatus]]
+ self._received_print_jobs = None # type: Optional[List[ClusterPrintJobStatus]]
# Reference to the uploaded print job / mesh
+ # We do this to prevent re-uploading the same file multiple times.
self._tool_path = None # type: Optional[bytes]
self._uploaded_print_job = None # type: Optional[CloudPrintJobResponse]
@@ -116,9 +105,12 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
super().connect()
Logger.log("i", "Connected to cluster %s", self.key)
CuraApplication.getInstance().getBackend().backendStateChange.connect(self._onBackendStateChange)
+ self._update()
## Disconnects the device
def disconnect(self) -> None:
+ if not self.isConnected():
+ return
super().disconnect()
Logger.log("i", "Disconnected from cluster %s", self.key)
CuraApplication.getInstance().getBackend().backendStateChange.disconnect(self._onBackendStateChange)
@@ -128,6 +120,149 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
self._tool_path = None
self._uploaded_print_job = None
+ ## Checks whether the given network key is found in the cloud's host name
+ def matchesNetworkKey(self, network_key: str) -> bool:
+ # Typically, a network key looks like "ultimakersystem-aabbccdd0011._ultimaker._tcp.local."
+ # the host name should then be "ultimakersystem-aabbccdd0011"
+ if network_key.startswith(str(self.clusterData.host_name or "")):
+ return True
+ # However, for manually added printers, the local IP address is used in lieu of a proper
+ # network key, so check for that as well. It is in the format "manual:10.1.10.1".
+ if network_key.endswith(str(self.clusterData.host_internal_ip or "")):
+ return True
+ return False
+
+ ## Set all the interface elements and texts for this output device.
+ def _setInterfaceElements(self) -> None:
+ self.setPriority(2) # Make sure we end up below the local networking and above 'save to file'.
+ self.setShortDescription(I18N_CATALOG.i18nc("@action:button", "Print via Cloud"))
+ self.setDescription(I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud"))
+ self.setConnectionText(I18N_CATALOG.i18nc("@info:status", "Connected via Cloud"))
+
+ ## Called when the network data should be updated.
+ def _update(self) -> None:
+ super()._update()
+ if time() - self._time_of_last_request < self.CHECK_CLUSTER_INTERVAL:
+ return # avoid calling the cloud too often
+ self._time_of_last_request = time()
+ if self._account.isLoggedIn:
+ self.setAuthenticationState(AuthState.Authenticated)
+ self._last_request_time = time()
+ self._api.getClusterStatus(self.key, self._onStatusCallFinished)
+ else:
+ self.setAuthenticationState(AuthState.NotAuthenticated)
+
+ ## Method called when HTTP request to status endpoint is finished.
+ # Contains both printers and print jobs statuses in a single response.
+ def _onStatusCallFinished(self, status: CloudClusterStatus) -> None:
+ self._responseReceived()
+ if status.printers != self._received_printers:
+ self._received_printers = status.printers
+ self._updatePrinters(status.printers)
+ if status.print_jobs != self._received_print_jobs:
+ self._received_print_jobs = status.print_jobs
+ self._updatePrintJobs(status.print_jobs)
+
+ ## Called when Cura requests an output device to receive a (G-code) file.
+ def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False,
+ file_handler: Optional[FileHandler] = None, filter_by_machine: bool = False, **kwargs) -> None:
+
+ # Show an error message if we're already sending a job.
+ if self._progress.visible:
+ PrintJobUploadBlockedMessage().show()
+ return
+
+ # Indicate we have started sending a job.
+ self.writeStarted.emit(self)
+
+ # The mesh didn't change, let's not upload it to the cloud again.
+ # Note that self.writeFinished is called in _onPrintUploadCompleted as well.
+ if self._uploaded_print_job:
+ self._api.requestPrint(self.key, self._uploaded_print_job.job_id, self._onPrintUploadCompleted)
+ return
+
+ # Export the scene to the correct file type.
+ job = ExportFileJob(file_handler=file_handler, nodes=nodes, firmware_version=self.firmwareVersion)
+ job.finished.connect(self._onPrintJobCreated)
+ job.start()
+
+ ## Handler for when the print job was created locally.
+ # It can now be sent over the cloud.
+ def _onPrintJobCreated(self, job: ExportFileJob) -> None:
+ output = job.getOutput()
+ self._tool_path = output # store the tool path to prevent re-uploading when printing the same file again
+ request = CloudPrintJobUploadRequest(
+ job_name=job.getFileName(),
+ file_size=len(output),
+ content_type=job.getMimeType(),
+ )
+ self._api.requestUpload(request, self._uploadPrintJob)
+
+ ## Uploads the mesh when the print job was registered with the cloud API.
+ # \param job_response: The response received from the cloud API.
+ def _uploadPrintJob(self, job_response: CloudPrintJobResponse) -> None:
+ if not self._tool_path:
+ return self._onUploadError()
+ self._progress.show()
+ self._uploaded_print_job = job_response # store the last uploaded job to prevent re-upload of the same file
+ self._api.uploadToolPath(job_response, self._tool_path, self._onPrintJobUploaded, self._progress.update,
+ self._onUploadError)
+
+ ## Requests the print to be sent to the printer when we finished uploading the mesh.
+ def _onPrintJobUploaded(self) -> None:
+ self._progress.update(100)
+ print_job = cast(CloudPrintJobResponse, self._uploaded_print_job)
+ self._api.requestPrint(self.key, print_job.job_id, self._onPrintUploadCompleted)
+
+ ## Shows a message when the upload has succeeded
+ # \param response: The response from the cloud API.
+ def _onPrintUploadCompleted(self, response: CloudPrintResponse) -> None:
+ self._progress.hide()
+ PrintJobUploadSuccessMessage().show()
+ self.writeFinished.emit()
+
+ ## Displays the given message if uploading the mesh has failed
+ # \param message: The message to display.
+ def _onUploadError(self, message: str = None) -> None:
+ self._progress.hide()
+ self._uploaded_print_job = None
+ PrintJobUploadErrorMessage(message).show()
+ self.writeError.emit()
+
+ ## Whether the printer that this output device represents supports print job actions via the cloud.
+ @pyqtProperty(bool, notify=_cloudClusterPrintersChanged)
+ def supportsPrintJobActions(self) -> bool:
+ if not self._printers:
+ return False
+ version_number = self.printers[0].firmwareVersion.split(".")
+ firmware_version = Version([version_number[0], version_number[1], version_number[2]])
+ return firmware_version >= self.PRINT_JOB_ACTIONS_MIN_VERSION
+
+ ## Set the remote print job state.
+ def setJobState(self, print_job_uuid: str, state: str) -> None:
+ self._api.doPrintJobAction(self._cluster.cluster_id, print_job_uuid, state)
+
+ @pyqtSlot(str, name="sendJobToTop")
+ def sendJobToTop(self, print_job_uuid: str) -> None:
+ self._api.doPrintJobAction(self._cluster.cluster_id, print_job_uuid, "move",
+ {"list": "queued", "to_position": 0})
+
+ @pyqtSlot(str, name="deleteJobFromQueue")
+ def deleteJobFromQueue(self, print_job_uuid: str) -> None:
+ self._api.doPrintJobAction(self._cluster.cluster_id, print_job_uuid, "remove")
+
+ @pyqtSlot(str, name="forceSendJob")
+ def forceSendJob(self, print_job_uuid: str) -> None:
+ self._api.doPrintJobAction(self._cluster.cluster_id, print_job_uuid, "force")
+
+ @pyqtSlot(name="openPrintJobControlPanel")
+ def openPrintJobControlPanel(self) -> None:
+ QDesktopServices.openUrl(QUrl(self.clusterCloudUrl))
+
+ @pyqtSlot(name="openPrinterControlPanel")
+ def openPrinterControlPanel(self) -> None:
+ QDesktopServices.openUrl(QUrl(self.clusterCloudUrl))
+
## Gets the cluster response from which this device was created.
@property
def clusterData(self) -> CloudClusterResponse:
@@ -138,298 +273,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
def clusterData(self, value: CloudClusterResponse) -> None:
self._cluster = value
- ## Checks whether the given network key is found in the cloud's host name
- def matchesNetworkKey(self, network_key: str) -> bool:
- # A network key looks like "ultimakersystem-aabbccdd0011._ultimaker._tcp.local."
- # the host name should then be "ultimakersystem-aabbccdd0011"
- return network_key.startswith(self.clusterData.host_name)
-
- ## Set all the interface elements and texts for this output device.
- def _setInterfaceElements(self) -> None:
- self.setPriority(2) # Make sure we end up below the local networking and above 'save to file'
- self.setName(self._id)
- self.setShortDescription(I18N_CATALOG.i18nc("@action:button", "Print via Cloud"))
- self.setDescription(I18N_CATALOG.i18nc("@properties:tooltip", "Print via Cloud"))
- self.setConnectionText(I18N_CATALOG.i18nc("@info:status", "Connected via Cloud"))
-
- ## Called when Cura requests an output device to receive a (G-code) file.
- def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False,
- file_handler: Optional[FileHandler] = None, **kwargs: str) -> None:
-
- # Show an error message if we're already sending a job.
- if self._progress.visible:
- message = Message(
- text = I18N_CATALOG.i18nc("@info:status", "Sending new jobs (temporarily) blocked, still sending the previous print job."),
- title = I18N_CATALOG.i18nc("@info:title", "Cloud error"),
- lifetime = 10
- )
- message.show()
- return
-
- if self._uploaded_print_job:
- # The mesh didn't change, let's not upload it again
- self._api.requestPrint(self.key, self._uploaded_print_job.job_id, self._onPrintUploadCompleted)
- return
-
- # Indicate we have started sending a job.
- self.writeStarted.emit(self)
-
- mesh_format = MeshFormatHandler(file_handler, self.firmwareVersion)
- if not mesh_format.is_valid:
- Logger.log("e", "Missing file or mesh writer!")
- return self._onUploadError(I18N_CATALOG.i18nc("@info:status", "Could not export print job."))
-
- mesh = mesh_format.getBytes(nodes)
-
- self._tool_path = mesh
- request = CloudPrintJobUploadRequest(
- job_name = file_name or mesh_format.file_extension,
- file_size = len(mesh),
- content_type = mesh_format.mime_type,
- )
- self._api.requestUpload(request, self._onPrintJobCreated)
-
- ## Called when the network data should be updated.
- def _update(self) -> None:
- super()._update()
- if self._last_request_time and time() - self._last_request_time < self.CHECK_CLUSTER_INTERVAL:
- return # Avoid calling the cloud too often
-
- Logger.log("d", "Updating: %s - %s >= %s", time(), self._last_request_time, self.CHECK_CLUSTER_INTERVAL)
- if self._account.isLoggedIn:
- self.setAuthenticationState(AuthState.Authenticated)
- self._last_request_time = time()
- self._api.getClusterStatus(self.key, self._onStatusCallFinished)
- else:
- self.setAuthenticationState(AuthState.NotAuthenticated)
-
- ## Method called when HTTP request to status endpoint is finished.
- # Contains both printers and print jobs statuses in a single response.
- def _onStatusCallFinished(self, status: CloudClusterStatus) -> None:
- # Update all data from the cluster.
- self._last_response_time = time()
- if self._received_printers != status.printers:
- self._received_printers = status.printers
- self._updatePrinters(status.printers)
-
- if status.print_jobs != self._received_print_jobs:
- self._received_print_jobs = status.print_jobs
- self._updatePrintJobs(status.print_jobs)
-
- ## Updates the local list of printers with the list received from the cloud.
- # \param jobs: The printers received from the cloud.
- def _updatePrinters(self, printers: List[CloudClusterPrinterStatus]) -> None:
- previous = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel]
- received = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinterStatus]
-
- removed_printers, added_printers, updated_printers = findChanges(previous, received)
-
- for removed_printer in removed_printers:
- if self._active_printer == removed_printer:
- self.setActivePrinter(None)
- self._printers.remove(removed_printer)
-
- for added_printer in added_printers:
- self._printers.append(added_printer.createOutputModel(CloudOutputController(self)))
-
- for model, printer in updated_printers:
- printer.updateOutputModel(model)
-
- # Always have an active printer
- if self._printers and not self._active_printer:
- self.setActivePrinter(self._printers[0])
-
- if added_printers or removed_printers:
- self.printersChanged.emit()
-
- ## Updates the local list of print jobs with the list received from the cloud.
- # \param jobs: The print jobs received from the cloud.
- def _updatePrintJobs(self, jobs: List[CloudClusterPrintJobStatus]) -> None:
- received = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJobStatus]
- previous = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel]
-
- removed_jobs, added_jobs, updated_jobs = findChanges(previous, received)
-
- for removed_job in removed_jobs:
- if removed_job.assignedPrinter:
- removed_job.assignedPrinter.updateActivePrintJob(None)
- removed_job.stateChanged.disconnect(self._onPrintJobStateChanged)
- self._print_jobs.remove(removed_job)
-
- for added_job in added_jobs:
- self._addPrintJob(added_job)
-
- for model, job in updated_jobs:
- job.updateOutputModel(model)
- if job.printer_uuid:
- self._updateAssignedPrinter(model, job.printer_uuid)
-
- # We only have to update when jobs are added or removed
- # updated jobs push their changes via their output model
- if added_jobs or removed_jobs:
- self.printJobsChanged.emit()
-
- ## Registers a new print job received via the cloud API.
- # \param job: The print job received.
- def _addPrintJob(self, job: CloudClusterPrintJobStatus) -> None:
- model = job.createOutputModel(CloudOutputController(self))
- model.stateChanged.connect(self._onPrintJobStateChanged)
- if job.printer_uuid:
- self._updateAssignedPrinter(model, job.printer_uuid)
- self._print_jobs.append(model)
-
- ## Handles the event of a change in a print job state
- def _onPrintJobStateChanged(self) -> None:
- user_name = self._getUserName()
- # TODO: confirm that notifications in Cura are still required
- for job in self._print_jobs:
- if job.state == "wait_cleanup" and job.key not in self._finished_jobs and job.owner == user_name:
- self._finished_jobs.add(job.key)
- Message(
- title = I18N_CATALOG.i18nc("@info:status", "Print finished"),
- text = (I18N_CATALOG.i18nc("@info:status", "Printer '{printer_name}' has finished printing '{job_name}'.").format(
- printer_name = job.assignedPrinter.name,
- job_name = job.name
- ) if job.assignedPrinter else
- I18N_CATALOG.i18nc("@info:status", "The print job '{job_name}' was finished.").format(
- job_name = job.name
- )),
- ).show()
-
- ## Updates the printer assignment for the given print job model.
- def _updateAssignedPrinter(self, model: UM3PrintJobOutputModel, printer_uuid: str) -> None:
- printer = next((p for p in self._printers if printer_uuid == p.key), None)
- if not printer:
- Logger.log("w", "Missing printer %s for job %s in %s", model.assignedPrinter, model.key,
- [p.key for p in self._printers])
- return
-
- printer.updateActivePrintJob(model)
- model.updateAssignedPrinter(printer)
-
- ## Uploads the mesh when the print job was registered with the cloud API.
- # \param job_response: The response received from the cloud API.
- def _onPrintJobCreated(self, job_response: CloudPrintJobResponse) -> None:
- self._progress.show()
- self._uploaded_print_job = job_response
- tool_path = cast(bytes, self._tool_path)
- self._api.uploadToolPath(job_response, tool_path, self._onPrintJobUploaded, self._progress.update, self._onUploadError)
-
- ## Requests the print to be sent to the printer when we finished uploading the mesh.
- def _onPrintJobUploaded(self) -> None:
- self._progress.update(100)
- print_job = cast(CloudPrintJobResponse, self._uploaded_print_job)
- self._api.requestPrint(self.key, print_job.job_id, self._onPrintUploadCompleted)
-
- ## Displays the given message if uploading the mesh has failed
- # \param message: The message to display.
- def _onUploadError(self, message: str = None) -> None:
- self._progress.hide()
- self._uploaded_print_job = None
- Message(
- text = message or I18N_CATALOG.i18nc("@info:text", "Could not upload the data to the printer."),
- title = I18N_CATALOG.i18nc("@info:title", "Cloud error"),
- lifetime = 10
- ).show()
- self.writeError.emit()
-
- ## Shows a message when the upload has succeeded
- # \param response: The response from the cloud API.
- def _onPrintUploadCompleted(self, response: CloudPrintResponse) -> None:
- Logger.log("d", "The cluster will be printing this print job with the ID %s", response.cluster_job_id)
- self._progress.hide()
- Message(
- text = I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer."),
- title = I18N_CATALOG.i18nc("@info:title", "Data Sent"),
- lifetime = 5
- ).show()
- self.writeFinished.emit()
-
- ## Gets the remote printers.
- @pyqtProperty("QVariantList", notify=_clusterPrintersChanged)
- def printers(self) -> List[PrinterOutputModel]:
- return self._printers
-
- ## Get the active printer in the UI (monitor page).
- @pyqtProperty(QObject, notify = activePrinterChanged)
- def activePrinter(self) -> Optional[PrinterOutputModel]:
- return self._active_printer
-
- ## Set the active printer in the UI (monitor page).
- @pyqtSlot(QObject)
- def setActivePrinter(self, printer: Optional[PrinterOutputModel] = None) -> None:
- if printer != self._active_printer:
- self._active_printer = printer
- self.activePrinterChanged.emit()
-
- @pyqtProperty(int, notify = _clusterPrintersChanged)
- def clusterSize(self) -> int:
- return len(self._printers)
-
- ## Get remote print jobs.
- @pyqtProperty("QVariantList", notify = printJobsChanged)
- def printJobs(self) -> List[UM3PrintJobOutputModel]:
- return self._print_jobs
-
- ## Get remote print jobs that are still in the print queue.
- @pyqtProperty("QVariantList", notify = printJobsChanged)
- def queuedPrintJobs(self) -> List[UM3PrintJobOutputModel]:
- return [print_job for print_job in self._print_jobs
- if print_job.state == "queued" or print_job.state == "error"]
-
- ## Get remote print jobs that are assigned to a printer.
- @pyqtProperty("QVariantList", notify = printJobsChanged)
- def activePrintJobs(self) -> List[UM3PrintJobOutputModel]:
- return [print_job for print_job in self._print_jobs if
- print_job.assignedPrinter is not None and print_job.state != "queued"]
-
- @pyqtSlot(int, result = str)
- def formatDuration(self, seconds: int) -> str:
- return Duration(seconds).getDisplayString(DurationFormat.Format.Short)
-
- @pyqtSlot(int, result = str)
- def getTimeCompleted(self, time_remaining: int) -> str:
- return formatTimeCompleted(time_remaining)
-
- @pyqtSlot(int, result = str)
- def getDateCompleted(self, time_remaining: int) -> str:
- return formatDateCompleted(time_remaining)
-
- ## TODO: The following methods are required by the monitor page QML, but are not actually available using cloud.
- # TODO: We fake the methods here to not break the monitor page.
-
- @pyqtProperty(QUrl, notify = _clusterPrintersChanged)
- def activeCameraUrl(self) -> "QUrl":
- return QUrl()
-
- @pyqtSlot(QUrl)
- def setActiveCameraUrl(self, camera_url: "QUrl") -> None:
- pass
-
- @pyqtProperty(bool, notify = printJobsChanged)
- def receivedPrintJobs(self) -> bool:
- return bool(self._print_jobs)
-
- @pyqtSlot()
- def openPrintJobControlPanel(self) -> None:
- pass
-
- @pyqtSlot()
- def openPrinterControlPanel(self) -> None:
- pass
-
- @pyqtSlot(str)
- def sendJobToTop(self, print_job_uuid: str) -> None:
- pass
-
- @pyqtSlot(str)
- def deleteJobFromQueue(self, print_job_uuid: str) -> None:
- pass
-
- @pyqtSlot(str)
- def forceSendJob(self, print_job_uuid: str) -> None:
- pass
-
- @pyqtProperty("QVariantList", notify = _clusterPrintersChanged)
- def connectedPrintersTypeCount(self) -> List[Dict[str, str]]:
- return []
+ ## Gets the URL on which to monitor the cluster via the cloud.
+ @property
+ def clusterCloudUrl(self) -> str:
+ root_url_prefix = "-staging" if self._account.is_staging else ""
+ return "https://mycloud{}.ultimaker.com/app/jobs/{}".format(root_url_prefix, self.clusterData.cluster_id)
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py
index e081beb99c..ccc64f8073 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py
+++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py
@@ -1,30 +1,29 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import Dict, List
+from typing import Dict, List, Optional
from PyQt5.QtCore import QTimer
from UM import i18nCatalog
-from UM.Logger import Logger
-from UM.Message import Message
-from UM.Signal import Signal, signalemitter
+from UM.Logger import Logger # To log errors talking to the API.
+from UM.Signal import Signal
from cura.API import Account
from cura.CuraApplication import CuraApplication
+from cura.Settings.CuraStackBuilder import CuraStackBuilder
from cura.Settings.GlobalStack import GlobalStack
+
from .CloudApiClient import CloudApiClient
from .CloudOutputDevice import CloudOutputDevice
-from .Models.CloudClusterResponse import CloudClusterResponse
-from .Models.CloudError import CloudError
-from .Utils import findChanges
+from ..Models.Http.CloudClusterResponse import CloudClusterResponse
-## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters.
-# Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code.
-#
-# API spec is available on https://api.ultimaker.com/docs/connect/spec/.
-#
+## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters.
+# Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code.
+# API spec is available on https://api.ultimaker.com/docs/connect/spec/.
class CloudOutputDeviceManager:
+
META_CLUSTER_ID = "um_cloud_cluster_id"
+ META_NETWORK_KEY = "um_network_key"
# The interval with which the remote clusters are checked
CHECK_CLUSTER_INTERVAL = 30.0 # seconds
@@ -32,144 +31,154 @@ class CloudOutputDeviceManager:
# The translation catalog for this device.
I18N_CATALOG = i18nCatalog("cura")
- addedCloudCluster = Signal()
- removedCloudCluster = Signal()
+ # Signal emitted when the list of discovered devices changed.
+ discoveredDevicesChanged = Signal()
def __init__(self) -> None:
# Persistent dict containing the remote clusters for the authenticated user.
self._remote_clusters = {} # type: Dict[str, CloudOutputDevice]
-
- self._application = CuraApplication.getInstance()
- self._output_device_manager = self._application.getOutputDeviceManager()
-
- self._account = self._application.getCuraAPI().account # type: Account
- self._api = CloudApiClient(self._account, self._onApiError)
+ self._account = CuraApplication.getInstance().getCuraAPI().account # type: Account
+ self._api = CloudApiClient(self._account, on_error = lambda error: Logger.log("e", str(error)))
+ self._account.loginStateChanged.connect(self._onLoginStateChanged)
# Create a timer to update the remote cluster list
self._update_timer = QTimer()
self._update_timer.setInterval(int(self.CHECK_CLUSTER_INTERVAL * 1000))
self._update_timer.setSingleShot(False)
+ self._update_timer.timeout.connect(self._getRemoteClusters)
+ # Ensure we don't start twice.
self._running = False
- # Called when the uses logs in or out
+ ## Starts running the cloud output device manager, thus periodically requesting cloud data.
+ def start(self):
+ if self._running:
+ return
+ if not self._account.isLoggedIn:
+ return
+ self._running = True
+ if not self._update_timer.isActive():
+ self._update_timer.start()
+ self._getRemoteClusters()
+
+ ## Stops running the cloud output device manager.
+ def stop(self):
+ if not self._running:
+ return
+ self._running = False
+ if self._update_timer.isActive():
+ self._update_timer.stop()
+ self._onGetRemoteClustersFinished([]) # Make sure we remove all cloud output devices.
+
+ ## Force refreshing connections.
+ def refreshConnections(self) -> None:
+ self._connectToActiveMachine()
+
+ ## Called when the uses logs in or out
def _onLoginStateChanged(self, is_logged_in: bool) -> None:
- Logger.log("d", "Log in state changed to %s", is_logged_in)
if is_logged_in:
- if not self._update_timer.isActive():
- self._update_timer.start()
- self._getRemoteClusters()
+ self.start()
else:
- if self._update_timer.isActive():
- self._update_timer.stop()
+ self.stop()
- # Notify that all clusters have disappeared
- self._onGetRemoteClustersFinished([])
-
- ## Gets all remote clusters from the API.
+ ## Gets all remote clusters from the API.
def _getRemoteClusters(self) -> None:
- Logger.log("d", "Retrieving remote clusters")
self._api.getClusters(self._onGetRemoteClustersFinished)
- ## Callback for when the request for getting the clusters. is finished.
+ ## Callback for when the request for getting the clusters is finished.
def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None:
online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse]
+ for device_id, cluster_data in online_clusters.items():
+ if device_id not in self._remote_clusters:
+ self._onDeviceDiscovered(cluster_data)
+ else:
+ self._onDiscoveredDeviceUpdated(cluster_data)
- removed_devices, added_clusters, updates = findChanges(self._remote_clusters, online_clusters)
-
- Logger.log("d", "Parsed remote clusters to %s", [cluster.toDict() for cluster in online_clusters.values()])
- Logger.log("d", "Removed: %s, added: %s, updates: %s", len(removed_devices), len(added_clusters), len(updates))
-
- # Remove output devices that are gone
- for removed_cluster in removed_devices:
- if removed_cluster.isConnected():
- removed_cluster.disconnect()
- removed_cluster.close()
- self._output_device_manager.removeOutputDevice(removed_cluster.key)
- self.removedCloudCluster.emit()
- del self._remote_clusters[removed_cluster.key]
-
- # Add an output device for each new remote cluster.
- # We only add when is_online as we don't want the option in the drop down if the cluster is not online.
- for added_cluster in added_clusters:
- device = CloudOutputDevice(self._api, added_cluster)
- self._remote_clusters[added_cluster.cluster_id] = device
- self.addedCloudCluster.emit()
-
- for device, cluster in updates:
- device.clusterData = cluster
+ removed_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys())
+ for device_id in removed_device_keys:
+ self._onDiscoveredDeviceRemoved(device_id)
+ def _onDeviceDiscovered(self, cluster_data: CloudClusterResponse) -> None:
+ device = CloudOutputDevice(self._api, cluster_data)
+ CuraApplication.getInstance().getDiscoveredPrintersModel().addDiscoveredPrinter(
+ ip_address=device.key,
+ key=device.getId(),
+ name=device.getName(),
+ create_callback=self._createMachineFromDiscoveredDevice,
+ machine_type=device.printerType,
+ device=device
+ )
+ self._remote_clusters[device.getId()] = device
+ self.discoveredDevicesChanged.emit()
self._connectToActiveMachine()
+ def _onDiscoveredDeviceUpdated(self, cluster_data: CloudClusterResponse) -> None:
+ device = self._remote_clusters.get(cluster_data.cluster_id)
+ if not device:
+ return
+ CuraApplication.getInstance().getDiscoveredPrintersModel().updateDiscoveredPrinter(
+ ip_address=device.key,
+ name=cluster_data.friendly_name,
+ machine_type=device.printerType
+ )
+ self.discoveredDevicesChanged.emit()
+
+ def _onDiscoveredDeviceRemoved(self, device_id: str) -> None:
+ device = self._remote_clusters.pop(device_id, None) # type: Optional[CloudOutputDevice]
+ if not device:
+ return
+ device.close()
+ CuraApplication.getInstance().getDiscoveredPrintersModel().removeDiscoveredPrinter(device.key)
+ output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
+ if device.key in output_device_manager.getOutputDeviceIds():
+ output_device_manager.removeOutputDevice(device.key)
+ self.discoveredDevicesChanged.emit()
+
+ def _createMachineFromDiscoveredDevice(self, key: str) -> None:
+ device = self._remote_clusters[key]
+ if not device:
+ return
+
+ # Create a new machine and activate it.
+ # We do not use use MachineManager.addMachine here because we need to set the cluster ID before activating it.
+ new_machine = CuraStackBuilder.createMachine(device.name, device.printerType)
+ if not new_machine:
+ Logger.log("e", "Failed creating a new machine")
+ return
+ new_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key)
+ CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId())
+ self._connectToOutputDevice(device, new_machine)
+
## Callback for when the active machine was changed by the user or a new remote cluster was found.
def _connectToActiveMachine(self) -> None:
active_machine = CuraApplication.getInstance().getGlobalContainerStack()
if not active_machine:
return
- # Remove all output devices that we have registered.
- # This is needed because when we switch machines we can only leave
- # output devices that are meant for that machine.
- for stored_cluster_id in self._remote_clusters:
- self._output_device_manager.removeOutputDevice(stored_cluster_id)
-
- # Check if the stored cluster_id for the active machine is in our list of remote clusters.
+ output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
stored_cluster_id = active_machine.getMetaDataEntry(self.META_CLUSTER_ID)
- if stored_cluster_id in self._remote_clusters:
- device = self._remote_clusters[stored_cluster_id]
- self._connectToOutputDevice(device, active_machine)
- Logger.log("d", "Device connected by metadata cluster ID %s", stored_cluster_id)
- else:
- self._connectByNetworkKey(active_machine)
-
- ## Tries to match the local network key to the cloud cluster host name.
- def _connectByNetworkKey(self, active_machine: GlobalStack) -> None:
- # Check if the active printer has a local network connection and match this key to the remote cluster.
- local_network_key = active_machine.getMetaDataEntry("um_network_key")
- if not local_network_key:
- return
-
- device = next((c for c in self._remote_clusters.values() if c.matchesNetworkKey(local_network_key)), None)
- if not device:
- return
-
- Logger.log("i", "Found cluster %s with network key %s", device, local_network_key)
- active_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key)
- self._connectToOutputDevice(device, active_machine)
+ local_network_key = active_machine.getMetaDataEntry(self.META_NETWORK_KEY)
+ for device in self._remote_clusters.values():
+ if device.key == stored_cluster_id:
+ # Connect to it if the stored ID matches.
+ self._connectToOutputDevice(device, active_machine)
+ elif local_network_key and device.matchesNetworkKey(local_network_key):
+ # Connect to it if we can match the local network key that was already present.
+ self._connectToOutputDevice(device, active_machine)
+ elif device.key in output_device_manager.getOutputDeviceIds():
+ # Remove device if it is not meant for the active machine.
+ output_device_manager.removeOutputDevice(device.key)
## Connects to an output device and makes sure it is registered in the output device manager.
- def _connectToOutputDevice(self, device: CloudOutputDevice, active_machine: GlobalStack) -> None:
- device.connect()
- self._output_device_manager.addOutputDevice(device)
- active_machine.addConfiguredConnectionType(device.connectionType.value)
+ def _connectToOutputDevice(self, device: CloudOutputDevice, machine: GlobalStack) -> None:
+ machine.setName(device.name)
+ machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key)
+ machine.setMetaDataEntry("group_name", device.name)
+ machine.addConfiguredConnectionType(device.connectionType.value)
- ## Handles an API error received from the cloud.
- # \param errors: The errors received
- def _onApiError(self, errors: List[CloudError] = None) -> None:
- Logger.log("w", str(errors))
- message = Message(
- text = self.I18N_CATALOG.i18nc("@info:description", "There was an error connecting to the cloud."),
- title = self.I18N_CATALOG.i18nc("@info:title", "Error"),
- lifetime = 10
- )
- message.show()
+ if not device.isConnected():
+ device.connect()
- ## Starts running the cloud output device manager, thus periodically requesting cloud data.
- def start(self):
- if self._running:
- return
- self._account.loginStateChanged.connect(self._onLoginStateChanged)
- # When switching machines we check if we have to activate a remote cluster.
- self._application.globalContainerStackChanged.connect(self._connectToActiveMachine)
- self._update_timer.timeout.connect(self._getRemoteClusters)
- self._onLoginStateChanged(is_logged_in = self._account.isLoggedIn)
-
- ## Stops running the cloud output device manager.
- def stop(self):
- if not self._running:
- return
- self._account.loginStateChanged.disconnect(self._onLoginStateChanged)
- # When switching machines we check if we have to activate a remote cluster.
- self._application.globalContainerStackChanged.disconnect(self._connectToActiveMachine)
- self._update_timer.timeout.disconnect(self._getRemoteClusters)
- self._onLoginStateChanged(is_logged_in = False)
+ output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
+ if device.key not in output_device_manager.getOutputDeviceIds():
+ output_device_manager.addOutputDevice(device)
\ No newline at end of file
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterBuildPlate.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterBuildPlate.py
deleted file mode 100644
index 4386bbb435..0000000000
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterBuildPlate.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from .BaseCloudModel import BaseCloudModel
-
-
-## Class representing a cluster printer
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterBuildPlate(BaseCloudModel):
- ## Create a new build plate
- # \param type: The type of buildplate glass or aluminium
- def __init__(self, type: str = "glass", **kwargs) -> None:
- self.type = type
- super().__init__(**kwargs)
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py
deleted file mode 100644
index 652cbdabda..0000000000
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterConfigurationMaterial.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from typing import Optional
-
-from UM.Logger import Logger
-from cura.CuraApplication import CuraApplication
-from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
-from .BaseCloudModel import BaseCloudModel
-
-
-## Class representing a cloud cluster printer configuration
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterPrinterConfigurationMaterial(BaseCloudModel):
- ## Creates a new material configuration model.
- # \param brand: The brand of material in this print core, e.g. 'Ultimaker'.
- # \param color: The color of material in this print core, e.g. 'Blue'.
- # \param guid: he GUID of the material in this print core, e.g. '506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9'.
- # \param material: The type of material in this print core, e.g. 'PLA'.
- def __init__(self, brand: Optional[str] = None, color: Optional[str] = None, guid: Optional[str] = None,
- material: Optional[str] = None, **kwargs) -> None:
- self.guid = guid
- self.brand = brand
- self.color = color
- self.material = material
- super().__init__(**kwargs)
-
- ## Creates a material output model based on this cloud printer material.
- def createOutputModel(self) -> MaterialOutputModel:
- material_manager = CuraApplication.getInstance().getMaterialManager()
- material_group_list = material_manager.getMaterialGroupListByGUID(self.guid) or []
-
- # Sort the material groups by "is_read_only = True" first, and then the name alphabetically.
- read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list))
- non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list))
- material_group = None
- if read_only_material_group_list:
- read_only_material_group_list = sorted(read_only_material_group_list, key = lambda x: x.name)
- material_group = read_only_material_group_list[0]
- elif non_read_only_material_group_list:
- non_read_only_material_group_list = sorted(non_read_only_material_group_list, key = lambda x: x.name)
- material_group = non_read_only_material_group_list[0]
-
- if material_group:
- container = material_group.root_material_node.getContainer()
- color = container.getMetaDataEntry("color_code")
- brand = container.getMetaDataEntry("brand")
- material_type = container.getMetaDataEntry("material")
- name = container.getName()
- else:
- Logger.log("w", "Unable to find material with guid {guid}. Using data as provided by cluster"
- .format(guid = self.guid))
- color = self.color
- brand = self.brand
- material_type = self.material
- name = "Empty" if self.material == "empty" else "Unknown"
-
- return MaterialOutputModel(guid = self.guid, type = material_type, brand = brand, color = color, name = name)
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py
deleted file mode 100644
index bd3e482bde..0000000000
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrinterStatus.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from typing import List, Union, Dict, Optional, Any
-
-from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
-from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
-from .CloudClusterBuildPlate import CloudClusterBuildPlate
-from .CloudClusterPrintCoreConfiguration import CloudClusterPrintCoreConfiguration
-from .BaseCloudModel import BaseCloudModel
-
-
-## Class representing a cluster printer
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterPrinterStatus(BaseCloudModel):
- ## Creates a new cluster printer status
- # \param enabled: A printer can be disabled if it should not receive new jobs. By default every printer is enabled.
- # \param firmware_version: Firmware version installed on the printer. Can differ for each printer in a cluster.
- # \param friendly_name: Human readable name of the printer. Can be used for identification purposes.
- # \param ip_address: The IP address of the printer in the local network.
- # \param machine_variant: The type of printer. Can be 'Ultimaker 3' or 'Ultimaker 3ext'.
- # \param status: The status of the printer.
- # \param unique_name: The unique name of the printer in the network.
- # \param uuid: The unique ID of the printer, also known as GUID.
- # \param configuration: The active print core configurations of this printer.
- # \param reserved_by: A printer can be claimed by a specific print job.
- # \param maintenance_required: Indicates if maintenance is necessary
- # \param firmware_update_status: Whether the printer's firmware is up-to-date, value is one of: "up_to_date",
- # "pending_update", "update_available", "update_in_progress", "update_failed", "update_impossible"
- # \param latest_available_firmware: The version of the latest firmware that is available
- # \param build_plate: The build plate that is on the printer
- def __init__(self, enabled: bool, firmware_version: str, friendly_name: str, ip_address: str, machine_variant: str,
- status: str, unique_name: str, uuid: str,
- configuration: List[Union[Dict[str, Any], CloudClusterPrintCoreConfiguration]],
- reserved_by: Optional[str] = None, maintenance_required: Optional[bool] = None,
- firmware_update_status: Optional[str] = None, latest_available_firmware: Optional[str] = None,
- build_plate: Union[Dict[str, Any], CloudClusterBuildPlate] = None, **kwargs) -> None:
-
- self.configuration = self.parseModels(CloudClusterPrintCoreConfiguration, configuration)
- self.enabled = enabled
- self.firmware_version = firmware_version
- self.friendly_name = friendly_name
- self.ip_address = ip_address
- self.machine_variant = machine_variant
- self.status = status
- self.unique_name = unique_name
- self.uuid = uuid
- self.reserved_by = reserved_by
- self.maintenance_required = maintenance_required
- self.firmware_update_status = firmware_update_status
- self.latest_available_firmware = latest_available_firmware
- self.build_plate = self.parseModel(CloudClusterBuildPlate, build_plate) if build_plate else None
- super().__init__(**kwargs)
-
- ## Creates a new output model.
- # \param controller - The controller of the model.
- def createOutputModel(self, controller: PrinterOutputController) -> PrinterOutputModel:
- model = PrinterOutputModel(controller, len(self.configuration), firmware_version = self.firmware_version)
- self.updateOutputModel(model)
- return model
-
- ## Updates the given output model.
- # \param model - The output model to update.
- def updateOutputModel(self, model: PrinterOutputModel) -> None:
- model.updateKey(self.uuid)
- model.updateName(self.friendly_name)
- model.updateType(self.machine_variant)
- model.updateState(self.status if self.enabled else "disabled")
- model.updateBuildplate(self.build_plate.type if self.build_plate else "glass")
-
- for configuration, extruder_output, extruder_config in \
- zip(self.configuration, model.extruders, model.printerConfiguration.extruderConfigurations):
- configuration.updateOutputModel(extruder_output)
- configuration.updateConfigurationModel(extruder_config)
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/__init__.py b/plugins/UM3NetworkPrinting/src/Cloud/Models/__init__.py
deleted file mode 100644
index f3f6970c54..0000000000
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py
index 176b7e6ab7..d5de7fe10a 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py
+++ b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# !/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5.QtCore import QUrl
@@ -6,7 +6,8 @@ from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManage
from typing import Optional, Callable, Any, Tuple, cast
from UM.Logger import Logger
-from .Models.CloudPrintJobResponse import CloudPrintJobResponse
+
+from ..Models.Http.CloudPrintJobResponse import CloudPrintJobResponse
## Class responsible for uploading meshes to the cloud in separate requests.
@@ -53,7 +54,7 @@ class ToolPathUploader:
def _createRequest(self) -> QNetworkRequest:
request = QNetworkRequest(QUrl(self._print_job.upload_url))
request.setHeader(QNetworkRequest.ContentTypeHeader, self._print_job.content_type)
-
+
first_byte, last_byte = self._chunkRange()
content_range = "bytes {}-{}/{}".format(first_byte, last_byte - 1, len(self._data))
request.setRawHeader(b"Content-Range", content_range.encode())
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Utils.py b/plugins/UM3NetworkPrinting/src/Cloud/Utils.py
deleted file mode 100644
index 5136e0e7db..0000000000
--- a/plugins/UM3NetworkPrinting/src/Cloud/Utils.py
+++ /dev/null
@@ -1,54 +0,0 @@
-from datetime import datetime, timedelta
-from typing import TypeVar, Dict, Tuple, List
-
-from UM import i18nCatalog
-
-T = TypeVar("T")
-U = TypeVar("U")
-
-
-## Splits the given dictionaries into three lists (in a tuple):
-# - `removed`: Items that were in the first argument but removed in the second one.
-# - `added`: Items that were not in the first argument but were included in the second one.
-# - `updated`: Items that were in both dictionaries. Both values are given in a tuple.
-# \param previous: The previous items
-# \param received: The received items
-# \return: The tuple (removed, added, updated) as explained above.
-def findChanges(previous: Dict[str, T], received: Dict[str, U]) -> Tuple[List[T], List[U], List[Tuple[T, U]]]:
- previous_ids = set(previous)
- received_ids = set(received)
-
- removed_ids = previous_ids.difference(received_ids)
- new_ids = received_ids.difference(previous_ids)
- updated_ids = received_ids.intersection(previous_ids)
-
- removed = [previous[removed_id] for removed_id in removed_ids]
- added = [received[new_id] for new_id in new_ids]
- updated = [(previous[updated_id], received[updated_id]) for updated_id in updated_ids]
-
- return removed, added, updated
-
-
-def formatTimeCompleted(seconds_remaining: int) -> str:
- completed = datetime.now() + timedelta(seconds=seconds_remaining)
- return "{hour:02d}:{minute:02d}".format(hour = completed.hour, minute = completed.minute)
-
-
-def formatDateCompleted(seconds_remaining: int) -> str:
- now = datetime.now()
- completed = now + timedelta(seconds=seconds_remaining)
- days = (completed.date() - now.date()).days
- i18n = i18nCatalog("cura")
-
- # If finishing date is more than 7 days out, using "Mon Dec 3 at HH:MM" format
- if days >= 7:
- return completed.strftime("%a %b ") + "{day}".format(day = completed.day)
- # If finishing date is within the next week, use "Monday at HH:MM" format
- elif days >= 2:
- return completed.strftime("%a")
- # If finishing tomorrow, use "tomorrow at HH:MM" format
- elif days >= 1:
- return i18n.i18nc("@info:status", "tomorrow")
- # If finishing today, use "today at HH:MM" format
- else:
- return i18n.i18nc("@info:status", "today")
diff --git a/plugins/UM3NetworkPrinting/src/ClusterOutputController.py b/plugins/UM3NetworkPrinting/src/ClusterOutputController.py
new file mode 100644
index 0000000000..02d8d174d1
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/ClusterOutputController.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
+from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
+from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
+
+
+class ClusterOutputController(PrinterOutputController):
+
+ def __init__(self, output_device: PrinterOutputDevice) -> None:
+ super().__init__(output_device)
+ self.can_pause = True
+ self.can_abort = True
+ self.can_pre_heat_bed = False
+ self.can_pre_heat_hotends = False
+ self.can_send_raw_gcode = False
+ self.can_control_manually = False
+ self.can_update_firmware = False
+
+ def setJobState(self, job: PrintJobOutputModel, state: str):
+ self._output_device.setJobState(job.key, state)
diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py
deleted file mode 100644
index c1a6362455..0000000000
--- a/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py
+++ /dev/null
@@ -1,697 +0,0 @@
-# Copyright (c) 2019 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from typing import Any, cast, Tuple, Union, Optional, Dict, List
-from time import time
-
-import io # To create the correct buffers for sending data to the printer.
-import json
-import os
-
-from UM.FileHandler.FileHandler import FileHandler
-from UM.FileHandler.WriteFileJob import WriteFileJob # To call the file writer asynchronously.
-from UM.Logger import Logger
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from UM.i18n import i18nCatalog
-from UM.Qt.Duration import Duration, DurationFormat
-
-from UM.Message import Message
-from UM.Scene.SceneNode import SceneNode # For typing.
-
-from cura.CuraApplication import CuraApplication
-from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
-from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
-from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice
-from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
-from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
-from cura.PrinterOutputDevice import ConnectionType
-
-from .Cloud.Utils import formatTimeCompleted, formatDateCompleted
-from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController
-from .ConfigurationChangeModel import ConfigurationChangeModel
-from .MeshFormatHandler import MeshFormatHandler
-from .SendMaterialJob import SendMaterialJob
-from .UM3PrintJobOutputModel import UM3PrintJobOutputModel
-
-from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
-from PyQt5.QtGui import QDesktopServices, QImage
-from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject
-
-i18n_catalog = i18nCatalog("cura")
-
-
-class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
- printJobsChanged = pyqtSignal()
- activePrinterChanged = pyqtSignal()
- activeCameraUrlChanged = pyqtSignal()
- receivedPrintJobsChanged = pyqtSignal()
-
- # Notify can only use signals that are defined by the class that they are in, not inherited ones.
- # Therefore we create a private signal used to trigger the printersChanged signal.
- _clusterPrintersChanged = pyqtSignal()
-
- def __init__(self, device_id, address, properties, parent = None) -> None:
- super().__init__(device_id = device_id, address = address, properties=properties, connection_type = ConnectionType.NetworkConnection, parent = parent)
- self._api_prefix = "/cluster-api/v1/"
-
- self._application = CuraApplication.getInstance()
-
- self._number_of_extruders = 2
-
- self._dummy_lambdas = (
- "", {}, io.BytesIO()
- ) # type: Tuple[Optional[str], Dict[str, Union[str, int, bool]], Union[io.StringIO, io.BytesIO]]
-
- self._print_jobs = [] # type: List[UM3PrintJobOutputModel]
- self._received_print_jobs = False # type: bool
-
- self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorStage.qml")
-
- # Trigger the printersChanged signal when the private signal is triggered
- self.printersChanged.connect(self._clusterPrintersChanged)
-
- self._accepts_commands = True # type: bool
-
- # Cluster does not have authentication, so default to authenticated
- self._authentication_state = AuthState.Authenticated
-
- self._error_message = None # type: Optional[Message]
- self._write_job_progress_message = None # type: Optional[Message]
- self._progress_message = None # type: Optional[Message]
-
- self._active_printer = None # type: Optional[PrinterOutputModel]
-
- self._printer_selection_dialog = None # type: QObject
-
- self.setPriority(3) # Make sure the output device gets selected above local file output
- self.setName(self._id)
- self.setShortDescription(i18n_catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print over network"))
- self.setDescription(i18n_catalog.i18nc("@properties:tooltip", "Print over network"))
-
- self.setConnectionText(i18n_catalog.i18nc("@info:status", "Connected over the network"))
-
- self._printer_uuid_to_unique_name_mapping = {} # type: Dict[str, str]
-
- self._finished_jobs = [] # type: List[UM3PrintJobOutputModel]
-
- self._cluster_size = int(properties.get(b"cluster_size", 0)) # type: int
-
- self._latest_reply_handler = None # type: Optional[QNetworkReply]
- self._sending_job = None
-
- self._active_camera_url = QUrl() # type: QUrl
-
- def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False,
- file_handler: Optional[FileHandler] = None, **kwargs: str) -> None:
- self.writeStarted.emit(self)
-
- self.sendMaterialProfiles()
-
- mesh_format = MeshFormatHandler(file_handler, self.firmwareVersion)
-
- # This function pauses with the yield, waiting on instructions on which printer it needs to print with.
- if not mesh_format.is_valid:
- Logger.log("e", "Missing file or mesh writer!")
- return
- self._sending_job = self._sendPrintJob(mesh_format, nodes)
- if self._sending_job is not None:
- self._sending_job.send(None) # Start the generator.
-
- if len(self._printers) > 1: # We need to ask the user.
- self._spawnPrinterSelectionDialog()
- is_job_sent = True
- else: # Just immediately continue.
- self._sending_job.send("") # No specifically selected printer.
- is_job_sent = self._sending_job.send(None)
-
- def _spawnPrinterSelectionDialog(self):
- if self._printer_selection_dialog is None:
- path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/PrintWindow.qml")
- self._printer_selection_dialog = self._application.createQmlComponent(path, {"OutputDevice": self})
- if self._printer_selection_dialog is not None:
- self._printer_selection_dialog.show()
-
- @pyqtProperty(int, constant=True)
- def clusterSize(self) -> int:
- return self._cluster_size
-
- ## Allows the user to choose a printer to print with from the printer
- # selection dialogue.
- # \param target_printer The name of the printer to target.
- @pyqtSlot(str)
- def selectPrinter(self, target_printer: str = "") -> None:
- if self._sending_job is not None:
- self._sending_job.send(target_printer)
-
- @pyqtSlot()
- def cancelPrintSelection(self) -> None:
- self._sending_gcode = False
-
- ## Greenlet to send a job to the printer over the network.
- #
- # This greenlet gets called asynchronously in requestWrite. It is a
- # greenlet in order to optionally wait for selectPrinter() to select a
- # printer.
- # The greenlet yields exactly three times: First time None,
- # \param mesh_format Object responsible for choosing the right kind of format to write with.
- def _sendPrintJob(self, mesh_format: MeshFormatHandler, nodes: List[SceneNode]):
- Logger.log("i", "Sending print job to printer.")
- if self._sending_gcode:
- self._error_message = Message(
- i18n_catalog.i18nc("@info:status",
- "Sending new jobs (temporarily) blocked, still sending the previous print job."))
- self._error_message.show()
- yield #Wait on the user to select a target printer.
- yield #Wait for the write job to be finished.
- yield False #Return whether this was a success or not.
- yield #Prevent StopIteration.
-
- self._sending_gcode = True
-
- # Potentially wait on the user to select a target printer.
- target_printer = yield # type: Optional[str]
-
- # Using buffering greatly reduces the write time for many lines of gcode
-
- stream = mesh_format.createStream()
-
- job = WriteFileJob(mesh_format.writer, stream, nodes, mesh_format.file_mode)
-
- self._write_job_progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"),
- lifetime = 0, dismissable = False, progress = -1,
- title = i18n_catalog.i18nc("@info:title", "Sending Data"),
- use_inactivity_timer = False)
- self._write_job_progress_message.show()
-
- if mesh_format.preferred_format is not None:
- self._dummy_lambdas = (target_printer, mesh_format.preferred_format, stream)
- job.finished.connect(self._sendPrintJobWaitOnWriteJobFinished)
- job.start()
- yield True # Return that we had success!
- yield # To prevent having to catch the StopIteration exception.
-
- def _sendPrintJobWaitOnWriteJobFinished(self, job: WriteFileJob) -> None:
- if self._write_job_progress_message:
- self._write_job_progress_message.hide()
-
- self._progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), lifetime = 0,
- dismissable = False, progress = -1,
- title = i18n_catalog.i18nc("@info:title", "Sending Data"))
- self._progress_message.addAction("Abort", i18n_catalog.i18nc("@action:button", "Cancel"), icon = "",
- description = "")
- self._progress_message.actionTriggered.connect(self._progressMessageActionTriggered)
- self._progress_message.show()
- parts = []
-
- target_printer, preferred_format, stream = self._dummy_lambdas
-
- # If a specific printer was selected, it should be printed with that machine.
- if target_printer:
- target_printer = self._printer_uuid_to_unique_name_mapping[target_printer]
- parts.append(self._createFormPart("name=require_printer_name", bytes(target_printer, "utf-8"), "text/plain"))
-
- # Add user name to the print_job
- parts.append(self._createFormPart("name=owner", bytes(self._getUserName(), "utf-8"), "text/plain"))
-
- file_name = self._application.getPrintInformation().jobName + "." + preferred_format["extension"]
-
- output = stream.getvalue() # Either str or bytes depending on the output mode.
- if isinstance(stream, io.StringIO):
- output = cast(str, output).encode("utf-8")
- output = cast(bytes, output)
-
- parts.append(self._createFormPart("name=\"file\"; filename=\"%s\"" % file_name, output))
-
- self._latest_reply_handler = self.postFormWithParts("print_jobs/", parts,
- on_finished = self._onPostPrintJobFinished,
- on_progress = self._onUploadPrintJobProgress)
-
- @pyqtProperty(QObject, notify = activePrinterChanged)
- def activePrinter(self) -> Optional[PrinterOutputModel]:
- return self._active_printer
-
- @pyqtSlot(QObject)
- def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None:
- if self._active_printer != printer:
- self._active_printer = printer
- self.activePrinterChanged.emit()
-
- @pyqtProperty(QUrl, notify = activeCameraUrlChanged)
- def activeCameraUrl(self) -> "QUrl":
- return self._active_camera_url
-
- @pyqtSlot(QUrl)
- def setActiveCameraUrl(self, camera_url: "QUrl") -> None:
- if self._active_camera_url != camera_url:
- self._active_camera_url = camera_url
- self.activeCameraUrlChanged.emit()
-
- def _onPostPrintJobFinished(self, reply: QNetworkReply) -> None:
- if self._progress_message:
- self._progress_message.hide()
- self._compressing_gcode = False
- self._sending_gcode = False
-
- ## The IP address of the printer.
- @pyqtProperty(str, constant = True)
- def address(self) -> str:
- return self._address
-
- def _onUploadPrintJobProgress(self, bytes_sent: int, bytes_total: int) -> None:
- if bytes_total > 0:
- new_progress = bytes_sent / bytes_total * 100
- # Treat upload progress as response. Uploading can take more than 10 seconds, so if we don't, we can get
- # timeout responses if this happens.
- self._last_response_time = time()
- if self._progress_message is not None and new_progress != self._progress_message.getProgress():
- self._progress_message.show() # Ensure that the message is visible.
- self._progress_message.setProgress(bytes_sent / bytes_total * 100)
-
- # If successfully sent:
- if bytes_sent == bytes_total:
- # Show a confirmation to the user so they know the job was sucessful and provide the option to switch to
- # the monitor tab.
- self._success_message = Message(
- i18n_catalog.i18nc("@info:status", "Print job was successfully sent to the printer."),
- lifetime=5, dismissable=True,
- title=i18n_catalog.i18nc("@info:title", "Data Sent"))
- self._success_message.addAction("View", i18n_catalog.i18nc("@action:button", "View in Monitor"), icon = "",
- description="")
- self._success_message.actionTriggered.connect(self._successMessageActionTriggered)
- self._success_message.show()
- else:
- if self._progress_message is not None:
- self._progress_message.setProgress(0)
- self._progress_message.hide()
-
- def _progressMessageActionTriggered(self, message_id: Optional[str] = None, action_id: Optional[str] = None) -> None:
- if action_id == "Abort":
- Logger.log("d", "User aborted sending print to remote.")
- if self._progress_message is not None:
- self._progress_message.hide()
- self._compressing_gcode = False
- self._sending_gcode = False
- self._application.getController().setActiveStage("PrepareStage")
-
- # After compressing the sliced model Cura sends data to printer, to stop receiving updates from the request
- # the "reply" should be disconnected
- if self._latest_reply_handler:
- self._latest_reply_handler.disconnect()
- self._latest_reply_handler = None
-
- def _successMessageActionTriggered(self, message_id: Optional[str] = None, action_id: Optional[str] = None) -> None:
- if action_id == "View":
- self._application.getController().setActiveStage("MonitorStage")
-
- @pyqtSlot()
- def openPrintJobControlPanel(self) -> None:
- Logger.log("d", "Opening print job control panel...")
- QDesktopServices.openUrl(QUrl("http://" + self._address + "/print_jobs"))
-
- @pyqtSlot()
- def openPrinterControlPanel(self) -> None:
- Logger.log("d", "Opening printer control panel...")
- QDesktopServices.openUrl(QUrl("http://" + self._address + "/printers"))
-
- @pyqtProperty("QVariantList", notify = printJobsChanged)
- def printJobs(self)-> List[UM3PrintJobOutputModel]:
- return self._print_jobs
-
- @pyqtProperty(bool, notify = receivedPrintJobsChanged)
- def receivedPrintJobs(self) -> bool:
- return self._received_print_jobs
-
- @pyqtProperty("QVariantList", notify = printJobsChanged)
- def queuedPrintJobs(self) -> List[UM3PrintJobOutputModel]:
- return [print_job for print_job in self._print_jobs if print_job.state == "queued" or print_job.state == "error"]
-
- @pyqtProperty("QVariantList", notify = printJobsChanged)
- def activePrintJobs(self) -> List[UM3PrintJobOutputModel]:
- return [print_job for print_job in self._print_jobs if print_job.assignedPrinter is not None and print_job.state != "queued"]
-
- @pyqtProperty("QVariantList", notify = _clusterPrintersChanged)
- def connectedPrintersTypeCount(self) -> List[Dict[str, str]]:
- printer_count = {} # type: Dict[str, int]
- for printer in self._printers:
- if printer.type in printer_count:
- printer_count[printer.type] += 1
- else:
- printer_count[printer.type] = 1
- result = []
- for machine_type in printer_count:
- result.append({"machine_type": machine_type, "count": str(printer_count[machine_type])})
- return result
-
- @pyqtProperty("QVariantList", notify=_clusterPrintersChanged)
- def printers(self):
- return self._printers
-
- @pyqtSlot(int, result = str)
- def getTimeCompleted(self, time_remaining: int) -> str:
- return formatTimeCompleted(time_remaining)
-
- @pyqtSlot(int, result = str)
- def getDateCompleted(self, time_remaining: int) -> str:
- return formatDateCompleted(time_remaining)
-
- @pyqtSlot(int, result = str)
- def formatDuration(self, seconds: int) -> str:
- return Duration(seconds).getDisplayString(DurationFormat.Format.Short)
-
- @pyqtSlot(str)
- def sendJobToTop(self, print_job_uuid: str) -> None:
- # This function is part of the output device (and not of the printjob output model) as this type of operation
- # is a modification of the cluster queue and not of the actual job.
- data = "{\"to_position\": 0}"
- self.put("print_jobs/{uuid}/move_to_position".format(uuid = print_job_uuid), data, on_finished=None)
-
- @pyqtSlot(str)
- def deleteJobFromQueue(self, print_job_uuid: str) -> None:
- # This function is part of the output device (and not of the printjob output model) as this type of operation
- # is a modification of the cluster queue and not of the actual job.
- self.delete("print_jobs/{uuid}".format(uuid = print_job_uuid), on_finished=None)
-
- @pyqtSlot(str)
- def forceSendJob(self, print_job_uuid: str) -> None:
- data = "{\"force\": true}"
- self.put("print_jobs/{uuid}".format(uuid=print_job_uuid), data, on_finished=None)
-
- def _printJobStateChanged(self) -> None:
- username = self._getUserName()
-
- if username is None:
- return # We only want to show notifications if username is set.
-
- finished_jobs = [job for job in self._print_jobs if job.state == "wait_cleanup"]
-
- newly_finished_jobs = [job for job in finished_jobs if job not in self._finished_jobs and job.owner == username]
- for job in newly_finished_jobs:
- if job.assignedPrinter:
- job_completed_text = i18n_catalog.i18nc("@info:status", "Printer '{printer_name}' has finished printing '{job_name}'.".format(printer_name=job.assignedPrinter.name, job_name = job.name))
- else:
- job_completed_text = i18n_catalog.i18nc("@info:status", "The print job '{job_name}' was finished.".format(job_name = job.name))
- job_completed_message = Message(text=job_completed_text, title = i18n_catalog.i18nc("@info:status", "Print finished"))
- job_completed_message.show()
-
- # Ensure UI gets updated
- self.printJobsChanged.emit()
-
- # Keep a list of all completed jobs so we know if something changed next time.
- self._finished_jobs = finished_jobs
-
- ## Called when the connection to the cluster changes.
- def connect(self) -> None:
- super().connect()
- self.sendMaterialProfiles()
-
- def _onGetPreviewImageFinished(self, reply: QNetworkReply) -> None:
- reply_url = reply.url().toString()
-
- uuid = reply_url[reply_url.find("print_jobs/")+len("print_jobs/"):reply_url.rfind("/preview_image")]
-
- print_job = findByKey(self._print_jobs, uuid)
- if print_job:
- image = QImage()
- image.loadFromData(reply.readAll())
- print_job.updatePreviewImage(image)
-
- def _update(self) -> None:
- super()._update()
- self.get("printers/", on_finished = self._onGetPrintersDataFinished)
- self.get("print_jobs/", on_finished = self._onGetPrintJobsFinished)
-
- for print_job in self._print_jobs:
- if print_job.getPreviewImage() is None:
- self.get("print_jobs/{uuid}/preview_image".format(uuid=print_job.key), on_finished=self._onGetPreviewImageFinished)
-
- def _onGetPrintJobsFinished(self, reply: QNetworkReply) -> None:
- self._received_print_jobs = True
- self.receivedPrintJobsChanged.emit()
-
- if not checkValidGetReply(reply):
- return
-
- result = loadJsonFromReply(reply)
- if result is None:
- return
-
- print_jobs_seen = []
- job_list_changed = False
- for idx, print_job_data in enumerate(result):
- print_job = findByKey(self._print_jobs, print_job_data["uuid"])
- if print_job is None:
- print_job = self._createPrintJobModel(print_job_data)
- job_list_changed = True
- elif not job_list_changed:
- # Check if the order of the jobs has changed since the last check
- if self._print_jobs.index(print_job) != idx:
- job_list_changed = True
-
- self._updatePrintJob(print_job, print_job_data)
-
- if print_job.state != "queued" and print_job.state != "error": # Print job should be assigned to a printer.
- if print_job.state in ["failed", "finished", "aborted", "none"]:
- # Print job was already completed, so don't attach it to a printer.
- printer = None
- else:
- printer = self._getPrinterByKey(print_job_data["printer_uuid"])
- else: # The job can "reserve" a printer if some changes are required.
- printer = self._getPrinterByKey(print_job_data["assigned_to"])
-
- if printer:
- printer.updateActivePrintJob(print_job)
-
- print_jobs_seen.append(print_job)
-
- # Check what jobs need to be removed.
- removed_jobs = [print_job for print_job in self._print_jobs if print_job not in print_jobs_seen]
-
- for removed_job in removed_jobs:
- job_list_changed = job_list_changed or self._removeJob(removed_job)
-
- if job_list_changed:
- # Override the old list with the new list (either because jobs were removed / added or order changed)
- self._print_jobs = print_jobs_seen
- self.printJobsChanged.emit() # Do a single emit for all print job changes.
-
- def _onGetPrintersDataFinished(self, reply: QNetworkReply) -> None:
- if not checkValidGetReply(reply):
- return
-
- result = loadJsonFromReply(reply)
- if result is None:
- return
-
- printer_list_changed = False
- printers_seen = []
-
- for printer_data in result:
- printer = findByKey(self._printers, printer_data["uuid"])
-
- if printer is None:
- printer = self._createPrinterModel(printer_data)
- printer_list_changed = True
-
- printers_seen.append(printer)
-
- self._updatePrinter(printer, printer_data)
-
- removed_printers = [printer for printer in self._printers if printer not in printers_seen]
- for printer in removed_printers:
- self._removePrinter(printer)
-
- if removed_printers or printer_list_changed:
- self.printersChanged.emit()
-
- def _createPrinterModel(self, data: Dict[str, Any]) -> PrinterOutputModel:
- printer = PrinterOutputModel(output_controller = ClusterUM3PrinterOutputController(self),
- number_of_extruders = self._number_of_extruders)
- printer.setCameraUrl(QUrl("http://" + data["ip_address"] + ":8080/?action=stream"))
- self._printers.append(printer)
- return printer
-
- def _createPrintJobModel(self, data: Dict[str, Any]) -> UM3PrintJobOutputModel:
- print_job = UM3PrintJobOutputModel(output_controller=ClusterUM3PrinterOutputController(self),
- key=data["uuid"], name= data["name"])
-
- configuration = ConfigurationModel()
- extruders = [ExtruderConfigurationModel(position = idx) for idx in range(0, self._number_of_extruders)]
- for index in range(0, self._number_of_extruders):
- try:
- extruder_data = data["configuration"][index]
- except IndexError:
- continue
- extruder = extruders[int(data["configuration"][index]["extruder_index"])]
- extruder.setHotendID(extruder_data.get("print_core_id", ""))
- extruder.setMaterial(self._createMaterialOutputModel(extruder_data.get("material", {})))
-
- configuration.setExtruderConfigurations(extruders)
- print_job.updateConfiguration(configuration)
- print_job.setCompatibleMachineFamilies(data.get("compatible_machine_families", []))
- print_job.stateChanged.connect(self._printJobStateChanged)
- return print_job
-
- def _updatePrintJob(self, print_job: UM3PrintJobOutputModel, data: Dict[str, Any]) -> None:
- print_job.updateTimeTotal(data["time_total"])
- print_job.updateTimeElapsed(data["time_elapsed"])
- impediments_to_printing = data.get("impediments_to_printing", [])
- print_job.updateOwner(data["owner"])
-
- status_set_by_impediment = False
- for impediment in impediments_to_printing:
- if impediment["severity"] == "UNFIXABLE":
- status_set_by_impediment = True
- print_job.updateState("error")
- break
-
- if not status_set_by_impediment:
- print_job.updateState(data["status"])
-
- print_job.updateConfigurationChanges(self._createConfigurationChanges(data["configuration_changes_required"]))
-
- def _createConfigurationChanges(self, data: List[Dict[str, Any]]) -> List[ConfigurationChangeModel]:
- result = []
- for change in data:
- result.append(ConfigurationChangeModel(type_of_change=change["type_of_change"],
- index=change["index"],
- target_name=change["target_name"],
- origin_name=change["origin_name"]))
- return result
-
- def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel":
- material_manager = self._application.getMaterialManager()
- material_group_list = None
-
- # Avoid crashing if there is no "guid" field in the metadata
- material_guid = material_data.get("guid")
- if material_guid:
- material_group_list = material_manager.getMaterialGroupListByGUID(material_guid)
-
- # This can happen if the connected machine has no material in one or more extruders (if GUID is empty), or the
- # material is unknown to Cura, so we should return an "empty" or "unknown" material model.
- if material_group_list is None:
- material_name = i18n_catalog.i18nc("@label:material", "Empty") if len(material_data.get("guid", "")) == 0 \
- else i18n_catalog.i18nc("@label:material", "Unknown")
-
- return MaterialOutputModel(guid = material_data.get("guid", ""),
- type = material_data.get("material", ""),
- color = material_data.get("color", ""),
- brand = material_data.get("brand", ""),
- name = material_data.get("name", material_name)
- )
-
- # Sort the material groups by "is_read_only = True" first, and then the name alphabetically.
- read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list))
- non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list))
- material_group = None
- if read_only_material_group_list:
- read_only_material_group_list = sorted(read_only_material_group_list, key = lambda x: x.name)
- material_group = read_only_material_group_list[0]
- elif non_read_only_material_group_list:
- non_read_only_material_group_list = sorted(non_read_only_material_group_list, key = lambda x: x.name)
- material_group = non_read_only_material_group_list[0]
-
- if material_group:
- container = material_group.root_material_node.getContainer()
- color = container.getMetaDataEntry("color_code")
- brand = container.getMetaDataEntry("brand")
- material_type = container.getMetaDataEntry("material")
- name = container.getName()
- else:
- Logger.log("w",
- "Unable to find material with guid {guid}. Using data as provided by cluster".format(
- guid=material_data["guid"]))
- color = material_data["color"]
- brand = material_data["brand"]
- material_type = material_data["material"]
- name = i18n_catalog.i18nc("@label:material", "Empty") if material_data["material"] == "empty" \
- else i18n_catalog.i18nc("@label:material", "Unknown")
- return MaterialOutputModel(guid = material_data["guid"], type = material_type,
- brand = brand, color = color, name = name)
-
- def _updatePrinter(self, printer: PrinterOutputModel, data: Dict[str, Any]) -> None:
- # For some unknown reason the cluster wants UUID for everything, except for sending a job directly to a printer.
- # Then we suddenly need the unique name. So in order to not have to mess up all the other code, we save a mapping.
- self._printer_uuid_to_unique_name_mapping[data["uuid"]] = data["unique_name"]
-
- definitions = ContainerRegistry.getInstance().findDefinitionContainers(name = data["machine_variant"])
- if not definitions:
- Logger.log("w", "Unable to find definition for machine variant %s", data["machine_variant"])
- return
-
- machine_definition = definitions[0]
-
- printer.updateName(data["friendly_name"])
- printer.updateKey(data["uuid"])
- printer.updateType(data["machine_variant"])
-
- # Do not store the build plate information that comes from connect if the current printer has not build plate information
- if "build_plate" in data and machine_definition.getMetaDataEntry("has_variant_buildplates", False):
- printer.updateBuildplate(data["build_plate"]["type"])
- if not data["enabled"]:
- printer.updateState("disabled")
- else:
- printer.updateState(data["status"])
-
- for index in range(0, self._number_of_extruders):
- extruder = printer.extruders[index]
- try:
- extruder_data = data["configuration"][index]
- except IndexError:
- break
-
- extruder.updateHotendID(extruder_data.get("print_core_id", ""))
-
- material_data = extruder_data["material"]
- if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_data["guid"]:
- material = self._createMaterialOutputModel(material_data)
- extruder.updateActiveMaterial(material)
-
- def _removeJob(self, job: UM3PrintJobOutputModel) -> bool:
- if job not in self._print_jobs:
- return False
-
- if job.assignedPrinter:
- job.assignedPrinter.updateActivePrintJob(None)
- job.stateChanged.disconnect(self._printJobStateChanged)
- self._print_jobs.remove(job)
-
- return True
-
- def _removePrinter(self, printer: PrinterOutputModel) -> None:
- self._printers.remove(printer)
- if self._active_printer == printer:
- self._active_printer = None
- self.activePrinterChanged.emit()
-
- ## Sync the material profiles in Cura with the printer.
- #
- # This gets called when connecting to a printer as well as when sending a
- # print.
- def sendMaterialProfiles(self) -> None:
- job = SendMaterialJob(device = self)
- job.run()
-
-def loadJsonFromReply(reply: QNetworkReply) -> Optional[List[Dict[str, Any]]]:
- try:
- result = json.loads(bytes(reply.readAll()).decode("utf-8"))
- except json.decoder.JSONDecodeError:
- Logger.logException("w", "Unable to decode JSON from reply.")
- return None
- return result
-
-
-def checkValidGetReply(reply: QNetworkReply) -> bool:
- status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
-
- if status_code != 200:
- Logger.log("w", "Got status code {status_code} while trying to get data".format(status_code=status_code))
- return False
- return True
-
-
-def findByKey(lst: List[Union[UM3PrintJobOutputModel, PrinterOutputModel]], key: str) -> Optional[UM3PrintJobOutputModel]:
- for item in lst:
- if item.key == key:
- return item
- return None
diff --git a/plugins/UM3NetworkPrinting/src/ClusterUM3PrinterOutputController.py b/plugins/UM3NetworkPrinting/src/ClusterUM3PrinterOutputController.py
deleted file mode 100644
index fc6798386a..0000000000
--- a/plugins/UM3NetworkPrinting/src/ClusterUM3PrinterOutputController.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
-
-MYPY = False
-if MYPY:
- from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
-
-class ClusterUM3PrinterOutputController(PrinterOutputController):
- def __init__(self, output_device):
- super().__init__(output_device)
- self.can_pre_heat_bed = False
- self.can_pre_heat_hotends = False
- self.can_control_manually = False
- self.can_send_raw_gcode = False
-
- def setJobState(self, job: "PrintJobOutputModel", state: str):
- data = "{\"action\": \"%s\"}" % state
- self._output_device.put("print_jobs/%s/action" % job.key, data, on_finished=None)
diff --git a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py b/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py
deleted file mode 100644
index ecc89b3948..0000000000
--- a/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-import os.path
-import time
-from typing import Optional, TYPE_CHECKING
-
-from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject
-
-from UM.PluginRegistry import PluginRegistry
-from UM.Logger import Logger
-from UM.i18n import i18nCatalog
-
-from cura.CuraApplication import CuraApplication
-from cura.MachineAction import MachineAction
-from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
-
-from .UM3OutputDevicePlugin import UM3OutputDevicePlugin
-
-if TYPE_CHECKING:
- from cura.PrinterOutputDevice import PrinterOutputDevice
-
-catalog = i18nCatalog("cura")
-
-
-class DiscoverUM3Action(MachineAction):
- discoveredDevicesChanged = pyqtSignal()
-
- def __init__(self) -> None:
- super().__init__("DiscoverUM3Action", catalog.i18nc("@action","Connect via Network"))
- self._qml_url = "resources/qml/DiscoverUM3Action.qml"
-
- self._network_plugin = None #type: Optional[UM3OutputDevicePlugin]
-
- self.__additional_components_view = None #type: Optional[QObject]
-
- CuraApplication.getInstance().engineCreatedSignal.connect(self._createAdditionalComponentsView)
-
- self._last_zero_conf_event_time = time.time() #type: float
-
- # Time to wait after a zero-conf service change before allowing a zeroconf reset
- self._zero_conf_change_grace_period = 0.25 #type: float
-
- @pyqtSlot()
- def startDiscovery(self):
- if not self._network_plugin:
- Logger.log("d", "Starting device discovery.")
- self._network_plugin = CuraApplication.getInstance().getOutputDeviceManager().getOutputDevicePlugin("UM3NetworkPrinting")
- self._network_plugin.discoveredDevicesChanged.connect(self._onDeviceDiscoveryChanged)
- self.discoveredDevicesChanged.emit()
-
- ## Re-filters the list of devices.
- @pyqtSlot()
- def reset(self):
- Logger.log("d", "Reset the list of found devices.")
- if self._network_plugin:
- self._network_plugin.resetLastManualDevice()
- self.discoveredDevicesChanged.emit()
-
- @pyqtSlot()
- def restartDiscovery(self):
- # Ensure that there is a bit of time after a printer has been discovered.
- # This is a work around for an issue with Qt 5.5.1 up to Qt 5.7 which can segfault if we do this too often.
- # It's most likely that the QML engine is still creating delegates, where the python side already deleted or
- # garbage collected the data.
- # Whatever the case, waiting a bit ensures that it doesn't crash.
- if time.time() - self._last_zero_conf_event_time > self._zero_conf_change_grace_period:
- if not self._network_plugin:
- self.startDiscovery()
- else:
- self._network_plugin.startDiscovery()
-
- @pyqtSlot(str, str)
- def removeManualDevice(self, key, address):
- if not self._network_plugin:
- return
-
- self._network_plugin.removeManualDevice(key, address)
-
- @pyqtSlot(str, str)
- def setManualDevice(self, key, address):
- if key != "":
- # This manual printer replaces a current manual printer
- self._network_plugin.removeManualDevice(key)
-
- if address != "":
- self._network_plugin.addManualDevice(address)
-
- def _onDeviceDiscoveryChanged(self, *args):
- self._last_zero_conf_event_time = time.time()
- self.discoveredDevicesChanged.emit()
-
- @pyqtProperty("QVariantList", notify = discoveredDevicesChanged)
- def foundDevices(self):
- if self._network_plugin:
-
- printers = list(self._network_plugin.getDiscoveredDevices().values())
- printers.sort(key = lambda k: k.name)
- return printers
- else:
- return []
-
- @pyqtSlot(str)
- def setGroupName(self, group_name: str) -> None:
- Logger.log("d", "Attempting to set the group name of the active machine to %s", group_name)
- global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
- if global_container_stack:
- meta_data = global_container_stack.getMetaData()
- if "group_name" in meta_data:
- previous_connect_group_name = meta_data["group_name"]
- global_container_stack.setMetaDataEntry("group_name", group_name)
- # Find all the places where there is the same group name and change it accordingly
- CuraApplication.getInstance().getMachineManager().replaceContainersMetadata(key = "group_name", value = previous_connect_group_name, new_value = group_name)
- else:
- global_container_stack.setMetaDataEntry("group_name", group_name)
- # Set the default value for "hidden", which is used when you have a group with multiple types of printers
- global_container_stack.setMetaDataEntry("hidden", False)
-
- if self._network_plugin:
- # Ensure that the connection states are refreshed.
- self._network_plugin.reCheckConnections()
-
- # Associates the currently active machine with the given printer device. The network connection information will be
- # stored into the metadata of the currently active machine.
- @pyqtSlot(QObject)
- def associateActiveMachineWithPrinterDevice(self, printer_device: Optional["PrinterOutputDevice"]) -> None:
- if not printer_device:
- return
-
- Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key)
-
- global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
- if not global_container_stack:
- return
-
- meta_data = global_container_stack.getMetaData()
-
- if "um_network_key" in meta_data: # Global stack already had a connection, but it's changed.
- old_network_key = meta_data["um_network_key"]
- # Since we might have a bunch of hidden stacks, we also need to change it there.
- metadata_filter = {"um_network_key": old_network_key}
- containers = CuraContainerRegistry.getInstance().findContainerStacks(type="machine", **metadata_filter)
-
- for container in containers:
- container.setMetaDataEntry("um_network_key", printer_device.key)
-
- # Delete old authentication data.
- Logger.log("d", "Removing old authentication id %s for device %s",
- global_container_stack.getMetaDataEntry("network_authentication_id", None), printer_device.key)
-
- container.removeMetaDataEntry("network_authentication_id")
- container.removeMetaDataEntry("network_authentication_key")
-
- # Ensure that these containers do know that they are configured for network connection
- container.addConfiguredConnectionType(printer_device.connectionType.value)
-
- else: # Global stack didn't have a connection yet, configure it.
- global_container_stack.setMetaDataEntry("um_network_key", printer_device.key)
- global_container_stack.addConfiguredConnectionType(printer_device.connectionType.value)
-
- if self._network_plugin:
- # Ensure that the connection states are refreshed.
- self._network_plugin.reCheckConnections()
-
- @pyqtSlot(result = str)
- def getStoredKey(self) -> str:
- global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
- if global_container_stack:
- meta_data = global_container_stack.getMetaData()
- if "um_network_key" in meta_data:
- return global_container_stack.getMetaDataEntry("um_network_key")
-
- return ""
-
- @pyqtSlot(result = str)
- def getLastManualEntryKey(self) -> str:
- if self._network_plugin:
- return self._network_plugin.getLastManualDevice()
- return ""
-
- @pyqtSlot(str, result = bool)
- def existsKey(self, key: str) -> bool:
- return CuraApplication.getInstance().getMachineManager().existNetworkInstances(network_key = key)
-
- @pyqtSlot()
- def loadConfigurationFromPrinter(self) -> None:
- machine_manager = CuraApplication.getInstance().getMachineManager()
- hotend_ids = machine_manager.printerOutputDevices[0].hotendIds
- for index in range(len(hotend_ids)):
- machine_manager.printerOutputDevices[0].hotendIdChanged.emit(index, hotend_ids[index])
- material_ids = machine_manager.printerOutputDevices[0].materialIds
- for index in range(len(material_ids)):
- machine_manager.printerOutputDevices[0].materialIdChanged.emit(index, material_ids[index])
-
- def _createAdditionalComponentsView(self) -> None:
- Logger.log("d", "Creating additional ui components for UM3.")
-
- # Create networking dialog
- plugin_path = PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting")
- if not plugin_path:
- return
- path = os.path.join(plugin_path, "resources/qml/UM3InfoComponents.qml")
- self.__additional_components_view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
- if not self.__additional_components_view:
- Logger.log("w", "Could not create ui components for UM3.")
- return
-
- # Create extra components
- CuraApplication.getInstance().addAdditionalComponent("monitorButtons", self.__additional_components_view.findChild(QObject, "networkPrinterConnectButton"))
diff --git a/plugins/UM3NetworkPrinting/src/ExportFileJob.py b/plugins/UM3NetworkPrinting/src/ExportFileJob.py
new file mode 100644
index 0000000000..56d15bc835
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/ExportFileJob.py
@@ -0,0 +1,39 @@
+from typing import List, Optional
+
+from UM.FileHandler.FileHandler import FileHandler
+from UM.FileHandler.WriteFileJob import WriteFileJob
+from UM.Logger import Logger
+from UM.Scene.SceneNode import SceneNode
+from cura.CuraApplication import CuraApplication
+
+from .MeshFormatHandler import MeshFormatHandler
+
+
+## Job that exports the build plate to the correct file format for the target cluster.
+class ExportFileJob(WriteFileJob):
+
+ def __init__(self, file_handler: Optional[FileHandler], nodes: List[SceneNode], firmware_version: str) -> None:
+
+ self._mesh_format_handler = MeshFormatHandler(file_handler, firmware_version)
+ if not self._mesh_format_handler.is_valid:
+ Logger.log("e", "Missing file or mesh writer!")
+ return
+
+ super().__init__(self._mesh_format_handler.writer, self._mesh_format_handler.createStream(), nodes,
+ self._mesh_format_handler.file_mode)
+
+ # Determine the filename.
+ job_name = CuraApplication.getInstance().getPrintInformation().jobName
+ extension = self._mesh_format_handler.preferred_format.get("extension", "")
+ self.setFileName("{}.{}".format(job_name, extension))
+
+ ## Get the mime type of the selected export file type.
+ def getMimeType(self) -> str:
+ return self._mesh_format_handler.mime_type
+
+ ## Get the job result as bytes as that is what we need to upload to the cluster.
+ def getOutput(self) -> bytes:
+ output = self.getStream().getvalue()
+ if isinstance(output, str):
+ output = output.encode("utf-8")
+ return output
diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py
deleted file mode 100644
index 3ce0460d6b..0000000000
--- a/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py
+++ /dev/null
@@ -1,639 +0,0 @@
-from typing import List, Optional
-
-from UM.FileHandler.FileHandler import FileHandler
-from UM.Scene.SceneNode import SceneNode
-from cura.CuraApplication import CuraApplication
-from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
-from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
-from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
-from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
-from cura.PrinterOutputDevice import ConnectionType
-
-from cura.Settings.ContainerManager import ContainerManager
-from cura.Settings.ExtruderManager import ExtruderManager
-
-from UM.Logger import Logger
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from UM.i18n import i18nCatalog
-from UM.Message import Message
-
-from PyQt5.QtNetwork import QNetworkRequest
-from PyQt5.QtCore import QTimer, QUrl
-from PyQt5.QtWidgets import QMessageBox
-
-from .LegacyUM3PrinterOutputController import LegacyUM3PrinterOutputController
-
-from time import time
-
-import json
-import os
-
-
-i18n_catalog = i18nCatalog("cura")
-
-
-## This is the output device for the "Legacy" API of the UM3. All firmware before 4.0.1 uses this API.
-# Everything after that firmware uses the ClusterUM3Output.
-# The Legacy output device can only have one printer (whereas the cluster can have 0 to n).
-#
-# Authentication is done in a number of steps;
-# 1. Request an id / key pair by sending the application & user name. (state = authRequested)
-# 2. Machine sends this back and will display an approve / deny message on screen. (state = AuthReceived)
-# 3. OutputDevice will poll if the button was pressed.
-# 4. At this point the machine either has the state Authenticated or AuthenticationDenied.
-# 5. As a final step, we verify the authentication, as this forces the QT manager to setup the authenticator.
-class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
- def __init__(self, device_id, address: str, properties, parent = None) -> None:
- super().__init__(device_id = device_id, address = address, properties = properties, connection_type = ConnectionType.NetworkConnection, parent = parent)
- self._api_prefix = "/api/v1/"
- self._number_of_extruders = 2
-
- self._authentication_id = None
- self._authentication_key = None
-
- self._authentication_counter = 0
- self._max_authentication_counter = 5 * 60 # Number of attempts before authentication timed out (5 min)
-
- self._authentication_timer = QTimer()
- self._authentication_timer.setInterval(1000) # TODO; Add preference for update interval
- self._authentication_timer.setSingleShot(False)
-
- self._authentication_timer.timeout.connect(self._onAuthenticationTimer)
-
- # The messages are created when connect is called the first time.
- # This ensures that the messages are only created for devices that actually want to connect.
- self._authentication_requested_message = None
- self._authentication_failed_message = None
- self._authentication_succeeded_message = None
- self._not_authenticated_message = None
-
- self.authenticationStateChanged.connect(self._onAuthenticationStateChanged)
-
- self.setPriority(3) # Make sure the output device gets selected above local file output
- self.setName(self._id)
- self.setShortDescription(i18n_catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print over network"))
- self.setDescription(i18n_catalog.i18nc("@properties:tooltip", "Print over network"))
-
- self.setIconName("print")
-
- self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorItem.qml")
-
- self._output_controller = LegacyUM3PrinterOutputController(self)
-
- def _onAuthenticationStateChanged(self):
- # We only accept commands if we are authenticated.
- self._setAcceptsCommands(self._authentication_state == AuthState.Authenticated)
-
- if self._authentication_state == AuthState.Authenticated:
- self.setConnectionText(i18n_catalog.i18nc("@info:status", "Connected over the network."))
- elif self._authentication_state == AuthState.AuthenticationRequested:
- self.setConnectionText(i18n_catalog.i18nc("@info:status",
- "Connected over the network. Please approve the access request on the printer."))
- elif self._authentication_state == AuthState.AuthenticationDenied:
- self.setConnectionText(i18n_catalog.i18nc("@info:status", "Connected over the network. No access to control the printer."))
-
-
- def _setupMessages(self):
- self._authentication_requested_message = Message(i18n_catalog.i18nc("@info:status",
- "Access to the printer requested. Please approve the request on the printer"),
- lifetime=0, dismissable=False, progress=0,
- title=i18n_catalog.i18nc("@info:title",
- "Authentication status"))
-
- self._authentication_failed_message = Message("", title=i18n_catalog.i18nc("@info:title", "Authentication Status"))
- self._authentication_failed_message.addAction("Retry", i18n_catalog.i18nc("@action:button", "Retry"), None,
- i18n_catalog.i18nc("@info:tooltip", "Re-send the access request"))
- self._authentication_failed_message.actionTriggered.connect(self._messageCallback)
- self._authentication_succeeded_message = Message(
- i18n_catalog.i18nc("@info:status", "Access to the printer accepted"),
- title=i18n_catalog.i18nc("@info:title", "Authentication Status"))
-
- self._not_authenticated_message = Message(
- i18n_catalog.i18nc("@info:status", "No access to print with this printer. Unable to send print job."),
- title=i18n_catalog.i18nc("@info:title", "Authentication Status"))
- self._not_authenticated_message.addAction("Request", i18n_catalog.i18nc("@action:button", "Request Access"),
- None, i18n_catalog.i18nc("@info:tooltip",
- "Send access request to the printer"))
- self._not_authenticated_message.actionTriggered.connect(self._messageCallback)
-
- def _messageCallback(self, message_id=None, action_id="Retry"):
- if action_id == "Request" or action_id == "Retry":
- if self._authentication_failed_message:
- self._authentication_failed_message.hide()
- if self._not_authenticated_message:
- self._not_authenticated_message.hide()
-
- self._requestAuthentication()
-
- def connect(self):
- super().connect()
- self._setupMessages()
- global_container = CuraApplication.getInstance().getGlobalContainerStack()
- if global_container:
- self._authentication_id = global_container.getMetaDataEntry("network_authentication_id", None)
- self._authentication_key = global_container.getMetaDataEntry("network_authentication_key", None)
-
- def close(self):
- super().close()
- if self._authentication_requested_message:
- self._authentication_requested_message.hide()
- if self._authentication_failed_message:
- self._authentication_failed_message.hide()
- if self._authentication_succeeded_message:
- self._authentication_succeeded_message.hide()
- self._sending_gcode = False
- self._compressing_gcode = False
- self._authentication_timer.stop()
-
- ## Send all material profiles to the printer.
- def _sendMaterialProfiles(self):
- Logger.log("i", "Sending material profiles to printer")
-
- # TODO: Might want to move this to a job...
- for container in ContainerRegistry.getInstance().findInstanceContainers(type="material"):
- try:
- xml_data = container.serialize()
- if xml_data == "" or xml_data is None:
- continue
-
- names = ContainerManager.getInstance().getLinkedMaterials(container.getId())
- if names:
- # There are other materials that share this GUID.
- if not container.isReadOnly():
- continue # If it's not readonly, it's created by user, so skip it.
-
- file_name = "none.xml"
-
- self.postForm("materials", "form-data; name=\"file\";filename=\"%s\"" % file_name, xml_data.encode(), on_finished=None)
-
- except NotImplementedError:
- # If the material container is not the most "generic" one it can't be serialized an will raise a
- # NotImplementedError. We can simply ignore these.
- pass
-
- def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None:
- if not self.activePrinter:
- # No active printer. Unable to write
- return
-
- if self.activePrinter.state not in ["idle", ""]:
- # Printer is not able to accept commands.
- return
-
- if self._authentication_state != AuthState.Authenticated:
- # Not authenticated, so unable to send job.
- return
-
- self.writeStarted.emit(self)
-
- gcode_dict = getattr(CuraApplication.getInstance().getController().getScene(), "gcode_dict", [])
- active_build_plate_id = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
- gcode_list = gcode_dict[active_build_plate_id]
-
- if not gcode_list:
- # Unable to find g-code. Nothing to send
- return
-
- self._gcode = gcode_list
-
- errors = self._checkForErrors()
- if errors:
- text = i18n_catalog.i18nc("@label", "Unable to start a new print job.")
- informative_text = i18n_catalog.i18nc("@label",
- "There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. "
- "Please resolve this issues before continuing.")
- detailed_text = ""
- for error in errors:
- detailed_text += error + "\n"
-
- CuraApplication.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Mismatched configuration"),
- text,
- informative_text,
- detailed_text,
- buttons=QMessageBox.Ok,
- icon=QMessageBox.Critical,
- callback = self._messageBoxCallback
- )
- return # Don't continue; Errors must block sending the job to the printer.
-
- # There might be multiple things wrong with the configuration. Check these before starting.
- warnings = self._checkForWarnings()
-
- if warnings:
- text = i18n_catalog.i18nc("@label", "Are you sure you wish to print with the selected configuration?")
- informative_text = i18n_catalog.i18nc("@label",
- "There is a mismatch between the configuration or calibration of the printer and Cura. "
- "For the best result, always slice for the PrintCores and materials that are inserted in your printer.")
- detailed_text = ""
- for warning in warnings:
- detailed_text += warning + "\n"
-
- CuraApplication.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Mismatched configuration"),
- text,
- informative_text,
- detailed_text,
- buttons=QMessageBox.Yes + QMessageBox.No,
- icon=QMessageBox.Question,
- callback=self._messageBoxCallback
- )
- return
-
- # No warnings or errors, so we're good to go.
- self._startPrint()
-
- # Notify the UI that a switch to the print monitor should happen
- CuraApplication.getInstance().getController().setActiveStage("MonitorStage")
-
- def _startPrint(self):
- Logger.log("i", "Sending print job to printer.")
- if self._sending_gcode:
- self._error_message = Message(
- i18n_catalog.i18nc("@info:status",
- "Sending new jobs (temporarily) blocked, still sending the previous print job."))
- self._error_message.show()
- return
-
- self._sending_gcode = True
-
- self._send_gcode_start = time()
- self._progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), 0, False, -1,
- i18n_catalog.i18nc("@info:title", "Sending Data"))
- self._progress_message.addAction("Abort", i18n_catalog.i18nc("@action:button", "Cancel"), None, "")
- self._progress_message.actionTriggered.connect(self._progressMessageActionTriggered)
- self._progress_message.show()
-
- compressed_gcode = self._compressGCode()
- if compressed_gcode is None:
- # Abort was called.
- return
-
- file_name = "%s.gcode.gz" % CuraApplication.getInstance().getPrintInformation().jobName
- self.postForm("print_job", "form-data; name=\"file\";filename=\"%s\"" % file_name, compressed_gcode,
- on_finished=self._onPostPrintJobFinished)
-
- return
-
- def _progressMessageActionTriggered(self, message_id=None, action_id=None):
- if action_id == "Abort":
- Logger.log("d", "User aborted sending print to remote.")
- self._progress_message.hide()
- self._compressing_gcode = False
- self._sending_gcode = False
- CuraApplication.getInstance().getController().setActiveStage("PrepareStage")
-
- def _onPostPrintJobFinished(self, reply):
- self._progress_message.hide()
- self._sending_gcode = False
-
- def _onUploadPrintJobProgress(self, bytes_sent, bytes_total):
- if bytes_total > 0:
- new_progress = bytes_sent / bytes_total * 100
- # Treat upload progress as response. Uploading can take more than 10 seconds, so if we don't, we can get
- # timeout responses if this happens.
- self._last_response_time = time()
- if new_progress > self._progress_message.getProgress():
- self._progress_message.show() # Ensure that the message is visible.
- self._progress_message.setProgress(bytes_sent / bytes_total * 100)
- else:
- self._progress_message.setProgress(0)
-
- self._progress_message.hide()
-
- def _messageBoxCallback(self, button):
- def delayedCallback():
- if button == QMessageBox.Yes:
- self._startPrint()
- else:
- CuraApplication.getInstance().getController().setActiveStage("PrepareStage")
- # For some unknown reason Cura on OSX will hang if we do the call back code
- # immediately without first returning and leaving QML's event system.
-
- QTimer.singleShot(100, delayedCallback)
-
- def _checkForErrors(self):
- errors = []
- print_information = CuraApplication.getInstance().getPrintInformation()
- if not print_information.materialLengths:
- Logger.log("w", "There is no material length information. Unable to check for errors.")
- return errors
-
- for index, extruder in enumerate(self.activePrinter.extruders):
- # Due to airflow issues, both slots must be loaded, regardless if they are actually used or not.
- if extruder.hotendID == "":
- # No Printcore loaded.
- errors.append(i18n_catalog.i18nc("@info:status", "No Printcore loaded in slot {slot_number}".format(slot_number=index + 1)))
-
- if index < len(print_information.materialLengths) and print_information.materialLengths[index] != 0:
- # The extruder is by this print.
- if extruder.activeMaterial is None:
- # No active material
- errors.append(i18n_catalog.i18nc("@info:status", "No material loaded in slot {slot_number}".format(slot_number=index + 1)))
- return errors
-
- def _checkForWarnings(self):
- warnings = []
- print_information = CuraApplication.getInstance().getPrintInformation()
-
- if not print_information.materialLengths:
- Logger.log("w", "There is no material length information. Unable to check for warnings.")
- return warnings
-
- extruder_manager = ExtruderManager.getInstance()
-
- for index, extruder in enumerate(self.activePrinter.extruders):
- if index < len(print_information.materialLengths) and print_information.materialLengths[index] != 0:
- # The extruder is by this print.
-
- # TODO: material length check
-
- # Check if the right Printcore is active.
- variant = extruder_manager.getExtruderStack(index).findContainer({"type": "variant"})
- if variant:
- if variant.getName() != extruder.hotendID:
- warnings.append(i18n_catalog.i18nc("@label", "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}".format(cura_printcore_name = variant.getName(), remote_printcore_name = extruder.hotendID, extruder_id = index + 1)))
- else:
- Logger.log("w", "Unable to find variant.")
-
- # Check if the right material is loaded.
- local_material = extruder_manager.getExtruderStack(index).findContainer({"type": "material"})
- if local_material:
- if extruder.activeMaterial.guid != local_material.getMetaDataEntry("GUID"):
- Logger.log("w", "Extruder %s has a different material (%s) as Cura (%s)", index + 1, extruder.activeMaterial.guid, local_material.getMetaDataEntry("GUID"))
- warnings.append(i18n_catalog.i18nc("@label", "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}").format(local_material.getName(), extruder.activeMaterial.name, index + 1))
- else:
- Logger.log("w", "Unable to find material.")
-
- return warnings
-
- def _update(self):
- if not super()._update():
- return
- if self._authentication_state == AuthState.NotAuthenticated:
- if self._authentication_id is None and self._authentication_key is None:
- # This machine doesn't have any authentication, so request it.
- self._requestAuthentication()
- elif self._authentication_id is not None and self._authentication_key is not None:
- # We have authentication info, but we haven't checked it out yet. Do so now.
- self._verifyAuthentication()
- elif self._authentication_state == AuthState.AuthenticationReceived:
- # We have an authentication, but it's not confirmed yet.
- self._checkAuthentication()
-
- # We don't need authentication for requesting info, so we can go right ahead with requesting this.
- self.get("printer", on_finished=self._onGetPrinterDataFinished)
- self.get("print_job", on_finished=self._onGetPrintJobFinished)
-
- def _resetAuthenticationRequestedMessage(self):
- if self._authentication_requested_message:
- self._authentication_requested_message.hide()
- self._authentication_timer.stop()
- self._authentication_counter = 0
-
- def _onAuthenticationTimer(self):
- self._authentication_counter += 1
- self._authentication_requested_message.setProgress(
- self._authentication_counter / self._max_authentication_counter * 100)
- if self._authentication_counter > self._max_authentication_counter:
- self._authentication_timer.stop()
- Logger.log("i", "Authentication timer ended. Setting authentication to denied for printer: %s" % self._id)
- self.setAuthenticationState(AuthState.AuthenticationDenied)
- self._resetAuthenticationRequestedMessage()
- self._authentication_failed_message.show()
-
- def _verifyAuthentication(self):
- Logger.log("d", "Attempting to verify authentication")
- # This will ensure that the "_onAuthenticationRequired" is triggered, which will setup the authenticator.
- self.get("auth/verify", on_finished=self._onVerifyAuthenticationCompleted)
-
- def _onVerifyAuthenticationCompleted(self, reply):
- status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
- if status_code == 401:
- # Something went wrong; We somehow tried to verify authentication without having one.
- Logger.log("d", "Attempted to verify auth without having one.")
- self._authentication_id = None
- self._authentication_key = None
- self.setAuthenticationState(AuthState.NotAuthenticated)
- elif status_code == 403 and self._authentication_state != AuthState.Authenticated:
- # If we were already authenticated, we probably got an older message back all of the sudden. Drop that.
- Logger.log("d",
- "While trying to verify the authentication state, we got a forbidden response. Our own auth state was %s. ",
- self._authentication_state)
- self.setAuthenticationState(AuthState.AuthenticationDenied)
- self._authentication_failed_message.show()
- elif status_code == 200:
- self.setAuthenticationState(AuthState.Authenticated)
-
- def _checkAuthentication(self):
- Logger.log("d", "Checking if authentication is correct for id %s and key %s", self._authentication_id, self._getSafeAuthKey())
- self.get("auth/check/" + str(self._authentication_id), on_finished=self._onCheckAuthenticationFinished)
-
- def _onCheckAuthenticationFinished(self, reply):
- if str(self._authentication_id) not in reply.url().toString():
- Logger.log("w", "Got an old id response.")
- # Got response for old authentication ID.
- return
- try:
- data = json.loads(bytes(reply.readAll()).decode("utf-8"))
- except json.decoder.JSONDecodeError:
- Logger.log("w", "Received an invalid authentication check from printer: Not valid JSON.")
- return
-
- if data.get("message", "") == "authorized":
- Logger.log("i", "Authentication was approved")
- self.setAuthenticationState(AuthState.Authenticated)
- self._saveAuthentication()
-
- # Double check that everything went well.
- self._verifyAuthentication()
-
- # Notify the user.
- self._resetAuthenticationRequestedMessage()
- self._authentication_succeeded_message.show()
- elif data.get("message", "") == "unauthorized":
- Logger.log("i", "Authentication was denied.")
- self.setAuthenticationState(AuthState.AuthenticationDenied)
- self._authentication_failed_message.show()
-
- def _saveAuthentication(self) -> None:
- global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
- if self._authentication_key is None:
- Logger.log("e", "Authentication key is None, nothing to save.")
- return
- if self._authentication_id is None:
- Logger.log("e", "Authentication id is None, nothing to save.")
- return
- if global_container_stack:
- global_container_stack.setMetaDataEntry("network_authentication_key", self._authentication_key)
-
- global_container_stack.setMetaDataEntry("network_authentication_id", self._authentication_id)
-
- # Force save so we are sure the data is not lost.
- CuraApplication.getInstance().saveStack(global_container_stack)
- Logger.log("i", "Authentication succeeded for id %s and key %s", self._authentication_id,
- self._getSafeAuthKey())
- else:
- Logger.log("e", "Unable to save authentication for id %s and key %s", self._authentication_id,
- self._getSafeAuthKey())
-
- def _onRequestAuthenticationFinished(self, reply):
- try:
- data = json.loads(bytes(reply.readAll()).decode("utf-8"))
- except json.decoder.JSONDecodeError:
- Logger.log("w", "Received an invalid authentication request reply from printer: Not valid JSON.")
- self.setAuthenticationState(AuthState.NotAuthenticated)
- return
-
- self.setAuthenticationState(AuthState.AuthenticationReceived)
- self._authentication_id = data["id"]
- self._authentication_key = data["key"]
- Logger.log("i", "Got a new authentication ID (%s) and KEY (%s). Waiting for authorization.",
- self._authentication_id, self._getSafeAuthKey())
-
- def _requestAuthentication(self):
- self._authentication_requested_message.show()
- self._authentication_timer.start()
-
- # Reset any previous authentication info. If this isn't done, the "Retry" action on the failed message might
- # give issues.
- self._authentication_key = None
- self._authentication_id = None
-
- self.post("auth/request",
- json.dumps({"application": "Cura-" + CuraApplication.getInstance().getVersion(),
- "user": self._getUserName()}),
- on_finished=self._onRequestAuthenticationFinished)
-
- self.setAuthenticationState(AuthState.AuthenticationRequested)
-
- def _onAuthenticationRequired(self, reply, authenticator):
- if self._authentication_id is not None and self._authentication_key is not None:
- Logger.log("d",
- "Authentication was required for printer: %s. Setting up authenticator with ID %s and key %s",
- self._id, self._authentication_id, self._getSafeAuthKey())
- authenticator.setUser(self._authentication_id)
- authenticator.setPassword(self._authentication_key)
- else:
- Logger.log("d", "No authentication is available to use for %s, but we did got a request for it.", self._id)
-
- def _onGetPrintJobFinished(self, reply):
- status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
-
- if not self._printers:
- return # Ignore the data for now, we don't have info about a printer yet.
- printer = self._printers[0]
-
- if status_code == 200:
- try:
- result = json.loads(bytes(reply.readAll()).decode("utf-8"))
- except json.decoder.JSONDecodeError:
- Logger.log("w", "Received an invalid print job state message: Not valid JSON.")
- return
- if printer.activePrintJob is None:
- print_job = PrintJobOutputModel(output_controller=self._output_controller)
- printer.updateActivePrintJob(print_job)
- else:
- print_job = printer.activePrintJob
- print_job.updateState(result["state"])
- print_job.updateTimeElapsed(result["time_elapsed"])
- print_job.updateTimeTotal(result["time_total"])
- print_job.updateName(result["name"])
- elif status_code == 404:
- # No job found, so delete the active print job (if any!)
- printer.updateActivePrintJob(None)
- else:
- Logger.log("w",
- "Got status code {status_code} while trying to get printer data".format(status_code=status_code))
-
- def materialHotendChangedMessage(self, callback):
- CuraApplication.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Sync with your printer"),
- i18n_catalog.i18nc("@label",
- "Would you like to use your current printer configuration in Cura?"),
- i18n_catalog.i18nc("@label",
- "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."),
- buttons=QMessageBox.Yes + QMessageBox.No,
- icon=QMessageBox.Question,
- callback=callback
- )
-
- def _onGetPrinterDataFinished(self, reply):
- status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
- if status_code == 200:
- try:
- result = json.loads(bytes(reply.readAll()).decode("utf-8"))
- except json.decoder.JSONDecodeError:
- Logger.log("w", "Received an invalid printer state message: Not valid JSON.")
- return
-
- if not self._printers:
- # Quickest way to get the firmware version is to grab it from the zeroconf.
- firmware_version = self._properties.get(b"firmware_version", b"").decode("utf-8")
- self._printers = [PrinterOutputModel(output_controller=self._output_controller, number_of_extruders=self._number_of_extruders, firmware_version=firmware_version)]
- self._printers[0].setCameraUrl(QUrl("http://" + self._address + ":8080/?action=stream"))
- for extruder in self._printers[0].extruders:
- extruder.activeMaterialChanged.connect(self.materialIdChanged)
- extruder.hotendIDChanged.connect(self.hotendIdChanged)
- self.printersChanged.emit()
-
- # LegacyUM3 always has a single printer.
- printer = self._printers[0]
- printer.updateBedTemperature(result["bed"]["temperature"]["current"])
- printer.updateTargetBedTemperature(result["bed"]["temperature"]["target"])
- printer.updateState(result["status"])
-
- try:
- # If we're still handling the request, we should ignore remote for a bit.
- if not printer.getController().isPreheatRequestInProgress():
- printer.updateIsPreheating(result["bed"]["pre_heat"]["active"])
- except KeyError:
- # Older firmwares don't support preheating, so we need to fake it.
- pass
-
- head_position = result["heads"][0]["position"]
- printer.updateHeadPosition(head_position["x"], head_position["y"], head_position["z"])
-
- for index in range(0, self._number_of_extruders):
- temperatures = result["heads"][0]["extruders"][index]["hotend"]["temperature"]
- extruder = printer.extruders[index]
- extruder.updateTargetHotendTemperature(temperatures["target"])
- extruder.updateHotendTemperature(temperatures["current"])
-
- material_guid = result["heads"][0]["extruders"][index]["active_material"]["guid"]
-
- if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_guid:
- # Find matching material (as we need to set brand, type & color)
- containers = ContainerRegistry.getInstance().findInstanceContainers(type="material",
- GUID=material_guid)
- if containers:
- color = containers[0].getMetaDataEntry("color_code")
- brand = containers[0].getMetaDataEntry("brand")
- material_type = containers[0].getMetaDataEntry("material")
- name = containers[0].getName()
- else:
- # Unknown material.
- color = "#00000000"
- brand = "Unknown"
- material_type = "Unknown"
- name = "Unknown"
- material = MaterialOutputModel(guid=material_guid, type=material_type,
- brand=brand, color=color, name = name)
- extruder.updateActiveMaterial(material)
-
- try:
- hotend_id = result["heads"][0]["extruders"][index]["hotend"]["id"]
- except KeyError:
- hotend_id = ""
- printer.extruders[index].updateHotendID(hotend_id)
-
- else:
- Logger.log("w",
- "Got status code {status_code} while trying to get printer data".format(status_code = status_code))
-
- ## Convenience function to "blur" out all but the last 5 characters of the auth key.
- # This can be used to debug print the key, without it compromising the security.
- def _getSafeAuthKey(self):
- if self._authentication_key is not None:
- result = self._authentication_key[-5:]
- result = "********" + result
- return result
-
- return self._authentication_key
diff --git a/plugins/UM3NetworkPrinting/src/LegacyUM3PrinterOutputController.py b/plugins/UM3NetworkPrinting/src/LegacyUM3PrinterOutputController.py
deleted file mode 100644
index 63167b4ffb..0000000000
--- a/plugins/UM3NetworkPrinting/src/LegacyUM3PrinterOutputController.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (c) 2019 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
-from PyQt5.QtCore import QTimer
-from UM.Version import Version
-
-MYPY = False
-if MYPY:
- from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
- from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
-
-
-class LegacyUM3PrinterOutputController(PrinterOutputController):
- def __init__(self, output_device):
- super().__init__(output_device)
- self._preheat_bed_timer = QTimer()
- self._preheat_bed_timer.setSingleShot(True)
- self._preheat_bed_timer.timeout.connect(self._onPreheatBedTimerFinished)
- self._preheat_printer = None
-
- self.can_control_manually = False
- self.can_send_raw_gcode = False
-
- # Are we still waiting for a response about preheat?
- # We need this so we can already update buttons, so it feels more snappy.
- self._preheat_request_in_progress = False
-
- def isPreheatRequestInProgress(self):
- return self._preheat_request_in_progress
-
- def setJobState(self, job: "PrintJobOutputModel", state: str):
- data = "{\"target\": \"%s\"}" % state
- self._output_device.put("print_job/state", data, on_finished=None)
-
- def setTargetBedTemperature(self, printer: "PrinterOutputModel", temperature: float):
- data = str(temperature)
- self._output_device.put("printer/bed/temperature/target", data, on_finished = self._onPutBedTemperatureCompleted)
-
- def _onPutBedTemperatureCompleted(self, reply):
- if Version(self._preheat_printer.firmwareVersion) < Version("3.5.92"):
- # If it was handling a preheat, it isn't anymore.
- self._preheat_request_in_progress = False
-
- def _onPutPreheatBedCompleted(self, reply):
- self._preheat_request_in_progress = False
-
- def moveHead(self, printer: "PrinterOutputModel", x, y, z, speed):
- head_pos = printer._head_position
- new_x = head_pos.x + x
- new_y = head_pos.y + y
- new_z = head_pos.z + z
- data = "{\n\"x\":%s,\n\"y\":%s,\n\"z\":%s\n}" %(new_x, new_y, new_z)
- self._output_device.put("printer/heads/0/position", data, on_finished=None)
-
- def homeBed(self, printer):
- self._output_device.put("printer/heads/0/position/z", "0", on_finished=None)
-
- def _onPreheatBedTimerFinished(self):
- self.setTargetBedTemperature(self._preheat_printer, 0)
- self._preheat_printer.updateIsPreheating(False)
- self._preheat_request_in_progress = True
-
- def cancelPreheatBed(self, printer: "PrinterOutputModel"):
- self.preheatBed(printer, temperature=0, duration=0)
- self._preheat_bed_timer.stop()
- printer.updateIsPreheating(False)
-
- def preheatBed(self, printer: "PrinterOutputModel", temperature, duration):
- try:
- temperature = round(temperature) # The API doesn't allow floating point.
- duration = round(duration)
- except ValueError:
- return # Got invalid values, can't pre-heat.
-
- if duration > 0:
- data = """{"temperature": "%i", "timeout": "%i"}""" % (temperature, duration)
- else:
- data = """{"temperature": "%i"}""" % temperature
-
- # Real bed pre-heating support is implemented from 3.5.92 and up.
-
- if Version(printer.firmwareVersion) < Version("3.5.92"):
- # No firmware-side duration support then, so just set target bed temp and set a timer.
- self.setTargetBedTemperature(printer, temperature=temperature)
- self._preheat_bed_timer.setInterval(duration * 1000)
- self._preheat_bed_timer.start()
- self._preheat_printer = printer
- printer.updateIsPreheating(True)
- return
-
- self._output_device.put("printer/bed/pre_heat", data, on_finished = self._onPutPreheatBedCompleted)
- printer.updateIsPreheating(True)
- self._preheat_request_in_progress = True
-
-
diff --git a/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py
index c3cd82a86d..9927bf744e 100644
--- a/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py
+++ b/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import io
from typing import Optional, Dict, Union, List, cast
@@ -32,7 +32,7 @@ class MeshFormatHandler:
# \return A dict with the file format details, with the following keys:
# {id: str, extension: str, description: str, mime_type: str, mode: int, hide_in_file_dialog: bool}
@property
- def preferred_format(self) -> Optional[Dict[str, Union[str, int, bool]]]:
+ def preferred_format(self) -> Dict[str, Union[str, int, bool]]:
return self._preferred_format
## Gets the file writer for the given file handler and mime type.
@@ -90,6 +90,7 @@ class MeshFormatHandler:
machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";")
machine_file_formats = [file_type.strip() for file_type in machine_file_formats]
+
# Exception for UM3 firmware version >=4.4: UFP is now supported and should be the preferred file format.
if "application/x-ufp" not in machine_file_formats and Version(firmware_version) >= Version("4.4"):
machine_file_formats = ["application/x-ufp"] + machine_file_formats
diff --git a/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py b/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py
new file mode 100644
index 0000000000..311356de8e
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py
@@ -0,0 +1,41 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+import os
+
+from PyQt5.QtCore import QUrl
+from PyQt5.QtGui import QDesktopServices
+
+from UM import i18nCatalog
+from UM.Message import Message
+from cura.CuraApplication import CuraApplication
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+class CloudFlowMessage(Message):
+
+ def __init__(self, address: str) -> None:
+
+ image_path = os.path.join(
+ CuraApplication.getInstance().getPluginRegistry().getPluginPath("UM3NetworkPrinting") or "",
+ "resources", "svg", "cloud-flow-start.svg"
+ )
+
+ super().__init__(
+ text=I18N_CATALOG.i18nc("@info:status",
+ "Send and monitor print jobs from anywhere using your Ultimaker account."),
+ lifetime=0,
+ dismissable=True,
+ option_state=False,
+ image_source=QUrl.fromLocalFile(image_path),
+ image_caption=I18N_CATALOG.i18nc("@info:status Ultimaker Cloud should not be translated.",
+ "Connect to Ultimaker Cloud"),
+ )
+ self._address = address
+ self.addAction("", I18N_CATALOG.i18nc("@action", "Get started"), "", "")
+ self.actionTriggered.connect(self._onCloudFlowStarted)
+
+ def _onCloudFlowStarted(self, messageId: str, actionId: str) -> None:
+ QDesktopServices.openUrl(QUrl("http://{}/cloud_connect".format(self._address)))
+ self.hide()
diff --git a/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py b/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py
new file mode 100644
index 0000000000..f4132dbcbc
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from UM import i18nCatalog
+from UM.Message import Message
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+## Message shown when trying to connect to a legacy printer device.
+class LegacyDeviceNoLongerSupportedMessage(Message):
+
+ # Singleton used to prevent duplicate messages of this type at the same time.
+ __is_visible = False
+
+ def __init__(self) -> None:
+ super().__init__(
+ text = I18N_CATALOG.i18nc("@info:status", "You are attempting to connect to a printer that is not "
+ "running Ultimaker Connect. Please update the printer to the "
+ "latest firmware."),
+ title = I18N_CATALOG.i18nc("@info:title", "Update your printer"),
+ lifetime = 10
+ )
+
+ def show(self) -> None:
+ if LegacyDeviceNoLongerSupportedMessage.__is_visible:
+ return
+ super().show()
+ LegacyDeviceNoLongerSupportedMessage.__is_visible = True
+
+ def hide(self, send_signal = True) -> None:
+ super().hide(send_signal)
+ LegacyDeviceNoLongerSupportedMessage.__is_visible = False
diff --git a/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py b/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py
new file mode 100644
index 0000000000..e021b2ae99
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py
@@ -0,0 +1,39 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import TYPE_CHECKING
+
+from UM import i18nCatalog
+from UM.Message import Message
+
+
+if TYPE_CHECKING:
+ from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOutputDevice
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+## Message shown when sending material files to cluster host.
+class MaterialSyncMessage(Message):
+
+ # Singleton used to prevent duplicate messages of this type at the same time.
+ __is_visible = False
+
+ def __init__(self, device: "UltimakerNetworkedPrinterOutputDevice") -> None:
+ super().__init__(
+ text = I18N_CATALOG.i18nc("@info:status", "Cura has detected material profiles that were not yet installed "
+ "on the host printer of group {0}.", device.name),
+ title = I18N_CATALOG.i18nc("@info:title", "Sending materials to printer"),
+ lifetime = 10,
+ dismissable = True
+ )
+
+ def show(self) -> None:
+ if MaterialSyncMessage.__is_visible:
+ return
+ super().show()
+ MaterialSyncMessage.__is_visible = True
+
+ def hide(self, send_signal = True) -> None:
+ super().hide(send_signal)
+ MaterialSyncMessage.__is_visible = False
diff --git a/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py b/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py
new file mode 100644
index 0000000000..77d7995fc7
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py
@@ -0,0 +1,50 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import TYPE_CHECKING
+
+from PyQt5.QtCore import QUrl
+from PyQt5.QtGui import QDesktopServices
+
+from UM import i18nCatalog
+from UM.Message import Message
+
+
+if TYPE_CHECKING:
+ from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOutputDevice
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+## Message shown when trying to connect to a printer that is not a host.
+class NotClusterHostMessage(Message):
+
+ # Singleton used to prevent duplicate messages of this type at the same time.
+ __is_visible = False
+
+ def __init__(self, device: "UltimakerNetworkedPrinterOutputDevice") -> None:
+ super().__init__(
+ text = I18N_CATALOG.i18nc("@info:status", "You are attempting to connect to {0} but it is not "
+ "the host of a group. You can visit the web page to configure "
+ "it as a group host.", device.name),
+ title = I18N_CATALOG.i18nc("@info:title", "Not a group host"),
+ lifetime = 0,
+ dismissable = True
+ )
+ self._address = device.address
+ self.addAction("", I18N_CATALOG.i18nc("@action", "Configure group"), "", "")
+ self.actionTriggered.connect(self._onConfigureClicked)
+
+ def show(self) -> None:
+ if NotClusterHostMessage.__is_visible:
+ return
+ super().show()
+ NotClusterHostMessage.__is_visible = True
+
+ def hide(self, send_signal = True) -> None:
+ super().hide(send_signal)
+ NotClusterHostMessage.__is_visible = False
+
+ def _onConfigureClicked(self, messageId: str, actionId: str) -> None:
+ QDesktopServices.openUrl(QUrl("http://{}/print_jobs".format(self._address)))
+ self.hide()
diff --git a/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py b/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py
new file mode 100644
index 0000000000..be00292559
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py
@@ -0,0 +1,18 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from UM import i18nCatalog
+from UM.Message import Message
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+## Message shown when uploading a print job to a cluster is blocked because another upload is already in progress.
+class PrintJobUploadBlockedMessage(Message):
+
+ def __init__(self) -> None:
+ super().__init__(
+ text = I18N_CATALOG.i18nc("@info:status", "Please wait until the current job has been sent."),
+ title = I18N_CATALOG.i18nc("@info:title", "Print error"),
+ lifetime = 10
+ )
diff --git a/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py b/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py
new file mode 100644
index 0000000000..bb26a84953
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py
@@ -0,0 +1,18 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from UM import i18nCatalog
+from UM.Message import Message
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+## Message shown when uploading a print job to a cluster failed.
+class PrintJobUploadErrorMessage(Message):
+
+ def __init__(self, message: str = None) -> None:
+ super().__init__(
+ text = message or I18N_CATALOG.i18nc("@info:text", "Could not upload the data to the printer."),
+ title = I18N_CATALOG.i18nc("@info:title", "Network error"),
+ lifetime = 10
+ )
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py b/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py
similarity index 82%
rename from plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py
rename to plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py
index d85f49c1a0..bdbab008e3 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/CloudProgressMessage.py
+++ b/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from UM import i18nCatalog
from UM.Message import Message
@@ -8,11 +8,11 @@ I18N_CATALOG = i18nCatalog("cura")
## Class responsible for showing a progress message while a mesh is being uploaded to the cloud.
-class CloudProgressMessage(Message):
+class PrintJobUploadProgressMessage(Message):
def __init__(self):
super().__init__(
- text = I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster"),
- title = I18N_CATALOG.i18nc("@info:status", "Sending data to remote cluster"),
+ title = I18N_CATALOG.i18nc("@info:status", "Sending Print Job"),
+ text = I18N_CATALOG.i18nc("@info:status", "Uploading print job to printer."),
progress = -1,
lifetime = 0,
dismissable = False,
diff --git a/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py b/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py
new file mode 100644
index 0000000000..c9be28d57f
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py
@@ -0,0 +1,18 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from UM import i18nCatalog
+from UM.Message import Message
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+## Message shown when uploading a print job to a cluster succeeded.
+class PrintJobUploadSuccessMessage(Message):
+
+ def __init__(self) -> None:
+ super().__init__(
+ text = I18N_CATALOG.i18nc("@info:status", "Print job was successfully sent to the printer."),
+ title = I18N_CATALOG.i18nc("@info:title", "Data Sent"),
+ lifetime = 5
+ )
diff --git a/plugins/UM3NetworkPrinting/src/Messages/__init__.py b/plugins/UM3NetworkPrinting/src/Messages/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/plugins/UM3NetworkPrinting/src/Models.py b/plugins/UM3NetworkPrinting/src/Models.py
deleted file mode 100644
index c5b9b16665..0000000000
--- a/plugins/UM3NetworkPrinting/src/Models.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-
-## Base model that maps kwargs to instance attributes.
-class BaseModel:
- def __init__(self, **kwargs) -> None:
- self.__dict__.update(kwargs)
- self.validate()
-
- # Validates the model, raising an exception if the model is invalid.
- def validate(self) -> None:
- pass
-
-
-## Class representing a material that was fetched from the cluster API.
-class ClusterMaterial(BaseModel):
- def __init__(self, guid: str, version: int, **kwargs) -> None:
- self.guid = guid # type: str
- self.version = version # type: int
- super().__init__(**kwargs)
-
- def validate(self) -> None:
- if not self.guid:
- raise ValueError("guid is required on ClusterMaterial")
- if not self.version:
- raise ValueError("version is required on ClusterMaterial")
-
-
-## Class representing a local material that was fetched from the container registry.
-class LocalMaterial(BaseModel):
- def __init__(self, GUID: str, id: str, version: int, **kwargs) -> None:
- self.GUID = GUID # type: str
- self.id = id # type: str
- self.version = version # type: int
- super().__init__(**kwargs)
-
- #
- def validate(self) -> None:
- super().validate()
- if not self.GUID:
- raise ValueError("guid is required on LocalMaterial")
- if not self.version:
- raise ValueError("version is required on LocalMaterial")
- if not self.id:
- raise ValueError("id is required on LocalMaterial")
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py b/plugins/UM3NetworkPrinting/src/Models/BaseModel.py
similarity index 81%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py
rename to plugins/UM3NetworkPrinting/src/Models/BaseModel.py
index 18a8cb5cba..3d38a4b116 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/BaseCloudModel.py
+++ b/plugins/UM3NetworkPrinting/src/Models/BaseModel.py
@@ -1,13 +1,23 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from datetime import datetime, timezone
-from typing import Dict, Union, TypeVar, Type, List, Any
-
-from ...Models import BaseModel
+from typing import TypeVar, Dict, List, Any, Type, Union
-## Base class for the models used in the interface with the Ultimaker cloud APIs.
-class BaseCloudModel(BaseModel):
+# Type variable used in the parse methods below, which should be a subclass of BaseModel.
+T = TypeVar("T", bound="BaseModel")
+
+
+class BaseModel:
+
+ def __init__(self, **kwargs) -> None:
+ self.__dict__.update(kwargs)
+ self.validate()
+
+ # Validates the model, raising an exception if the model is invalid.
+ def validate(self) -> None:
+ pass
+
## Checks whether the two models are equal.
# \param other: The other model.
# \return True if they are equal, False if they are different.
@@ -24,9 +34,6 @@ class BaseCloudModel(BaseModel):
def toDict(self) -> Dict[str, Any]:
return self.__dict__
- # Type variable used in the parse methods below, which should be a subclass of BaseModel.
- T = TypeVar("T", bound=BaseModel)
-
## Parses a single model.
# \param model_class: The model class.
# \param values: The value of the model, which is usually a dictionary, but may also be already parsed.
diff --git a/plugins/UM3NetworkPrinting/src/ConfigurationChangeModel.py b/plugins/UM3NetworkPrinting/src/Models/ConfigurationChangeModel.py
similarity index 63%
rename from plugins/UM3NetworkPrinting/src/ConfigurationChangeModel.py
rename to plugins/UM3NetworkPrinting/src/Models/ConfigurationChangeModel.py
index ef8a212b76..58fae03679 100644
--- a/plugins/UM3NetworkPrinting/src/ConfigurationChangeModel.py
+++ b/plugins/UM3NetworkPrinting/src/Models/ConfigurationChangeModel.py
@@ -1,13 +1,18 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+from PyQt5.QtCore import pyqtProperty, QObject
+
+
+BLOCKING_CHANGE_TYPES = [
+ "material_insert", "buildplate_change"
+]
-from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot
class ConfigurationChangeModel(QObject):
def __init__(self, type_of_change: str, index: int, target_name: str, origin_name: str) -> None:
super().__init__()
- self._type_of_change = type_of_change
- # enum = ["material", "print_core_change"]
+ self._type_of_change = type_of_change # enum = ["material", "print_core_change"]
+ self._can_override = self._type_of_change not in BLOCKING_CHANGE_TYPES
self._index = index
self._target_name = target_name
self._origin_name = origin_name
@@ -27,3 +32,7 @@ class ConfigurationChangeModel(QObject):
@pyqtProperty(str, constant = True)
def originName(self) -> str:
return self._origin_name
+
+ @pyqtProperty(bool, constant = True)
+ def canOverride(self) -> bool:
+ return self._can_override
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py b/plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterResponse.py
similarity index 67%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterResponse.py
index 9c0853e7c9..7ecfe8b0a3 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterResponse.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterResponse.py
@@ -1,13 +1,13 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional
-from .BaseCloudModel import BaseCloudModel
+from ..BaseModel import BaseModel
## Class representing a cloud connected cluster.
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterResponse(BaseCloudModel):
+class CloudClusterResponse(BaseModel):
+
## Creates a new cluster response object.
# \param cluster_id: The secret unique ID, e.g. 'kBEeZWEifXbrXviO8mRYLx45P8k5lHVGs43XKvRniPg='.
# \param host_guid: The unique identifier of the print cluster host, e.g. 'e90ae0ac-1257-4403-91ee-a44c9b7e8050'.
@@ -15,14 +15,21 @@ class CloudClusterResponse(BaseCloudModel):
# \param is_online: Whether this cluster is currently connected to the cloud.
# \param status: The status of the cluster authentication (active or inactive).
# \param host_version: The firmware version of the cluster host. This is where the Stardust client is running on.
+ # \param host_internal_ip: The internal IP address of the host printer.
+ # \param friendly_name: The human readable name of the host printer.
+ # \param printer_type: The machine type of the host printer.
def __init__(self, cluster_id: str, host_guid: str, host_name: str, is_online: bool, status: str,
- host_version: Optional[str] = None, **kwargs) -> None:
+ host_internal_ip: Optional[str] = None, host_version: Optional[str] = None,
+ friendly_name: Optional[str] = None, printer_type: str = "ultimaker3", **kwargs) -> None:
self.cluster_id = cluster_id
self.host_guid = host_guid
self.host_name = host_name
self.status = status
self.is_online = is_online
self.host_version = host_version
+ self.host_internal_ip = host_internal_ip
+ self.friendly_name = friendly_name
+ self.printer_type = printer_type
super().__init__(**kwargs)
# Validates the model, raising an exception if the model is invalid.
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py b/plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterStatus.py
similarity index 52%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterStatus.py
index b0250c2ebb..330e61d343 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterStatus.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/CloudClusterStatus.py
@@ -1,26 +1,26 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from datetime import datetime
from typing import List, Dict, Union, Any
-from .CloudClusterPrinterStatus import CloudClusterPrinterStatus
-from .CloudClusterPrintJobStatus import CloudClusterPrintJobStatus
-from .BaseCloudModel import BaseCloudModel
+from ..BaseModel import BaseModel
+from .ClusterPrinterStatus import ClusterPrinterStatus
+from .ClusterPrintJobStatus import ClusterPrintJobStatus
# Model that represents the status of the cluster for the cloud
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterStatus(BaseCloudModel):
+class CloudClusterStatus(BaseModel):
+
## Creates a new cluster status model object.
# \param printers: The latest status of each printer in the cluster.
# \param print_jobs: The latest status of each print job in the cluster.
# \param generated_time: The datetime when the object was generated on the server-side.
def __init__(self,
- printers: List[Union[CloudClusterPrinterStatus, Dict[str, Any]]],
- print_jobs: List[Union[CloudClusterPrintJobStatus, Dict[str, Any]]],
+ printers: List[Union[ClusterPrinterStatus, Dict[str, Any]]],
+ print_jobs: List[Union[ClusterPrintJobStatus, Dict[str, Any]]],
generated_time: Union[str, datetime],
**kwargs) -> None:
self.generated_time = self.parseDate(generated_time)
- self.printers = self.parseModels(CloudClusterPrinterStatus, printers)
- self.print_jobs = self.parseModels(CloudClusterPrintJobStatus, print_jobs)
+ self.printers = self.parseModels(ClusterPrinterStatus, printers)
+ self.print_jobs = self.parseModels(ClusterPrintJobStatus, print_jobs)
super().__init__(**kwargs)
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudError.py b/plugins/UM3NetworkPrinting/src/Models/Http/CloudError.py
similarity index 88%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudError.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/CloudError.py
index b53361022e..9381e4b8cf 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudError.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/CloudError.py
@@ -1,13 +1,13 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Dict, Optional, Any
-from .BaseCloudModel import BaseCloudModel
+from ..BaseModel import BaseModel
## Class representing errors generated by the cloud servers, according to the JSON-API standard.
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudError(BaseCloudModel):
+class CloudError(BaseModel):
+
## Creates a new error object.
# \param id: Unique identifier for this particular occurrence of the problem.
# \param title: A short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobResponse.py b/plugins/UM3NetworkPrinting/src/Models/Http/CloudPrintJobResponse.py
similarity index 88%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobResponse.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/CloudPrintJobResponse.py
index 79196ee38c..a1880e8751 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobResponse.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/CloudPrintJobResponse.py
@@ -1,13 +1,13 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional
-from .BaseCloudModel import BaseCloudModel
+from ..BaseModel import BaseModel
# Model that represents the response received from the cloud after requesting to upload a print job
-# Spec: https://api-staging.ultimaker.com/cura/v1/spec
-class CloudPrintJobResponse(BaseCloudModel):
+class CloudPrintJobResponse(BaseModel):
+
## Creates a new print job response model.
# \param job_id: The job unique ID, e.g. 'kBEeZWEifXbrXviO8mRYLx45P8k5lHVGs43XKvRniPg='.
# \param status: The status of the print job.
@@ -28,6 +28,5 @@ class CloudPrintJobResponse(BaseCloudModel):
self.upload_url = upload_url
self.content_type = content_type
self.status_description = status_description
- # TODO: Implement slicing details
self.slicing_details = slicing_details
super().__init__(**kwargs)
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobUploadRequest.py b/plugins/UM3NetworkPrinting/src/Models/Http/CloudPrintJobUploadRequest.py
similarity index 77%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobUploadRequest.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/CloudPrintJobUploadRequest.py
index e59c571558..ff705ae495 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintJobUploadRequest.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/CloudPrintJobUploadRequest.py
@@ -1,11 +1,11 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from .BaseCloudModel import BaseCloudModel
+from ..BaseModel import BaseModel
# Model that represents the request to upload a print job to the cloud
-# Spec: https://api-staging.ultimaker.com/cura/v1/spec
-class CloudPrintJobUploadRequest(BaseCloudModel):
+class CloudPrintJobUploadRequest(BaseModel):
+
## Creates a new print job upload request.
# \param job_name: The name of the print job.
# \param file_size: The size of the file in bytes.
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py b/plugins/UM3NetworkPrinting/src/Models/Http/CloudPrintResponse.py
similarity index 85%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/CloudPrintResponse.py
index 919d1b3c3a..b108f40e27 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudPrintResponse.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/CloudPrintResponse.py
@@ -1,14 +1,14 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from datetime import datetime
from typing import Optional, Union
-from .BaseCloudModel import BaseCloudModel
+from ..BaseModel import BaseModel
# Model that represents the responses received from the cloud after requesting a job to be printed.
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudPrintResponse(BaseCloudModel):
+class CloudPrintResponse(BaseModel):
+
## Creates a new print response object.
# \param job_id: The unique ID of a print job inside of the cluster. This ID is generated by Cura Connect.
# \param status: The status of the print request (queued or failed).
diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterBuildPlate.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterBuildPlate.py
new file mode 100644
index 0000000000..a5a392488d
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterBuildPlate.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from ..BaseModel import BaseModel
+
+
+## Class representing a cluster printer
+class ClusterBuildPlate(BaseModel):
+
+ ## Create a new build plate
+ # \param type: The type of build plate glass or aluminium
+ def __init__(self, type: str = "glass", **kwargs) -> None:
+ self.type = type
+ super().__init__(**kwargs)
diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterMaterial.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterMaterial.py
new file mode 100644
index 0000000000..afc0851211
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterMaterial.py
@@ -0,0 +1,16 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from ..BaseModel import BaseModel
+
+
+class ClusterMaterial(BaseModel):
+ def __init__(self, guid: str, version: int, **kwargs) -> None:
+ self.guid = guid # type: str
+ self.version = version # type: int
+ super().__init__(**kwargs)
+
+ def validate(self) -> None:
+ if not self.guid:
+ raise ValueError("guid is required on ClusterMaterial")
+ if not self.version:
+ raise ValueError("version is required on ClusterMaterial")
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintCoreConfiguration.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintCoreConfiguration.py
similarity index 72%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintCoreConfiguration.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintCoreConfiguration.py
index 7454401d09..e11d2be2d2 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintCoreConfiguration.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintCoreConfiguration.py
@@ -1,26 +1,28 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Union, Dict, Optional, Any
-from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
-from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel
-from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial
-from .BaseCloudModel import BaseCloudModel
+from cura.PrinterOutput.Models.ExtruderConfigurationModel import ExtruderConfigurationModel
+from cura.PrinterOutput.Models.ExtruderOutputModel import ExtruderOutputModel
+
+from .ClusterPrinterConfigurationMaterial import ClusterPrinterConfigurationMaterial
+from ..BaseModel import BaseModel
-## Class representing a cloud cluster printer configuration
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterPrintCoreConfiguration(BaseCloudModel):
+## Class representing a cloud cluster printer configuration
+# Also used for representing slots in a Material Station (as from Cura's perspective these are the same).
+class ClusterPrintCoreConfiguration(BaseModel):
+
## Creates a new cloud cluster printer configuration object
# \param extruder_index: The position of the extruder on the machine as list index. Numbered from left to right.
# \param material: The material of a configuration object in a cluster printer. May be in a dict or an object.
# \param nozzle_diameter: The diameter of the print core at this position in millimeters, e.g. '0.4'.
# \param print_core_id: The type of print core inserted at this position, e.g. 'AA 0.4'.
def __init__(self, extruder_index: int,
- material: Union[None, Dict[str, Any], CloudClusterPrinterConfigurationMaterial],
+ material: Union[None, Dict[str, Any], ClusterPrinterConfigurationMaterial] = None,
print_core_id: Optional[str] = None, **kwargs) -> None:
self.extruder_index = extruder_index
- self.material = self.parseModel(CloudClusterPrinterConfigurationMaterial, material) if material else None
+ self.material = self.parseModel(ClusterPrinterConfigurationMaterial, material) if material else None
self.print_core_id = print_core_id
super().__init__(**kwargs)
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobConfigurationChange.py
similarity index 84%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobConfigurationChange.py
index 9ff4154666..88251bbf53 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConfigurationChange.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobConfigurationChange.py
@@ -1,13 +1,13 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional
-from .BaseCloudModel import BaseCloudModel
+from ..BaseModel import BaseModel
## Model for the types of changes that are needed before a print job can start
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterPrintJobConfigurationChange(BaseCloudModel):
+class ClusterPrintJobConfigurationChange(BaseModel):
+
## Creates a new print job constraint.
# \param type_of_change: The type of configuration change, one of: "material", "print_core_change"
# \param index: The hotend slot or extruder index to change
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobConstraint.py
similarity index 75%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobConstraint.py
index 8236ec06b9..9239004b18 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobConstraint.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobConstraint.py
@@ -1,13 +1,13 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional
-from .BaseCloudModel import BaseCloudModel
+from ..BaseModel import BaseModel
## Class representing a cloud cluster print job constraint
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterPrintJobConstraints(BaseCloudModel):
+class ClusterPrintJobConstraints(BaseModel):
+
## Creates a new print job constraint.
# \param require_printer_name: Unique name of the printer that this job should be printed on.
# Should be one of the unique_name field values in the cluster, e.g. 'ultimakersystem-ccbdd30044ec'
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobImpediment.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobImpediment.py
similarity index 68%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobImpediment.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobImpediment.py
index 12b67996c1..5a8f0aa46d 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobImpediment.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobImpediment.py
@@ -1,13 +1,14 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from .BaseCloudModel import BaseCloudModel
+from ..BaseModel import BaseModel
## Class representing the reasons that prevent this job from being printed on the associated printer
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterPrintJobImpediment(BaseCloudModel):
+class ClusterPrintJobImpediment(BaseModel):
+
## Creates a new print job constraint.
- # \param translation_key: A string indicating a reason the print cannot be printed, such as 'does_not_fit_in_build_volume'
+ # \param translation_key: A string indicating a reason the print cannot be printed,
+ # such as 'does_not_fit_in_build_volume'
# \param severity: A number indicating the severity of the problem, with higher being more severe
def __init__(self, translation_key: str, severity: int, **kwargs) -> None:
self.translation_key = translation_key
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobStatus.py
similarity index 76%
rename from plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py
rename to plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobStatus.py
index 45b7d838a5..9794da1bbb 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/Models/CloudClusterPrintJobStatus.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobStatus.py
@@ -1,22 +1,23 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import List, Optional, Union, Dict, Any
-from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
-from ...UM3PrintJobOutputModel import UM3PrintJobOutputModel
-from ...ConfigurationChangeModel import ConfigurationChangeModel
-from ..CloudOutputController import CloudOutputController
-from .BaseCloudModel import BaseCloudModel
-from .CloudClusterBuildPlate import CloudClusterBuildPlate
-from .CloudClusterPrintJobConfigurationChange import CloudClusterPrintJobConfigurationChange
-from .CloudClusterPrintJobImpediment import CloudClusterPrintJobImpediment
-from .CloudClusterPrintCoreConfiguration import CloudClusterPrintCoreConfiguration
-from .CloudClusterPrintJobConstraint import CloudClusterPrintJobConstraints
+from cura.PrinterOutput.Models.PrinterConfigurationModel import PrinterConfigurationModel
+
+from .ClusterBuildPlate import ClusterBuildPlate
+from .ClusterPrintJobConfigurationChange import ClusterPrintJobConfigurationChange
+from .ClusterPrintJobImpediment import ClusterPrintJobImpediment
+from .ClusterPrintCoreConfiguration import ClusterPrintCoreConfiguration
+from .ClusterPrintJobConstraint import ClusterPrintJobConstraints
+from ..UM3PrintJobOutputModel import UM3PrintJobOutputModel
+from ..ConfigurationChangeModel import ConfigurationChangeModel
+from ..BaseModel import BaseModel
+from ...ClusterOutputController import ClusterOutputController
## Model for the status of a single print job in a cluster.
-# Spec: https://api-staging.ultimaker.com/connect/v1/spec
-class CloudClusterPrintJobStatus(BaseCloudModel):
+class ClusterPrintJobStatus(BaseModel):
+
## Creates a new cloud print job status model.
# \param assigned_to: The name of the printer this job is assigned to while being queued.
# \param configuration: The required print core configurations of this print job.
@@ -45,21 +46,21 @@ class CloudClusterPrintJobStatus(BaseCloudModel):
# printer
def __init__(self, created_at: str, force: bool, machine_variant: str, name: str, started: bool, status: str,
time_total: int, uuid: str,
- configuration: List[Union[Dict[str, Any], CloudClusterPrintCoreConfiguration]],
- constraints: List[Union[Dict[str, Any], CloudClusterPrintJobConstraints]],
+ configuration: List[Union[Dict[str, Any], ClusterPrintCoreConfiguration]],
+ constraints: List[Union[Dict[str, Any], ClusterPrintJobConstraints]],
last_seen: Optional[float] = None, network_error_count: Optional[int] = None,
owner: Optional[str] = None, printer_uuid: Optional[str] = None, time_elapsed: Optional[int] = None,
assigned_to: Optional[str] = None, deleted_at: Optional[str] = None,
printed_on_uuid: Optional[str] = None,
configuration_changes_required: List[
- Union[Dict[str, Any], CloudClusterPrintJobConfigurationChange]] = None,
- build_plate: Union[Dict[str, Any], CloudClusterBuildPlate] = None,
+ Union[Dict[str, Any], ClusterPrintJobConfigurationChange]] = None,
+ build_plate: Union[Dict[str, Any], ClusterBuildPlate] = None,
compatible_machine_families: List[str] = None,
- impediments_to_printing: List[Union[Dict[str, Any], CloudClusterPrintJobImpediment]] = None,
+ impediments_to_printing: List[Union[Dict[str, Any], ClusterPrintJobImpediment]] = None,
**kwargs) -> None:
self.assigned_to = assigned_to
- self.configuration = self.parseModels(CloudClusterPrintCoreConfiguration, configuration)
- self.constraints = self.parseModels(CloudClusterPrintJobConstraints, constraints)
+ self.configuration = self.parseModels(ClusterPrintCoreConfiguration, configuration)
+ self.constraints = self.parseModels(ClusterPrintJobConstraints, constraints)
self.created_at = created_at
self.force = force
self.last_seen = last_seen
@@ -76,29 +77,29 @@ class CloudClusterPrintJobStatus(BaseCloudModel):
self.deleted_at = deleted_at
self.printed_on_uuid = printed_on_uuid
- self.configuration_changes_required = self.parseModels(CloudClusterPrintJobConfigurationChange,
+ self.configuration_changes_required = self.parseModels(ClusterPrintJobConfigurationChange,
configuration_changes_required) \
if configuration_changes_required else []
- self.build_plate = self.parseModel(CloudClusterBuildPlate, build_plate) if build_plate else None
+ self.build_plate = self.parseModel(ClusterBuildPlate, build_plate) if build_plate else None
self.compatible_machine_families = compatible_machine_families if compatible_machine_families else []
- self.impediments_to_printing = self.parseModels(CloudClusterPrintJobImpediment, impediments_to_printing) \
+ self.impediments_to_printing = self.parseModels(ClusterPrintJobImpediment, impediments_to_printing) \
if impediments_to_printing else []
super().__init__(**kwargs)
## Creates an UM3 print job output model based on this cloud cluster print job.
# \param printer: The output model of the printer
- def createOutputModel(self, controller: CloudOutputController) -> UM3PrintJobOutputModel:
+ def createOutputModel(self, controller: ClusterOutputController) -> UM3PrintJobOutputModel:
model = UM3PrintJobOutputModel(controller, self.uuid, self.name)
self.updateOutputModel(model)
-
return model
## Creates a new configuration model
- def _createConfigurationModel(self) -> ConfigurationModel:
+ def _createConfigurationModel(self) -> PrinterConfigurationModel:
extruders = [extruder.createConfigurationModel() for extruder in self.configuration or ()]
- configuration = ConfigurationModel()
+ configuration = PrinterConfigurationModel()
configuration.setExtruderConfigurations(extruders)
+ configuration.setPrinterType(self.machine_variant)
return configuration
## Updates an UM3 print job output model based on this cloud cluster print job.
diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterConfigurationMaterial.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterConfigurationMaterial.py
new file mode 100644
index 0000000000..8edb9fb808
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterConfigurationMaterial.py
@@ -0,0 +1,51 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Optional
+
+from UM.Settings.ContainerRegistry import ContainerRegistry
+from cura.PrinterOutput.Models.MaterialOutputModel import MaterialOutputModel
+
+from ..BaseModel import BaseModel
+
+
+## Class representing a cloud cluster printer configuration
+class ClusterPrinterConfigurationMaterial(BaseModel):
+
+ ## Creates a new material configuration model.
+ # \param brand: The brand of material in this print core, e.g. 'Ultimaker'.
+ # \param color: The color of material in this print core, e.g. 'Blue'.
+ # \param guid: he GUID of the material in this print core, e.g. '506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9'.
+ # \param material: The type of material in this print core, e.g. 'PLA'.
+ def __init__(self, brand: Optional[str] = None, color: Optional[str] = None, guid: Optional[str] = None,
+ material: Optional[str] = None, **kwargs) -> None:
+ self.guid = guid
+ self.brand = brand
+ self.color = color
+ self.material = material
+ super().__init__(**kwargs)
+
+ ## Creates a material output model based on this cloud printer material.
+ #
+ # A material is chosen that matches the current GUID. If multiple such
+ # materials are available, read-only materials are preferred and the
+ # material with the earliest alphabetical name will be selected.
+ # \return A material output model that matches the current GUID.
+ def createOutputModel(self) -> MaterialOutputModel:
+ container_registry = ContainerRegistry.getInstance()
+ same_guid = container_registry.findInstanceContainersMetadata(GUID = self.guid)
+ if same_guid:
+ read_only = sorted(filter(lambda metadata: container_registry.isReadOnly(metadata["id"]), same_guid), key = lambda metadata: metadata["name"])
+ if read_only:
+ material_metadata = read_only[0]
+ else:
+ material_metadata = min(same_guid, key = lambda metadata: metadata["name"])
+ else:
+ material_metadata = {
+ "color_code": self.color,
+ "brand": self.brand,
+ "material": self.material,
+ "name": "Empty" if self.material == "empty" else "Unknown"
+ }
+
+ return MaterialOutputModel(guid = self.guid, type = material_metadata["material"], brand = material_metadata["brand"], color = material_metadata["color_code"], name = material_metadata["name"])
diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterMaterialStation.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterMaterialStation.py
new file mode 100644
index 0000000000..c51e07bcfc
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterMaterialStation.py
@@ -0,0 +1,23 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import Union, Dict, Any, List
+
+from ..BaseModel import BaseModel
+from .ClusterPrinterMaterialStationSlot import ClusterPrinterMaterialStationSlot
+
+
+## Class representing the data of a Material Station in the cluster.
+class ClusterPrinterMaterialStation(BaseModel):
+
+ ## Creates a new Material Station status.
+ # \param status: The status of the material station.
+ # \param: supported: Whether the material station is supported on this machine or not.
+ # \param material_slots: The active slots configurations of this material station.
+ def __init__(self, status: str, supported: bool = False,
+ material_slots: List[Union[ClusterPrinterMaterialStationSlot, Dict[str, Any]]] = None,
+ **kwargs) -> None:
+ self.status = status
+ self.supported = supported
+ self.material_slots = self.parseModels(ClusterPrinterMaterialStationSlot, material_slots)\
+ if material_slots else [] # type: List[ClusterPrinterMaterialStationSlot]
+ super().__init__(**kwargs)
diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterMaterialStationSlot.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterMaterialStationSlot.py
new file mode 100644
index 0000000000..80deb1c9a8
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterMaterialStationSlot.py
@@ -0,0 +1,22 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import Optional
+
+from .ClusterPrintCoreConfiguration import ClusterPrintCoreConfiguration
+
+
+## Class representing the data of a single slot in the material station.
+class ClusterPrinterMaterialStationSlot(ClusterPrintCoreConfiguration):
+
+ ## Create a new material station slot object.
+ # \param slot_index: The index of the slot in the material station (ranging 0 to 5).
+ # \param compatible: Whether the configuration is compatible with the print core.
+ # \param material_remaining: How much material is remaining on the spool (between 0 and 1, or -1 for missing data).
+ # \param material_empty: Whether the material spool is too empty to be used.
+ def __init__(self, slot_index: int, compatible: bool, material_remaining: float,
+ material_empty: Optional[bool] = False, **kwargs):
+ self.slot_index = slot_index
+ self.compatible = compatible
+ self.material_remaining = material_remaining
+ self.material_empty = material_empty
+ super().__init__(**kwargs)
diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterStatus.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterStatus.py
new file mode 100644
index 0000000000..2e0912f057
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterStatus.py
@@ -0,0 +1,147 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from itertools import product
+from typing import List, Union, Dict, Optional, Any
+
+from PyQt5.QtCore import QUrl
+
+from cura.PrinterOutput.Models.PrinterConfigurationModel import PrinterConfigurationModel
+from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
+from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
+
+from .ClusterBuildPlate import ClusterBuildPlate
+from .ClusterPrintCoreConfiguration import ClusterPrintCoreConfiguration
+from .ClusterPrinterMaterialStation import ClusterPrinterMaterialStation
+from .ClusterPrinterMaterialStationSlot import ClusterPrinterMaterialStationSlot
+from .ClusterPrinterConfigurationMaterial import ClusterPrinterConfigurationMaterial
+from ..BaseModel import BaseModel
+
+
+## Class representing a cluster printer
+class ClusterPrinterStatus(BaseModel):
+
+ ## Creates a new cluster printer status
+ # \param enabled: A printer can be disabled if it should not receive new jobs. By default every printer is enabled.
+ # \param firmware_version: Firmware version installed on the printer. Can differ for each printer in a cluster.
+ # \param friendly_name: Human readable name of the printer. Can be used for identification purposes.
+ # \param ip_address: The IP address of the printer in the local network.
+ # \param machine_variant: The type of printer. Can be 'Ultimaker 3' or 'Ultimaker 3ext'.
+ # \param status: The status of the printer.
+ # \param unique_name: The unique name of the printer in the network.
+ # \param uuid: The unique ID of the printer, also known as GUID.
+ # \param configuration: The active print core configurations of this printer.
+ # \param reserved_by: A printer can be claimed by a specific print job.
+ # \param maintenance_required: Indicates if maintenance is necessary.
+ # \param firmware_update_status: Whether the printer's firmware is up-to-date, value is one of: "up_to_date",
+ # "pending_update", "update_available", "update_in_progress", "update_failed", "update_impossible".
+ # \param latest_available_firmware: The version of the latest firmware that is available.
+ # \param build_plate: The build plate that is on the printer.
+ # \param material_station: The material station that is on the printer.
+ def __init__(self, enabled: bool, firmware_version: str, friendly_name: str, ip_address: str, machine_variant: str,
+ status: str, unique_name: str, uuid: str,
+ configuration: List[Union[Dict[str, Any], ClusterPrintCoreConfiguration]],
+ reserved_by: Optional[str] = None, maintenance_required: Optional[bool] = None,
+ firmware_update_status: Optional[str] = None, latest_available_firmware: Optional[str] = None,
+ build_plate: Union[Dict[str, Any], ClusterBuildPlate] = None,
+ material_station: Union[Dict[str, Any], ClusterPrinterMaterialStation] = None, **kwargs) -> None:
+
+ self.configuration = self.parseModels(ClusterPrintCoreConfiguration, configuration)
+ self.enabled = enabled
+ self.firmware_version = firmware_version
+ self.friendly_name = friendly_name
+ self.ip_address = ip_address
+ self.machine_variant = machine_variant
+ self.status = status
+ self.unique_name = unique_name
+ self.uuid = uuid
+ self.reserved_by = reserved_by
+ self.maintenance_required = maintenance_required
+ self.firmware_update_status = firmware_update_status
+ self.latest_available_firmware = latest_available_firmware
+ self.build_plate = self.parseModel(ClusterBuildPlate, build_plate) if build_plate else None
+ self.material_station = self.parseModel(ClusterPrinterMaterialStation,
+ material_station) if material_station else None
+ super().__init__(**kwargs)
+
+ ## Creates a new output model.
+ # \param controller - The controller of the model.
+ def createOutputModel(self, controller: PrinterOutputController) -> PrinterOutputModel:
+ # FIXME
+ # Note that we're using '2' here as extruder count. We have hardcoded this for now to prevent issues where the
+ # amount of extruders coming back from the API is actually lower (which it can be if a printer was just added
+ # to a cluster). This should be fixed in the future, probably also on the cluster API side.
+ model = PrinterOutputModel(controller, 2, firmware_version = self.firmware_version)
+ self.updateOutputModel(model)
+ return model
+
+ ## Updates the given output model.
+ # \param model - The output model to update.
+ def updateOutputModel(self, model: PrinterOutputModel) -> None:
+ model.updateKey(self.uuid)
+ model.updateName(self.friendly_name)
+ model.updateUniqueName(self.unique_name)
+ model.updateType(self.machine_variant)
+ model.updateState(self.status if self.enabled else "disabled")
+ model.updateBuildplate(self.build_plate.type if self.build_plate else "glass")
+ model.setCameraUrl(QUrl("http://{}:8080/?action=stream".format(self.ip_address)))
+
+ if not model.printerConfiguration:
+ # Prevent accessing printer configuration when not available.
+ # This sometimes happens when a printer was just added to a group and Cura is connected to that group.
+ return
+
+ # Set the possible configurations based on whether a Material Station is present or not.
+ if self.material_station and self.material_station.material_slots:
+ self._updateAvailableConfigurations(model)
+ if self.configuration:
+ self._updateActiveConfiguration(model)
+
+ def _updateActiveConfiguration(self, model: PrinterOutputModel) -> None:
+ configurations = zip(self.configuration, model.extruders, model.printerConfiguration.extruderConfigurations)
+ for configuration, extruder_output, extruder_config in configurations:
+ configuration.updateOutputModel(extruder_output)
+ configuration.updateConfigurationModel(extruder_config)
+
+ def _updateAvailableConfigurations(self, model: PrinterOutputModel) -> None:
+ available_configurations = [self._createAvailableConfigurationFromPrinterConfiguration(
+ left_slot = left_slot,
+ right_slot = right_slot,
+ printer_configuration = model.printerConfiguration
+ ) for left_slot, right_slot in product(self._getSlotsForExtruder(0), self._getSlotsForExtruder(1))]
+ model.setAvailableConfigurations(available_configurations)
+
+ ## Create a list of Material Station slots for the given extruder index.
+ # Returns a list with a single empty material slot if none are found to ensure we don't miss configurations.
+ def _getSlotsForExtruder(self, extruder_index: int) -> List[ClusterPrinterMaterialStationSlot]:
+ if not self.material_station: # typing guard
+ return []
+ slots = [slot for slot in self.material_station.material_slots if self._isSupportedConfiguration(
+ slot = slot,
+ extruder_index = extruder_index
+ )]
+ return slots or [self._createEmptyMaterialSlot(extruder_index)]
+
+ ## Check if a configuration is supported in order to make it selectable by the user.
+ # We filter out any slot that is not supported by the extruder index, print core type or if the material is empty.
+ @staticmethod
+ def _isSupportedConfiguration(slot: ClusterPrinterMaterialStationSlot, extruder_index: int) -> bool:
+ return slot.extruder_index == extruder_index and slot.compatible and not slot.material_empty
+
+ ## Create an empty material slot with a fake empty material.
+ @staticmethod
+ def _createEmptyMaterialSlot(extruder_index: int) -> ClusterPrinterMaterialStationSlot:
+ empty_material = ClusterPrinterConfigurationMaterial(guid = "", material = "empty", brand = "", color = "")
+ return ClusterPrinterMaterialStationSlot(slot_index = 0, extruder_index = extruder_index,
+ compatible = True, material_remaining = 0, material = empty_material)
+
+ @staticmethod
+ def _createAvailableConfigurationFromPrinterConfiguration(left_slot: ClusterPrinterMaterialStationSlot,
+ right_slot: ClusterPrinterMaterialStationSlot,
+ printer_configuration: PrinterConfigurationModel
+ ) -> PrinterConfigurationModel:
+ available_configuration = PrinterConfigurationModel()
+ available_configuration.setExtruderConfigurations([left_slot.createConfigurationModel(),
+ right_slot.createConfigurationModel()])
+ available_configuration.setPrinterType(printer_configuration.printerType)
+ available_configuration.setBuildplateConfiguration(printer_configuration.buildplateConfiguration)
+ return available_configuration
diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/PrinterSystemStatus.py b/plugins/UM3NetworkPrinting/src/Models/Http/PrinterSystemStatus.py
new file mode 100644
index 0000000000..ad7b9c8698
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/PrinterSystemStatus.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import Dict, Any
+
+from ..BaseModel import BaseModel
+
+
+## Class representing the system status of a printer.
+class PrinterSystemStatus(BaseModel):
+
+ def __init__(self, guid: str, firmware: str, hostname: str, name: str, platform: str, variant: str,
+ hardware: Dict[str, Any], **kwargs
+ ) -> None:
+ self.guid = guid
+ self.firmware = firmware
+ self.hostname = hostname
+ self.name = name
+ self.platform = platform
+ self.variant = variant
+ self.hardware = hardware
+ super().__init__(**kwargs)
diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/__init__.py b/plugins/UM3NetworkPrinting/src/Models/Http/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/plugins/UM3NetworkPrinting/src/Models/LocalMaterial.py b/plugins/UM3NetworkPrinting/src/Models/LocalMaterial.py
new file mode 100644
index 0000000000..b45289e1c4
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Models/LocalMaterial.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from .BaseModel import BaseModel
+
+
+class LocalMaterial(BaseModel):
+
+ def __init__(self, GUID: str, id: str, version: int, **kwargs) -> None:
+ self.GUID = GUID # type: str
+ self.id = id # type: str
+ self.version = version # type: int
+ super().__init__(**kwargs)
+
+ def validate(self) -> None:
+ super().validate()
+ if not self.GUID:
+ raise ValueError("guid is required on LocalMaterial")
+ if not self.version:
+ raise ValueError("version is required on LocalMaterial")
+ if not self.id:
+ raise ValueError("id is required on LocalMaterial")
diff --git a/plugins/UM3NetworkPrinting/src/UM3PrintJobOutputModel.py b/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py
similarity index 64%
rename from plugins/UM3NetworkPrinting/src/UM3PrintJobOutputModel.py
rename to plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py
index 4f44ca4af8..bfde233a35 100644
--- a/plugins/UM3NetworkPrinting/src/UM3PrintJobOutputModel.py
+++ b/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py
@@ -1,21 +1,22 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-
from typing import List
from PyQt5.QtCore import pyqtProperty, pyqtSignal
+from PyQt5.QtGui import QImage
-from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
+from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
+
from .ConfigurationChangeModel import ConfigurationChangeModel
class UM3PrintJobOutputModel(PrintJobOutputModel):
configurationChangesChanged = pyqtSignal()
- def __init__(self, output_controller: "PrinterOutputController", key: str = "", name: str = "", parent=None) -> None:
+ def __init__(self, output_controller: PrinterOutputController, key: str = "", name: str = "", parent=None) -> None:
super().__init__(output_controller, key, name, parent)
- self._configuration_changes = [] # type: List[ConfigurationChangeModel]
+ self._configuration_changes = [] # type: List[ConfigurationChangeModel]
@pyqtProperty("QVariantList", notify=configurationChangesChanged)
def configurationChanges(self) -> List[ConfigurationChangeModel]:
@@ -26,3 +27,8 @@ class UM3PrintJobOutputModel(PrintJobOutputModel):
return
self._configuration_changes = changes
self.configurationChangesChanged.emit()
+
+ def updatePreviewImageData(self, data: bytes) -> None:
+ image = QImage()
+ image.loadFromData(data)
+ self.updatePreviewImage(image)
diff --git a/plugins/UM3NetworkPrinting/src/Models/__init__.py b/plugins/UM3NetworkPrinting/src/Models/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/plugins/UM3NetworkPrinting/src/Network/ClusterApiClient.py b/plugins/UM3NetworkPrinting/src/Network/ClusterApiClient.py
new file mode 100644
index 0000000000..6a8b9f625c
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Network/ClusterApiClient.py
@@ -0,0 +1,173 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+import json
+from json import JSONDecodeError
+from typing import Callable, List, Optional, Dict, Union, Any, Type, cast, TypeVar, Tuple
+
+from PyQt5.QtCore import QUrl
+from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
+
+from UM.Logger import Logger
+
+from ..Models.BaseModel import BaseModel
+from ..Models.Http.ClusterPrintJobStatus import ClusterPrintJobStatus
+from ..Models.Http.ClusterPrinterStatus import ClusterPrinterStatus
+from ..Models.Http.PrinterSystemStatus import PrinterSystemStatus
+from ..Models.Http.ClusterMaterial import ClusterMaterial
+
+
+## The generic type variable used to document the methods below.
+ClusterApiClientModel = TypeVar("ClusterApiClientModel", bound=BaseModel)
+
+
+## The ClusterApiClient is responsible for all network calls to local network clusters.
+class ClusterApiClient:
+
+ PRINTER_API_PREFIX = "/api/v1"
+ CLUSTER_API_PREFIX = "/cluster-api/v1"
+
+ # In order to avoid garbage collection we keep the callbacks in this list.
+ _anti_gc_callbacks = [] # type: List[Callable[[], None]]
+
+ ## Initializes a new cluster API client.
+ # \param address: The network address of the cluster to call.
+ # \param on_error: The callback to be called whenever we receive errors from the server.
+ def __init__(self, address: str, on_error: Callable) -> None:
+ super().__init__()
+ self._manager = QNetworkAccessManager()
+ self._address = address
+ self._on_error = on_error
+
+ ## Get printer system information.
+ # \param on_finished: The callback in case the response is successful.
+ def getSystem(self, on_finished: Callable) -> None:
+ url = "{}/system".format(self.PRINTER_API_PREFIX)
+ reply = self._manager.get(self._createEmptyRequest(url))
+ self._addCallback(reply, on_finished, PrinterSystemStatus)
+
+ ## Get the installed materials on the printer.
+ # \param on_finished: The callback in case the response is successful.
+ def getMaterials(self, on_finished: Callable[[List[ClusterMaterial]], Any]) -> None:
+ url = "{}/materials".format(self.CLUSTER_API_PREFIX)
+ reply = self._manager.get(self._createEmptyRequest(url))
+ self._addCallback(reply, on_finished, ClusterMaterial)
+
+ ## Get the printers in the cluster.
+ # \param on_finished: The callback in case the response is successful.
+ def getPrinters(self, on_finished: Callable[[List[ClusterPrinterStatus]], Any]) -> None:
+ url = "{}/printers".format(self.CLUSTER_API_PREFIX)
+ reply = self._manager.get(self._createEmptyRequest(url))
+ self._addCallback(reply, on_finished, ClusterPrinterStatus)
+
+ ## Get the print jobs in the cluster.
+ # \param on_finished: The callback in case the response is successful.
+ def getPrintJobs(self, on_finished: Callable[[List[ClusterPrintJobStatus]], Any]) -> None:
+ url = "{}/print_jobs".format(self.CLUSTER_API_PREFIX)
+ reply = self._manager.get(self._createEmptyRequest(url))
+ self._addCallback(reply, on_finished, ClusterPrintJobStatus)
+
+ ## Move a print job to the top of the queue.
+ def movePrintJobToTop(self, print_job_uuid: str) -> None:
+ url = "{}/print_jobs/{}/action/move".format(self.CLUSTER_API_PREFIX, print_job_uuid)
+ self._manager.post(self._createEmptyRequest(url), json.dumps({"to_position": 0, "list": "queued"}).encode())
+
+ ## Override print job configuration and force it to be printed.
+ def forcePrintJob(self, print_job_uuid: str) -> None:
+ url = "{}/print_jobs/{}".format(self.CLUSTER_API_PREFIX, print_job_uuid)
+ self._manager.put(self._createEmptyRequest(url), json.dumps({"force": True}).encode())
+
+ ## Delete a print job from the queue.
+ def deletePrintJob(self, print_job_uuid: str) -> None:
+ url = "{}/print_jobs/{}".format(self.CLUSTER_API_PREFIX, print_job_uuid)
+ self._manager.deleteResource(self._createEmptyRequest(url))
+
+ ## Set the state of a print job.
+ def setPrintJobState(self, print_job_uuid: str, state: str) -> None:
+ url = "{}/print_jobs/{}/action".format(self.CLUSTER_API_PREFIX, print_job_uuid)
+ # We rewrite 'resume' to 'print' here because we are using the old print job action endpoints.
+ action = "print" if state == "resume" else state
+ self._manager.put(self._createEmptyRequest(url), json.dumps({"action": action}).encode())
+
+ ## Get the preview image data of a print job.
+ def getPrintJobPreviewImage(self, print_job_uuid: str, on_finished: Callable) -> None:
+ url = "{}/print_jobs/{}/preview_image".format(self.CLUSTER_API_PREFIX, print_job_uuid)
+ reply = self._manager.get(self._createEmptyRequest(url))
+ self._addCallback(reply, on_finished)
+
+ ## We override _createEmptyRequest in order to add the user credentials.
+ # \param url: The URL to request
+ # \param content_type: The type of the body contents.
+ def _createEmptyRequest(self, path: str, content_type: Optional[str] = "application/json") -> QNetworkRequest:
+ url = QUrl("http://" + self._address + path)
+ request = QNetworkRequest(url)
+ request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True)
+ if content_type:
+ request.setHeader(QNetworkRequest.ContentTypeHeader, content_type)
+ return request
+
+ ## Parses the given JSON network reply into a status code and a dictionary, handling unexpected errors as well.
+ # \param reply: The reply from the server.
+ # \return A tuple with a status code and a dictionary.
+ @staticmethod
+ def _parseReply(reply: QNetworkReply) -> Tuple[int, Dict[str, Any]]:
+ status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
+ try:
+ response = bytes(reply.readAll()).decode()
+ return status_code, json.loads(response)
+ except (UnicodeDecodeError, JSONDecodeError, ValueError) as err:
+ Logger.logException("e", "Could not parse the cluster response: %s", err)
+ return status_code, {"errors": [err]}
+
+ ## Parses the given models and calls the correct callback depending on the result.
+ # \param response: The response from the server, after being converted to a dict.
+ # \param on_finished: The callback in case the response is successful.
+ # \param model_class: The type of the model to convert the response to. It may either be a single record or a list.
+ def _parseModels(self, response: Dict[str, Any],
+ on_finished: Union[Callable[[ClusterApiClientModel], Any],
+ Callable[[List[ClusterApiClientModel]], Any]],
+ model_class: Type[ClusterApiClientModel]) -> None:
+ try:
+ if isinstance(response, list):
+ results = [model_class(**c) for c in response] # type: List[ClusterApiClientModel]
+ on_finished_list = cast(Callable[[List[ClusterApiClientModel]], Any], on_finished)
+ on_finished_list(results)
+ else:
+ result = model_class(**response) # type: ClusterApiClientModel
+ on_finished_item = cast(Callable[[ClusterApiClientModel], Any], on_finished)
+ on_finished_item(result)
+ except (JSONDecodeError, TypeError, ValueError):
+ Logger.log("e", "Could not parse response from network: %s", str(response))
+
+ ## Creates a callback function so that it includes the parsing of the response into the correct model.
+ # The callback is added to the 'finished' signal of the reply.
+ # \param reply: The reply that should be listened to.
+ # \param on_finished: The callback in case the response is successful.
+ def _addCallback(self,
+ reply: QNetworkReply,
+ on_finished: Union[Callable[[ClusterApiClientModel], Any],
+ Callable[[List[ClusterApiClientModel]], Any]],
+ model: Type[ClusterApiClientModel] = None,
+ ) -> None:
+
+ def parse() -> None:
+ self._anti_gc_callbacks.remove(parse)
+
+ # Don't try to parse the reply if we didn't get one
+ if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None:
+ return
+
+ if reply.error() > 0:
+ self._on_error(reply.errorString())
+ return
+
+ # If no parse model is given, simply return the raw data in the callback.
+ if not model:
+ on_finished(reply.readAll())
+ return
+
+ # Otherwise parse the result and return the formatted data in the callback.
+ status_code, response = self._parseReply(reply)
+ self._parseModels(response, on_finished, model)
+
+ self._anti_gc_callbacks.append(parse)
+ reply.finished.connect(parse)
diff --git a/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py
new file mode 100644
index 0000000000..1266afcca8
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py
@@ -0,0 +1,209 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+import os
+from typing import Optional, Dict, List, Callable, Any
+
+from PyQt5.QtGui import QDesktopServices
+from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject
+from PyQt5.QtNetwork import QNetworkReply
+
+from UM.FileHandler.FileHandler import FileHandler
+from UM.i18n import i18nCatalog
+from UM.Logger import Logger
+from UM.Scene.SceneNode import SceneNode
+from cura.CuraApplication import CuraApplication
+from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState
+from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
+
+from .ClusterApiClient import ClusterApiClient
+from .SendMaterialJob import SendMaterialJob
+from ..ExportFileJob import ExportFileJob
+from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOutputDevice
+from ..Messages.PrintJobUploadBlockedMessage import PrintJobUploadBlockedMessage
+from ..Messages.PrintJobUploadErrorMessage import PrintJobUploadErrorMessage
+from ..Messages.PrintJobUploadSuccessMessage import PrintJobUploadSuccessMessage
+from ..Models.Http.ClusterMaterial import ClusterMaterial
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+class LocalClusterOutputDevice(UltimakerNetworkedPrinterOutputDevice):
+
+ activeCameraUrlChanged = pyqtSignal()
+
+ def __init__(self, device_id: str, address: str, properties: Dict[bytes, bytes], parent=None) -> None:
+
+ super().__init__(
+ device_id=device_id,
+ address=address,
+ properties=properties,
+ connection_type=ConnectionType.NetworkConnection,
+ parent=parent
+ )
+
+ self._cluster_api = None # type: Optional[ClusterApiClient]
+ self._active_exported_job = None # type: Optional[ExportFileJob]
+ self._printer_select_dialog = None # type: Optional[QObject]
+
+ # We don't have authentication over local networking, so we're always authenticated.
+ self.setAuthenticationState(AuthState.Authenticated)
+ self._setInterfaceElements()
+ self._active_camera_url = QUrl() # type: QUrl
+
+ ## Set all the interface elements and texts for this output device.
+ def _setInterfaceElements(self) -> None:
+ self.setPriority(3) # Make sure the output device gets selected above local file output
+ self.setShortDescription(I18N_CATALOG.i18nc("@action:button Preceded by 'Ready to'.", "Print over network"))
+ self.setDescription(I18N_CATALOG.i18nc("@properties:tooltip", "Print over network"))
+ self.setConnectionText(I18N_CATALOG.i18nc("@info:status", "Connected over the network"))
+
+ ## Called when the connection to the cluster changes.
+ def connect(self) -> None:
+ super().connect()
+ self._update()
+ self.sendMaterialProfiles()
+
+ @pyqtProperty(QUrl, notify=activeCameraUrlChanged)
+ def activeCameraUrl(self) -> QUrl:
+ return self._active_camera_url
+
+ @pyqtSlot(QUrl, name="setActiveCameraUrl")
+ def setActiveCameraUrl(self, camera_url: QUrl) -> None:
+ if self._active_camera_url != camera_url:
+ self._active_camera_url = camera_url
+ self.activeCameraUrlChanged.emit()
+
+ @pyqtSlot(name="openPrintJobControlPanel")
+ def openPrintJobControlPanel(self) -> None:
+ QDesktopServices.openUrl(QUrl("http://" + self._address + "/print_jobs"))
+
+ @pyqtSlot(name="openPrinterControlPanel")
+ def openPrinterControlPanel(self) -> None:
+ QDesktopServices.openUrl(QUrl("http://" + self._address + "/printers"))
+
+ @pyqtSlot(str, name="sendJobToTop")
+ def sendJobToTop(self, print_job_uuid: str) -> None:
+ self._getApiClient().movePrintJobToTop(print_job_uuid)
+
+ @pyqtSlot(str, name="deleteJobFromQueue")
+ def deleteJobFromQueue(self, print_job_uuid: str) -> None:
+ self._getApiClient().deletePrintJob(print_job_uuid)
+
+ @pyqtSlot(str, name="forceSendJob")
+ def forceSendJob(self, print_job_uuid: str) -> None:
+ self._getApiClient().forcePrintJob(print_job_uuid)
+
+ ## Set the remote print job state.
+ # \param print_job_uuid: The UUID of the print job to set the state for.
+ # \param action: The action to undertake ('pause', 'resume', 'abort').
+ def setJobState(self, print_job_uuid: str, action: str) -> None:
+ self._getApiClient().setPrintJobState(print_job_uuid, action)
+
+ def _update(self) -> None:
+ super()._update()
+ self._getApiClient().getPrinters(self._updatePrinters)
+ self._getApiClient().getPrintJobs(self._updatePrintJobs)
+ self._updatePrintJobPreviewImages()
+
+ ## Get a list of materials that are installed on the cluster host.
+ def getMaterials(self, on_finished: Callable[[List[ClusterMaterial]], Any]) -> None:
+ self._getApiClient().getMaterials(on_finished = on_finished)
+
+ ## Sync the material profiles in Cura with the printer.
+ # This gets called when connecting to a printer as well as when sending a print.
+ def sendMaterialProfiles(self) -> None:
+ job = SendMaterialJob(device = self)
+ job.run()
+
+ ## Send a print job to the cluster.
+ def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False,
+ file_handler: Optional[FileHandler] = None, filter_by_machine: bool = False, **kwargs) -> None:
+
+ # Show an error message if we're already sending a job.
+ if self._progress.visible:
+ PrintJobUploadBlockedMessage().show()
+ return
+
+ self.writeStarted.emit(self)
+
+ # Export the scene to the correct file type.
+ job = ExportFileJob(file_handler=file_handler, nodes=nodes, firmware_version=self.firmwareVersion)
+ job.finished.connect(self._onPrintJobCreated)
+ job.start()
+
+ ## Allows the user to choose a printer to print with from the printer selection dialogue.
+ # \param unique_name: The unique name of the printer to target.
+ @pyqtSlot(str, name="selectTargetPrinter")
+ def selectTargetPrinter(self, unique_name: str = "") -> None:
+ self._startPrintJobUpload(unique_name if unique_name != "" else None)
+
+ ## Handler for when the print job was created locally.
+ # It can now be sent over the network.
+ def _onPrintJobCreated(self, job: ExportFileJob) -> None:
+ self._active_exported_job = job
+ # TODO: add preference to enable/disable this feature?
+ if self.clusterSize > 1:
+ self._showPrinterSelectionDialog() # self._startPrintJobUpload will be triggered from this dialog
+ return
+ self._startPrintJobUpload()
+
+ ## Shows a dialog allowing the user to select which printer in a group to send a job to.
+ def _showPrinterSelectionDialog(self) -> None:
+ if not self._printer_select_dialog:
+ plugin_path = CuraApplication.getInstance().getPluginRegistry().getPluginPath("UM3NetworkPrinting") or ""
+ path = os.path.join(plugin_path, "resources", "qml", "PrintWindow.qml")
+ self._printer_select_dialog = CuraApplication.getInstance().createQmlComponent(path, {"OutputDevice": self})
+ if self._printer_select_dialog is not None:
+ self._printer_select_dialog.show()
+
+ ## Upload the print job to the group.
+ def _startPrintJobUpload(self, unique_name: str = None) -> None:
+ if not self._active_exported_job:
+ Logger.log("e", "No active exported job to upload!")
+ return
+ self._progress.show()
+ parts = [
+ self._createFormPart("name=owner", bytes(self._getUserName(), "utf-8"), "text/plain"),
+ self._createFormPart("name=\"file\"; filename=\"%s\"" % self._active_exported_job.getFileName(),
+ self._active_exported_job.getOutput())
+ ]
+ # If a specific printer was selected we include the name in the request.
+ # FIXME: Connect should allow the printer UUID here instead of the 'unique_name'.
+ if unique_name is not None:
+ parts.append(self._createFormPart("name=require_printer_name", bytes(unique_name, "utf-8"), "text/plain"))
+ # FIXME: move form posting to API client
+ self.postFormWithParts("/cluster-api/v1/print_jobs/", parts, on_finished=self._onPrintUploadCompleted,
+ on_progress=self._onPrintJobUploadProgress)
+ self._active_exported_job = None
+
+ ## Handler for print job upload progress.
+ def _onPrintJobUploadProgress(self, bytes_sent: int, bytes_total: int) -> None:
+ percentage = (bytes_sent / bytes_total) if bytes_total else 0
+ self._progress.setProgress(percentage * 100)
+ self.writeProgress.emit()
+
+ ## Handler for when the print job was fully uploaded to the cluster.
+ def _onPrintUploadCompleted(self, _: QNetworkReply) -> None:
+ self._progress.hide()
+ PrintJobUploadSuccessMessage().show()
+ self.writeFinished.emit()
+
+ ## Displays the given message if uploading the mesh has failed
+ # \param message: The message to display.
+ def _onUploadError(self, message: str = None) -> None:
+ self._progress.hide()
+ PrintJobUploadErrorMessage(message).show()
+ self.writeError.emit()
+
+ ## Download all the images from the cluster and load their data in the print job models.
+ def _updatePrintJobPreviewImages(self):
+ for print_job in self._print_jobs:
+ if print_job.getPreviewImage() is None:
+ self._getApiClient().getPrintJobPreviewImage(print_job.key, print_job.updatePreviewImageData)
+
+ ## Get the API client instance.
+ def _getApiClient(self) -> ClusterApiClient:
+ if not self._cluster_api:
+ self._cluster_api = ClusterApiClient(self.address, on_error = lambda error: Logger.log("e", str(error)))
+ return self._cluster_api
diff --git a/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDeviceManager.py
new file mode 100644
index 0000000000..273c64ef4d
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDeviceManager.py
@@ -0,0 +1,274 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Dict, Optional, Callable, List
+
+from UM import i18nCatalog
+from UM.Logger import Logger
+from UM.Signal import Signal
+from UM.Version import Version
+
+from cura.CuraApplication import CuraApplication
+from cura.Settings.CuraStackBuilder import CuraStackBuilder
+from cura.Settings.GlobalStack import GlobalStack
+
+from .ZeroConfClient import ZeroConfClient
+from .ClusterApiClient import ClusterApiClient
+from .LocalClusterOutputDevice import LocalClusterOutputDevice
+from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOutputDevice
+from ..Messages.CloudFlowMessage import CloudFlowMessage
+from ..Messages.LegacyDeviceNoLongerSupportedMessage import LegacyDeviceNoLongerSupportedMessage
+from ..Models.Http.PrinterSystemStatus import PrinterSystemStatus
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+## The LocalClusterOutputDeviceManager is responsible for discovering and managing local networked clusters.
+class LocalClusterOutputDeviceManager:
+
+ META_NETWORK_KEY = "um_network_key"
+
+ MANUAL_DEVICES_PREFERENCE_KEY = "um3networkprinting/manual_instances"
+ MIN_SUPPORTED_CLUSTER_VERSION = Version("4.0.0")
+
+ # The translation catalog for this device.
+ I18N_CATALOG = i18nCatalog("cura")
+
+ # Signal emitted when the list of discovered devices changed.
+ discoveredDevicesChanged = Signal()
+
+ def __init__(self) -> None:
+
+ # Persistent dict containing the networked clusters.
+ self._discovered_devices = {} # type: Dict[str, LocalClusterOutputDevice]
+ self._output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
+
+ # Hook up ZeroConf client.
+ self._zero_conf_client = ZeroConfClient()
+ self._zero_conf_client.addedNetworkCluster.connect(self._onDeviceDiscovered)
+ self._zero_conf_client.removedNetworkCluster.connect(self._onDiscoveredDeviceRemoved)
+
+ ## Start the network discovery.
+ def start(self) -> None:
+ self._zero_conf_client.start()
+ for address in self._getStoredManualAddresses():
+ self.addManualDevice(address)
+
+ ## Stop network discovery and clean up discovered devices.
+ def stop(self) -> None:
+ self._zero_conf_client.stop()
+ for instance_name in list(self._discovered_devices):
+ self._onDiscoveredDeviceRemoved(instance_name)
+
+ ## Restart discovery on the local network.
+ def startDiscovery(self):
+ self.stop()
+ self.start()
+
+ ## Add a networked printer manually by address.
+ def addManualDevice(self, address: str, callback: Optional[Callable[[bool, str], None]] = None) -> None:
+ api_client = ClusterApiClient(address, lambda error: Logger.log("e", str(error)))
+ api_client.getSystem(lambda status: self._onCheckManualDeviceResponse(address, status, callback))
+
+ ## Remove a manually added networked printer.
+ def removeManualDevice(self, device_id: str, address: Optional[str] = None) -> None:
+ if device_id not in self._discovered_devices and address is not None:
+ device_id = "manual:{}".format(address)
+
+ if device_id in self._discovered_devices:
+ address = address or self._discovered_devices[device_id].ipAddress
+ self._onDiscoveredDeviceRemoved(device_id)
+
+ if address in self._getStoredManualAddresses():
+ self._removeStoredManualAddress(address)
+
+ ## Force reset all network device connections.
+ def refreshConnections(self) -> None:
+ self._connectToActiveMachine()
+
+ ## Get the discovered devices.
+ def getDiscoveredDevices(self) -> Dict[str, LocalClusterOutputDevice]:
+ return self._discovered_devices
+
+ ## Connect the active machine to a given device.
+ def associateActiveMachineWithPrinterDevice(self, device: LocalClusterOutputDevice) -> None:
+ active_machine = CuraApplication.getInstance().getGlobalContainerStack()
+ if not active_machine:
+ return
+ self._connectToOutputDevice(device, active_machine)
+ self._connectToActiveMachine()
+
+ # Pre-select the correct machine type of the group host.
+ # We first need to find the correct definition because the machine manager only takes name as input, not ID.
+ definitions = CuraApplication.getInstance().getContainerRegistry().findContainers(id = device.printerType)
+ if not definitions:
+ return
+ CuraApplication.getInstance().getMachineManager().switchPrinterType(definitions[0].getName())
+
+ ## Callback for when the active machine was changed by the user or a new remote cluster was found.
+ def _connectToActiveMachine(self) -> None:
+ active_machine = CuraApplication.getInstance().getGlobalContainerStack()
+ if not active_machine:
+ return
+
+ output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
+ stored_device_id = active_machine.getMetaDataEntry(self.META_NETWORK_KEY)
+ for device in self._discovered_devices.values():
+ if device.key == stored_device_id:
+ # Connect to it if the stored key matches.
+ self._connectToOutputDevice(device, active_machine)
+ elif device.key in output_device_manager.getOutputDeviceIds():
+ # Remove device if it is not meant for the active machine.
+ output_device_manager.removeOutputDevice(device.key)
+
+ ## Callback for when a manual device check request was responded to.
+ def _onCheckManualDeviceResponse(self, address: str, status: PrinterSystemStatus,
+ callback: Optional[Callable[[bool, str], None]] = None) -> None:
+ self._onDeviceDiscovered("manual:{}".format(address), address, {
+ b"name": status.name.encode("utf-8"),
+ b"address": address.encode("utf-8"),
+ b"machine": str(status.hardware.get("typeid", "")).encode("utf-8"),
+ b"manual": b"true",
+ b"firmware_version": status.firmware.encode("utf-8"),
+ b"cluster_size": b"1"
+ })
+ self._storeManualAddress(address)
+ if callback is not None:
+ CuraApplication.getInstance().callLater(callback, True, address)
+
+ ## Returns a dict of printer BOM numbers to machine types.
+ # These numbers are available in the machine definition already so we just search for them here.
+ @staticmethod
+ def _getPrinterTypeIdentifiers() -> Dict[str, str]:
+ container_registry = CuraApplication.getInstance().getContainerRegistry()
+ ultimaker_machines = container_registry.findContainersMetadata(type="machine", manufacturer="Ultimaker B.V.")
+ found_machine_type_identifiers = {} # type: Dict[str, str]
+ for machine in ultimaker_machines:
+ machine_type = machine.get("id", None)
+ machine_bom_numbers = machine.get("bom_numbers", [])
+ if machine_type and machine_bom_numbers:
+ for bom_number in machine_bom_numbers:
+ # This produces a n:1 mapping of bom numbers to machine types
+ # allowing the S5R1 and S5R2 hardware to use a single S5 definition.
+ found_machine_type_identifiers[str(bom_number)] = machine_type
+ return found_machine_type_identifiers
+
+ ## Add a new device.
+ def _onDeviceDiscovered(self, key: str, address: str, properties: Dict[bytes, bytes]) -> None:
+ machine_identifier = properties.get(b"machine", b"").decode("utf-8")
+ printer_type_identifiers = self._getPrinterTypeIdentifiers()
+
+ # Detect the machine type based on the BOM number that is sent over the network.
+ properties[b"printer_type"] = b"Unknown"
+ for bom, p_type in printer_type_identifiers.items():
+ if machine_identifier.startswith(bom):
+ properties[b"printer_type"] = bytes(p_type, encoding="utf8")
+ break
+
+ device = LocalClusterOutputDevice(key, address, properties)
+ discovered_printers_model = CuraApplication.getInstance().getDiscoveredPrintersModel()
+ if address in list(discovered_printers_model.discoveredPrintersByAddress.keys()):
+ # The printer was already added, we just update the available data.
+ discovered_printers_model.updateDiscoveredPrinter(
+ ip_address=address,
+ name=device.getName(),
+ machine_type=device.printerType
+ )
+ else:
+ # The printer was not added yet so let's do that.
+ discovered_printers_model.addDiscoveredPrinter(
+ ip_address=address,
+ key=device.getId(),
+ name=device.getName(),
+ create_callback=self._createMachineFromDiscoveredDevice,
+ machine_type=device.printerType,
+ device=device
+ )
+ self._discovered_devices[device.getId()] = device
+ self.discoveredDevicesChanged.emit()
+ self._connectToActiveMachine()
+
+ ## Remove a device.
+ def _onDiscoveredDeviceRemoved(self, device_id: str) -> None:
+ device = self._discovered_devices.pop(device_id, None) # type: Optional[LocalClusterOutputDevice]
+ if not device:
+ return
+ device.close()
+ CuraApplication.getInstance().getDiscoveredPrintersModel().removeDiscoveredPrinter(device.address)
+ self.discoveredDevicesChanged.emit()
+
+ ## Create a machine instance based on the discovered network printer.
+ def _createMachineFromDiscoveredDevice(self, device_id: str) -> None:
+ device = self._discovered_devices.get(device_id)
+ if device is None:
+ return
+
+ # Create a new machine and activate it.
+ # We do not use use MachineManager.addMachine here because we need to set the network key before activating it.
+ # If we do not do this the auto-pairing with the cloud-equivalent device will not work.
+ new_machine = CuraStackBuilder.createMachine(device.name, device.printerType)
+ if not new_machine:
+ Logger.log("e", "Failed creating a new machine")
+ return
+ new_machine.setMetaDataEntry(self.META_NETWORK_KEY, device.key)
+ CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId())
+ self._connectToOutputDevice(device, new_machine)
+ self._showCloudFlowMessage(device)
+
+ ## Add an address to the stored preferences.
+ def _storeManualAddress(self, address: str) -> None:
+ stored_addresses = self._getStoredManualAddresses()
+ if address in stored_addresses:
+ return # Prevent duplicates.
+ stored_addresses.append(address)
+ new_value = ",".join(stored_addresses)
+ CuraApplication.getInstance().getPreferences().setValue(self.MANUAL_DEVICES_PREFERENCE_KEY, new_value)
+
+ ## Remove an address from the stored preferences.
+ def _removeStoredManualAddress(self, address: str) -> None:
+ stored_addresses = self._getStoredManualAddresses()
+ try:
+ stored_addresses.remove(address) # Can throw a ValueError
+ new_value = ",".join(stored_addresses)
+ CuraApplication.getInstance().getPreferences().setValue(self.MANUAL_DEVICES_PREFERENCE_KEY, new_value)
+ except ValueError:
+ Logger.log("w", "Could not remove address from stored_addresses, it was not there")
+
+ ## Load the user-configured manual devices from Cura preferences.
+ def _getStoredManualAddresses(self) -> List[str]:
+ preferences = CuraApplication.getInstance().getPreferences()
+ preferences.addPreference(self.MANUAL_DEVICES_PREFERENCE_KEY, "")
+ manual_instances = preferences.getValue(self.MANUAL_DEVICES_PREFERENCE_KEY).split(",")
+ return manual_instances
+
+ ## Add a device to the current active machine.
+ def _connectToOutputDevice(self, device: UltimakerNetworkedPrinterOutputDevice, machine: GlobalStack) -> None:
+
+ # Make sure users know that we no longer support legacy devices.
+ if Version(device.firmwareVersion) < self.MIN_SUPPORTED_CLUSTER_VERSION:
+ LegacyDeviceNoLongerSupportedMessage().show()
+ return
+
+ machine.setName(device.name)
+ machine.setMetaDataEntry(self.META_NETWORK_KEY, device.key)
+ machine.setMetaDataEntry("group_name", device.name)
+ machine.addConfiguredConnectionType(device.connectionType.value)
+
+ if not device.isConnected():
+ device.connect()
+
+ output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
+ if device.key not in output_device_manager.getOutputDeviceIds():
+ output_device_manager.addOutputDevice(device)
+
+ ## Nudge the user to start using Ultimaker Cloud.
+ @staticmethod
+ def _showCloudFlowMessage(device: LocalClusterOutputDevice) -> None:
+ if CuraApplication.getInstance().getMachineManager().activeMachineIsUsingCloudConnection:
+ # This printer is already cloud connected, so we do not bother the user anymore.
+ return
+ if not CuraApplication.getInstance().getCuraAPI().account.isLoggedIn:
+ # Do not show the message if the user is not signed in.
+ return
+ CloudFlowMessage(device.ipAddress).show()
diff --git a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py
similarity index 59%
rename from plugins/UM3NetworkPrinting/src/SendMaterialJob.py
rename to plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py
index f0fde818c4..09949ed37e 100644
--- a/plugins/UM3NetworkPrinting/src/SendMaterialJob.py
+++ b/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py
@@ -1,20 +1,20 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-
-import json
import os
-from typing import Dict, TYPE_CHECKING, Set, Optional
+from typing import Dict, TYPE_CHECKING, Set, List
from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
from UM.Job import Job
from UM.Logger import Logger
+from UM.Settings import ContainerRegistry
from cura.CuraApplication import CuraApplication
-# Absolute imports don't work in plugins
-from .Models import ClusterMaterial, LocalMaterial
+from ..Models.Http.ClusterMaterial import ClusterMaterial
+from ..Models.LocalMaterial import LocalMaterial
+from ..Messages.MaterialSyncMessage import MaterialSyncMessage
if TYPE_CHECKING:
- from .ClusterUM3OutputDevice import ClusterUM3OutputDevice
+ from .LocalClusterOutputDevice import LocalClusterOutputDevice
## Asynchronous job to send material profiles to the printer.
@@ -22,75 +22,56 @@ if TYPE_CHECKING:
# This way it won't freeze up the interface while sending those materials.
class SendMaterialJob(Job):
- def __init__(self, device: "ClusterUM3OutputDevice") -> None:
+ def __init__(self, device: "LocalClusterOutputDevice") -> None:
super().__init__()
- self.device = device # type: ClusterUM3OutputDevice
+ self.device = device # type: LocalClusterOutputDevice
## Send the request to the printer and register a callback
def run(self) -> None:
- self.device.get("materials/", on_finished = self._onGetRemoteMaterials)
+ self.device.getMaterials(on_finished = self._onGetMaterials)
- ## Process the materials reply from the printer.
- #
- # \param reply The reply from the printer, a json file.
- def _onGetRemoteMaterials(self, reply: QNetworkReply) -> None:
- # Got an error from the HTTP request. If we did not receive a 200 something happened.
- if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
- Logger.log("e", "Error fetching materials from printer: %s", reply.errorString())
- return
-
- # Collect materials from the printer's reply and send the missing ones if needed.
- remote_materials_by_guid = self._parseReply(reply)
- if remote_materials_by_guid:
- self._sendMissingMaterials(remote_materials_by_guid)
+ ## Callback for when the remote materials were returned.
+ def _onGetMaterials(self, materials: List[ClusterMaterial]) -> None:
+ remote_materials_by_guid = {material.guid: material for material in materials}
+ self._sendMissingMaterials(remote_materials_by_guid)
## Determine which materials should be updated and send them to the printer.
- #
# \param remote_materials_by_guid The remote materials by GUID.
def _sendMissingMaterials(self, remote_materials_by_guid: Dict[str, ClusterMaterial]) -> None:
- # Collect local materials
local_materials_by_guid = self._getLocalMaterials()
if len(local_materials_by_guid) == 0:
Logger.log("d", "There are no local materials to synchronize with the printer.")
return
-
- # Find out what materials are new or updated and must be sent to the printer
material_ids_to_send = self._determineMaterialsToSend(local_materials_by_guid, remote_materials_by_guid)
if len(material_ids_to_send) == 0:
Logger.log("d", "There are no remote materials to update.")
return
-
- # Send materials to the printer
self._sendMaterials(material_ids_to_send)
## From the local and remote materials, determine which ones should be synchronized.
- #
# Makes a Set of id's containing only the id's of the materials that are not on the printer yet or the ones that
# are newer in Cura.
- #
# \param local_materials The local materials by GUID.
# \param remote_materials The remote materials by GUID.
@staticmethod
def _determineMaterialsToSend(local_materials: Dict[str, LocalMaterial],
remote_materials: Dict[str, ClusterMaterial]) -> Set[str]:
return {
- material.id
- for guid, material in local_materials.items()
- if guid not in remote_materials or material.version > remote_materials[guid].version
+ local_material.id
+ for guid, local_material in local_materials.items()
+ if guid not in remote_materials.keys() or local_material.version > remote_materials[guid].version
}
## Send the materials to the printer.
- #
# The given materials will be loaded from disk en sent to to printer.
# The given id's will be matched with filenames of the locally stored materials.
- #
# \param materials_to_send A set with id's of materials that must be sent.
def _sendMaterials(self, materials_to_send: Set[str]) -> None:
container_registry = CuraApplication.getInstance().getContainerRegistry()
- material_manager = CuraApplication.getInstance().getMaterialManager()
- material_group_dict = material_manager.getAllMaterialGroups()
+ all_materials = container_registry.findInstanceContainersMetadata(type = "material")
+ all_base_files = {material["base_file"] for material in all_materials if "base_file" in material} # Filters out uniques by making it a set. Don't include files without base file (i.e. empty material).
- for root_material_id in material_group_dict:
+ for root_material_id in all_base_files:
if root_material_id not in materials_to_send:
# If the material does not have to be sent we skip it.
continue
@@ -104,9 +85,7 @@ class SendMaterialJob(Job):
self._sendMaterialFile(file_path, file_name, root_material_id)
## Send a single material file to the printer.
- #
# Also add the material signature file if that is available.
- #
# \param file_path The path of the material file.
# \param file_name The name of the material file.
# \param material_id The ID of the material in the file.
@@ -126,61 +105,41 @@ class SendMaterialJob(Job):
parts.append(self.device.createFormPart("name=\"signature_file\"; filename=\"{file_name}\""
.format(file_name = signature_file_name), f.read()))
- Logger.log("d", "Syncing material {material_id} with cluster.".format(material_id = material_id))
- self.device.postFormWithParts(target = "materials/", parts = parts, on_finished = self.sendingFinished)
+ # FIXME: move form posting to API client
+ self.device.postFormWithParts(target = "/cluster-api/v1/materials/", parts = parts,
+ on_finished = self._sendingFinished)
## Check a reply from an upload to the printer and log an error when the call failed
- @staticmethod
- def sendingFinished(reply: QNetworkReply) -> None:
+ def _sendingFinished(self, reply: QNetworkReply) -> None:
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
- Logger.log("e", "Received error code from printer when syncing material: {code}, {text}".format(
- code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute),
- text = reply.errorString()
- ))
-
- ## Parse the reply from the printer
- #
- # Parses the reply to a "/materials" request to the printer
- #
- # \return a dictionary of ClusterMaterial objects by GUID
- # \throw KeyError Raised when on of the materials does not include a valid guid
- @classmethod
- def _parseReply(cls, reply: QNetworkReply) -> Optional[Dict[str, ClusterMaterial]]:
- try:
- remote_materials = json.loads(reply.readAll().data().decode("utf-8"))
- return {material["guid"]: ClusterMaterial(**material) for material in remote_materials}
- except UnicodeDecodeError:
- Logger.log("e", "Request material storage on printer: I didn't understand the printer's answer.")
- except json.JSONDecodeError:
- Logger.log("e", "Request material storage on printer: I didn't understand the printer's answer.")
- except ValueError:
- Logger.log("e", "Request material storage on printer: Printer's answer had an incorrect value.")
- except TypeError:
- Logger.log("e", "Request material storage on printer: Printer's answer was missing a required value.")
- return None
+ Logger.log("w", "Error while syncing material: %s", reply.errorString())
+ return
+ body = reply.readAll().data().decode('utf8')
+ if "not added" in body:
+ # For some reason the cluster returns a 200 sometimes even when syncing failed.
+ return
+ # Inform the user that materials have been synced. This message only shows itself when not already visible.
+ # Because of the guards above it is not shown when syncing failed (which is not always an actual problem).
+ MaterialSyncMessage(self.device).show()
## Retrieves a list of local materials
- #
# Only the new newest version of the local materials is returned
- #
# \return a dictionary of LocalMaterial objects by GUID
- def _getLocalMaterials(self) -> Dict[str, LocalMaterial]:
+ @staticmethod
+ def _getLocalMaterials() -> Dict[str, LocalMaterial]:
result = {} # type: Dict[str, LocalMaterial]
- material_manager = CuraApplication.getInstance().getMaterialManager()
-
- material_group_dict = material_manager.getAllMaterialGroups()
+ all_materials = CuraApplication.getInstance().getContainerRegistry().findInstanceContainersMetadata(type = "material")
+ all_base_files = [material for material in all_materials if material["id"] == material.get("base_file")] # Don't send materials without base_file: The empty material doesn't need to be sent.
# Find the latest version of all material containers in the registry.
- for root_material_id, material_group in material_group_dict.items():
- material_metadata = material_group.root_material_node.getMetadata()
-
+ for material_metadata in all_base_files:
try:
# material version must be an int
material_metadata["version"] = int(material_metadata["version"])
# Create a new local material
local_material = LocalMaterial(**material_metadata)
- local_material.id = root_material_id
+ local_material.id = material_metadata["id"]
if local_material.GUID not in result or \
local_material.GUID not in result or \
diff --git a/plugins/UM3NetworkPrinting/src/Network/ZeroConfClient.py b/plugins/UM3NetworkPrinting/src/Network/ZeroConfClient.py
new file mode 100644
index 0000000000..421246fb95
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Network/ZeroConfClient.py
@@ -0,0 +1,146 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from queue import Queue
+from threading import Thread, Event
+from time import time
+from typing import Optional
+
+from zeroconf import Zeroconf, ServiceBrowser, ServiceStateChange, ServiceInfo
+
+from UM.Logger import Logger
+from UM.Signal import Signal
+from cura.CuraApplication import CuraApplication
+
+
+## The ZeroConfClient handles all network discovery logic.
+# It emits signals when new network services were found or disappeared.
+class ZeroConfClient:
+
+ # The discovery protocol name for Ultimaker printers.
+ ZERO_CONF_NAME = u"_ultimaker._tcp.local."
+
+ # Signals emitted when new services were discovered or removed on the network.
+ addedNetworkCluster = Signal()
+ removedNetworkCluster = Signal()
+
+ def __init__(self) -> None:
+ self._zero_conf = None # type: Optional[Zeroconf]
+ self._zero_conf_browser = None # type: Optional[ServiceBrowser]
+ self._service_changed_request_queue = None # type: Optional[Queue]
+ self._service_changed_request_event = None # type: Optional[Event]
+ self._service_changed_request_thread = None # type: Optional[Thread]
+
+ ## The ZeroConf service changed requests are handled in a separate thread so we don't block the UI.
+ # We can also re-schedule the requests when they fail to get detailed service info.
+ # Any new or re-reschedule requests will be appended to the request queue and the thread will process them.
+ def start(self) -> None:
+ self._service_changed_request_queue = Queue()
+ self._service_changed_request_event = Event()
+ try:
+ self._zero_conf = Zeroconf()
+ # CURA-6855 catch WinErrors
+ except OSError:
+ Logger.logException("e", "Failed to create zeroconf instance.")
+ return
+
+ self._service_changed_request_thread = Thread(target = self._handleOnServiceChangedRequests, daemon = True, name = "ZeroConfServiceChangedThread")
+ self._service_changed_request_thread.start()
+ self._zero_conf_browser = ServiceBrowser(self._zero_conf, self.ZERO_CONF_NAME, [self._queueService])
+
+ # Cleanup ZeroConf resources.
+ def stop(self) -> None:
+ if self._zero_conf is not None:
+ self._zero_conf.close()
+ self._zero_conf = None
+ if self._zero_conf_browser is not None:
+ self._zero_conf_browser.cancel()
+ self._zero_conf_browser = None
+
+ ## Handles a change is discovered network services.
+ def _queueService(self, zeroconf: Zeroconf, service_type, name: str, state_change: ServiceStateChange) -> None:
+ item = (zeroconf, service_type, name, state_change)
+ if not self._service_changed_request_queue or not self._service_changed_request_event:
+ return
+ self._service_changed_request_queue.put(item)
+ self._service_changed_request_event.set()
+
+ ## Callback for when a ZeroConf service has changes.
+ def _handleOnServiceChangedRequests(self) -> None:
+ if not self._service_changed_request_queue or not self._service_changed_request_event:
+ return
+
+ while True:
+ # Wait for the event to be set
+ self._service_changed_request_event.wait(timeout=5.0)
+
+ # Stop if the application is shutting down
+ if CuraApplication.getInstance().isShuttingDown():
+ return
+
+ self._service_changed_request_event.clear()
+
+ # Handle all pending requests
+ reschedule_requests = [] # A list of requests that have failed so later they will get re-scheduled
+ while not self._service_changed_request_queue.empty():
+ request = self._service_changed_request_queue.get()
+ zeroconf, service_type, name, state_change = request
+ try:
+ result = self._onServiceChanged(zeroconf, service_type, name, state_change)
+ if not result:
+ reschedule_requests.append(request)
+ except Exception:
+ Logger.logException("e", "Failed to get service info for [%s] [%s], the request will be rescheduled",
+ service_type, name)
+ reschedule_requests.append(request)
+
+ # Re-schedule the failed requests if any
+ if reschedule_requests:
+ for request in reschedule_requests:
+ self._service_changed_request_queue.put(request)
+
+ ## Handler for zeroConf detection.
+ # Return True or False indicating if the process succeeded.
+ # Note that this function can take over 3 seconds to complete. Be careful calling it from the main thread.
+ def _onServiceChanged(self, zero_conf: Zeroconf, service_type: str, name: str, state_change: ServiceStateChange
+ ) -> bool:
+ if state_change == ServiceStateChange.Added:
+ return self._onServiceAdded(zero_conf, service_type, name)
+ elif state_change == ServiceStateChange.Removed:
+ return self._onServiceRemoved(name)
+ return True
+
+ ## Handler for when a ZeroConf service was added.
+ def _onServiceAdded(self, zero_conf: Zeroconf, service_type: str, name: str) -> bool:
+ # First try getting info from zero-conf cache
+ info = ServiceInfo(service_type, name, properties={})
+ for record in zero_conf.cache.entries_with_name(name.lower()):
+ info.update_record(zero_conf, time(), record)
+
+ for record in zero_conf.cache.entries_with_name(info.server):
+ info.update_record(zero_conf, time(), record)
+ if info.address:
+ break
+
+ # Request more data if info is not complete
+ if not info.address:
+ info = zero_conf.get_service_info(service_type, name)
+
+ if info:
+ type_of_device = info.properties.get(b"type", None)
+ if type_of_device:
+ if type_of_device == b"printer":
+ address = '.'.join(map(lambda n: str(n), info.address))
+ self.addedNetworkCluster.emit(str(name), address, info.properties)
+ else:
+ Logger.log("w", "The type of the found device is '%s', not 'printer'." % type_of_device)
+ else:
+ Logger.log("w", "Could not get information about %s" % name)
+ return False
+
+ return True
+
+ ## Handler for when a ZeroConf service was removed.
+ def _onServiceRemoved(self, name: str) -> bool:
+ Logger.log("d", "ZeroConf service removed: %s" % name)
+ self.removedNetworkCluster.emit(str(name))
+ return True
diff --git a/plugins/UM3NetworkPrinting/src/Network/__init__.py b/plugins/UM3NetworkPrinting/src/Network/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py
index e9f47f1937..3ab37297b5 100644
--- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py
+++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py
@@ -1,525 +1,73 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-import json
-from queue import Queue
-from threading import Event, Thread
-from time import time
-import os
-
-from zeroconf import Zeroconf, ServiceBrowser, ServiceStateChange, ServiceInfo
-from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager
-from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject
-from PyQt5.QtGui import QDesktopServices
+from typing import Optional, Callable, Dict
+from UM.Signal import Signal
from cura.CuraApplication import CuraApplication
-from cura.PrinterOutputDevice import ConnectionType
-from cura.Settings.GlobalStack import GlobalStack # typing
-from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
-from UM.Logger import Logger
-from UM.Signal import Signal, signalemitter
-from UM.Version import Version
-from UM.Message import Message
-from UM.i18n import i18nCatalog
-from . import ClusterUM3OutputDevice, LegacyUM3OutputDevice
+from UM.OutputDevice.OutputDeviceManager import ManualDeviceAdditionAttempt
+from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
+
+from .Network.LocalClusterOutputDevice import LocalClusterOutputDevice
+from .Network.LocalClusterOutputDeviceManager import LocalClusterOutputDeviceManager
from .Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager
-from typing import Optional
-i18n_catalog = i18nCatalog("cura")
-
-## This plugin handles the connection detection & creation of output device objects for the UM3 printer.
-# Zero-Conf is used to detect printers, which are saved in a dict.
-# If we discover a printer that has the same key as the active machine instance a connection is made.
-@signalemitter
+## This plugin handles the discovery and networking for Ultimaker 3D printers that support network and cloud printing.
class UM3OutputDevicePlugin(OutputDevicePlugin):
- addDeviceSignal = Signal()
- removeDeviceSignal = Signal()
+
+ # Signal emitted when the list of discovered devices changed. Used by printer action in this plugin.
discoveredDevicesChanged = Signal()
- cloudFlowIsPossible = Signal()
- def __init__(self):
+ def __init__(self) -> None:
super().__init__()
-
- self._zero_conf = None
- self._zero_conf_browser = None
- self._application = CuraApplication.getInstance()
+ # Create a network output device manager that abstracts all network connection logic away.
+ self._network_output_device_manager = LocalClusterOutputDeviceManager()
+ self._network_output_device_manager.discoveredDevicesChanged.connect(self.discoveredDevicesChanged)
# Create a cloud output device manager that abstracts all cloud connection logic away.
self._cloud_output_device_manager = CloudOutputDeviceManager()
- # Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
- self.addDeviceSignal.connect(self._onAddDevice)
- self.removeDeviceSignal.connect(self._onRemoveDevice)
+ # Refresh network connections when another machine was selected in Cura.
+ # This ensures no output devices are still connected that do not belong to the new active machine.
+ CuraApplication.getInstance().globalContainerStackChanged.connect(self.refreshConnections)
- self._application.globalContainerStackChanged.connect(self.reCheckConnections)
-
- self._discovered_devices = {}
-
- self._network_manager = QNetworkAccessManager()
- self._network_manager.finished.connect(self._onNetworkRequestFinished)
-
- self._min_cluster_version = Version("4.0.0")
- self._min_cloud_version = Version("5.2.0")
-
- self._api_version = "1"
- self._api_prefix = "/api/v" + self._api_version + "/"
- self._cluster_api_version = "1"
- self._cluster_api_prefix = "/cluster-api/v" + self._cluster_api_version + "/"
-
- # Get list of manual instances from preferences
- self._preferences = CuraApplication.getInstance().getPreferences()
- self._preferences.addPreference("um3networkprinting/manual_instances",
- "") # A comma-separated list of ip adresses or hostnames
-
- self._manual_instances = self._preferences.getValue("um3networkprinting/manual_instances").split(",")
-
- # Store the last manual entry key
- self._last_manual_entry_key = "" # type: str
-
- # The zero-conf service changed requests are handled in a separate thread, so we can re-schedule the requests
- # which fail to get detailed service info.
- # Any new or re-scheduled requests will be appended to the request queue, and the handling thread will pick
- # them up and process them.
- self._service_changed_request_queue = Queue()
- self._service_changed_request_event = Event()
- self._service_changed_request_thread = Thread(target=self._handleOnServiceChangedRequests, daemon=True)
- self._service_changed_request_thread.start()
-
- self._account = self._application.getCuraAPI().account
-
- # Check if cloud flow is possible when user logs in
- self._account.loginStateChanged.connect(self.checkCloudFlowIsPossible)
-
- # Check if cloud flow is possible when user switches machines
- self._application.globalContainerStackChanged.connect(self._onMachineSwitched)
-
- # Listen for when cloud flow is possible
- self.cloudFlowIsPossible.connect(self._onCloudFlowPossible)
-
- # Listen if cloud cluster was added
- self._cloud_output_device_manager.addedCloudCluster.connect(self._onCloudPrintingConfigured)
-
- # Listen if cloud cluster was removed
- self._cloud_output_device_manager.removedCloudCluster.connect(self.checkCloudFlowIsPossible)
-
- self._start_cloud_flow_message = None # type: Optional[Message]
- self._cloud_flow_complete_message = None # type: Optional[Message]
-
- def getDiscoveredDevices(self):
- return self._discovered_devices
-
- def getLastManualDevice(self) -> str:
- return self._last_manual_entry_key
-
- def resetLastManualDevice(self) -> None:
- self._last_manual_entry_key = ""
-
- ## Start looking for devices on network.
+ ## Start looking for devices in the network and cloud.
def start(self):
- self.startDiscovery()
+ self._network_output_device_manager.start()
self._cloud_output_device_manager.start()
- def startDiscovery(self):
- self.stop()
- if self._zero_conf_browser:
- self._zero_conf_browser.cancel()
- self._zero_conf_browser = None # Force the old ServiceBrowser to be destroyed.
-
- for instance_name in list(self._discovered_devices):
- self._onRemoveDevice(instance_name)
-
- self._zero_conf = Zeroconf()
- self._zero_conf_browser = ServiceBrowser(self._zero_conf, u'_ultimaker._tcp.local.',
- [self._appendServiceChangedRequest])
-
- # Look for manual instances from preference
- for address in self._manual_instances:
- if address:
- self.addManualDevice(address)
- self.resetLastManualDevice()
-
- def reCheckConnections(self):
- active_machine = CuraApplication.getInstance().getGlobalContainerStack()
- if not active_machine:
- return
-
- um_network_key = active_machine.getMetaDataEntry("um_network_key")
-
- for key in self._discovered_devices:
- if key == um_network_key:
- if not self._discovered_devices[key].isConnected():
- Logger.log("d", "Attempting to connect with [%s]" % key)
- # It should already be set, but if it actually connects we know for sure it's supported!
- active_machine.addConfiguredConnectionType(self._discovered_devices[key].connectionType.value)
- self._discovered_devices[key].connect()
- self._discovered_devices[key].connectionStateChanged.connect(self._onDeviceConnectionStateChanged)
- else:
- self._onDeviceConnectionStateChanged(key)
- else:
- if self._discovered_devices[key].isConnected():
- Logger.log("d", "Attempting to close connection with [%s]" % key)
- self._discovered_devices[key].close()
- self._discovered_devices[key].connectionStateChanged.disconnect(self._onDeviceConnectionStateChanged)
-
- def _onDeviceConnectionStateChanged(self, key):
- if key not in self._discovered_devices:
- return
- if self._discovered_devices[key].isConnected():
- # Sometimes the status changes after changing the global container and maybe the device doesn't belong to this machine
- um_network_key = CuraApplication.getInstance().getGlobalContainerStack().getMetaDataEntry("um_network_key")
- if key == um_network_key:
- self.getOutputDeviceManager().addOutputDevice(self._discovered_devices[key])
- self.checkCloudFlowIsPossible()
- else:
- self.getOutputDeviceManager().removeOutputDevice(key)
-
- def stop(self):
- if self._zero_conf is not None:
- Logger.log("d", "zeroconf close...")
- self._zero_conf.close()
+ # Stop network and cloud discovery.
+ def stop(self) -> None:
+ self._network_output_device_manager.stop()
self._cloud_output_device_manager.stop()
- def removeManualDevice(self, key, address = None):
- if key in self._discovered_devices:
- if not address:
- address = self._discovered_devices[key].ipAddress
- self._onRemoveDevice(key)
- self.resetLastManualDevice()
+ ## Restart network discovery.
+ def startDiscovery(self) -> None:
+ self._network_output_device_manager.startDiscovery()
- if address in self._manual_instances:
- self._manual_instances.remove(address)
- self._preferences.setValue("um3networkprinting/manual_instances", ",".join(self._manual_instances))
+ ## Force refreshing the network connections.
+ def refreshConnections(self) -> None:
+ self._network_output_device_manager.refreshConnections()
+ self._cloud_output_device_manager.refreshConnections()
- def addManualDevice(self, address):
- if address not in self._manual_instances:
- self._manual_instances.append(address)
- self._preferences.setValue("um3networkprinting/manual_instances", ",".join(self._manual_instances))
+ ## Indicate that this plugin supports adding networked printers manually.
+ def canAddManualDevice(self, address: str = "") -> ManualDeviceAdditionAttempt:
+ return ManualDeviceAdditionAttempt.PRIORITY
- instance_name = "manual:%s" % address
- properties = {
- b"name": address.encode("utf-8"),
- b"address": address.encode("utf-8"),
- b"manual": b"true",
- b"incomplete": b"true",
- b"temporary": b"true" # Still a temporary device until all the info is retrieved in _onNetworkRequestFinished
- }
+ ## Add a networked printer manually based on its network address.
+ def addManualDevice(self, address: str, callback: Optional[Callable[[bool, str], None]] = None) -> None:
+ self._network_output_device_manager.addManualDevice(address, callback)
- if instance_name not in self._discovered_devices:
- # Add a preliminary printer instance
- self._onAddDevice(instance_name, address, properties)
- self._last_manual_entry_key = instance_name
-
- self._checkManualDevice(address)
-
- def _checkManualDevice(self, address):
- # Check if a UM3 family device exists at this address.
- # If a printer responds, it will replace the preliminary printer created above
- # origin=manual is for tracking back the origin of the call
- url = QUrl("http://" + address + self._api_prefix + "system")
- name_request = QNetworkRequest(url)
- self._network_manager.get(name_request)
-
- def _onNetworkRequestFinished(self, reply):
- reply_url = reply.url().toString()
-
- if "system" in reply_url:
- if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
- # Something went wrong with checking the firmware version!
- return
-
- try:
- system_info = json.loads(bytes(reply.readAll()).decode("utf-8"))
- except:
- Logger.log("e", "Something went wrong converting the JSON.")
- return
-
- address = reply.url().host()
- has_cluster_capable_firmware = Version(system_info["firmware"]) > self._min_cluster_version
- instance_name = "manual:%s" % address
- properties = {
- b"name": (system_info["name"] + " (manual)").encode("utf-8"),
- b"address": address.encode("utf-8"),
- b"firmware_version": system_info["firmware"].encode("utf-8"),
- b"manual": b"true",
- b"machine": str(system_info['hardware']["typeid"]).encode("utf-8")
- }
-
- if has_cluster_capable_firmware:
- # Cluster needs an additional request, before it's completed.
- properties[b"incomplete"] = b"true"
-
- # Check if the device is still in the list & re-add it with the updated
- # information.
- if instance_name in self._discovered_devices:
- self._onRemoveDevice(instance_name)
- self._onAddDevice(instance_name, address, properties)
-
- if has_cluster_capable_firmware:
- # We need to request more info in order to figure out the size of the cluster.
- cluster_url = QUrl("http://" + address + self._cluster_api_prefix + "printers/")
- cluster_request = QNetworkRequest(cluster_url)
- self._network_manager.get(cluster_request)
-
- elif "printers" in reply_url:
- if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
- # Something went wrong with checking the amount of printers the cluster has!
- return
- # So we confirmed that the device is in fact a cluster printer, and we should now know how big it is.
- try:
- cluster_printers_list = json.loads(bytes(reply.readAll()).decode("utf-8"))
- except:
- Logger.log("e", "Something went wrong converting the JSON.")
- return
- address = reply.url().host()
- instance_name = "manual:%s" % address
- if instance_name in self._discovered_devices:
- device = self._discovered_devices[instance_name]
- properties = device.getProperties().copy()
- if b"incomplete" in properties:
- del properties[b"incomplete"]
- properties[b"cluster_size"] = len(cluster_printers_list)
- self._onRemoveDevice(instance_name)
- self._onAddDevice(instance_name, address, properties)
-
- def _onRemoveDevice(self, device_id):
- device = self._discovered_devices.pop(device_id, None)
- if device:
- if device.isConnected():
- device.disconnect()
- try:
- device.connectionStateChanged.disconnect(self._onDeviceConnectionStateChanged)
- except TypeError:
- # Disconnect already happened.
- pass
-
- self.discoveredDevicesChanged.emit()
-
- def _onAddDevice(self, name, address, properties):
- # Check what kind of device we need to add; Depending on the firmware we either add a "Connect"/"Cluster"
- # or "Legacy" UM3 device.
- cluster_size = int(properties.get(b"cluster_size", -1))
-
- printer_type = properties.get(b"machine", b"").decode("utf-8")
- printer_type_identifiers = {
- "9066": "ultimaker3",
- "9511": "ultimaker3_extended",
- "9051": "ultimaker_s5"
- }
-
- for key, value in printer_type_identifiers.items():
- if printer_type.startswith(key):
- properties[b"printer_type"] = bytes(value, encoding="utf8")
- break
- else:
- properties[b"printer_type"] = b"Unknown"
- if cluster_size >= 0:
- device = ClusterUM3OutputDevice.ClusterUM3OutputDevice(name, address, properties)
- else:
- device = LegacyUM3OutputDevice.LegacyUM3OutputDevice(name, address, properties)
-
- self._discovered_devices[device.getId()] = device
- self.discoveredDevicesChanged.emit()
-
- global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
- if global_container_stack and device.getId() == global_container_stack.getMetaDataEntry("um_network_key"):
- # Ensure that the configured connection type is set.
- global_container_stack.addConfiguredConnectionType(device.connectionType.value)
- device.connect()
- device.connectionStateChanged.connect(self._onDeviceConnectionStateChanged)
-
- ## Appends a service changed request so later the handling thread will pick it up and processes it.
- def _appendServiceChangedRequest(self, zeroconf, service_type, name, state_change):
- # append the request and set the event so the event handling thread can pick it up
- item = (zeroconf, service_type, name, state_change)
- self._service_changed_request_queue.put(item)
- self._service_changed_request_event.set()
-
- def _handleOnServiceChangedRequests(self):
- while True:
- # Wait for the event to be set
- self._service_changed_request_event.wait(timeout = 5.0)
-
- # Stop if the application is shutting down
- if CuraApplication.getInstance().isShuttingDown():
- return
-
- self._service_changed_request_event.clear()
-
- # Handle all pending requests
- reschedule_requests = [] # A list of requests that have failed so later they will get re-scheduled
- while not self._service_changed_request_queue.empty():
- request = self._service_changed_request_queue.get()
- zeroconf, service_type, name, state_change = request
- try:
- result = self._onServiceChanged(zeroconf, service_type, name, state_change)
- if not result:
- reschedule_requests.append(request)
- except Exception:
- Logger.logException("e", "Failed to get service info for [%s] [%s], the request will be rescheduled",
- service_type, name)
- reschedule_requests.append(request)
-
- # Re-schedule the failed requests if any
- if reschedule_requests:
- for request in reschedule_requests:
- self._service_changed_request_queue.put(request)
-
- ## Handler for zeroConf detection.
- # Return True or False indicating if the process succeeded.
- # Note that this function can take over 3 seconds to complete. Be careful
- # calling it from the main thread.
- def _onServiceChanged(self, zero_conf, service_type, name, state_change):
- if state_change == ServiceStateChange.Added:
- # First try getting info from zero-conf cache
- info = ServiceInfo(service_type, name, properties = {})
- for record in zero_conf.cache.entries_with_name(name.lower()):
- info.update_record(zero_conf, time(), record)
-
- for record in zero_conf.cache.entries_with_name(info.server):
- info.update_record(zero_conf, time(), record)
- if info.address:
- break
-
- # Request more data if info is not complete
- if not info.address:
- info = zero_conf.get_service_info(service_type, name)
-
- if info:
- type_of_device = info.properties.get(b"type", None)
- if type_of_device:
- if type_of_device == b"printer":
- address = '.'.join(map(lambda n: str(n), info.address))
- self.addDeviceSignal.emit(str(name), address, info.properties)
- else:
- Logger.log("w",
- "The type of the found device is '%s', not 'printer'! Ignoring.." % type_of_device)
- else:
- Logger.log("w", "Could not get information about %s" % name)
- return False
-
- elif state_change == ServiceStateChange.Removed:
- Logger.log("d", "Bonjour service removed: %s" % name)
- self.removeDeviceSignal.emit(str(name))
-
- return True
-
- ## Check if the prerequsites are in place to start the cloud flow
- def checkCloudFlowIsPossible(self) -> None:
- Logger.log("d", "Checking if cloud connection is possible...")
-
- # Pre-Check: Skip if active machine already has been cloud connected or you said don't ask again
- active_machine = self._application.getMachineManager().activeMachine # type: Optional["GlobalStack"]
- if active_machine:
-
- # Check 1A: Printer isn't already configured for cloud
- if ConnectionType.CloudConnection.value in active_machine.configuredConnectionTypes:
- Logger.log("d", "Active machine was already configured for cloud.")
- return
-
- # Check 1B: Printer isn't already configured for cloud
- if active_machine.getMetaDataEntry("cloud_flow_complete", False):
- Logger.log("d", "Active machine was already configured for cloud.")
- return
-
- # Check 2: User did not already say "Don't ask me again"
- if active_machine.getMetaDataEntry("do_not_show_cloud_message", False):
- Logger.log("d", "Active machine shouldn't ask about cloud anymore.")
- return
+ ## Remove a manually connected networked printer.
+ def removeManualDevice(self, key: str, address: Optional[str] = None) -> None:
+ self._network_output_device_manager.removeManualDevice(key, address)
- # Check 3: User is logged in with an Ultimaker account
- if not self._account.isLoggedIn:
- Logger.log("d", "Cloud Flow not possible: User not logged in!")
- return
+ ## Get the discovered devices from the local network.
+ def getDiscoveredDevices(self) -> Dict[str, LocalClusterOutputDevice]:
+ return self._network_output_device_manager.getDiscoveredDevices()
- # Check 4: Machine is configured for network connectivity
- if not self._application.getMachineManager().activeMachineHasNetworkConnection:
- Logger.log("d", "Cloud Flow not possible: Machine is not connected!")
- return
-
- # Check 5: Machine has correct firmware version
- firmware_version = self._application.getMachineManager().activeMachineFirmwareVersion # type: str
- if not Version(firmware_version) > self._min_cloud_version:
- Logger.log("d", "Cloud Flow not possible: Machine firmware (%s) is too low! (Requires version %s)",
- firmware_version,
- self._min_cloud_version)
- return
-
- Logger.log("d", "Cloud flow is possible!")
- self.cloudFlowIsPossible.emit()
-
- def _onCloudFlowPossible(self) -> None:
- # Cloud flow is possible, so show the message
- if not self._start_cloud_flow_message:
- self._start_cloud_flow_message = Message(
- text = i18n_catalog.i18nc("@info:status", "Send and monitor print jobs from anywhere using your Ultimaker account."),
- lifetime = 0,
- image_source = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "resources", "svg",
- "cloud-flow-start.svg"),
- image_caption = i18n_catalog.i18nc("@info:status", "Connect to Ultimaker Cloud"),
- option_text = i18n_catalog.i18nc("@action", "Don't ask me again for this printer."),
- option_state = False
- )
- self._start_cloud_flow_message.addAction("", i18n_catalog.i18nc("@action", "Get started"), "", "")
- self._start_cloud_flow_message.optionToggled.connect(self._onDontAskMeAgain)
- self._start_cloud_flow_message.actionTriggered.connect(self._onCloudFlowStarted)
- self._start_cloud_flow_message.show()
- return
-
- def _onCloudPrintingConfigured(self) -> None:
- if self._start_cloud_flow_message:
- self._start_cloud_flow_message.hide()
- self._start_cloud_flow_message = None
-
- # Show the successful pop-up
- if not self._start_cloud_flow_message:
- self._cloud_flow_complete_message = Message(
- text = i18n_catalog.i18nc("@info:status", "You can now send and monitor print jobs from anywhere using your Ultimaker account."),
- lifetime = 30,
- image_source = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "resources", "svg",
- "cloud-flow-completed.svg"),
- image_caption = i18n_catalog.i18nc("@info:status", "Connected!")
- )
- self._cloud_flow_complete_message.addAction("", i18n_catalog.i18nc("@action", "Review your connection"), "", "", 1) # TODO: Icon
- self._cloud_flow_complete_message.actionTriggered.connect(self._onReviewCloudConnection)
- self._cloud_flow_complete_message.show()
-
- # Set the machine's cloud flow as complete so we don't ask the user again and again for cloud connected printers
- active_machine = self._application.getMachineManager().activeMachine
- if active_machine:
- active_machine.setMetaDataEntry("do_not_show_cloud_message", True)
- return
-
- def _onDontAskMeAgain(self, checked: bool) -> None:
- active_machine = self._application.getMachineManager().activeMachine # type: Optional["GlobalStack"]
- if active_machine:
- active_machine.setMetaDataEntry("do_not_show_cloud_message", checked)
- if checked:
- Logger.log("d", "Will not ask the user again to cloud connect for current printer.")
- return
-
- def _onCloudFlowStarted(self, messageId: str, actionId: str) -> None:
- address = self._application.getMachineManager().activeMachineAddress # type: str
- if address:
- QDesktopServices.openUrl(QUrl("http://" + address + "/cloud_connect"))
- if self._start_cloud_flow_message:
- self._start_cloud_flow_message.hide()
- self._start_cloud_flow_message = None
- return
-
- def _onReviewCloudConnection(self, messageId: str, actionId: str) -> None:
- address = self._application.getMachineManager().activeMachineAddress # type: str
- if address:
- QDesktopServices.openUrl(QUrl("http://" + address + "/settings"))
- return
-
- def _onMachineSwitched(self) -> None:
- if self._start_cloud_flow_message is not None:
- self._start_cloud_flow_message.hide()
- self._start_cloud_flow_message = None
- if self._cloud_flow_complete_message is not None:
- self._cloud_flow_complete_message.hide()
- self._cloud_flow_complete_message = None
-
- self.checkCloudFlowIsPossible()
+ ## Connect the active machine to a device.
+ def associateActiveMachineWithPrinterDevice(self, device: LocalClusterOutputDevice) -> None:
+ self._network_output_device_manager.associateActiveMachineWithPrinterDevice(device)
diff --git a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py
new file mode 100644
index 0000000000..8c5f5c12ea
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py
@@ -0,0 +1,87 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import Optional, cast
+
+from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty, QObject
+
+from UM import i18nCatalog
+from cura.CuraApplication import CuraApplication
+from cura.MachineAction import MachineAction
+
+from .UM3OutputDevicePlugin import UM3OutputDevicePlugin
+from .Network.LocalClusterOutputDevice import LocalClusterOutputDevice
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+## Machine action that allows to connect the active machine to a networked devices.
+# TODO: in the future this should be part of the new discovery workflow baked into Cura.
+class UltimakerNetworkedPrinterAction(MachineAction):
+
+ # Signal emitted when discovered devices have changed.
+ discoveredDevicesChanged = pyqtSignal()
+
+ def __init__(self) -> None:
+ super().__init__("DiscoverUM3Action", I18N_CATALOG.i18nc("@action", "Connect via Network"))
+ self._qml_url = "resources/qml/DiscoverUM3Action.qml"
+ self._network_plugin = None # type: Optional[UM3OutputDevicePlugin]
+
+ ## Override the default value.
+ def needsUserInteraction(self) -> bool:
+ return False
+
+ ## Start listening to network discovery events via the plugin.
+ @pyqtSlot(name = "startDiscovery")
+ def startDiscovery(self) -> None:
+ self._networkPlugin.discoveredDevicesChanged.connect(self._onDeviceDiscoveryChanged)
+ self.discoveredDevicesChanged.emit() # trigger at least once to populate the list
+
+ ## Reset the discovered devices.
+ @pyqtSlot(name = "reset")
+ def reset(self) -> None:
+ self.discoveredDevicesChanged.emit() # trigger to reset the list
+
+ ## Reset the discovered devices.
+ @pyqtSlot(name = "restartDiscovery")
+ def restartDiscovery(self) -> None:
+ self._networkPlugin.startDiscovery()
+ self.discoveredDevicesChanged.emit() # trigger to reset the list
+
+ ## Remove a manually added device.
+ @pyqtSlot(str, str, name = "removeManualDevice")
+ def removeManualDevice(self, key: str, address: str) -> None:
+ self._networkPlugin.removeManualDevice(key, address)
+
+ ## Add a new manual device. Can replace an existing one by key.
+ @pyqtSlot(str, str, name = "setManualDevice")
+ def setManualDevice(self, key: str, address: str) -> None:
+ if key != "":
+ self._networkPlugin.removeManualDevice(key)
+ if address != "":
+ self._networkPlugin.addManualDevice(address)
+
+ ## Get the devices discovered in the local network sorted by name.
+ @pyqtProperty("QVariantList", notify = discoveredDevicesChanged)
+ def foundDevices(self):
+ discovered_devices = list(self._networkPlugin.getDiscoveredDevices().values())
+ discovered_devices.sort(key = lambda d: d.name)
+ return discovered_devices
+
+ ## Connect a device selected in the list with the active machine.
+ @pyqtSlot(QObject, name = "associateActiveMachineWithPrinterDevice")
+ def associateActiveMachineWithPrinterDevice(self, device: LocalClusterOutputDevice) -> None:
+ self._networkPlugin.associateActiveMachineWithPrinterDevice(device)
+
+ ## Callback for when the list of discovered devices in the plugin was changed.
+ def _onDeviceDiscoveryChanged(self) -> None:
+ self.discoveredDevicesChanged.emit()
+
+ ## Get the network manager from the plugin.
+ @property
+ def _networkPlugin(self) -> UM3OutputDevicePlugin:
+ if not self._network_plugin:
+ output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
+ network_plugin = output_device_manager.getOutputDevicePlugin("UM3NetworkPrinting")
+ self._network_plugin = cast(UM3OutputDevicePlugin, network_plugin)
+ return self._network_plugin
diff --git a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py
new file mode 100644
index 0000000000..73b5b456f9
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py
@@ -0,0 +1,353 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+import os
+from time import time
+from typing import List, Optional, Dict
+
+from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, pyqtSlot, QUrl
+
+from UM.Logger import Logger
+from UM.Qt.Duration import Duration, DurationFormat
+from cura.CuraApplication import CuraApplication
+from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
+from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
+from cura.PrinterOutput.PrinterOutputDevice import ConnectionType, ConnectionState
+
+from .Utils import formatTimeCompleted, formatDateCompleted
+from .ClusterOutputController import ClusterOutputController
+from .Messages.PrintJobUploadProgressMessage import PrintJobUploadProgressMessage
+from .Messages.NotClusterHostMessage import NotClusterHostMessage
+from .Models.UM3PrintJobOutputModel import UM3PrintJobOutputModel
+from .Models.Http.ClusterPrinterStatus import ClusterPrinterStatus
+from .Models.Http.ClusterPrintJobStatus import ClusterPrintJobStatus
+
+
+## Output device class that forms the basis of Ultimaker networked printer output devices.
+# Currently used for local networking and cloud printing using Ultimaker Connect.
+# This base class primarily contains all the Qt properties and slots needed for the monitor page to work.
+class UltimakerNetworkedPrinterOutputDevice(NetworkedPrinterOutputDevice):
+
+ META_NETWORK_KEY = "um_network_key"
+ META_CLUSTER_ID = "um_cloud_cluster_id"
+
+ # Signal emitted when the status of the print jobs for this cluster were changed over the network.
+ printJobsChanged = pyqtSignal()
+
+ # Signal emitted when the currently visible printer card in the UI was changed by the user.
+ activePrinterChanged = pyqtSignal()
+
+ # Notify can only use signals that are defined by the class that they are in, not inherited ones.
+ # Therefore we create a private signal used to trigger the printersChanged signal.
+ _clusterPrintersChanged = pyqtSignal()
+
+ # States indicating if a print job is queued.
+ QUEUED_PRINT_JOBS_STATES = {"queued", "error"}
+
+ # Time in seconds since last network response after which we consider this device offline.
+ # We set this a bit higher than some of the other intervals to make sure they don't overlap.
+ NETWORK_RESPONSE_CONSIDER_OFFLINE = 10.0 # seconds
+
+ def __init__(self, device_id: str, address: str, properties: Dict[bytes, bytes], connection_type: ConnectionType,
+ parent=None) -> None:
+
+ super().__init__(device_id=device_id, address=address, properties=properties, connection_type=connection_type,
+ parent=parent)
+
+ # Trigger the printersChanged signal when the private signal is triggered.
+ self.printersChanged.connect(self._clusterPrintersChanged)
+
+ # Keeps track the last network response to determine if we are still connected.
+ self._time_of_last_response = time()
+ self._time_of_last_request = time()
+
+ # Set the display name from the properties.
+ self.setName(self.getProperty("name"))
+
+ # Set the display name of the printer type.
+ definitions = CuraApplication.getInstance().getContainerRegistry().findContainers(id = self.printerType)
+ self._printer_type_name = definitions[0].getName() if definitions else ""
+
+ # Keeps track of all printers in the cluster.
+ self._printers = [] # type: List[PrinterOutputModel]
+ self._has_received_printers = False
+
+ # Keeps track of all print jobs in the cluster.
+ self._print_jobs = [] # type: List[UM3PrintJobOutputModel]
+
+ # Keep track of the printer currently selected in the UI.
+ self._active_printer = None # type: Optional[PrinterOutputModel]
+
+ # By default we are not authenticated. This state will be changed later.
+ self._authentication_state = AuthState.NotAuthenticated
+
+ # Load the Monitor UI elements.
+ self._loadMonitorTab()
+
+ # The job upload progress message modal.
+ self._progress = PrintJobUploadProgressMessage()
+
+ ## The IP address of the printer.
+ @pyqtProperty(str, constant=True)
+ def address(self) -> str:
+ return self._address
+
+ ## The display name of the printer.
+ @pyqtProperty(str, constant=True)
+ def printerTypeName(self) -> str:
+ return self._printer_type_name
+
+ # Get all print jobs for this cluster.
+ @pyqtProperty("QVariantList", notify=printJobsChanged)
+ def printJobs(self) -> List[UM3PrintJobOutputModel]:
+ return self._print_jobs
+
+ # Get all print jobs for this cluster that are queued.
+ @pyqtProperty("QVariantList", notify=printJobsChanged)
+ def queuedPrintJobs(self) -> List[UM3PrintJobOutputModel]:
+ return [print_job for print_job in self._print_jobs if print_job.state in self.QUEUED_PRINT_JOBS_STATES]
+
+ # Get all print jobs for this cluster that are currently printing.
+ @pyqtProperty("QVariantList", notify=printJobsChanged)
+ def activePrintJobs(self) -> List[UM3PrintJobOutputModel]:
+ return [print_job for print_job in self._print_jobs if
+ print_job.assignedPrinter is not None and print_job.state not in self.QUEUED_PRINT_JOBS_STATES]
+
+ @pyqtProperty(bool, notify=_clusterPrintersChanged)
+ def receivedData(self) -> bool:
+ return self._has_received_printers
+
+ # Get the amount of printers in the cluster.
+ @pyqtProperty(int, notify=_clusterPrintersChanged)
+ def clusterSize(self) -> int:
+ if not self._has_received_printers:
+ discovered_size = self.getProperty("cluster_size")
+ if discovered_size == "":
+ return 1 # prevent false positives for new devices
+ return int(discovered_size)
+ return len(self._printers)
+
+ # Get the amount of printer in the cluster per type.
+ @pyqtProperty("QVariantList", notify=_clusterPrintersChanged)
+ def connectedPrintersTypeCount(self) -> List[Dict[str, str]]:
+ printer_count = {} # type: Dict[str, int]
+ for printer in self._printers:
+ if printer.type in printer_count:
+ printer_count[printer.type] += 1
+ else:
+ printer_count[printer.type] = 1
+ result = []
+ for machine_type in printer_count:
+ result.append({"machine_type": machine_type, "count": str(printer_count[machine_type])})
+ return result
+
+ # Get a list of all printers.
+ @pyqtProperty("QVariantList", notify=_clusterPrintersChanged)
+ def printers(self) -> List[PrinterOutputModel]:
+ return self._printers
+
+ # Get the currently active printer in the UI.
+ @pyqtProperty(QObject, notify=activePrinterChanged)
+ def activePrinter(self) -> Optional[PrinterOutputModel]:
+ return self._active_printer
+
+ # Set the currently active printer from the UI.
+ @pyqtSlot(QObject, name="setActivePrinter")
+ def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None:
+ if self.activePrinter == printer:
+ return
+ self._active_printer = printer
+ self.activePrinterChanged.emit()
+
+ ## Whether the printer that this output device represents supports print job actions via the local network.
+ @pyqtProperty(bool, constant=True)
+ def supportsPrintJobActions(self) -> bool:
+ return True
+
+ ## Set the remote print job state.
+ def setJobState(self, print_job_uuid: str, state: str) -> None:
+ raise NotImplementedError("setJobState must be implemented")
+
+ @pyqtSlot(str, name="sendJobToTop")
+ def sendJobToTop(self, print_job_uuid: str) -> None:
+ raise NotImplementedError("sendJobToTop must be implemented")
+
+ @pyqtSlot(str, name="deleteJobFromQueue")
+ def deleteJobFromQueue(self, print_job_uuid: str) -> None:
+ raise NotImplementedError("deleteJobFromQueue must be implemented")
+
+ @pyqtSlot(str, name="forceSendJob")
+ def forceSendJob(self, print_job_uuid: str) -> None:
+ raise NotImplementedError("forceSendJob must be implemented")
+
+ @pyqtSlot(name="openPrintJobControlPanel")
+ def openPrintJobControlPanel(self) -> None:
+ raise NotImplementedError("openPrintJobControlPanel must be implemented")
+
+ @pyqtSlot(name="openPrinterControlPanel")
+ def openPrinterControlPanel(self) -> None:
+ raise NotImplementedError("openPrinterControlPanel must be implemented")
+
+ @pyqtProperty(QUrl, notify=_clusterPrintersChanged)
+ def activeCameraUrl(self) -> QUrl:
+ return QUrl()
+
+ @pyqtSlot(QUrl, name="setActiveCameraUrl")
+ def setActiveCameraUrl(self, camera_url: QUrl) -> None:
+ pass
+
+ @pyqtSlot(int, result=str, name="getTimeCompleted")
+ def getTimeCompleted(self, time_remaining: int) -> str:
+ return formatTimeCompleted(time_remaining)
+
+ @pyqtSlot(int, result=str, name="getDateCompleted")
+ def getDateCompleted(self, time_remaining: int) -> str:
+ return formatDateCompleted(time_remaining)
+
+ @pyqtSlot(int, result=str, name="formatDuration")
+ def formatDuration(self, seconds: int) -> str:
+ return Duration(seconds).getDisplayString(DurationFormat.Format.Short)
+
+ def _update(self) -> None:
+ self._checkStillConnected()
+ super()._update()
+
+ ## Check if we're still connected by comparing the last timestamps for network response and the current time.
+ # This implementation is similar to the base NetworkedPrinterOutputDevice, but is tweaked slightly.
+ # Re-connecting is handled automatically by the output device managers in this plugin.
+ # TODO: it would be nice to have this logic in the managers, but connecting those with signals causes crashes.
+ def _checkStillConnected(self) -> None:
+ time_since_last_response = time() - self._time_of_last_response
+ if time_since_last_response > self.NETWORK_RESPONSE_CONSIDER_OFFLINE:
+ self.setConnectionState(ConnectionState.Closed)
+ if self.key in CuraApplication.getInstance().getOutputDeviceManager().getOutputDeviceIds():
+ CuraApplication.getInstance().getOutputDeviceManager().removeOutputDevice(self.key)
+ elif self.connectionState == ConnectionState.Closed:
+ self._reconnectForActiveMachine()
+
+ ## Reconnect for the active output device.
+ # Does nothing if the device is not meant for the active machine.
+ def _reconnectForActiveMachine(self) -> None:
+ active_machine = CuraApplication.getInstance().getGlobalContainerStack()
+ if not active_machine:
+ return
+
+ # Indicate this device is now connected again.
+ self.setConnectionState(ConnectionState.Connected)
+
+ # If the device was already registered we don't need to register it again.
+ if self.key in CuraApplication.getInstance().getOutputDeviceManager().getOutputDeviceIds():
+ return
+
+ # Try for local network device.
+ stored_device_id = active_machine.getMetaDataEntry(self.META_NETWORK_KEY)
+ if self.key == stored_device_id:
+ CuraApplication.getInstance().getOutputDeviceManager().addOutputDevice(self)
+
+ # Try for cloud device.
+ stored_cluster_id = active_machine.getMetaDataEntry(self.META_CLUSTER_ID)
+ if self.key == stored_cluster_id:
+ CuraApplication.getInstance().getOutputDeviceManager().addOutputDevice(self)
+
+ def _responseReceived(self) -> None:
+ self._time_of_last_response = time()
+
+ def _updatePrinters(self, remote_printers: List[ClusterPrinterStatus]) -> None:
+ self._responseReceived()
+
+ # Keep track of the new printers to show.
+ # We create a new list instead of changing the existing one to get the correct order.
+ new_printers = [] # type: List[PrinterOutputModel]
+
+ # Check which printers need to be created or updated.
+ for index, printer_data in enumerate(remote_printers):
+ printer = next(iter(printer for printer in self._printers if printer.key == printer_data.uuid), None)
+ if printer is None:
+ printer = printer_data.createOutputModel(ClusterOutputController(self))
+ else:
+ printer_data.updateOutputModel(printer)
+ new_printers.append(printer)
+
+ # Check which printers need to be removed (de-referenced).
+ remote_printers_keys = [printer_data.uuid for printer_data in remote_printers]
+ removed_printers = [printer for printer in self._printers if printer.key not in remote_printers_keys]
+ for removed_printer in removed_printers:
+ if self._active_printer and self._active_printer.key == removed_printer.key:
+ self.setActivePrinter(None)
+
+ self._printers = new_printers
+ self._has_received_printers = True
+ if self._printers and not self.activePrinter:
+ self.setActivePrinter(self._printers[0])
+
+ self.printersChanged.emit()
+ self._checkIfClusterHost()
+
+ ## Check is this device is a cluster host and takes the needed actions when it is not.
+ def _checkIfClusterHost(self):
+ if len(self._printers) < 1 and self.isConnected():
+ NotClusterHostMessage(self).show()
+ self.close()
+ CuraApplication.getInstance().getOutputDeviceManager().removeOutputDevice(self.key)
+
+ ## Updates the local list of print jobs with the list received from the cluster.
+ # \param remote_jobs: The print jobs received from the cluster.
+ def _updatePrintJobs(self, remote_jobs: List[ClusterPrintJobStatus]) -> None:
+ self._responseReceived()
+
+ # Keep track of the new print jobs to show.
+ # We create a new list instead of changing the existing one to get the correct order.
+ new_print_jobs = []
+
+ # Check which print jobs need to be created or updated.
+ for index, print_job_data in enumerate(remote_jobs):
+ print_job = next(
+ iter(print_job for print_job in self._print_jobs if print_job.key == print_job_data.uuid), None)
+ if not print_job:
+ new_print_jobs.append(self._createPrintJobModel(print_job_data))
+ else:
+ print_job_data.updateOutputModel(print_job)
+ if print_job_data.printer_uuid:
+ self._updateAssignedPrinter(print_job, print_job_data.printer_uuid)
+ if print_job_data.assigned_to:
+ self._updateAssignedPrinter(print_job, print_job_data.assigned_to)
+ new_print_jobs.append(print_job)
+
+ # Check which print job need to be removed (de-referenced).
+ remote_job_keys = [print_job_data.uuid for print_job_data in remote_jobs]
+ removed_jobs = [print_job for print_job in self._print_jobs if print_job.key not in remote_job_keys]
+ for removed_job in removed_jobs:
+ if removed_job.assignedPrinter:
+ removed_job.assignedPrinter.updateActivePrintJob(None)
+
+ self._print_jobs = new_print_jobs
+ self.printJobsChanged.emit()
+
+ ## Create a new print job model based on the remote status of the job.
+ # \param remote_job: The remote print job data.
+ def _createPrintJobModel(self, remote_job: ClusterPrintJobStatus) -> UM3PrintJobOutputModel:
+ model = remote_job.createOutputModel(ClusterOutputController(self))
+ if remote_job.printer_uuid:
+ self._updateAssignedPrinter(model, remote_job.printer_uuid)
+ if remote_job.assigned_to:
+ self._updateAssignedPrinter(model, remote_job.assigned_to)
+ return model
+
+ ## Updates the printer assignment for the given print job model.
+ def _updateAssignedPrinter(self, model: UM3PrintJobOutputModel, printer_uuid: str) -> None:
+ printer = next((p for p in self._printers if printer_uuid == p.key), None)
+ if not printer:
+ return
+ printer.updateActivePrintJob(model)
+ model.updateAssignedPrinter(printer)
+
+ ## Load Monitor tab QML.
+ def _loadMonitorTab(self) -> None:
+ plugin_registry = CuraApplication.getInstance().getPluginRegistry()
+ if not plugin_registry:
+ Logger.log("e", "Could not get plugin registry")
+ return
+ plugin_path = plugin_registry.getPluginPath("UM3NetworkPrinting")
+ if not plugin_path:
+ Logger.log("e", "Could not get plugin path")
+ return
+ self._monitor_view_qml_path = os.path.join(plugin_path, "resources", "qml", "MonitorStage.qml")
diff --git a/plugins/UM3NetworkPrinting/src/Utils.py b/plugins/UM3NetworkPrinting/src/Utils.py
new file mode 100644
index 0000000000..a628130416
--- /dev/null
+++ b/plugins/UM3NetworkPrinting/src/Utils.py
@@ -0,0 +1,30 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from datetime import datetime, timedelta
+
+from UM import i18nCatalog
+
+
+def formatTimeCompleted(seconds_remaining: int) -> str:
+ completed = datetime.now() + timedelta(seconds=seconds_remaining)
+ return "{hour:02d}:{minute:02d}".format(hour = completed.hour, minute = completed.minute)
+
+
+def formatDateCompleted(seconds_remaining: int) -> str:
+ now = datetime.now()
+ completed = now + timedelta(seconds=seconds_remaining)
+ days = (completed.date() - now.date()).days
+ i18n = i18nCatalog("cura")
+
+ # If finishing date is more than 7 days out, using "Mon Dec 3 at HH:MM" format
+ if days >= 7:
+ return completed.strftime("%a %b ") + "{day}".format(day = completed.day)
+ # If finishing date is within the next week, use "Monday at HH:MM" format
+ elif days >= 2:
+ return completed.strftime("%a")
+ # If finishing tomorrow, use "tomorrow at HH:MM" format
+ elif days >= 1:
+ return i18n.i18nc("@info:status", "tomorrow")
+ # If finishing today, use "today at HH:MM" format
+ else:
+ return i18n.i18nc("@info:status", "today")
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/__init__.py b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/__init__.py
deleted file mode 100644
index 777afc92c2..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-import json
-import os
-
-
-def readFixture(fixture_name: str) -> bytes:
- with open("{}/{}.json".format(os.path.dirname(__file__), fixture_name), "rb") as f:
- return f.read()
-
-def parseFixture(fixture_name: str) -> dict:
- return json.loads(readFixture(fixture_name).decode())
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json
deleted file mode 100644
index 4f9f47fc75..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusterStatusResponse.json
+++ /dev/null
@@ -1,95 +0,0 @@
-{
- "data": {
- "generated_time": "2018-12-10T08:23:55.110Z",
- "printers": [
- {
- "configuration": [
- {
- "extruder_index": 0,
- "material": {
- "material": "empty"
- },
- "print_core_id": "AA 0.4"
- },
- {
- "extruder_index": 1,
- "material": {
- "material": "empty"
- },
- "print_core_id": "AA 0.4"
- }
- ],
- "enabled": true,
- "firmware_version": "5.1.2.20180807",
- "friendly_name": "Master-Luke",
- "ip_address": "10.183.1.140",
- "machine_variant": "Ultimaker 3",
- "status": "maintenance",
- "unique_name": "ultimakersystem-ccbdd30044ec",
- "uuid": "b3a47ea3-1eeb-4323-9626-6f9c3c888f9e"
- },
- {
- "configuration": [
- {
- "extruder_index": 0,
- "material": {
- "brand": "Generic",
- "color": "Generic",
- "guid": "506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9",
- "material": "PLA"
- },
- "print_core_id": "AA 0.4"
- },
- {
- "extruder_index": 1,
- "material": {
- "brand": "Ultimaker",
- "color": "Red",
- "guid": "9cfe5bf1-bdc5-4beb-871a-52c70777842d",
- "material": "PLA"
- },
- "print_core_id": "AA 0.4"
- }
- ],
- "enabled": true,
- "firmware_version": "4.3.3.20180529",
- "friendly_name": "UM-Marijn",
- "ip_address": "10.183.1.166",
- "machine_variant": "Ultimaker 3",
- "status": "idle",
- "unique_name": "ultimakersystem-ccbdd30058ab",
- "uuid": "6e62c40a-4601-4b0e-9fec-c7c02c59c30a"
- }
- ],
- "print_jobs": [
- {
- "assigned_to": "6e62c40a-4601-4b0e-9fec-c7c02c59c30a",
- "configuration": [
- {
- "extruder_index": 0,
- "material": {
- "brand": "Ultimaker",
- "color": "Black",
- "guid": "3ee70a86-77d8-4b87-8005-e4a1bc57d2ce",
- "material": "PLA"
- },
- "print_core_id": "AA 0.4"
- }
- ],
- "constraints": {},
- "created_at": "2018-12-10T08:28:04.108Z",
- "force": false,
- "last_seen": 500165.109491861,
- "machine_variant": "Ultimaker 3",
- "name": "UM3_dragon",
- "network_error_count": 0,
- "owner": "Daniel Testing",
- "started": false,
- "status": "queued",
- "time_elapsed": 0,
- "time_total": 14145,
- "uuid": "d1c8bd52-5e9f-486a-8c25-a123cc8c7702"
- }
- ]
- }
-}
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusters.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusters.json
deleted file mode 100644
index 5200e3b971..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/getClusters.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "data": [{
- "cluster_id": "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq",
- "host_guid": "e90ae0ac-1257-4403-91ee-a44c9b7e8050",
- "host_name": "ultimakersystem-ccbdd30044ec",
- "host_version": "5.0.0.20170101",
- "is_online": true,
- "status": "active"
- }, {
- "cluster_id": "NWKV6vJP_LdYsXgXqAcaNCR0YcLJwar1ugh0ikEZsZs8",
- "host_guid": "e0ace90a-91ee-1257-4403-e8050a44c9b7",
- "host_name": "ultimakersystem-30044ecccbdd",
- "host_version": "5.1.2.20180807",
- "is_online": true,
- "status": "active"
- }]
-}
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json
deleted file mode 100644
index caedcd8732..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/postJobPrintResponse.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "data": {
- "cluster_job_id": "9a59d8e9-91d3-4ff6-b4cb-9db91c4094dd",
- "job_id": "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=",
- "status": "queued",
- "generated_time": "2018-12-10T08:23:55.110Z"
- }
-}
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json b/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json
deleted file mode 100644
index 1304f3a9f6..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/Fixtures/putJobUploadResponse.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "data": {
- "content_type": "text/plain",
- "job_id": "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE=",
- "job_name": "Ultimaker Robot v3.0",
- "status": "uploading",
- "upload_url": "https://api.ultimaker.com/print-job-upload"
- }
-}
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/Models/__init__.py b/plugins/UM3NetworkPrinting/tests/Cloud/Models/__init__.py
deleted file mode 100644
index f3f6970c54..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/Models/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py b/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py
deleted file mode 100644
index e504509d67..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/NetworkManagerMock.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-import json
-from typing import Dict, Tuple, Union, Optional, Any
-from unittest.mock import MagicMock
-
-from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
-
-from UM.Logger import Logger
-from UM.Signal import Signal
-
-
-class FakeSignal:
- def __init__(self):
- self._callbacks = []
-
- def connect(self, callback):
- self._callbacks.append(callback)
-
- def disconnect(self, callback):
- self._callbacks.remove(callback)
-
- def emit(self, *args, **kwargs):
- for callback in self._callbacks:
- callback(*args, **kwargs)
-
-
-## This class can be used to mock the QNetworkManager class and test the code using it.
-# After patching the QNetworkManager class, requests are prepared before they can be executed.
-# Any requests not prepared beforehand will cause KeyErrors.
-class NetworkManagerMock:
-
- # An enumeration of the supported operations and their code for the network access manager.
- _OPERATIONS = {
- "GET": QNetworkAccessManager.GetOperation,
- "POST": QNetworkAccessManager.PostOperation,
- "PUT": QNetworkAccessManager.PutOperation,
- "DELETE": QNetworkAccessManager.DeleteOperation,
- "HEAD": QNetworkAccessManager.HeadOperation,
- } # type: Dict[str, int]
-
- ## Initializes the network manager mock.
- def __init__(self) -> None:
- # A dict with the prepared replies, using the format {(http_method, url): reply}
- self.replies = {} # type: Dict[Tuple[str, str], MagicMock]
- self.request_bodies = {} # type: Dict[Tuple[str, str], bytes]
-
- # Signals used in the network manager.
- self.finished = Signal()
- self.authenticationRequired = Signal()
-
- ## Mock implementation of the get, post, put, delete and head methods from the network manager.
- # Since the methods are very simple and the same it didn't make sense to repeat the code.
- # \param method: The method being called.
- # \return The mocked function, if the method name is known. Defaults to the standard getattr function.
- def __getattr__(self, method: str) -> Any:
- ## This mock implementation will simply return the reply from the prepared ones.
- # it raises a KeyError if requests are done without being prepared.
- def doRequest(request: QNetworkRequest, body: Optional[bytes] = None, *_):
- key = method.upper(), request.url().toString()
- if body:
- self.request_bodies[key] = body
- return self.replies[key]
-
- operation = self._OPERATIONS.get(method.upper())
- if operation:
- return doRequest
-
- # the attribute is not one of the implemented methods, default to the standard implementation.
- return getattr(super(), method)
-
- ## Prepares a server reply for the given parameters.
- # \param method: The HTTP method.
- # \param url: The URL being requested.
- # \param status_code: The HTTP status code for the response.
- # \param response: The response body from the server (generally json-encoded).
- def prepareReply(self, method: str, url: str, status_code: int, response: Union[bytes, dict]) -> None:
- reply_mock = MagicMock()
- reply_mock.url().toString.return_value = url
- reply_mock.operation.return_value = self._OPERATIONS[method]
- reply_mock.attribute.return_value = status_code
- reply_mock.finished = FakeSignal()
- reply_mock.isFinished.return_value = False
- reply_mock.readAll.return_value = response if isinstance(response, bytes) else json.dumps(response).encode()
- self.replies[method, url] = reply_mock
- Logger.log("i", "Prepared mock {}-response to {} {}", status_code, method, url)
-
- ## Gets the request that was sent to the network manager for the given method and URL.
- # \param method: The HTTP method.
- # \param url: The URL.
- def getRequestBody(self, method: str, url: str) -> Optional[bytes]:
- return self.request_bodies.get((method.upper(), url))
-
- ## Emits the signal that the reply is ready to all prepared replies.
- def flushReplies(self) -> None:
- for key, reply in self.replies.items():
- Logger.log("i", "Flushing reply to {} {}", *key)
- reply.isFinished.return_value = True
- reply.finished.emit()
- self.finished.emit(reply)
- self.reset()
-
- ## Deletes all prepared replies
- def reset(self) -> None:
- self.replies.clear()
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py
deleted file mode 100644
index b79d009c31..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudApiClient.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from typing import List
-from unittest import TestCase
-from unittest.mock import patch, MagicMock
-
-from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot
-from ...src.Cloud import CloudApiClient
-from ...src.Cloud.Models.CloudClusterResponse import CloudClusterResponse
-from ...src.Cloud.Models.CloudClusterStatus import CloudClusterStatus
-from ...src.Cloud.Models.CloudPrintJobResponse import CloudPrintJobResponse
-from ...src.Cloud.Models.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
-from ...src.Cloud.Models.CloudError import CloudError
-from .Fixtures import readFixture, parseFixture
-from .NetworkManagerMock import NetworkManagerMock
-
-
-class TestCloudApiClient(TestCase):
- maxDiff = None
-
- def _errorHandler(self, errors: List[CloudError]):
- raise Exception("Received unexpected error: {}".format(errors))
-
- def setUp(self):
- super().setUp()
- self.account = MagicMock()
- self.account.isLoggedIn.return_value = True
-
- self.network = NetworkManagerMock()
- with patch.object(CloudApiClient, 'QNetworkAccessManager', return_value = self.network):
- self.api = CloudApiClient.CloudApiClient(self.account, self._errorHandler)
-
- def test_getClusters(self):
- result = []
-
- response = readFixture("getClusters")
- data = parseFixture("getClusters")["data"]
-
- self.network.prepareReply("GET", CuraCloudAPIRoot + "/connect/v1/clusters", 200, response)
- # The callback is a function that adds the result of the call to getClusters to the result list
- self.api.getClusters(lambda clusters: result.extend(clusters))
-
- self.network.flushReplies()
-
- self.assertEqual([CloudClusterResponse(**data[0]), CloudClusterResponse(**data[1])], result)
-
- def test_getClusterStatus(self):
- result = []
-
- response = readFixture("getClusterStatusResponse")
- data = parseFixture("getClusterStatusResponse")["data"]
-
- url = CuraCloudAPIRoot + "/connect/v1/clusters/R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC/status"
- self.network.prepareReply("GET", url, 200, response)
- self.api.getClusterStatus("R0YcLJwar1ugh0ikEZsZs8NWKV6vJP_LdYsXgXqAcaNC", lambda s: result.append(s))
-
- self.network.flushReplies()
-
- self.assertEqual([CloudClusterStatus(**data)], result)
-
- def test_requestUpload(self):
-
- results = []
-
- response = readFixture("putJobUploadResponse")
-
- self.network.prepareReply("PUT", CuraCloudAPIRoot + "/cura/v1/jobs/upload", 200, response)
- request = CloudPrintJobUploadRequest(job_name = "job name", file_size = 143234, content_type = "text/plain")
- self.api.requestUpload(request, lambda r: results.append(r))
- self.network.flushReplies()
-
- self.assertEqual(["text/plain"], [r.content_type for r in results])
- self.assertEqual(["uploading"], [r.status for r in results])
-
- def test_uploadToolPath(self):
-
- results = []
- progress = MagicMock()
-
- data = parseFixture("putJobUploadResponse")["data"]
- upload_response = CloudPrintJobResponse(**data)
-
- # Network client doesn't look into the reply
- self.network.prepareReply("PUT", upload_response.upload_url, 200, b'{}')
-
- mesh = ("1234" * 100000).encode()
- self.api.uploadToolPath(upload_response, mesh, lambda: results.append("sent"), progress.advance, progress.error)
-
- for _ in range(10):
- self.network.flushReplies()
- self.network.prepareReply("PUT", upload_response.upload_url, 200, b'{}')
-
- self.assertEqual(["sent"], results)
-
- def test_requestPrint(self):
-
- results = []
-
- response = readFixture("postJobPrintResponse")
-
- cluster_id = "NWKV6vJP_LdYsXgXqAcaNCR0YcLJwar1ugh0ikEZsZs8"
- cluster_job_id = "9a59d8e9-91d3-4ff6-b4cb-9db91c4094dd"
- job_id = "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE="
-
- self.network.prepareReply("POST",
- CuraCloudAPIRoot + "/connect/v1/clusters/{}/print/{}"
- .format(cluster_id, job_id),
- 200, response)
-
- self.api.requestPrint(cluster_id, job_id, lambda r: results.append(r))
-
- self.network.flushReplies()
-
- self.assertEqual([job_id], [r.job_id for r in results])
- self.assertEqual([cluster_job_id], [r.cluster_job_id for r in results])
- self.assertEqual(["queued"], [r.status for r in results])
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py
deleted file mode 100644
index c4d891302e..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDevice.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-import json
-from unittest import TestCase
-from unittest.mock import patch, MagicMock
-
-from UM.Scene.SceneNode import SceneNode
-from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot
-from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
-from ...src.Cloud import CloudApiClient
-from ...src.Cloud.CloudOutputDevice import CloudOutputDevice
-from ...src.Cloud.Models.CloudClusterResponse import CloudClusterResponse
-from .Fixtures import readFixture, parseFixture
-from .NetworkManagerMock import NetworkManagerMock
-
-
-class TestCloudOutputDevice(TestCase):
- maxDiff = None
-
- CLUSTER_ID = "RIZ6cZbWA_Ua7RZVJhrdVfVpf0z-MqaSHQE4v8aRTtYq"
- JOB_ID = "ABCDefGHIjKlMNOpQrSTUvYxWZ0-1234567890abcDE="
- HOST_NAME = "ultimakersystem-ccbdd30044ec"
- HOST_GUID = "e90ae0ac-1257-4403-91ee-a44c9b7e8050"
- HOST_VERSION = "5.2.0"
-
- STATUS_URL = "{}/connect/v1/clusters/{}/status".format(CuraCloudAPIRoot, CLUSTER_ID)
- PRINT_URL = "{}/connect/v1/clusters/{}/print/{}".format(CuraCloudAPIRoot, CLUSTER_ID, JOB_ID)
- REQUEST_UPLOAD_URL = "{}/cura/v1/jobs/upload".format(CuraCloudAPIRoot)
-
- def setUp(self):
- super().setUp()
- self.app = MagicMock()
-
- self.patches = [patch("UM.Qt.QtApplication.QtApplication.getInstance", return_value=self.app),
- patch("UM.Application.Application.getInstance", return_value=self.app)]
- for patched_method in self.patches:
- patched_method.start()
-
- self.cluster = CloudClusterResponse(self.CLUSTER_ID, self.HOST_GUID, self.HOST_NAME, is_online=True,
- status="active", host_version=self.HOST_VERSION)
-
- self.network = NetworkManagerMock()
- self.account = MagicMock(isLoggedIn=True, accessToken="TestAccessToken")
- self.onError = MagicMock()
- with patch.object(CloudApiClient, "QNetworkAccessManager", return_value = self.network):
- self._api = CloudApiClient.CloudApiClient(self.account, self.onError)
-
- self.device = CloudOutputDevice(self._api, self.cluster)
- self.cluster_status = parseFixture("getClusterStatusResponse")
- self.network.prepareReply("GET", self.STATUS_URL, 200, readFixture("getClusterStatusResponse"))
-
- def tearDown(self):
- try:
- super().tearDown()
- self.network.flushReplies()
- finally:
- for patched_method in self.patches:
- patched_method.stop()
-
- # We test for these in order to make sure the correct file type is selected depending on the firmware version.
- def test_properties(self):
- self.assertEqual(self.device.firmwareVersion, self.HOST_VERSION)
- self.assertEqual(self.device.name, self.HOST_NAME)
-
- def test_status(self):
- self.device._update()
- self.network.flushReplies()
-
- self.assertEqual([PrinterOutputModel, PrinterOutputModel], [type(printer) for printer in self.device.printers])
-
- controller_fields = {
- "_output_device": self.device,
- "can_abort": False,
- "can_control_manually": False,
- "can_pause": False,
- "can_pre_heat_bed": False,
- "can_pre_heat_hotends": False,
- "can_send_raw_gcode": False,
- "can_update_firmware": False,
- }
-
- self.assertEqual({printer["uuid"] for printer in self.cluster_status["data"]["printers"]},
- {printer.key for printer in self.device.printers})
- self.assertEqual([controller_fields, controller_fields],
- [printer.getController().__dict__ for printer in self.device.printers])
-
- self.assertEqual(["UM3PrintJobOutputModel"], [type(printer).__name__ for printer in self.device.printJobs])
- self.assertEqual({job["uuid"] for job in self.cluster_status["data"]["print_jobs"]},
- {job.key for job in self.device.printJobs})
- self.assertEqual({job["owner"] for job in self.cluster_status["data"]["print_jobs"]},
- {job.owner for job in self.device.printJobs})
- self.assertEqual({job["name"] for job in self.cluster_status["data"]["print_jobs"]},
- {job.name for job in self.device.printJobs})
-
- def test_remove_print_job(self):
- self.device._update()
- self.network.flushReplies()
- self.assertEqual(1, len(self.device.printJobs))
-
- self.cluster_status["data"]["print_jobs"].clear()
- self.network.prepareReply("GET", self.STATUS_URL, 200, self.cluster_status)
-
- self.device._last_request_time = None
- self.device._update()
- self.network.flushReplies()
- self.assertEqual([], self.device.printJobs)
-
- def test_remove_printers(self):
- self.device._update()
- self.network.flushReplies()
- self.assertEqual(2, len(self.device.printers))
-
- self.cluster_status["data"]["printers"].clear()
- self.network.prepareReply("GET", self.STATUS_URL, 200, self.cluster_status)
-
- self.device._last_request_time = None
- self.device._update()
- self.network.flushReplies()
- self.assertEqual([], self.device.printers)
-
- def test_print_to_cloud(self):
- active_machine_mock = self.app.getGlobalContainerStack.return_value
- active_machine_mock.getMetaDataEntry.side_effect = {"file_formats": "application/x-ufp"}.get
-
- request_upload_response = parseFixture("putJobUploadResponse")
- request_print_response = parseFixture("postJobPrintResponse")
- self.network.prepareReply("PUT", self.REQUEST_UPLOAD_URL, 201, request_upload_response)
- self.network.prepareReply("PUT", request_upload_response["data"]["upload_url"], 201, b"{}")
- self.network.prepareReply("POST", self.PRINT_URL, 200, request_print_response)
-
- file_handler = MagicMock()
- file_handler.getSupportedFileTypesWrite.return_value = [{
- "extension": "ufp",
- "mime_type": "application/x-ufp",
- "mode": 2
- }, {
- "extension": "gcode.gz",
- "mime_type": "application/gzip",
- "mode": 2,
- }]
- file_handler.getWriterByMimeType.return_value.write.side_effect = \
- lambda stream, nodes: stream.write(str(nodes).encode())
-
- scene_nodes = [SceneNode()]
- expected_mesh = str(scene_nodes).encode()
- self.device.requestWrite(scene_nodes, file_handler=file_handler, file_name="FileName")
-
- self.network.flushReplies()
- self.assertEqual(
- {"data": {"content_type": "application/x-ufp", "file_size": len(expected_mesh), "job_name": "FileName"}},
- json.loads(self.network.getRequestBody("PUT", self.REQUEST_UPLOAD_URL).decode())
- )
- self.assertEqual(expected_mesh,
- self.network.getRequestBody("PUT", request_upload_response["data"]["upload_url"]))
- self.assertIsNone(self.network.getRequestBody("POST", self.PRINT_URL))
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py
deleted file mode 100644
index e24ca1694e..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/TestCloudOutputDeviceManager.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from unittest import TestCase
-from unittest.mock import patch, MagicMock
-
-from UM.OutputDevice.OutputDeviceManager import OutputDeviceManager
-from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot
-from ...src.Cloud import CloudApiClient
-from ...src.Cloud import CloudOutputDeviceManager
-from .Fixtures import parseFixture, readFixture
-from .NetworkManagerMock import NetworkManagerMock, FakeSignal
-
-
-class TestCloudOutputDeviceManager(TestCase):
- maxDiff = None
-
- URL = CuraCloudAPIRoot + "/connect/v1/clusters"
-
- def setUp(self):
- super().setUp()
- self.app = MagicMock()
- self.device_manager = OutputDeviceManager()
- self.app.getOutputDeviceManager.return_value = self.device_manager
-
- self.patches = [patch("UM.Qt.QtApplication.QtApplication.getInstance", return_value=self.app),
- patch("UM.Application.Application.getInstance", return_value=self.app)]
- for patched_method in self.patches:
- patched_method.start()
-
- self.network = NetworkManagerMock()
- self.timer = MagicMock(timeout = FakeSignal())
- with patch.object(CloudApiClient, "QNetworkAccessManager", return_value = self.network), \
- patch.object(CloudOutputDeviceManager, "QTimer", return_value = self.timer):
- self.manager = CloudOutputDeviceManager.CloudOutputDeviceManager()
- self.clusters_response = parseFixture("getClusters")
- self.network.prepareReply("GET", self.URL, 200, readFixture("getClusters"))
-
- def tearDown(self):
- try:
- self._beforeTearDown()
-
- self.network.flushReplies()
- self.manager.stop()
- for patched_method in self.patches:
- patched_method.stop()
- finally:
- super().tearDown()
-
- ## Before tear down method we check whether the state of the output device manager is what we expect based on the
- # mocked API response.
- def _beforeTearDown(self):
- # let the network send replies
- self.network.flushReplies()
- # get the created devices
- devices = self.device_manager.getOutputDevices()
- # TODO: Check active device
-
- response_clusters = self.clusters_response.get("data", [])
- manager_clusters = sorted([device.clusterData.toDict() for device in self.manager._remote_clusters.values()],
- key=lambda cluster: cluster['cluster_id'], reverse=True)
- self.assertEqual(response_clusters, manager_clusters)
-
- ## Runs the initial request to retrieve the clusters.
- def _loadData(self):
- self.manager.start()
- self.network.flushReplies()
-
- def test_device_is_created(self):
- # just create the cluster, it is checked at tearDown
- self._loadData()
-
- def test_device_is_updated(self):
- self._loadData()
-
- # update the cluster from member variable, which is checked at tearDown
- self.clusters_response["data"][0]["host_name"] = "New host name"
- self.network.prepareReply("GET", self.URL, 200, self.clusters_response)
-
- self.manager._update_timer.timeout.emit()
-
- def test_device_is_removed(self):
- self._loadData()
-
- # delete the cluster from member variable, which is checked at tearDown
- del self.clusters_response["data"][1]
- self.network.prepareReply("GET", self.URL, 200, self.clusters_response)
-
- self.manager._update_timer.timeout.emit()
-
- def test_device_connects_by_cluster_id(self):
- active_machine_mock = self.app.getGlobalContainerStack.return_value
- cluster1, cluster2 = self.clusters_response["data"]
- cluster_id = cluster1["cluster_id"]
- active_machine_mock.getMetaDataEntry.side_effect = {"um_cloud_cluster_id": cluster_id}.get
-
- self._loadData()
-
- self.assertTrue(self.device_manager.getOutputDevice(cluster1["cluster_id"]).isConnected())
- self.assertIsNone(self.device_manager.getOutputDevice(cluster2["cluster_id"]))
- self.assertEquals([], active_machine_mock.setMetaDataEntry.mock_calls)
-
- def test_device_connects_by_network_key(self):
- active_machine_mock = self.app.getGlobalContainerStack.return_value
-
- cluster1, cluster2 = self.clusters_response["data"]
- network_key = cluster2["host_name"] + ".ultimaker.local"
- active_machine_mock.getMetaDataEntry.side_effect = {"um_network_key": network_key}.get
-
- self._loadData()
-
- self.assertIsNone(self.device_manager.getOutputDevice(cluster1["cluster_id"]))
- self.assertTrue(self.device_manager.getOutputDevice(cluster2["cluster_id"]).isConnected())
-
- active_machine_mock.setMetaDataEntry.assert_called_with("um_cloud_cluster_id", cluster2["cluster_id"])
-
- @patch.object(CloudOutputDeviceManager, "Message")
- def test_api_error(self, message_mock):
- self.clusters_response = {
- "errors": [{"id": "notFound", "title": "Not found!", "http_status": "404", "code": "notFound"}]
- }
- self.network.prepareReply("GET", self.URL, 200, self.clusters_response)
- self._loadData()
- message_mock.return_value.show.assert_called_once_with()
diff --git a/plugins/UM3NetworkPrinting/tests/Cloud/__init__.py b/plugins/UM3NetworkPrinting/tests/Cloud/__init__.py
deleted file mode 100644
index f3f6970c54..0000000000
--- a/plugins/UM3NetworkPrinting/tests/Cloud/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
diff --git a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py b/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py
deleted file mode 100644
index 952d38dcf4..0000000000
--- a/plugins/UM3NetworkPrinting/tests/TestSendMaterialJob.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-import io
-import json
-from unittest import TestCase, mock
-from unittest.mock import patch, call, MagicMock
-
-from PyQt5.QtCore import QByteArray
-
-from UM.Application import Application
-
-from cura.Machines.MaterialGroup import MaterialGroup
-from cura.Machines.MaterialNode import MaterialNode
-
-from ..src.SendMaterialJob import SendMaterialJob
-
-_FILES_MAP = {"generic_pla_white": "/materials/generic_pla_white.xml.fdm_material",
- "generic_pla_black": "/materials/generic_pla_black.xml.fdm_material",
- }
-
-
-@patch("builtins.open", lambda _, __: io.StringIO(""))
-class TestSendMaterialJob(TestCase):
- # version 1
- _LOCAL_MATERIAL_WHITE = {"type": "material", "status": "unknown", "id": "generic_pla_white",
- "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA",
- "brand": "Generic", "material": "PLA", "color_name": "White",
- "GUID": "badb0ee7-87c8-4f3f-9398-938587b67dce", "version": "1", "color_code": "#ffffff",
- "description": "Test PLA White", "adhesion_info": "Use glue.", "approximate_diameter": "3",
- "properties": {"density": "1.00", "diameter": "2.85", "weight": "750"},
- "definition": "fdmprinter", "compatible": True}
-
- # version 2
- _LOCAL_MATERIAL_WHITE_NEWER = {"type": "material", "status": "unknown", "id": "generic_pla_white",
- "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA",
- "brand": "Generic", "material": "PLA", "color_name": "White",
- "GUID": "badb0ee7-87c8-4f3f-9398-938587b67dce", "version": "2",
- "color_code": "#ffffff",
- "description": "Test PLA White", "adhesion_info": "Use glue.",
- "approximate_diameter": "3",
- "properties": {"density": "1.00", "diameter": "2.85", "weight": "750"},
- "definition": "fdmprinter", "compatible": True}
-
- # invalid version: "one"
- _LOCAL_MATERIAL_WHITE_INVALID_VERSION = {"type": "material", "status": "unknown", "id": "generic_pla_white",
- "base_file": "generic_pla_white", "setting_version": "5", "name": "White PLA",
- "brand": "Generic", "material": "PLA", "color_name": "White",
- "GUID": "badb0ee7-87c8-4f3f-9398-938587b67dce", "version": "one",
- "color_code": "#ffffff",
- "description": "Test PLA White", "adhesion_info": "Use glue.",
- "approximate_diameter": "3",
- "properties": {"density": "1.00", "diameter": "2.85", "weight": "750"},
- "definition": "fdmprinter", "compatible": True}
-
- _LOCAL_MATERIAL_WHITE_ALL_RESULT = {"generic_pla_white": MaterialGroup("generic_pla_white",
- MaterialNode(_LOCAL_MATERIAL_WHITE))}
-
- _LOCAL_MATERIAL_WHITE_NEWER_ALL_RESULT = {"generic_pla_white": MaterialGroup("generic_pla_white",
- MaterialNode(_LOCAL_MATERIAL_WHITE_NEWER))}
-
- _LOCAL_MATERIAL_WHITE_INVALID_VERSION_ALL_RESULT = {"generic_pla_white": MaterialGroup("generic_pla_white",
- MaterialNode(_LOCAL_MATERIAL_WHITE_INVALID_VERSION))}
-
- _LOCAL_MATERIAL_BLACK = {"type": "material", "status": "unknown", "id": "generic_pla_black",
- "base_file": "generic_pla_black", "setting_version": "5", "name": "Yellow CPE",
- "brand": "Ultimaker", "material": "CPE", "color_name": "Black",
- "GUID": "5fbb362a-41f9-4818-bb43-15ea6df34aa4", "version": "1", "color_code": "#000000",
- "description": "Test PLA Black", "adhesion_info": "Use glue.", "approximate_diameter": "3",
- "properties": {"density": "1.01", "diameter": "2.85", "weight": "750"},
- "definition": "fdmprinter", "compatible": True}
-
- _LOCAL_MATERIAL_BLACK_ALL_RESULT = {"generic_pla_black": MaterialGroup("generic_pla_black",
- MaterialNode(_LOCAL_MATERIAL_BLACK))}
-
- _REMOTE_MATERIAL_WHITE = {
- "guid": "badb0ee7-87c8-4f3f-9398-938587b67dce",
- "material": "PLA",
- "brand": "Generic",
- "version": 1,
- "color": "White",
- "density": 1.00
- }
-
- _REMOTE_MATERIAL_BLACK = {
- "guid": "5fbb362a-41f9-4818-bb43-15ea6df34aa4",
- "material": "PLA",
- "brand": "Generic",
- "version": 2,
- "color": "Black",
- "density": 1.00
- }
-
- def test_run(self):
- device_mock = MagicMock()
- job = SendMaterialJob(device_mock)
- job.run()
-
- # We expect the materials endpoint to be called when the job runs.
- device_mock.get.assert_called_with("materials/", on_finished = job._onGetRemoteMaterials)
-
- def test__onGetRemoteMaterials_withFailedRequest(self):
- reply_mock = MagicMock()
- device_mock = MagicMock()
- reply_mock.attribute.return_value = 404
- job = SendMaterialJob(device_mock)
- job._onGetRemoteMaterials(reply_mock)
-
- # We expect the device not to be called for any follow up.
- self.assertEqual(0, device_mock.createFormPart.call_count)
-
- def test__onGetRemoteMaterials_withWrongEncoding(self):
- reply_mock = MagicMock()
- device_mock = MagicMock()
- reply_mock.attribute.return_value = 200
- reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("cp500"))
- job = SendMaterialJob(device_mock)
- job._onGetRemoteMaterials(reply_mock)
-
- # Given that the parsing fails we do no expect the device to be called for any follow up.
- self.assertEqual(0, device_mock.createFormPart.call_count)
-
- def test__onGetRemoteMaterials_withBadJsonAnswer(self):
- reply_mock = MagicMock()
- device_mock = MagicMock()
- reply_mock.attribute.return_value = 200
- reply_mock.readAll.return_value = QByteArray(b"Six sick hicks nick six slick bricks with picks and sticks.")
- job = SendMaterialJob(device_mock)
- job._onGetRemoteMaterials(reply_mock)
-
- # Given that the parsing fails we do no expect the device to be called for any follow up.
- self.assertEqual(0, device_mock.createFormPart.call_count)
-
- def test__onGetRemoteMaterials_withMissingGuidInRemoteMaterial(self):
- reply_mock = MagicMock()
- device_mock = MagicMock()
- reply_mock.attribute.return_value = 200
- remote_material_without_guid = self._REMOTE_MATERIAL_WHITE.copy()
- del remote_material_without_guid["guid"]
- reply_mock.readAll.return_value = QByteArray(json.dumps([remote_material_without_guid]).encode("ascii"))
- job = SendMaterialJob(device_mock)
- job._onGetRemoteMaterials(reply_mock)
-
- # Given that parsing fails we do not expect the device to be called for any follow up.
- self.assertEqual(0, device_mock.createFormPart.call_count)
-
- @patch("cura.Machines.MaterialManager.MaterialManager")
- @patch("cura.Settings.CuraContainerRegistry")
- @patch("UM.Application")
- def test__onGetRemoteMaterials_withInvalidVersionInLocalMaterial(self, application_mock, container_registry_mock,
- material_manager_mock):
- reply_mock = MagicMock()
- device_mock = MagicMock()
- application_mock.getContainerRegistry.return_value = container_registry_mock
- application_mock.getMaterialManager.return_value = material_manager_mock
-
- reply_mock.attribute.return_value = 200
- reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii"))
-
- material_manager_mock.getAllMaterialGroups.return_value = self._LOCAL_MATERIAL_WHITE_INVALID_VERSION_ALL_RESULT.copy()
-
- with mock.patch.object(Application, "getInstance", new = lambda: application_mock):
- job = SendMaterialJob(device_mock)
- job._onGetRemoteMaterials(reply_mock)
-
- self.assertEqual(0, device_mock.createFormPart.call_count)
-
- @patch("UM.Application.Application.getInstance")
- def test__onGetRemoteMaterials_withNoUpdate(self, application_mock):
- reply_mock = MagicMock()
- device_mock = MagicMock()
- container_registry_mock = application_mock.getContainerRegistry.return_value
- material_manager_mock = application_mock.getMaterialManager.return_value
-
- device_mock.createFormPart.return_value = "_xXx_"
-
- material_manager_mock.getAllMaterialGroups.return_value = self._LOCAL_MATERIAL_WHITE_ALL_RESULT.copy()
-
- reply_mock.attribute.return_value = 200
- reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii"))
-
- with mock.patch.object(Application, "getInstance", new = lambda: application_mock):
- job = SendMaterialJob(device_mock)
- job._onGetRemoteMaterials(reply_mock)
-
- self.assertEqual(0, device_mock.createFormPart.call_count)
- self.assertEqual(0, device_mock.postFormWithParts.call_count)
-
- @patch("UM.Application.Application.getInstance")
- def test__onGetRemoteMaterials_withUpdatedMaterial(self, get_instance_mock):
- reply_mock = MagicMock()
- device_mock = MagicMock()
- application_mock = get_instance_mock.return_value
- container_registry_mock = application_mock.getContainerRegistry.return_value
- material_manager_mock = application_mock.getMaterialManager.return_value
-
- container_registry_mock.getContainerFilePathById = lambda x: _FILES_MAP.get(x)
-
- device_mock.createFormPart.return_value = "_xXx_"
-
- material_manager_mock.getAllMaterialGroups.return_value = self._LOCAL_MATERIAL_WHITE_NEWER_ALL_RESULT.copy()
-
- reply_mock.attribute.return_value = 200
- reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_WHITE]).encode("ascii"))
-
- job = SendMaterialJob(device_mock)
- job._onGetRemoteMaterials(reply_mock)
-
- self.assertEqual(1, device_mock.createFormPart.call_count)
- self.assertEqual(1, device_mock.postFormWithParts.call_count)
- self.assertEquals(
- [call.createFormPart("name=\"file\"; filename=\"generic_pla_white.xml.fdm_material\"", ""),
- call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)],
- device_mock.method_calls)
-
- @patch("UM.Application.Application.getInstance")
- def test__onGetRemoteMaterials_withNewMaterial(self, application_mock):
- reply_mock = MagicMock()
- device_mock = MagicMock()
- container_registry_mock = application_mock.getContainerRegistry.return_value
- material_manager_mock = application_mock.getMaterialManager.return_value
-
- container_registry_mock.getContainerFilePathById = lambda x: _FILES_MAP.get(x)
-
- device_mock.createFormPart.return_value = "_xXx_"
-
- all_results = self._LOCAL_MATERIAL_WHITE_ALL_RESULT.copy()
- for key, value in self._LOCAL_MATERIAL_BLACK_ALL_RESULT.items():
- all_results[key] = value
- material_manager_mock.getAllMaterialGroups.return_value = all_results
-
- reply_mock.attribute.return_value = 200
- reply_mock.readAll.return_value = QByteArray(json.dumps([self._REMOTE_MATERIAL_BLACK]).encode("ascii"))
-
- with mock.patch.object(Application, "getInstance", new = lambda: application_mock):
- job = SendMaterialJob(device_mock)
- job._onGetRemoteMaterials(reply_mock)
-
- self.assertEqual(1, device_mock.createFormPart.call_count)
- self.assertEqual(1, device_mock.postFormWithParts.call_count)
- self.assertEquals(
- [call.createFormPart("name=\"file\"; filename=\"generic_pla_white.xml.fdm_material\"", ""),
- call.postFormWithParts(target = "materials/", parts = ["_xXx_"], on_finished = job.sendingFinished)],
- device_mock.method_calls)
diff --git a/plugins/UM3NetworkPrinting/tests/__init__.py b/plugins/UM3NetworkPrinting/tests/__init__.py
deleted file mode 100644
index f3f6970c54..0000000000
--- a/plugins/UM3NetworkPrinting/tests/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
diff --git a/plugins/USBPrinting/AvrFirmwareUpdater.py b/plugins/USBPrinting/AvrFirmwareUpdater.py
index 56e3f99c23..0f7146560d 100644
--- a/plugins/USBPrinting/AvrFirmwareUpdater.py
+++ b/plugins/USBPrinting/AvrFirmwareUpdater.py
@@ -13,7 +13,7 @@ from time import sleep
MYPY = False
if MYPY:
- from cura.PrinterOutputDevice import PrinterOutputDevice
+ from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
class AvrFirmwareUpdater(FirmwareUpdater):
diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py
index 752773723e..c9758d88d4 100644
--- a/plugins/USBPrinting/USBPrinterOutputDevice.py
+++ b/plugins/USBPrinting/USBPrinterOutputDevice.py
@@ -1,29 +1,38 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+
import os
-from UM.Logger import Logger
from UM.i18n import i18nCatalog
+from UM.Logger import Logger
+from UM.Mesh.MeshWriter import MeshWriter #To get the g-code output.
+from UM.Message import Message #Show an error when already printing.
+from UM.PluginRegistry import PluginRegistry #To get the g-code output.
from UM.Qt.Duration import DurationFormat
from cura.CuraApplication import CuraApplication
-from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType
-from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
-from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
+from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType
+from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
+from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
from cura.PrinterOutput.GenericOutputController import GenericOutputController
from .AutoDetectBaudJob import AutoDetectBaudJob
from .AvrFirmwareUpdater import AvrFirmwareUpdater
+from io import StringIO #To write the g-code output.
+from queue import Queue
from serial import Serial, SerialException, SerialTimeoutException
from threading import Thread, Event
from time import time
-from queue import Queue
-from typing import Union, Optional, List, cast
+from typing import Union, Optional, List, cast, TYPE_CHECKING
import re
import functools # Used for reduce
+if TYPE_CHECKING:
+ from UM.FileHandler.FileHandler import FileHandler
+ from UM.Scene.SceneNode import SceneNode
+
catalog = i18nCatalog("cura")
@@ -52,7 +61,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._all_baud_rates = [115200, 250000, 500000, 230400, 57600, 38400, 19200, 9600]
# Instead of using a timer, we really need the update to be as a thread, as reading from serial can block.
- self._update_thread = Thread(target = self._update, daemon = True)
+ self._update_thread = Thread(target = self._update, daemon = True, name = "USBPrinterUpdate")
self._last_temperature_request = None # type: Optional[int]
self._firmware_idle_count = 0
@@ -108,34 +117,39 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
## Request the current scene to be sent to a USB-connected printer.
#
# \param nodes A collection of scene nodes to send. This is ignored.
- # \param file_name \type{string} A suggestion for a file name to write.
+ # \param file_name A suggestion for a file name to write.
# \param filter_by_machine Whether to filter MIME types by machine. This
# is ignored.
# \param kwargs Keyword arguments.
- def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs):
+ def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, limit_mimetypes: bool = False,
+ file_handler: Optional["FileHandler"] = None, filter_by_machine: bool = False, **kwargs) -> None:
if self._is_printing:
- return # Aleady printing
+ message = Message(text = catalog.i18nc("@message", "A print is still in progress. Cura cannot start another print via USB until the previous print has completed."), title = catalog.i18nc("@message", "Print in Progress"))
+ message.show()
+ return # Already printing
self.writeStarted.emit(self)
# cancel any ongoing preheat timer before starting a print
- self._printers[0].getController().stopPreheatTimers()
+ controller = cast(GenericOutputController, self._printers[0].getController())
+ controller.stopPreheatTimers()
CuraApplication.getInstance().getController().setActiveStage("MonitorStage")
- # find the G-code for the active build plate to print
- active_build_plate_id = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
- gcode_dict = getattr(CuraApplication.getInstance().getController().getScene(), "gcode_dict")
- gcode_list = gcode_dict[active_build_plate_id]
+ #Find the g-code to print.
+ gcode_textio = StringIO()
+ gcode_writer = cast(MeshWriter, PluginRegistry.getInstance().getPluginObject("GCodeWriter"))
+ success = gcode_writer.write(gcode_textio, None)
+ if not success:
+ return
- self._printGCode(gcode_list)
+ self._printGCode(gcode_textio.getvalue())
## Start a print based on a g-code.
- # \param gcode_list List with gcode (strings).
- def _printGCode(self, gcode_list: List[str]):
+ # \param gcode The g-code to print.
+ def _printGCode(self, gcode: str):
self._gcode.clear()
self._paused = False
- for layer in gcode_list:
- self._gcode.extend(layer.split("\n"))
+ self._gcode.extend(gcode.split("\n"))
# Reset line number. If this is not done, first line is sometimes ignored
self._gcode.insert(0, "M110")
@@ -176,7 +190,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
try:
self._serial = Serial(str(self._serial_port), self._baud_rate, timeout=self._timeout, writeTimeout=self._timeout)
except SerialException:
- Logger.log("w", "An exception occured while trying to create serial connection")
+ Logger.log("w", "An exception occurred while trying to create serial connection")
return
CuraApplication.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged)
self._onGlobalContainerStackChanged()
@@ -198,7 +212,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._serial.close()
# Re-create the thread so it can be started again later.
- self._update_thread = Thread(target=self._update, daemon=True)
+ self._update_thread = Thread(target=self._update, daemon=True, name = "USBPrinterUpdate")
self._serial = None
## Send a command to printer.
@@ -221,6 +235,9 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
except SerialTimeoutException:
Logger.log("w", "Timeout when sending command to printer via USB.")
self._command_received.set()
+ except SerialException:
+ Logger.logException("w", "An unexpected exception occurred while writing to the serial.")
+ self.setConnectionState(ConnectionState.Error)
def _update(self):
while self._connection_state == ConnectionState.Connected and self._serial is not None:
@@ -243,7 +260,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._last_temperature_request = time()
if re.search(b"[B|T\d*]: ?\d+\.?\d*", line): # Temperature message. 'T:' for extruder and 'B:' for bed
- extruder_temperature_matches = re.findall(b"T(\d*): ?(\d+\.?\d*) ?\/?(\d+\.?\d*)?", line)
+ extruder_temperature_matches = re.findall(b"T(\d*): ?(\d+\.?\d*)\s*\/?(\d+\.?\d*)?", line)
# Update all temperature values
matched_extruder_nrs = []
for match in extruder_temperature_matches:
@@ -265,7 +282,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
if match[2]:
extruder.updateTargetHotendTemperature(float(match[2]))
- bed_temperature_matches = re.findall(b"B: ?(\d+\.?\d*) ?\/?(\d+\.?\d*) ?", line)
+ bed_temperature_matches = re.findall(b"B: ?(\d+\.?\d*)\s*\/?(\d+\.?\d*)?", line)
if bed_temperature_matches:
match = bed_temperature_matches[0]
if match[0]:
@@ -311,7 +328,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
def _setFirmwareName(self, name):
new_name = re.findall(r"FIRMWARE_NAME:(.*);", str(name))
- if new_name:
+ if new_name:
self._firmware_name = new_name[0]
Logger.log("i", "USB output device Firmware name: %s", self._firmware_name)
else:
@@ -366,10 +383,17 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._sendCommand("N%d%s*%d" % (self._gcode_position, line, checksum))
- progress = (self._gcode_position / len(self._gcode))
+ print_job = self._printers[0].activePrintJob
+ try:
+ progress = self._gcode_position / len(self._gcode)
+ except ZeroDivisionError:
+ # There is nothing to send!
+ if print_job is not None:
+ print_job.updateState("error")
+ return
elapsed_time = int(time() - self._print_start_time)
- print_job = self._printers[0].activePrintJob
+
if print_job is None:
controller = GenericOutputController(self)
controller.setCanUpdateFirmware(True)
diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py
index d4c0d1828e..56f53145b0 100644
--- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py
+++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py
@@ -4,16 +4,16 @@
import threading
import time
import serial.tools.list_ports
+from os import environ
+from re import search
-from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
+from PyQt5.QtCore import QObject, pyqtSignal
-from UM.Logger import Logger
from UM.Signal import Signal, signalemitter
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
from UM.i18n import i18nCatalog
-from cura.PrinterOutputDevice import ConnectionState
-from cura.CuraApplication import CuraApplication
+from cura.PrinterOutput.PrinterOutputDevice import ConnectionState
from . import USBPrinterOutputDevice
@@ -114,6 +114,27 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin):
port = (port.device, port.description, port.hwid)
if only_list_usb and not port[2].startswith("USB"):
continue
+
+ # To prevent cura from messing with serial ports of other devices,
+ # filter by regular expressions passed in as environment variables.
+ # Get possible patterns with python3 -m serial.tools.list_ports -v
+
+ # set CURA_DEVICENAMES=USB[1-9] -> e.g. not matching /dev/ttyUSB0
+ pattern = environ.get('CURA_DEVICENAMES')
+ if pattern and not search(pattern, port[0]):
+ continue
+
+ # set CURA_DEVICETYPES=CP2102 -> match a type of serial converter
+ pattern = environ.get('CURA_DEVICETYPES')
+ if pattern and not search(pattern, port[1]):
+ continue
+
+ # set CURA_DEVICEINFOS=LOCATION=2-1.4 -> match a physical port
+ # set CURA_DEVICEINFOS=VID:PID=10C4:EA60 -> match a vendor:product
+ pattern = environ.get('CURA_DEVICEINFOS')
+ if pattern and not search(pattern, port[2]):
+ continue
+
base_list += [port[0]]
return list(base_list)
diff --git a/plugins/USBPrinting/plugin.json b/plugins/USBPrinting/plugin.json
index 45971d858b..c05ea65f2d 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.2",
- "api": "6.0",
+ "api": "7.0",
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
"i18n-catalog": "cura"
}
diff --git a/plugins/UltimakerMachineActions/BedLevelMachineAction.py b/plugins/UltimakerMachineActions/BedLevelMachineAction.py
index d6de21c89b..818ad0e4f0 100644
--- a/plugins/UltimakerMachineActions/BedLevelMachineAction.py
+++ b/plugins/UltimakerMachineActions/BedLevelMachineAction.py
@@ -4,7 +4,7 @@
from typing import List
from cura.MachineAction import MachineAction
-from cura.PrinterOutputDevice import PrinterOutputDevice
+from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
from UM.FlameProfiler import pyqtSlot
diff --git a/plugins/UltimakerMachineActions/BedLevelMachineAction.qml b/plugins/UltimakerMachineActions/BedLevelMachineAction.qml
index 262d5df376..a9f7e93d44 100644
--- a/plugins/UltimakerMachineActions/BedLevelMachineAction.qml
+++ b/plugins/UltimakerMachineActions/BedLevelMachineAction.qml
@@ -1,24 +1,27 @@
-// Copyright (c) 2016 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
-import QtQuick.Controls 1.1
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
+import QtQuick 2.10
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.3
-import UM 1.2 as UM
-import Cura 1.0 as Cura
+import UM 1.3 as UM
+import Cura 1.1 as Cura
Cura.MachineAction
{
- anchors.fill: parent;
+ UM.I18nCatalog { id: catalog; name: "cura"; }
+
+ anchors.fill: parent
+
Item
{
id: bedLevelMachineAction
- anchors.fill: parent;
-
- UM.I18nCatalog { id: catalog; name: "cura"; }
+ anchors.top: parent.top
+ anchors.topMargin: UM.Theme.getSize("default_margin").height * 3
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: parent.width * 3 / 4
Label
{
@@ -26,17 +29,24 @@ Cura.MachineAction
width: parent.width
text: catalog.i18nc("@title", "Build Plate Leveling")
wrapMode: Text.WordWrap
- font.pointSize: 18;
+ font: UM.Theme.getFont("medium")
+ color: UM.Theme.getColor("text")
+ renderType: Text.NativeRendering
}
+
Label
{
id: pageDescription
anchors.top: pageTitle.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
+ anchors.topMargin: UM.Theme.getSize("default_margin").height * 3
width: parent.width
wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "To make sure your prints will come out great, you can now adjust your buildplate. When you click 'Move to Next Position' the nozzle will move to the different positions that can be adjusted.")
+ font: UM.Theme.getFont("default")
+ color: UM.Theme.getColor("text")
+ renderType: Text.NativeRendering
}
+
Label
{
id: bedlevelingText
@@ -45,37 +55,40 @@ Cura.MachineAction
width: parent.width
wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle.")
+ font: UM.Theme.getFont("default")
+ color: UM.Theme.getColor("text")
+ renderType: Text.NativeRendering
}
Row
{
id: bedlevelingWrapper
anchors.top: bedlevelingText.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
+ anchors.topMargin: UM.Theme.getSize("default_margin").height * 3
anchors.horizontalCenter: parent.horizontalCenter
width: childrenRect.width
spacing: UM.Theme.getSize("default_margin").width
- Button
+ Cura.ActionButton
{
id: startBedLevelingButton
- text: catalog.i18nc("@action:button","Start Build Plate Leveling")
+ text: catalog.i18nc("@action:button", "Start Build Plate Leveling")
onClicked:
{
- startBedLevelingButton.visible = false;
- bedlevelingButton.visible = true;
- manager.startBedLeveling();
+ startBedLevelingButton.visible = false
+ bedlevelingButton.visible = true
+ manager.startBedLeveling()
}
}
- Button
+ Cura.ActionButton
{
id: bedlevelingButton
- text: catalog.i18nc("@action:button","Move to Next Position")
+ text: catalog.i18nc("@action:button", "Move to Next Position")
visible: false
onClicked:
{
- manager.moveToNextLevelPosition();
+ manager.moveToNextLevelPosition()
}
}
}
diff --git a/plugins/UltimakerMachineActions/UM2UpgradeSelection.py b/plugins/UltimakerMachineActions/UM2UpgradeSelection.py
deleted file mode 100644
index 6ff3f0b629..0000000000
--- a/plugins/UltimakerMachineActions/UM2UpgradeSelection.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (c) 2018 Ultimaker B.V.
-# Uranium is released under the terms of the LGPLv3 or higher.
-
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from cura.MachineAction import MachineAction
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty
-
-from UM.i18n import i18nCatalog
-from UM.Application import Application
-from UM.Util import parseBool
-catalog = i18nCatalog("cura")
-
-
-## The Ultimaker 2 can have a few revisions & upgrades.
-class UM2UpgradeSelection(MachineAction):
- def __init__(self):
- super().__init__("UM2UpgradeSelection", catalog.i18nc("@action", "Select upgrades"))
- self._qml_url = "UM2UpgradeSelectionMachineAction.qml"
-
- self._container_registry = ContainerRegistry.getInstance()
-
- self._current_global_stack = None
-
- Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
- self._reset()
-
- def _reset(self):
- self.hasVariantsChanged.emit()
-
- def _onGlobalStackChanged(self):
- if self._current_global_stack:
- self._current_global_stack.metaDataChanged.disconnect(self._onGlobalStackMetaDataChanged)
-
- self._current_global_stack = Application.getInstance().getGlobalContainerStack()
- if self._current_global_stack:
- self._current_global_stack.metaDataChanged.connect(self._onGlobalStackMetaDataChanged)
- self._reset()
-
- def _onGlobalStackMetaDataChanged(self):
- self._reset()
-
- hasVariantsChanged = pyqtSignal()
-
- def setHasVariants(self, has_variants = True):
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if global_container_stack:
- variant_container = global_container_stack.extruders["0"].variant
-
- if has_variants:
- global_container_stack.setMetaDataEntry("has_variants", True)
-
- # Set the variant container to a sane default
- empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
- if type(variant_container) == type(empty_container):
- search_criteria = { "type": "variant", "definition": "ultimaker2", "id": "*0.4*" }
- containers = self._container_registry.findInstanceContainers(**search_criteria)
- if containers:
- global_container_stack.extruders["0"].variant = containers[0]
- else:
- # The metadata entry is stored in an ini, and ini files are parsed as strings only.
- # Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
- if "has_variants" in global_container_stack.getMetaData():
- global_container_stack.removeMetaDataEntry("has_variants")
-
- # Set the variant container to an empty variant
- global_container_stack.extruders["0"].variant = ContainerRegistry.getInstance().getEmptyInstanceContainer()
-
- Application.getInstance().globalContainerStackChanged.emit()
- self._reset()
-
- @pyqtProperty(bool, fset = setHasVariants, notify = hasVariantsChanged)
- def hasVariants(self):
- if self._current_global_stack:
- return parseBool(self._current_global_stack.getMetaDataEntry("has_variants", "false"))
diff --git a/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml b/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml
deleted file mode 100644
index 793f3f00a8..0000000000
--- a/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2016 Ultimaker B.V.
-// Cura is released under the terms of the LGPLv3 or higher.
-
-import QtQuick 2.2
-import QtQuick.Controls 1.1
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
-
-import UM 1.2 as UM
-import Cura 1.0 as Cura
-
-
-Cura.MachineAction
-{
- anchors.fill: parent;
-
- Item
- {
- id: upgradeSelectionMachineAction
- anchors.fill: parent
-
- Label
- {
- id: pageTitle
- width: parent.width
- text: catalog.i18nc("@title", "Select Printer Upgrades")
- wrapMode: Text.WordWrap
- font.pointSize: 18;
- }
-
- Label
- {
- id: pageDescription
- anchors.top: pageTitle.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
- width: parent.width
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker 2.");
- }
-
- CheckBox
- {
- id: olssonBlockCheckBox
- anchors.top: pageDescription.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
-
- text: catalog.i18nc("@label", "Olsson Block")
- checked: manager.hasVariants
- onClicked: manager.hasVariants = checked
-
- Connections
- {
- target: manager
- onHasVariantsChanged: olssonBlockCheckBox.checked = manager.hasVariants
- }
- }
-
- UM.I18nCatalog { id: catalog; name: "cura"; }
- }
-}
\ No newline at end of file
diff --git a/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py b/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py
deleted file mode 100644
index f9ad4789e5..0000000000
--- a/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py
+++ /dev/null
@@ -1,193 +0,0 @@
-from cura.MachineAction import MachineAction
-from cura.PrinterOutputDevice import PrinterOutputDevice
-from UM.Application import Application
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty
-
-from UM.Logger import Logger
-from UM.i18n import i18nCatalog
-catalog = i18nCatalog("cura")
-
-
-## Action to check up if the self-built UMO was done correctly.
-class UMOCheckupMachineAction(MachineAction):
- def __init__(self):
- super().__init__("UMOCheckup", catalog.i18nc("@action", "Checkup"))
- self._qml_url = "UMOCheckupMachineAction.qml"
- self._hotend_target_temp = 180
- self._bed_target_temp = 60
- self._output_device = None
- self._bed_test_completed = False
- self._hotend_test_completed = False
-
- # Endstop tests
- self._x_min_endstop_test_completed = False
- self._y_min_endstop_test_completed = False
- self._z_min_endstop_test_completed = False
-
- self._check_started = False
-
- Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
-
- onBedTestCompleted = pyqtSignal()
- onHotendTestCompleted = pyqtSignal()
-
- onXMinEndstopTestCompleted = pyqtSignal()
- onYMinEndstopTestCompleted = pyqtSignal()
- onZMinEndstopTestCompleted = pyqtSignal()
-
- bedTemperatureChanged = pyqtSignal()
- hotendTemperatureChanged = pyqtSignal()
-
- def _onOutputDevicesChanged(self):
- # Check if this action was started, but no output device was found the first time.
- # If so, re-try now that an output device has been added/removed.
- if self._output_device is None and self._check_started:
- self.startCheck()
-
- def _getPrinterOutputDevices(self):
- return [printer_output_device for printer_output_device in
- Application.getInstance().getOutputDeviceManager().getOutputDevices() if
- isinstance(printer_output_device, PrinterOutputDevice)]
-
- def _reset(self):
- if self._output_device:
- self._output_device.bedTemperatureChanged.disconnect(self.bedTemperatureChanged)
- self._output_device.hotendTemperaturesChanged.disconnect(self.hotendTemperatureChanged)
- self._output_device.bedTemperatureChanged.disconnect(self._onBedTemperatureChanged)
- self._output_device.hotendTemperaturesChanged.disconnect(self._onHotendTemperatureChanged)
- self._output_device.endstopStateChanged.disconnect(self._onEndstopStateChanged)
- try:
- self._output_device.stopPollEndstop()
- except AttributeError as e: # Connection is probably not a USB connection. Something went pretty wrong if this happens.
- Logger.log("e", "An exception occurred while stopping end stop polling: %s" % str(e))
-
- self._output_device = None
-
- self._check_started = False
- self.checkStartedChanged.emit()
-
- # Ensure everything is reset (and right signals are emitted again)
- self._bed_test_completed = False
- self.onBedTestCompleted.emit()
- self._hotend_test_completed = False
- self.onHotendTestCompleted.emit()
-
- self._x_min_endstop_test_completed = False
- self.onXMinEndstopTestCompleted.emit()
- self._y_min_endstop_test_completed = False
- self.onYMinEndstopTestCompleted.emit()
- self._z_min_endstop_test_completed = False
- self.onZMinEndstopTestCompleted.emit()
-
- self.heatedBedChanged.emit()
-
- @pyqtProperty(bool, notify = onBedTestCompleted)
- def bedTestCompleted(self):
- return self._bed_test_completed
-
- @pyqtProperty(bool, notify = onHotendTestCompleted)
- def hotendTestCompleted(self):
- return self._hotend_test_completed
-
- @pyqtProperty(bool, notify = onXMinEndstopTestCompleted)
- def xMinEndstopTestCompleted(self):
- return self._x_min_endstop_test_completed
-
- @pyqtProperty(bool, notify=onYMinEndstopTestCompleted)
- def yMinEndstopTestCompleted(self):
- return self._y_min_endstop_test_completed
-
- @pyqtProperty(bool, notify=onZMinEndstopTestCompleted)
- def zMinEndstopTestCompleted(self):
- return self._z_min_endstop_test_completed
-
- @pyqtProperty(float, notify = bedTemperatureChanged)
- def bedTemperature(self):
- if not self._output_device:
- return 0
- return self._output_device.bedTemperature
-
- @pyqtProperty(float, notify=hotendTemperatureChanged)
- def hotendTemperature(self):
- if not self._output_device:
- return 0
- return self._output_device.hotendTemperatures[0]
-
- def _onHotendTemperatureChanged(self):
- if not self._output_device:
- return
- if not self._hotend_test_completed:
- if self._output_device.hotendTemperatures[0] + 10 > self._hotend_target_temp and self._output_device.hotendTemperatures[0] - 10 < self._hotend_target_temp:
- self._hotend_test_completed = True
- self.onHotendTestCompleted.emit()
-
- def _onBedTemperatureChanged(self):
- if not self._output_device:
- return
- if not self._bed_test_completed:
- if self._output_device.bedTemperature + 5 > self._bed_target_temp and self._output_device.bedTemperature - 5 < self._bed_target_temp:
- self._bed_test_completed = True
- self.onBedTestCompleted.emit()
-
- def _onEndstopStateChanged(self, switch_type, state):
- if state:
- if switch_type == "x_min":
- self._x_min_endstop_test_completed = True
- self.onXMinEndstopTestCompleted.emit()
- elif switch_type == "y_min":
- self._y_min_endstop_test_completed = True
- self.onYMinEndstopTestCompleted.emit()
- elif switch_type == "z_min":
- self._z_min_endstop_test_completed = True
- self.onZMinEndstopTestCompleted.emit()
-
- checkStartedChanged = pyqtSignal()
-
- @pyqtProperty(bool, notify = checkStartedChanged)
- def checkStarted(self):
- return self._check_started
-
- @pyqtSlot()
- def startCheck(self):
- self._check_started = True
- self.checkStartedChanged.emit()
- output_devices = self._getPrinterOutputDevices()
- if output_devices:
- self._output_device = output_devices[0]
- try:
- self._output_device.sendCommand("M18") # Turn off all motors so the user can move the axes
- self._output_device.startPollEndstop()
- self._output_device.bedTemperatureChanged.connect(self.bedTemperatureChanged)
- self._output_device.hotendTemperaturesChanged.connect(self.hotendTemperatureChanged)
- self._output_device.bedTemperatureChanged.connect(self._onBedTemperatureChanged)
- self._output_device.hotendTemperaturesChanged.connect(self._onHotendTemperatureChanged)
- self._output_device.endstopStateChanged.connect(self._onEndstopStateChanged)
- except AttributeError as e: # Connection is probably not a USB connection. Something went pretty wrong if this happens.
- Logger.log("e", "An exception occurred while starting end stop polling: %s" % str(e))
-
- @pyqtSlot()
- def cooldownHotend(self):
- if self._output_device is not None:
- self._output_device.setTargetHotendTemperature(0, 0)
-
- @pyqtSlot()
- def cooldownBed(self):
- if self._output_device is not None:
- self._output_device.setTargetBedTemperature(0)
-
- @pyqtSlot()
- def heatupHotend(self):
- if self._output_device is not None:
- self._output_device.setTargetHotendTemperature(0, self._hotend_target_temp)
-
- @pyqtSlot()
- def heatupBed(self):
- if self._output_device is not None:
- self._output_device.setTargetBedTemperature(self._bed_target_temp)
-
- heatedBedChanged = pyqtSignal()
-
- @pyqtProperty(bool, notify = heatedBedChanged)
- def hasHeatedBed(self):
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- return global_container_stack.getProperty("machine_heated_bed", "value")
\ No newline at end of file
diff --git a/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml b/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml
deleted file mode 100644
index 2a01cfaa40..0000000000
--- a/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml
+++ /dev/null
@@ -1,288 +0,0 @@
-import UM 1.2 as UM
-import Cura 1.0 as Cura
-
-import QtQuick 2.2
-import QtQuick.Controls 1.1
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
-
-Cura.MachineAction
-{
- anchors.fill: parent;
- Item
- {
- id: checkupMachineAction
- anchors.fill: parent;
- property int leftRow: (checkupMachineAction.width * 0.40) | 0
- property int rightRow: (checkupMachineAction.width * 0.60) | 0
- property bool heatupHotendStarted: false
- property bool heatupBedStarted: false
- property bool printerConnected: Cura.MachineManager.printerConnected
-
- UM.I18nCatalog { id: catalog; name: "cura"}
- Label
- {
- id: pageTitle
- width: parent.width
- text: catalog.i18nc("@title", "Check Printer")
- wrapMode: Text.WordWrap
- font.pointSize: 18;
- }
-
- Label
- {
- id: pageDescription
- anchors.top: pageTitle.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
- width: parent.width
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@label", "It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional");
- }
-
- Row
- {
- id: startStopButtons
- anchors.top: pageDescription.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
- anchors.horizontalCenter: parent.horizontalCenter
- width: childrenRect.width
- spacing: UM.Theme.getSize("default_margin").width
- Button
- {
- id: startCheckButton
- text: catalog.i18nc("@action:button","Start Printer Check");
- onClicked:
- {
- checkupMachineAction.heatupHotendStarted = false;
- checkupMachineAction.heatupBedStarted = false;
- manager.startCheck();
- startCheckButton.visible = false;
- }
- }
- }
-
- Item
- {
- id: checkupContent
- anchors.top: startStopButtons.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
- visible: manager.checkStarted
- width: parent.width
- height: 250
- //////////////////////////////////////////////////////////
- Label
- {
- id: connectionLabel
- width: checkupMachineAction.leftRow
- anchors.left: parent.left
- anchors.top: parent.top
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@label","Connection: ")
- }
- Label
- {
- id: connectionStatus
- width: checkupMachineAction.rightRow
- anchors.left: connectionLabel.right
- anchors.top: parent.top
- wrapMode: Text.WordWrap
- text: checkupMachineAction.printerConnected ? catalog.i18nc("@info:status","Connected"): catalog.i18nc("@info:status","Not connected")
- }
- //////////////////////////////////////////////////////////
- Label
- {
- id: endstopXLabel
- width: checkupMachineAction.leftRow
- anchors.left: parent.left
- anchors.top: connectionLabel.bottom
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@label","Min endstop X: ")
- visible: checkupMachineAction.printerConnected
- }
- Label
- {
- id: endstopXStatus
- width: checkupMachineAction.rightRow
- anchors.left: endstopXLabel.right
- anchors.top: connectionLabel.bottom
- wrapMode: Text.WordWrap
- text: manager.xMinEndstopTestCompleted ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
- visible: checkupMachineAction.printerConnected
- }
- //////////////////////////////////////////////////////////////
- Label
- {
- id: endstopYLabel
- width: checkupMachineAction.leftRow
- anchors.left: parent.left
- anchors.top: endstopXLabel.bottom
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@label","Min endstop Y: ")
- visible: checkupMachineAction.printerConnected
- }
- Label
- {
- id: endstopYStatus
- width: checkupMachineAction.rightRow
- anchors.left: endstopYLabel.right
- anchors.top: endstopXLabel.bottom
- wrapMode: Text.WordWrap
- text: manager.yMinEndstopTestCompleted ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
- visible: checkupMachineAction.printerConnected
- }
- /////////////////////////////////////////////////////////////////////
- Label
- {
- id: endstopZLabel
- width: checkupMachineAction.leftRow
- anchors.left: parent.left
- anchors.top: endstopYLabel.bottom
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@label","Min endstop Z: ")
- visible: checkupMachineAction.printerConnected
- }
- Label
- {
- id: endstopZStatus
- width: checkupMachineAction.rightRow
- anchors.left: endstopZLabel.right
- anchors.top: endstopYLabel.bottom
- wrapMode: Text.WordWrap
- text: manager.zMinEndstopTestCompleted ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
- visible: checkupMachineAction.printerConnected
- }
- ////////////////////////////////////////////////////////////
- Label
- {
- id: nozzleTempLabel
- width: checkupMachineAction.leftRow
- height: nozzleTempButton.height
- anchors.left: parent.left
- anchors.top: endstopZLabel.bottom
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@label","Nozzle temperature check: ")
- visible: checkupMachineAction.printerConnected
- }
- Label
- {
- id: nozzleTempStatus
- width: (checkupMachineAction.rightRow * 0.4) | 0
- anchors.top: nozzleTempLabel.top
- anchors.left: nozzleTempLabel.right
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@info:status","Not checked")
- visible: checkupMachineAction.printerConnected
- }
- Item
- {
- id: nozzleTempButton
- width: (checkupMachineAction.rightRow * 0.3) | 0
- height: childrenRect.height
- anchors.top: nozzleTempLabel.top
- anchors.left: bedTempStatus.right
- anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width/2)
- visible: checkupMachineAction.printerConnected
- Button
- {
- text: checkupMachineAction.heatupHotendStarted ? catalog.i18nc("@action:button","Stop Heating") : catalog.i18nc("@action:button","Start Heating")
- onClicked:
- {
- if (checkupMachineAction.heatupHotendStarted)
- {
- manager.cooldownHotend()
- checkupMachineAction.heatupHotendStarted = false
- } else
- {
- manager.heatupHotend()
- checkupMachineAction.heatupHotendStarted = true
- }
- }
- }
- }
- Label
- {
- id: nozzleTemp
- anchors.top: nozzleTempLabel.top
- anchors.left: nozzleTempButton.right
- anchors.leftMargin: UM.Theme.getSize("default_margin").width
- width: (checkupMachineAction.rightRow * 0.2) | 0
- wrapMode: Text.WordWrap
- text: manager.hotendTemperature + "°C"
- font.bold: true
- visible: checkupMachineAction.printerConnected
- }
- /////////////////////////////////////////////////////////////////////////////
- Label
- {
- id: bedTempLabel
- width: checkupMachineAction.leftRow
- height: bedTempButton.height
- anchors.left: parent.left
- anchors.top: nozzleTempLabel.bottom
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@label","Build plate temperature check:")
- visible: checkupMachineAction.printerConnected && manager.hasHeatedBed
- }
-
- Label
- {
- id: bedTempStatus
- width: (checkupMachineAction.rightRow * 0.4) | 0
- anchors.top: bedTempLabel.top
- anchors.left: bedTempLabel.right
- wrapMode: Text.WordWrap
- text: manager.bedTestCompleted ? catalog.i18nc("@info:status","Not checked"): catalog.i18nc("@info:status","Checked")
- visible: checkupMachineAction.printerConnected && manager.hasHeatedBed
- }
- Item
- {
- id: bedTempButton
- width: (checkupMachineAction.rightRow * 0.3) | 0
- height: childrenRect.height
- anchors.top: bedTempLabel.top
- anchors.left: bedTempStatus.right
- anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width/2)
- visible: checkupMachineAction.printerConnected && manager.hasHeatedBed
- Button
- {
- text: checkupMachineAction.heatupBedStarted ?catalog.i18nc("@action:button","Stop Heating") : catalog.i18nc("@action:button","Start Heating")
- onClicked:
- {
- if (checkupMachineAction.heatupBedStarted)
- {
- manager.cooldownBed()
- checkupMachineAction.heatupBedStarted = false
- } else
- {
- manager.heatupBed()
- checkupMachineAction.heatupBedStarted = true
- }
- }
- }
- }
- Label
- {
- id: bedTemp
- width: (checkupMachineAction.rightRow * 0.2) | 0
- anchors.top: bedTempLabel.top
- anchors.left: bedTempButton.right
- anchors.leftMargin: UM.Theme.getSize("default_margin").width
- wrapMode: Text.WordWrap
- text: manager.bedTemperature + "°C"
- font.bold: true
- visible: checkupMachineAction.printerConnected && manager.hasHeatedBed
- }
- Label
- {
- id: resultText
- visible: false
- anchors.top: bedTemp.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
- anchors.left: parent.left
- width: parent.width
- wrapMode: Text.WordWrap
- text: catalog.i18nc("@label", "Everything is in order! You're done with your CheckUp.")
- }
- }
- }
-}
\ No newline at end of file
diff --git a/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml b/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml
index 2b973ca1bb..565ba2fa0e 100644
--- a/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml
+++ b/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml
@@ -1,43 +1,39 @@
-// Copyright (c) 2016 Ultimaker B.V.
+// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
-import QtQuick.Controls 1.1
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
+import QtQuick 2.10
+import QtQuick.Controls 2.3
-import UM 1.2 as UM
-import Cura 1.0 as Cura
+import UM 1.3 as UM
+import Cura 1.1 as Cura
Cura.MachineAction
{
- anchors.fill: parent;
+ UM.I18nCatalog { id: catalog; name: "cura"; }
+ anchors.fill: parent
+
Item
{
id: upgradeSelectionMachineAction
anchors.fill: parent
-
- Label
- {
- id: pageTitle
- width: parent.width
- text: catalog.i18nc("@title", "Select Printer Upgrades")
- wrapMode: Text.WordWrap
- font.pointSize: 18;
- }
+ anchors.topMargin: UM.Theme.getSize("default_margin").width * 5
+ anchors.leftMargin: UM.Theme.getSize("default_margin").width * 4
Label
{
id: pageDescription
- anchors.top: pageTitle.bottom
+ anchors.top: parent.top
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
wrapMode: Text.WordWrap
- text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker Original");
+ text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker Original")
+ font: UM.Theme.getFont("medium")
+ color: UM.Theme.getColor("text")
+ renderType: Text.NativeRendering
}
- CheckBox
+ Cura.CheckBox
{
anchors.top: pageDescription.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
@@ -46,7 +42,5 @@ Cura.MachineAction
checked: manager.hasHeatedBed
onClicked: manager.setHeatedBed(checked)
}
-
- UM.I18nCatalog { id: catalog; name: "cura"; }
}
-}
\ No newline at end of file
+}
diff --git a/plugins/UltimakerMachineActions/__init__.py b/plugins/UltimakerMachineActions/__init__.py
index e87949580a..aecb3b0ad6 100644
--- a/plugins/UltimakerMachineActions/__init__.py
+++ b/plugins/UltimakerMachineActions/__init__.py
@@ -1,9 +1,8 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from . import BedLevelMachineAction
from . import UMOUpgradeSelection
-from . import UM2UpgradeSelection
def getMetaData():
return {}
@@ -11,6 +10,5 @@ def getMetaData():
def register(app):
return { "machine_action": [
BedLevelMachineAction.BedLevelMachineAction(),
- UMOUpgradeSelection.UMOUpgradeSelection(),
- UM2UpgradeSelection.UM2UpgradeSelection()
+ UMOUpgradeSelection.UMOUpgradeSelection()
]}
diff --git a/plugins/UltimakerMachineActions/plugin.json b/plugins/UltimakerMachineActions/plugin.json
index 3e3e0af9b0..e33d77c154 100644
--- a/plugins/UltimakerMachineActions/plugin.json
+++ b/plugins/UltimakerMachineActions/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/UserAgreement/UserAgreement.py b/plugins/UserAgreement/UserAgreement.py
deleted file mode 100644
index 4ea1ccf9bb..0000000000
--- a/plugins/UserAgreement/UserAgreement.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-import os
-
-from PyQt5.QtCore import QObject, pyqtSlot
-
-from UM.Extension import Extension
-from UM.Logger import Logger
-
-
-class UserAgreement(QObject, Extension):
- def __init__(self, application):
- super(UserAgreement, self).__init__()
- self._application = application
- self._user_agreement_window = None
- self._user_agreement_context = None
- self._application.engineCreatedSignal.connect(self._onEngineCreated)
-
- self._application.getPreferences().addPreference("general/accepted_user_agreement", False)
-
- def _onEngineCreated(self):
- if not self._application.getPreferences().getValue("general/accepted_user_agreement"):
- self.showUserAgreement()
-
- def showUserAgreement(self):
- if not self._user_agreement_window:
- self.createUserAgreementWindow()
-
- self._user_agreement_window.show()
-
- @pyqtSlot(bool)
- def didAgree(self, user_choice):
- if user_choice:
- Logger.log("i", "User agreed to the user agreement")
- self._application.getPreferences().setValue("general/accepted_user_agreement", True)
- self._user_agreement_window.hide()
- else:
- Logger.log("i", "User did NOT agree to the user agreement")
- self._application.getPreferences().setValue("general/accepted_user_agreement", False)
- self._application.quit()
- self._application.setNeedToShowUserAgreement(False)
-
- def createUserAgreementWindow(self):
- path = os.path.join(self._application.getPluginRegistry().getPluginPath(self.getPluginId()), "UserAgreement.qml")
- self._user_agreement_window = self._application.createQmlComponent(path, {"manager": self})
diff --git a/plugins/UserAgreement/UserAgreement.qml b/plugins/UserAgreement/UserAgreement.qml
deleted file mode 100644
index 2e5893fc41..0000000000
--- a/plugins/UserAgreement/UserAgreement.qml
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2017 Ultimaker B.V.
-// Cura is released under the terms of the LGPLv3 or higher.
-
-import QtQuick 2.2
-import QtQuick.Controls 1.4
-
-import UM 1.3 as UM
-
-UM.Dialog
-{
- id: baseDialog
- minimumWidth: Math.round(UM.Theme.getSize("modal_window_minimum").width * 0.75)
- minimumHeight: Math.round(UM.Theme.getSize("modal_window_minimum").height * 0.5)
- width: minimumWidth
- height: minimumHeight
- title: catalog.i18nc("@title:window", "User Agreement")
-
- TextArea
- {
- anchors.top: parent.top
- width: parent.width
- anchors.bottom: buttonRow.top
- text: '
DISCLAIMER BY ULTIMAKER
-
PLEASE READ THIS DISCLAIMER CAREFULLY.
-
EXCEPT WHEN OTHERWISE STATED IN WRITING, ULTIMAKER PROVIDES ANY ULTIMAKER SOFTWARE OR THIRD PARTY SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF ULTIMAKER SOFTWARE IS WITH YOU.
-
UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, IN NO EVENT WILL ULTIMAKER BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE ANY ULTIMAKER SOFTWARE OR THIRD PARTY SOFTWARE.
- '
- readOnly: true;
- textFormat: TextEdit.RichText
- }
-
- Item
- {
- id: buttonRow
- anchors.bottom: parent.bottom
- width: parent.width
- anchors.bottomMargin: UM.Theme.getSize("default_margin").height
-
- UM.I18nCatalog { id: catalog; name: "cura" }
-
- Button
- {
- anchors.right: parent.right
- text: catalog.i18nc("@action:button", "I understand and agree")
- onClicked: {
- baseDialog.accepted()
- }
- }
-
- Button
- {
- anchors.left: parent.left
- text: catalog.i18nc("@action:button", "I don't agree")
- onClicked: {
- baseDialog.rejected()
- }
- }
- }
-
- onAccepted: manager.didAgree(true)
- onRejected: manager.didAgree(false)
- onClosing: manager.didAgree(false)
-}
diff --git a/plugins/UserAgreement/__init__.py b/plugins/UserAgreement/__init__.py
deleted file mode 100644
index 3cf81c64f4..0000000000
--- a/plugins/UserAgreement/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from . import UserAgreement
-
-def getMetaData():
- return {}
-
-def register(app):
- return {"extension": UserAgreement.UserAgreement(app)}
diff --git a/plugins/UserAgreement/plugin.json b/plugins/UserAgreement/plugin.json
deleted file mode 100644
index b172d1f9a2..0000000000
--- a/plugins/UserAgreement/plugin.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "UserAgreement",
- "author": "Ultimaker B.V.",
- "version": "1.0.1",
- "description": "Ask the user once if he/she agrees with our license.",
- "api": "6.0",
- "i18n-catalog": "cura"
-}
diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py
index af9635d384..8419b3beeb 100644
--- a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py
+++ b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py
@@ -6,7 +6,7 @@ import io #To write config files to strings as if they were files.
from typing import Dict, List, Optional, Tuple
import UM.VersionUpgrade
-from UM.Logger import Logger
+
## Creates a new profile instance by parsing a serialised profile in version 1
# of the file format.
@@ -20,6 +20,7 @@ def importFrom(serialised: str, filename: str) -> Optional["Profile"]:
except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException):
return None
+
## A representation of a profile used as intermediary form for conversion from
# one format to the other.
class Profile:
diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json
index cad94c2eb5..547c1f9f4e 100644
--- a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json
index 7da1e7a56d..51e3cd6794 100644
--- a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json
index e1f0a47685..4a2c04ad8e 100644
--- a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py
index 9d7c7646cc..45cdaebe87 100644
--- a/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py
+++ b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py
@@ -1,5 +1,8 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+import os.path
+import sys
+sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
import configparser #To check whether the appropriate exceptions are raised.
import pytest #To register tests with.
diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
index 6cdbd64cbb..a72c5210f9 100644
--- a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py b/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py
index eebaca23c6..6235578238 100644
--- a/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py
+++ b/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py
@@ -3,7 +3,9 @@
import configparser #To check whether the appropriate exceptions are raised.
import pytest #To register tests with.
-
+import os.path
+import sys
+sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
import VersionUpgrade26to27 #The module we're testing.
## Creates an instance of the upgrader to test with.
diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json
index 885d741a8c..787d03fdf3 100644
--- a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.7 to Cura 3.0.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py b/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py
index cae08ebcfd..8ac6616511 100644
--- a/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py
+++ b/plugins/VersionUpgrade/VersionUpgrade27to30/tests/TestVersionUpgrade27to30.py
@@ -1,6 +1,8 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-
+import os.path
+import sys
+sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
import configparser #To parse the resulting config files.
import pytest #To register tests with.
diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json
index d5f22649c1..7303d576cc 100644
--- a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 3.0 to Cura 3.1.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
index eb489169e0..a6f8f743e6 100644
--- a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json
index 9649010643..4f8c7b0a94 100644
--- a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 3.3 to Cura 3.4.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json
index 71b13ee5a9..bdcb6598d1 100644
--- a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 3.4 to Cura 3.5.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py b/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py
index b74e6f35ac..9f306e74fa 100644
--- a/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py
+++ b/plugins/VersionUpgrade/VersionUpgrade34to35/tests/TestVersionUpgrade34to35.py
@@ -1,6 +1,8 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-
+import os.path
+import sys
+sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
import configparser #To parse the resulting config files.
import pytest #To register tests with.
diff --git a/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py b/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py
index 900c0a7396..71ce2e4fd0 100644
--- a/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py
+++ b/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py
@@ -3,7 +3,7 @@ from typing import Tuple, List, Set, Dict
import io
from UM.VersionUpgrade import VersionUpgrade
-from cura.PrinterOutputDevice import ConnectionType
+from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
deleted_settings = {"bridge_wall_max_overhang"} # type: Set[str]
renamed_configurations = {"connect_group_name": "group_name"} # type: Dict[str, str]
diff --git a/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json b/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json
index 578594fb6d..68259c1b9c 100644
--- a/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 3.5 to Cura 4.0.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py b/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py
index d80e0007aa..b63d1842b7 100644
--- a/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py
+++ b/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py
@@ -1,8 +1,9 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import configparser
import io
+import uuid
from typing import Dict, List, Tuple
from UM.VersionUpgrade import VersionUpgrade
@@ -18,6 +19,7 @@ _renamed_quality_profiles = {
"gmax15plus_pla_very_thick": "gmax15plus_global_very_thick"
} # type: Dict[str, str]
+
## Upgrades configurations from the state they were in at version 4.0 to the
# state they should be in at version 4.1.
class VersionUpgrade40to41(VersionUpgrade):
@@ -49,6 +51,15 @@ class VersionUpgrade40to41(VersionUpgrade):
parser["general"]["version"] = "4"
parser["metadata"]["setting_version"] = "7"
+ # Limit Maximum Deviation instead of Maximum Resolution. This should have approximately the same effect as before the algorithm change, only more consistent.
+ if "values" in parser and "meshfix_maximum_resolution" in parser["values"]:
+ resolution = parser["values"]["meshfix_maximum_resolution"]
+ if resolution.startswith("="):
+ resolution = resolution[1:]
+ deviation = "=(" + resolution + ") / 2"
+ parser["values"]["meshfix_maximum_deviation"] = deviation
+ del parser["values"]["meshfix_maximum_resolution"]
+
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]
@@ -62,6 +73,11 @@ class VersionUpgrade40to41(VersionUpgrade):
parser["general"]["version"] = "6"
if "metadata" not in parser:
parser["metadata"] = {}
+
+ # Remove changelog plugin
+ if "latest_version_changelog_shown" in parser["general"]:
+ del parser["general"]["latest_version_changelog_shown"]
+
parser["metadata"]["setting_version"] = "7"
result = io.StringIO()
@@ -81,6 +97,13 @@ class VersionUpgrade40to41(VersionUpgrade):
if parser["containers"]["4"] in _renamed_quality_profiles:
parser["containers"]["4"] = _renamed_quality_profiles[parser["containers"]["4"]]
+ # Assign a GlobalStack to a unique group_id. If the GlobalStack has a UM network connection, use the UM network
+ # key as the group_id.
+ if "um_network_key" in parser["metadata"]:
+ parser["metadata"]["group_id"] = parser["metadata"]["um_network_key"]
+ elif "group_id" not in parser["metadata"]:
+ parser["metadata"]["group_id"] = str(uuid.uuid4())
+
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]
diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py b/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py
index 7f39bb9d39..09be805147 100644
--- a/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py
+++ b/plugins/VersionUpgrade/VersionUpgrade40to41/__init__.py
@@ -14,7 +14,7 @@ def getMetaData() -> Dict[str, Any]:
return {
"version_upgrade": {
# From To Upgrade function
- ("preferences", 6000006): ("preferences", 6000007, upgrade.upgradePreferences),
+ ("preferences", 6000006): ("preferences", 6000007, upgrade.upgradePreferences),
("machine_stack", 4000006): ("machine_stack", 4000007, upgrade.upgradeStack),
("extruder_train", 4000006): ("extruder_train", 4000007, upgrade.upgradeStack),
("definition_changes", 4000006): ("definition_changes", 4000007, upgrade.upgradeInstanceContainer),
diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json b/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json
index b1c6d75669..67474508ec 100644
--- a/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 4.0 to Cura 4.1.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade41to42/VersionUpgrade41to42.py b/plugins/VersionUpgrade/VersionUpgrade41to42/VersionUpgrade41to42.py
new file mode 100644
index 0000000000..305cce16c6
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade41to42/VersionUpgrade41to42.py
@@ -0,0 +1,340 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+import configparser
+import io
+import os.path # To get the file ID.
+from typing import Dict, List, Tuple
+
+from UM.VersionUpgrade import VersionUpgrade
+
+_renamed_settings = {
+ "support_minimal_diameter": "support_tower_maximum_supported_diameter"
+} # type: Dict[str, str]
+_removed_settings = ["prime_tower_circular", "max_feedrate_z_override"] # type: List[str]
+_renamed_profiles = {
+ # Include CreawsomeMod profiles here as well for the people who installed that.
+ # Definitions.
+ "creawsome_base": "creality_base",
+ "creawsome_cr10": "creality_cr10",
+ "creawsome_cr10mini": "creality_cr10mini",
+ "creawsome_cr10s": "creality_cr10s",
+ "creawsome_cr10s4": "creality_cr10s4",
+ "creawsome_cr10s5": "creality_cr10s5",
+ "creawsome_cr10spro": "creality_cr10spro",
+ "creawsome_cr20": "creality_cr20",
+ "creawsome_cr20pro": "creality_cr20pro",
+ "creawsome_ender2": "creality_ender2",
+ "creawsome_ender3": "creality_ender3",
+ "creawsome_ender4": "creality_ender4",
+ "creawsome_ender5": "creality_ender5",
+
+ # Extruder definitions.
+ "creawsome_base_extruder_0": "creality_base_extruder_0",
+
+ # Variants.
+ "creawsome_base_0.2": "creality_base_0.2",
+ "creawsome_base_0.3": "creality_base_0.3",
+ "creawsome_base_0.4": "creality_base_0.4",
+ "creawsome_base_0.5": "creality_base_0.5",
+ "creawsome_base_0.6": "creality_base_0.6",
+ "creawsome_base_0.8": "creality_base_0.8",
+ "creawsome_base_1.0": "creality_base_1.0",
+ "creawsome_cr10_0.2": "creality_cr10_0.2",
+ "creawsome_cr10_0.3": "creality_cr10_0.3",
+ "creawsome_cr10_0.4": "creality_cr10_0.4",
+ "creawsome_cr10_0.5": "creality_cr10_0.5",
+ "creawsome_cr10_0.6": "creality_cr10_0.6",
+ "creawsome_cr10_0.8": "creality_cr10_0.8",
+ "creawsome_cr10_1.0": "creality_cr10_1.0",
+ "creawsome_cr10mini_0.2": "creality_cr10mini_0.2",
+ "creawsome_cr10mini_0.3": "creality_cr10mini_0.3",
+ "creawsome_cr10mini_0.4": "creality_cr10mini_0.4",
+ "creawsome_cr10mini_0.5": "creality_cr10mini_0.5",
+ "creawsome_cr10mini_0.6": "creality_cr10mini_0.6",
+ "creawsome_cr10mini_0.8": "creality_cr10mini_0.8",
+ "creawsome_cr10mini_1.0": "creality_cr10mini_1.0",
+ "creawsome_cr10s4_0.2": "creality_cr10s4_0.2",
+ "creawsome_cr10s4_0.3": "creality_cr10s4_0.3",
+ "creawsome_cr10s4_0.4": "creality_cr10s4_0.4",
+ "creawsome_cr10s4_0.5": "creality_cr10s4_0.5",
+ "creawsome_cr10s4_0.6": "creality_cr10s4_0.6",
+ "creawsome_cr10s4_0.8": "creality_cr10s4_0.8",
+ "creawsome_cr10s4_1.0": "creality_cr10s4_1.0",
+ "creawsome_cr10s5_0.2": "creality_cr10s5_0.2",
+ "creawsome_cr10s5_0.3": "creality_cr10s5_0.3",
+ "creawsome_cr10s5_0.4": "creality_cr10s5_0.4",
+ "creawsome_cr10s5_0.5": "creality_cr10s5_0.5",
+ "creawsome_cr10s5_0.6": "creality_cr10s5_0.6",
+ "creawsome_cr10s5_0.8": "creality_cr10s5_0.8",
+ "creawsome_cr10s5_1.0": "creality_cr10s5_1.0",
+ "creawsome_cr10s_0.2": "creality_cr10s_0.2",
+ "creawsome_cr10s_0.3": "creality_cr10s_0.3",
+ "creawsome_cr10s_0.4": "creality_cr10s_0.4",
+ "creawsome_cr10s_0.5": "creality_cr10s_0.5",
+ "creawsome_cr10s_0.6": "creality_cr10s_0.6",
+ "creawsome_cr10s_0.8": "creality_cr10s_0.8",
+ "creawsome_cr10s_1.0": "creality_cr10s_1.0",
+ "creawsome_cr10spro_0.2": "creality_cr10spro_0.2",
+ "creawsome_cr10spro_0.3": "creality_cr10spro_0.3",
+ "creawsome_cr10spro_0.4": "creality_cr10spro_0.4",
+ "creawsome_cr10spro_0.5": "creality_cr10spro_0.5",
+ "creawsome_cr10spro_0.6": "creality_cr10spro_0.6",
+ "creawsome_cr10spro_0.8": "creality_cr10spro_0.8",
+ "creawsome_cr10spro_1.0": "creality_cr10spro_1.0",
+ "creawsome_cr20_0.2": "creality_cr20_0.2",
+ "creawsome_cr20_0.3": "creality_cr20_0.3",
+ "creawsome_cr20_0.4": "creality_cr20_0.4",
+ "creawsome_cr20_0.5": "creality_cr20_0.5",
+ "creawsome_cr20_0.6": "creality_cr20_0.6",
+ "creawsome_cr20_0.8": "creality_cr20_0.8",
+ "creawsome_cr20_1.0": "creality_cr20_1.0",
+ "creawsome_cr20pro_0.2": "creality_cr20pro_0.2",
+ "creawsome_cr20pro_0.3": "creality_cr20pro_0.3",
+ "creawsome_cr20pro_0.4": "creality_cr20pro_0.4",
+ "creawsome_cr20pro_0.5": "creality_cr20pro_0.5",
+ "creawsome_cr20pro_0.6": "creality_cr20pro_0.6",
+ "creawsome_cr20pro_0.8": "creality_cr20pro_0.8",
+ "creawsome_cr20pro_1.0": "creality_cr20pro_1.0",
+ "creawsome_ender2_0.2": "creality_ender2_0.2",
+ "creawsome_ender2_0.3": "creality_ender2_0.3",
+ "creawsome_ender2_0.4": "creality_ender2_0.4",
+ "creawsome_ender2_0.5": "creality_ender2_0.5",
+ "creawsome_ender2_0.6": "creality_ender2_0.6",
+ "creawsome_ender2_0.8": "creality_ender2_0.8",
+ "creawsome_ender2_1.0": "creality_ender2_1.0",
+ "creawsome_ender3_0.2": "creality_ender3_0.2",
+ "creawsome_ender3_0.3": "creality_ender3_0.3",
+ "creawsome_ender3_0.4": "creality_ender3_0.4",
+ "creawsome_ender3_0.5": "creality_ender3_0.5",
+ "creawsome_ender3_0.6": "creality_ender3_0.6",
+ "creawsome_ender3_0.8": "creality_ender3_0.8",
+ "creawsome_ender3_1.0": "creality_ender3_1.0",
+ "creawsome_ender4_0.2": "creality_ender4_0.2",
+ "creawsome_ender4_0.3": "creality_ender4_0.3",
+ "creawsome_ender4_0.4": "creality_ender4_0.4",
+ "creawsome_ender4_0.5": "creality_ender4_0.5",
+ "creawsome_ender4_0.6": "creality_ender4_0.6",
+ "creawsome_ender4_0.8": "creality_ender4_0.8",
+ "creawsome_ender4_1.0": "creality_ender4_1.0",
+ "creawsome_ender5_0.2": "creality_ender5_0.2",
+ "creawsome_ender5_0.3": "creality_ender5_0.3",
+ "creawsome_ender5_0.4": "creality_ender5_0.4",
+ "creawsome_ender5_0.5": "creality_ender5_0.5",
+ "creawsome_ender5_0.6": "creality_ender5_0.6",
+ "creawsome_ender5_0.8": "creality_ender5_0.8",
+ "creawsome_ender5_1.0": "creality_ender5_1.0",
+
+ # Upgrade for people who had the original Creality profiles from 4.1 and earlier.
+ "creality_cr10_extruder_0": "creality_base_extruder_0",
+ "creality_cr10s4_extruder_0": "creality_base_extruder_0",
+ "creality_cr10s5_extruder_0": "creality_base_extruder_0",
+ "creality_ender3_extruder_0": "creality_base_extruder_0"
+}
+
+# For legacy Creality printers, select the correct quality profile depending on the material.
+_creality_quality_per_material = {
+ # Since legacy Creality printers didn't have different variants, we always pick the 0.4mm variant.
+ "generic_abs_175": {
+ "high": "base_0.4_ABS_super",
+ "normal": "base_0.4_ABS_super",
+ "fast": "base_0.4_ABS_super",
+ "draft": "base_0.4_ABS_standard",
+ "extra_fast": "base_0.4_ABS_low",
+ "coarse": "base_0.4_ABS_low",
+ "extra_coarse": "base_0.4_ABS_low"
+ },
+ "generic_petg_175": {
+ "high": "base_0.4_PETG_super",
+ "normal": "base_0.4_PETG_super",
+ "fast": "base_0.4_PETG_super",
+ "draft": "base_0.4_PETG_standard",
+ "extra_fast": "base_0.4_PETG_low",
+ "coarse": "base_0.4_PETG_low",
+ "extra_coarse": "base_0.4_PETG_low"
+ },
+ "generic_pla_175": {
+ "high": "base_0.4_PLA_super",
+ "normal": "base_0.4_PLA_super",
+ "fast": "base_0.4_PLA_super",
+ "draft": "base_0.4_PLA_standard",
+ "extra_fast": "base_0.4_PLA_low",
+ "coarse": "base_0.4_PLA_low",
+ "extra_coarse": "base_0.4_PLA_low"
+ },
+ "generic_tpu_175": {
+ "high": "base_0.4_TPU_super",
+ "normal": "base_0.4_TPU_super",
+ "fast": "base_0.4_TPU_super",
+ "draft": "base_0.4_TPU_standard",
+ "extra_fast": "base_0.4_TPU_standard",
+ "coarse": "base_0.4_TPU_standard",
+ "extra_coarse": "base_0.4_TPU_standard"
+ },
+ "empty_material": { # For the global stack.
+ "high": "base_global_super",
+ "normal": "base_global_super",
+ "fast": "base_global_super",
+ "draft": "base_global_standard",
+ "extra_fast": "base_global_low",
+ "coarse": "base_global_low",
+ "extra_coarse": "base_global_low"
+ }
+}
+
+# Default variant to select for legacy Creality printers, now that we have variants.
+_default_variants = {
+ "creality_cr10_extruder_0": "creality_cr10_0.4",
+ "creality_cr10s4_extruder_0": "creality_cr10s4_0.4",
+ "creality_cr10s5_extruder_0": "creality_cr10s5_0.4",
+ "creality_ender3_extruder_0": "creality_ender3_0.4"
+}
+
+# Whether the quality changes profile belongs to one of the upgraded printers can only be recognised by how they start.
+# If they are, they must use the creality base definition so that they still belong to those printers.
+_quality_changes_to_creality_base = {
+ "creality_cr10_extruder_0",
+ "creality_cr10s4_extruder_0",
+ "creality_cr10s5_extruder_0",
+ "creality_ender3_extruder_0",
+ "creality_cr10",
+ "creality_cr10s",
+ "creality_cr10s4",
+ "creality_cr10s5",
+ "creality_ender3",
+}
+_creality_limited_quality_type = {
+ "high": "super",
+ "normal": "super",
+ "fast": "super",
+ "draft": "draft",
+ "extra_fast": "draft",
+ "coarse": "draft",
+ "extra_coarse": "draft"
+}
+
+## Upgrades configurations from the state they were in at version 4.1 to the
+# state they should be in at version 4.2.
+class VersionUpgrade41to42(VersionUpgrade):
+ ## Gets the version number from a CFG file in Uranium's 4.1 format.
+ #
+ # Since the format may change, this is implemented for the 4.1 format only
+ # and needs to be included in the version upgrade system rather than
+ # globally in Uranium.
+ #
+ # \param serialised The serialised form of a CFG file.
+ # \return The version number stored in the CFG file.
+ # \raises ValueError The format of the version number in the file is
+ # incorrect.
+ # \raises KeyError The format of the file is incorrect.
+ def getCfgVersion(self, serialised: str) -> int:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialised)
+ format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
+ setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
+ return format_version * 1000000 + setting_version
+
+ ## Upgrades instance containers to have the new version
+ # number.
+ #
+ # 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.read_string(serialized)
+
+ # Update version number.
+ parser["metadata"]["setting_version"] = "8"
+
+ # Certain instance containers (such as definition changes) reference to a certain definition container
+ # Since a number of those changed name, we also need to update those.
+ old_definition = parser["general"]["definition"]
+ if old_definition in _renamed_profiles:
+ parser["general"]["definition"] = _renamed_profiles[old_definition]
+
+ # Rename settings.
+ if "values" in parser:
+ for old_name, new_name in _renamed_settings.items():
+ if old_name in parser["values"]:
+ parser["values"][new_name] = parser["values"][old_name]
+ del parser["values"][old_name]
+ # Remove settings.
+ for key in _removed_settings:
+ if key in parser["values"]:
+ del parser["values"][key]
+
+ # For quality-changes profiles made for Creality printers, change the definition to the creality_base and make sure that the quality is something we have a profile for.
+ if parser["metadata"].get("type", "") == "quality_changes":
+ for possible_printer in _quality_changes_to_creality_base:
+ if os.path.basename(filename).startswith(possible_printer + "_"):
+ parser["general"]["definition"] = "creality_base"
+ parser["metadata"]["quality_type"] = _creality_limited_quality_type.get(parser["metadata"]["quality_type"], "draft")
+ break
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
+
+ ## Upgrades Preferences to have the new version number.
+ #
+ # This renames the renamed settings in the list of visible settings.
+ def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ # Update version number.
+ parser["metadata"]["setting_version"] = "8"
+
+ # Renamed settings.
+ if "visible_settings" in parser["general"]:
+ visible_settings = parser["general"]["visible_settings"]
+ visible_setting_set = set(visible_settings.split(";"))
+ for old_name, new_name in _renamed_settings.items():
+ if old_name in visible_setting_set:
+ visible_setting_set.remove(old_name)
+ visible_setting_set.add(new_name)
+ for removed_key in _removed_settings:
+ if removed_key in visible_setting_set:
+ visible_setting_set.remove(removed_key)
+ parser["general"]["visible_settings"] = ";".join(visible_setting_set)
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
+
+ ## Upgrades stacks to have the new version number.
+ def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ # Update version number.
+ parser["metadata"]["setting_version"] = "8"
+
+ # Change renamed profiles.
+ if "containers" in parser:
+ # For legacy Creality printers, change the variant to 0.4.
+ definition_id = parser["containers"]["6"]
+ if parser["metadata"].get("type", "machine") == "extruder_train":
+ if parser["containers"]["4"] == "empty_variant": # Necessary for people entering from CreawsomeMod who already had a variant.
+ if definition_id in _default_variants:
+ parser["containers"]["4"] = _default_variants[definition_id]
+ if definition_id == "creality_cr10_extruder_0": # We can't disambiguate between Creality CR-10 and Creality-CR10S since they share the same extruder definition. Have to go by the name.
+ if "cr-10s" in parser["metadata"].get("machine", "Creality CR-10").lower(): # Not perfect, since the user can change this name :(
+ parser["containers"]["4"] = "creality_cr10s_0.4"
+
+ # Also change the quality to go along with it.
+ material_id = parser["containers"]["3"]
+ old_quality_id = parser["containers"]["2"]
+ if material_id in _creality_quality_per_material and old_quality_id in _creality_quality_per_material[material_id]:
+ if definition_id == "creality_cr10_extruder_0": # We can't disambiguate between Creality CR-10 and Creality-CR10S since they share the same extruder definition. Have to go by the name.
+ if "cr-10s" in parser["metadata"].get("machine", "Creality CR-10").lower(): # Not perfect, since the user can change this name :(
+ parser["containers"]["2"] = _creality_quality_per_material[material_id][old_quality_id]
+
+ stack_copy = {} # type: Dict[str, str] # Make a copy so that we don't modify the dict we're iterating over.
+ stack_copy.update(parser["containers"])
+ for position, profile_id in stack_copy.items():
+ if profile_id in _renamed_profiles:
+ parser["containers"][position] = _renamed_profiles[profile_id]
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
diff --git a/plugins/VersionUpgrade/VersionUpgrade41to42/__init__.py b/plugins/VersionUpgrade/VersionUpgrade41to42/__init__.py
new file mode 100644
index 0000000000..8fe718ca83
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade41to42/__init__.py
@@ -0,0 +1,59 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Any, Dict, TYPE_CHECKING
+
+from . import VersionUpgrade41to42
+
+if TYPE_CHECKING:
+ from UM.Application import Application
+
+upgrade = VersionUpgrade41to42.VersionUpgrade41to42()
+
+def getMetaData() -> Dict[str, Any]:
+ return {
+ "version_upgrade": {
+ # From To Upgrade function
+ ("preferences", 6000007): ("preferences", 6000008, upgrade.upgradePreferences),
+ ("machine_stack", 4000007): ("machine_stack", 4000008, upgrade.upgradeStack),
+ ("extruder_train", 4000007): ("extruder_train", 4000008, upgrade.upgradeStack),
+ ("definition_changes", 4000007): ("definition_changes", 4000008, upgrade.upgradeInstanceContainer),
+ ("quality_changes", 4000007): ("quality_changes", 4000008, upgrade.upgradeInstanceContainer),
+ ("quality", 4000007): ("quality", 4000008, upgrade.upgradeInstanceContainer),
+ ("user", 4000007): ("user", 4000008, upgrade.upgradeInstanceContainer),
+ },
+ "sources": {
+ "preferences": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"."}
+ },
+ "machine_stack": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./machine_instances"}
+ },
+ "extruder_train": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./extruders"}
+ },
+ "definition_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./definition_changes"}
+ },
+ "quality_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality_changes"}
+ },
+ "quality": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality"}
+ },
+ "user": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./user"}
+ }
+ }
+ }
+
+
+def register(app: "Application") -> Dict[str, Any]:
+ return { "version_upgrade": upgrade }
diff --git a/plugins/VersionUpgrade/VersionUpgrade41to42/plugin.json b/plugins/VersionUpgrade/VersionUpgrade41to42/plugin.json
new file mode 100644
index 0000000000..506000aae9
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade41to42/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "Version Upgrade 4.1 to 4.2",
+ "author": "Ultimaker B.V.",
+ "version": "1.0.0",
+ "description": "Upgrades configurations from Cura 4.1 to Cura 4.2.",
+ "api": "7.0",
+ "i18n-catalog": "cura"
+}
diff --git a/plugins/VersionUpgrade/VersionUpgrade42to43/VersionUpgrade42to43.py b/plugins/VersionUpgrade/VersionUpgrade42to43/VersionUpgrade42to43.py
new file mode 100644
index 0000000000..d6489f6d8b
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade42to43/VersionUpgrade42to43.py
@@ -0,0 +1,160 @@
+import configparser
+import io
+from typing import Dict, Tuple, List
+
+from UM.VersionUpgrade import VersionUpgrade
+
+_renamed_profiles = {"generic_pla_0.4_coarse": "jbo_generic_pla_0.4_coarse",
+ "generic_pla_0.4_fine": "jbo_generic_pla_fine",
+ "generic_pla_0.4_medium": "jbo_generic_pla_medium",
+ "generic_pla_0.4_ultrafine": "jbo_generic_pla_ultrafine",
+
+ "generic_petg_0.4_coarse": "jbo_generic_petg_0.4_coarse",
+ "generic_petg_0.4_fine": "jbo_generic_petg_fine",
+ "generic_petg_0.4_medium": "jbo_generic_petg_medium",
+ }
+
+# - The variant "imade3d jellybox 0.4 mm 2-fans" for machine definition "imade3d_jellybox"
+# is now "0.4 mm" for machine definition "imade3d jellybox_2".
+# - Materials "imade3d_petg_green" and "imade3d_petg_pink" are now "imade3d_petg_175".
+# - Materials "imade3d_pla_green" and "imade3d_pla_pink" are now "imade3d_petg_175".
+#
+# Note: Theoretically, the old material profiles with "_2-fans" at the end should be updated to:
+# - machine definition: imade3d_jellybox_2
+# - variant: 0.4 mm (for jellybox 2)
+# - material: (as an example) imade3d_petg_175_imade3d_jellybox_2_0.4_mm
+#
+# But this involves changing the definition of the global stack and the extruder stacks, which can cause more trouble
+# than what we can fix. So, here, we update all material variants, regardless of having "_2-fans" at the end or not, to
+# jellybox_0.4_mm.
+#
+_renamed_material_profiles = { # PETG
+ "imade3d_petg_green": "imade3d_petg_175",
+ "imade3d_petg_green_imade3d_jellybox": "imade3d_petg_175_imade3d_jellybox",
+ "imade3d_petg_green_imade3d_jellybox_0.4_mm": "imade3d_petg_175_imade3d_jellybox_0.4_mm",
+ "imade3d_petg_green_imade3d_jellybox_0.4_mm_2-fans": "imade3d_petg_175_imade3d_jellybox_0.4_mm",
+ "imade3d_petg_pink": "imade3d_petg_175",
+ "imade3d_petg_pink_imade3d_jellybox": "imade3d_petg_175_imade3d_jellybox",
+ "imade3d_petg_pink_imade3d_jellybox_0.4_mm": "imade3d_petg_175_imade3d_jellybox_0.4_mm",
+ "imade3d_petg_pink_imade3d_jellybox_0.4_mm_2-fans": "imade3d_petg_175_imade3d_jellybox_0.4_mm",
+ # PLA
+ "imade3d_pla_green": "imade3d_pla_175",
+ "imade3d_pla_green_imade3d_jellybox": "imade3d_pla_175_imade3d_jellybox",
+ "imade3d_pla_green_imade3d_jellybox_0.4_mm": "imade3d_pla_175_imade3d_jellybox_0.4_mm",
+ "imade3d_pla_green_imade3d_jellybox_0.4_mm_2-fans": "imade3d_pla_175_imade3d_jellybox_0.4_mm",
+ "imade3d_pla_pink": "imade3d_pla_175",
+ "imade3d_pla_pink_imade3d_jellybox": "imade3d_pla_175_imade3d_jellybox",
+ "imade3d_pla_pink_imade3d_jellybox_0.4_mm": "imade3d_pla_175_imade3d_jellybox_0.4_mm",
+ "imade3d_pla_pink_imade3d_jellybox_0.4_mm_2-fans": "imade3d_pla_175_imade3d_jellybox_0.4_mm",
+ }
+
+_removed_settings = {
+ "start_layers_at_same_position"
+}
+
+_renamed_settings = {
+ "support_infill_angle": "support_infill_angles"
+} # type: Dict[str, str]
+
+## Upgrades configurations from the state they were in at version 4.2 to the
+# state they should be in at version 4.3.
+class VersionUpgrade42to43(VersionUpgrade):
+ ## Gets the version number from a CFG file in Uranium's 4.2 format.
+ #
+ # Since the format may change, this is implemented for the 4.2 format only
+ # and needs to be included in the version upgrade system rather than
+ # globally in Uranium.
+ #
+ # \param serialised The serialised form of a CFG file.
+ # \return The version number stored in the CFG file.
+ # \raises ValueError The format of the version number in the file is
+ # incorrect.
+ # \raises KeyError The format of the file is incorrect.
+ def getCfgVersion(self, serialised: str) -> int:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialised)
+ format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
+ setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
+ return format_version * 1000000 + setting_version
+
+ def upgradePreferences(self, serialized: str, filename: str):
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ if "camera_perspective_mode" in parser["general"] and parser["general"]["camera_perspective_mode"] == "orthogonal":
+ parser["general"]["camera_perspective_mode"] = "orthographic"
+
+ # Fix renamed settings for visibility
+ if "visible_settings" in parser["general"]:
+ all_setting_keys = parser["general"]["visible_settings"].strip().split(";")
+ if all_setting_keys:
+ for idx, key in enumerate(all_setting_keys):
+ if key in _renamed_settings:
+ all_setting_keys[idx] = _renamed_settings[key]
+ parser["general"]["visible_settings"] = ";".join(all_setting_keys)
+
+ parser["metadata"]["setting_version"] = "9"
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
+
+ ## Upgrades instance containers to have the new version
+ # number.
+ #
+ # 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.read_string(serialized)
+
+ # Update version number.
+ parser["metadata"]["setting_version"] = "9"
+
+ if "values" in parser:
+ for old_name, new_name in _renamed_settings.items():
+ if old_name in parser["values"]:
+ parser["values"][new_name] = parser["values"][old_name]
+ del parser["values"][old_name]
+ for key in _removed_settings:
+ if key in parser["values"]:
+ del parser["values"][key]
+
+ if "support_infill_angles" in parser["values"]:
+ old_value = float(parser["values"]["support_infill_angles"])
+ new_value = [int(round(old_value))]
+ parser["values"]["support_infill_angles"] = str(new_value)
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
+
+ ## Upgrades stacks to have the new version number.
+ def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ # Update version number.
+ parser["metadata"]["setting_version"] = "9"
+ # Handle changes for the imade3d jellybox. The machine was split up into parts (eg; a 2 fan version and a single
+ # fan version. Perviously it used variants for this. The only upgrade we can do here is strip that variant.
+ # This is because we only upgrade per stack (and to fully do these changes, we'd need to switch out something
+ # in the global container based on changes made to the extruder stack)
+ if parser["containers"]["6"] == "imade3d_jellybox_extruder_0":
+ quality_id = parser["containers"]["2"]
+ if quality_id.endswith("_2-fans"):
+ parser["containers"]["2"] = quality_id.replace("_2-fans", "")
+
+ if parser["containers"]["2"] in _renamed_profiles:
+ parser["containers"]["2"] = _renamed_profiles[parser["containers"]["2"]]
+
+ material_id = parser["containers"]["3"]
+ if material_id in _renamed_material_profiles:
+ parser["containers"]["3"] = _renamed_material_profiles[material_id]
+ variant_id = parser["containers"]["4"]
+
+ if variant_id.endswith("_2-fans"):
+ parser["containers"]["4"] = variant_id.replace("_2-fans", "")
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
diff --git a/plugins/VersionUpgrade/VersionUpgrade42to43/__init__.py b/plugins/VersionUpgrade/VersionUpgrade42to43/__init__.py
new file mode 100644
index 0000000000..7400bbb989
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade42to43/__init__.py
@@ -0,0 +1,59 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Any, Dict, TYPE_CHECKING
+
+from . import VersionUpgrade42to43
+
+if TYPE_CHECKING:
+ from UM.Application import Application
+
+upgrade = VersionUpgrade42to43.VersionUpgrade42to43()
+
+def getMetaData() -> Dict[str, Any]:
+ return {
+ "version_upgrade": {
+ # From To Upgrade function
+ ("preferences", 6000008): ("preferences", 6000009, upgrade.upgradePreferences),
+ ("machine_stack", 4000008): ("machine_stack", 4000009, upgrade.upgradeStack),
+ ("extruder_train", 4000008): ("extruder_train", 4000009, upgrade.upgradeStack),
+ ("definition_changes", 4000008): ("definition_changes", 4000009, upgrade.upgradeInstanceContainer),
+ ("quality_changes", 4000008): ("quality_changes", 4000009, upgrade.upgradeInstanceContainer),
+ ("quality", 4000008): ("quality", 4000009, upgrade.upgradeInstanceContainer),
+ ("user", 4000008): ("user", 4000009, upgrade.upgradeInstanceContainer),
+ },
+ "sources": {
+ "preferences": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"."}
+ },
+ "machine_stack": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./machine_instances"}
+ },
+ "extruder_train": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./extruders"}
+ },
+ "definition_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./definition_changes"}
+ },
+ "quality_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality_changes"}
+ },
+ "quality": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality"}
+ },
+ "user": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./user"}
+ }
+ }
+ }
+
+
+def register(app: "Application") -> Dict[str, Any]:
+ return { "version_upgrade": upgrade }
\ No newline at end of file
diff --git a/plugins/VersionUpgrade/VersionUpgrade42to43/plugin.json b/plugins/VersionUpgrade/VersionUpgrade42to43/plugin.json
new file mode 100644
index 0000000000..8a5e838668
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade42to43/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "Version Upgrade 4.2 to 4.3",
+ "author": "Ultimaker B.V.",
+ "version": "1.0.0",
+ "description": "Upgrades configurations from Cura 4.2 to Cura 4.3.",
+ "api": "7.0",
+ "i18n-catalog": "cura"
+}
diff --git a/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py b/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py
new file mode 100644
index 0000000000..8b69852cb2
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py
@@ -0,0 +1,122 @@
+import configparser
+from typing import Tuple, List
+import io
+from UM.VersionUpgrade import VersionUpgrade
+from UM.Util import parseBool # To parse whether the Alternate Skin Rotations function is activated.
+
+_renamed_container_id_map = {
+ "ultimaker2_0.25": "ultimaker2_olsson_0.25",
+ "ultimaker2_0.4": "ultimaker2_olsson_0.4",
+ "ultimaker2_0.6": "ultimaker2_olsson_0.6",
+ "ultimaker2_0.8": "ultimaker2_olsson_0.8",
+ "ultimaker2_extended_0.25": "ultimaker2_extended_olsson_0.25",
+ "ultimaker2_extended_0.4": "ultimaker2_extended_olsson_0.4",
+ "ultimaker2_extended_0.6": "ultimaker2_extended_olsson_0.6",
+ "ultimaker2_extended_0.8": "ultimaker2_extended_olsson_0.8",
+ # HMS434 "extra coarse", "super coarse", and "ultra coarse" are removed.
+ "hms434_global_Extra_Coarse_Quality": "hms434_global_Normal_Quality",
+ "hms434_global_Super_Coarse_Quality": "hms434_global_Normal_Quality",
+ "hms434_global_Ultra_Coarse_Quality": "hms434_global_Normal_Quality",
+ # HMS434 "0.25", "0.6", "1.2", and "1.5" nozzles are removed.
+ "hms434_0.25tpnozzle": "hms434_0.4tpnozzle",
+ "hms434_0.6tpnozzle": "hms434_0.4tpnozzle",
+ "hms434_1.2tpnozzle": "hms434_0.4tpnozzle",
+ "hms434_1.5tpnozzle": "hms434_0.4tpnozzle",
+}
+
+
+class VersionUpgrade43to44(VersionUpgrade):
+ def getCfgVersion(self, serialised: str) -> int:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialised)
+ format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
+ setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
+ return format_version * 1000000 + setting_version
+
+ ## Upgrades Preferences to have the new version number.
+ #
+ # This renames the renamed settings in the list of visible settings.
+ def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ # Update version number.
+ parser["metadata"]["setting_version"] = "10"
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
+
+ ## Upgrades instance containers to have the new version
+ # number.
+ #
+ # 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.read_string(serialized)
+
+ # Update version number.
+ parser["metadata"]["setting_version"] = "10"
+
+ # Intent profiles were added, so the quality changes should match with no intent (so "default")
+ if parser["metadata"].get("type", "") == "quality_changes":
+ parser["metadata"]["intent_category"] = "default"
+
+ if "values" in parser:
+ # Alternate skin rotation should be translated to top/bottom line directions.
+ if "skin_alternate_rotation" in parser["values"] and parseBool(parser["values"]["skin_alternate_rotation"]):
+ parser["values"]["skin_angles"] = "[45, 135, 0, 90]"
+ # Unit of adaptive layers topography size changed.
+ if "adaptive_layer_height_threshold" in parser["values"]:
+ val = parser["values"]["adaptive_layer_height_threshold"]
+ if val.startswith("="):
+ val = val[1:]
+ val = "=({val}) / 1000".format(val = val) # Convert microns to millimetres. Works even if the profile contained a formula.
+ parser["values"]["adaptive_layer_height_threshold"] = val
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
+
+ ## Upgrades stacks to have the new version number.
+ def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ # Update version number.
+ if "metadata" not in parser:
+ parser["metadata"] = {}
+ parser["metadata"]["setting_version"] = "10"
+
+ if "containers" in parser:
+ # With the ContainerTree refactor, UM2 with Olsson block got moved to a separate definition.
+ if "6" in parser["containers"]:
+ if parser["containers"]["6"] == "ultimaker2":
+ if "metadata" in parser and "has_variants" in parser["metadata"] and parser["metadata"]["has_variants"] == "True": # This is an Olsson block upgraded UM2!
+ parser["containers"]["6"] = "ultimaker2_olsson"
+ del parser["metadata"]["has_variants"]
+ elif parser["containers"]["6"] == "ultimaker2_extended":
+ if "metadata" in parser and "has_variants" in parser["metadata"] and parser["metadata"]["has_variants"] == "True": # This is an Olsson block upgraded UM2E!
+ parser["containers"]["6"] = "ultimaker2_extended_olsson"
+ del parser["metadata"]["has_variants"]
+
+ # We should only have 6 levels when we start.
+ if "7" in parser["containers"]:
+ return ([], [])
+
+ # We added the intent container in Cura 4.4. This means that all other containers move one step down.
+ parser["containers"]["7"] = parser["containers"]["6"]
+ parser["containers"]["6"] = parser["containers"]["5"]
+ parser["containers"]["5"] = parser["containers"]["4"]
+ parser["containers"]["4"] = parser["containers"]["3"]
+ parser["containers"]["3"] = parser["containers"]["2"]
+ parser["containers"]["2"] = "empty_intent"
+
+ # Update renamed containers
+ for key, value in parser["containers"].items():
+ if value in _renamed_container_id_map:
+ parser["containers"][key] = _renamed_container_id_map[value]
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
diff --git a/plugins/VersionUpgrade/VersionUpgrade43to44/__init__.py b/plugins/VersionUpgrade/VersionUpgrade43to44/__init__.py
new file mode 100644
index 0000000000..506ec6c03d
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade43to44/__init__.py
@@ -0,0 +1,61 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Any, Dict, TYPE_CHECKING
+
+from . import VersionUpgrade43to44
+
+
+if TYPE_CHECKING:
+ from UM.Application import Application
+
+upgrade = VersionUpgrade43to44.VersionUpgrade43to44()
+
+
+def getMetaData() -> Dict[str, Any]:
+ return {
+ "version_upgrade": {
+ # From To Upgrade function
+ ("preferences", 6000009): ("preferences", 6000010, upgrade.upgradePreferences),
+ ("machine_stack", 4000009): ("machine_stack", 4000010, upgrade.upgradeStack),
+ ("extruder_train", 4000009): ("extruder_train", 4000010, upgrade.upgradeStack),
+ ("definition_changes", 4000009): ("definition_changes", 4000010, upgrade.upgradeInstanceContainer),
+ ("quality_changes", 4000009): ("quality_changes", 4000010, upgrade.upgradeInstanceContainer),
+ ("quality", 4000009): ("quality", 4000010, upgrade.upgradeInstanceContainer),
+ ("user", 4000009): ("user", 4000010, upgrade.upgradeInstanceContainer),
+ },
+ "sources": {
+ "preferences": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"."}
+ },
+ "machine_stack": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./machine_instances"}
+ },
+ "extruder_train": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./extruders"}
+ },
+ "definition_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./definition_changes"}
+ },
+ "quality_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality_changes"}
+ },
+ "quality": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality"}
+ },
+ "user": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./user"}
+ }
+ }
+ }
+
+
+def register(app: "Application") -> Dict[str, Any]:
+ return {"version_upgrade": upgrade}
diff --git a/plugins/VersionUpgrade/VersionUpgrade43to44/plugin.json b/plugins/VersionUpgrade/VersionUpgrade43to44/plugin.json
new file mode 100644
index 0000000000..37575396e3
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade43to44/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "Version Upgrade 4.3 to 4.4",
+ "author": "Ultimaker B.V.",
+ "version": "1.0.0",
+ "description": "Upgrades configurations from Cura 4.3 to Cura 4.4.",
+ "api": "7.0",
+ "i18n-catalog": "cura"
+}
diff --git a/plugins/VersionUpgrade/VersionUpgrade43to44/tests/TestVersionUpgrade43To44.py b/plugins/VersionUpgrade/VersionUpgrade43to44/tests/TestVersionUpgrade43To44.py
new file mode 100644
index 0000000000..dc770c2c6f
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade43to44/tests/TestVersionUpgrade43To44.py
@@ -0,0 +1,36 @@
+import configparser
+
+import VersionUpgrade43to44
+
+before_update = """[general]
+version = 4
+name = Ultimaker 3
+id = Ultimaker 3
+
+[metadata]
+type = machine
+
+[containers]
+0 = user_profile
+1 = quality_changes
+2 = quality
+3 = material
+4 = variant
+5 = definition_changes
+6 = definition
+"""
+
+
+def test_upgrade():
+ upgrader = VersionUpgrade43to44.VersionUpgrade43to44()
+ file_name, new_data = upgrader.upgradeStack(before_update, "whatever")
+ parser = configparser.ConfigParser(interpolation=None)
+ parser.read_string(new_data[0])
+ assert parser["containers"]["0"] == "user_profile"
+ assert parser["containers"]["1"] == "quality_changes"
+ assert parser["containers"]["2"] == "empty_intent"
+ assert parser["containers"]["3"] == "quality"
+ assert parser["containers"]["4"] == "material"
+ assert parser["containers"]["5"] == "variant"
+ assert parser["containers"]["6"] == "definition_changes"
+ assert parser["containers"]["7"] == "definition"
\ No newline at end of file
diff --git a/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py b/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py
new file mode 100644
index 0000000000..1d278764f0
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py
@@ -0,0 +1,69 @@
+import configparser
+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
+
+
+class VersionUpgrade44to45(VersionUpgrade):
+ def getCfgVersion(self, serialised: str) -> int:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialised)
+ format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
+ setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
+ return format_version * 1000000 + setting_version
+
+ ## Upgrades Preferences to have the new version number.
+ #
+ # This renames the renamed settings in the list of visible settings.
+ def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ # Update version number.
+ parser["metadata"]["setting_version"] = "11"
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
+
+ ## Upgrades instance containers to have the new version
+ # number.
+ #
+ # 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.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"]
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
+
+ ## Upgrades stacks to have the new version number.
+ def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ # Update version number.
+ if "metadata" not in parser:
+ parser["metadata"] = {}
+ parser["metadata"]["setting_version"] = "11"
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
diff --git a/plugins/VersionUpgrade/VersionUpgrade44to45/__init__.py b/plugins/VersionUpgrade/VersionUpgrade44to45/__init__.py
new file mode 100644
index 0000000000..06a9d66c50
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade44to45/__init__.py
@@ -0,0 +1,61 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Any, Dict, TYPE_CHECKING
+
+from . import VersionUpgrade44to45
+
+
+if TYPE_CHECKING:
+ from UM.Application import Application
+
+upgrade = VersionUpgrade44to45.VersionUpgrade44to45()
+
+
+def getMetaData() -> Dict[str, Any]:
+ return {
+ "version_upgrade": {
+ # From To Upgrade function
+ ("preferences", 6000010): ("preferences", 6000011, upgrade.upgradePreferences),
+ ("machine_stack", 4000010): ("machine_stack", 4000011, upgrade.upgradeStack),
+ ("extruder_train", 4000010): ("extruder_train", 4000011, upgrade.upgradeStack),
+ ("definition_changes", 4000010): ("definition_changes", 4000011, upgrade.upgradeInstanceContainer),
+ ("quality_changes", 4000010): ("quality_changes", 4000011, upgrade.upgradeInstanceContainer),
+ ("quality", 4000010): ("quality", 4000011, upgrade.upgradeInstanceContainer),
+ ("user", 4000010): ("user", 4000011, upgrade.upgradeInstanceContainer),
+ },
+ "sources": {
+ "preferences": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"."}
+ },
+ "machine_stack": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./machine_instances"}
+ },
+ "extruder_train": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./extruders"}
+ },
+ "definition_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./definition_changes"}
+ },
+ "quality_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality_changes"}
+ },
+ "quality": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality"}
+ },
+ "user": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./user"}
+ }
+ }
+ }
+
+
+def register(app: "Application") -> Dict[str, Any]:
+ return {"version_upgrade": upgrade}
diff --git a/plugins/VersionUpgrade/VersionUpgrade44to45/plugin.json b/plugins/VersionUpgrade/VersionUpgrade44to45/plugin.json
new file mode 100644
index 0000000000..f7b6157118
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade44to45/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "Version Upgrade 4.4 to 4.5",
+ "author": "Ultimaker B.V.",
+ "version": "1.0.0",
+ "description": "Upgrades configurations from Cura 4.4 to Cura 4.5.",
+ "api": "7.0",
+ "i18n-catalog": "cura"
+}
diff --git a/plugins/VersionUpgrade/VersionUpgrade44to45/tests/TestVersionUpgrade44To45.py b/plugins/VersionUpgrade/VersionUpgrade44to45/tests/TestVersionUpgrade44To45.py
new file mode 100644
index 0000000000..0c1bb55985
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade44to45/tests/TestVersionUpgrade44To45.py
@@ -0,0 +1,42 @@
+import configparser
+
+import VersionUpgrade44to45
+import pytest
+
+before_update = """[general]
+version = 4
+name = Creality CR-10S_settings
+definition = creality_cr10s
+
+[metadata]
+type = definition_changes
+setting_version = 11
+
+[values]
+%s
+"""
+before_after_list = [
+ ("machine_head_with_fans_polygon = [[-99, 99], [-99, -44], [45, 99], [45, -44]]", "[[-99, 99], [-99, -44], [45, 99], [45, -44]]"),
+ ("", None),
+ ("machine_head_polygon = [[-98, 99], [-99, -44], [45, 99], [45, -44]]", "[[-98, 99], [-99, -44], [45, 99], [45, -44]]"),
+ ("machine_head_polygon = [[-87, 99], [-99, -44], [45, 99], [45, -44]]\nmachine_head_with_fans_polygon = [[-99, 99], [-99, -44], [45, 99], [45, -44]]", "[[-99, 99], [-99, -44], [45, 99], [45, -44]]"),
+ ]
+
+
+class TestVersionUpgrade44to45:
+
+ @pytest.mark.parametrize("after_string, after_value", before_after_list)
+ def test_upgrade(self, after_string, after_value):
+ upgrader = VersionUpgrade44to45.VersionUpgrade44to45()
+
+
+ file_name, new_data = upgrader.upgradeInstanceContainer(before_update % after_string, "whatever")
+ parser = configparser.ConfigParser(interpolation=None)
+ parser.read_string(new_data[0])
+
+ if after_value is None:
+ assert "machine_head_with_fans_polygon" not in parser["values"]
+ else:
+ assert parser["values"]["machine_head_with_fans_polygon"] == after_value
+
+ assert "machine_head_polygon" not in parser["values"]
\ No newline at end of file
diff --git a/plugins/X3DReader/plugin.json b/plugins/X3DReader/plugin.json
index 1fc14104ed..17bb3a96d1 100644
--- a/plugins/X3DReader/plugin.json
+++ b/plugins/X3DReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Seva Alekseyev",
"version": "1.0.1",
"description": "Provides support for reading X3D files.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py
index 86533fe51c..88a5a441b8 100644
--- a/plugins/XRayView/XRayView.py
+++ b/plugins/XRayView/XRayView.py
@@ -10,21 +10,21 @@ from UM.Math.Color import Color
from UM.PluginRegistry import PluginRegistry
from UM.Platform import Platform
from UM.Event import Event
-from UM.View.View import View
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
from UM.View.RenderBatch import RenderBatch
from UM.View.GL.OpenGL import OpenGL
from cura.CuraApplication import CuraApplication
+from cura.CuraView import CuraView
from cura.Scene.ConvexHullNode import ConvexHullNode
from . import XRayPass
## View used to display a see-through version of objects with errors highlighted.
-class XRayView(View):
+class XRayView(CuraView):
def __init__(self):
- super().__init__()
+ super().__init__(parent = None, use_empty_menu_placeholder = True)
self._xray_shader = None
self._xray_pass = None
diff --git a/plugins/XRayView/plugin.json b/plugins/XRayView/plugin.json
index 71cc165b6c..ff220ed97c 100644
--- a/plugins/XRayView/plugin.json
+++ b/plugins/XRayView/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides the X-Ray view.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/XRayView/xray.shader b/plugins/XRayView/xray.shader
index 41b00154ea..45cb16c44c 100644
--- a/plugins/XRayView/xray.shader
+++ b/plugins/XRayView/xray.shader
@@ -1,12 +1,14 @@
[shaders]
vertex =
- uniform highp mat4 u_modelViewProjectionMatrix;
+ uniform highp mat4 u_modelMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
attribute highp vec4 a_vertex;
void main()
{
- gl_Position = u_modelViewProjectionMatrix * a_vertex;
+ gl_Position = u_projectionMatrix * u_viewMatrix * u_modelMatrix * a_vertex;
}
fragment =
@@ -19,13 +21,15 @@ fragment =
vertex41core =
#version 410
- uniform highp mat4 u_modelViewProjectionMatrix;
+ uniform highp mat4 u_modelMatrix;
+ uniform highp mat4 u_viewMatrix;
+ uniform highp mat4 u_projectionMatrix;
in highp vec4 a_vertex;
void main()
{
- gl_Position = u_modelViewProjectionMatrix * a_vertex;
+ gl_Position = u_projectionMatrix * u_viewMatrix * u_modelMatrix * a_vertex;
}
fragment41core =
@@ -43,7 +47,9 @@ fragment41core =
u_color = [0.02, 0.02, 0.02, 1.0]
[bindings]
-u_modelViewProjectionMatrix = model_view_projection_matrix
+u_modelMatrix = model_matrix
+u_viewMatrix = view_matrix
+u_projectionMatrix = projection_matrix
[attributes]
a_vertex = vertex
diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py
index 1a0d3bc85e..52b204affc 100644
--- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py
+++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py
@@ -6,7 +6,7 @@ import io
import json #To parse the product-to-id mapping file.
import os.path #To find the product-to-id mapping.
import sys
-from typing import Any, Dict, List, Optional, Tuple, cast, Set
+from typing import Any, Dict, List, Optional, Tuple, cast, Set, Union
import xml.etree.ElementTree as ET
from UM.Resources import Resources
@@ -17,9 +17,13 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
from cura.CuraApplication import CuraApplication
+from cura.Machines.ContainerTree import ContainerTree
from cura.Machines.VariantType import VariantType
-from .XmlMaterialValidator import XmlMaterialValidator
+try:
+ from .XmlMaterialValidator import XmlMaterialValidator
+except (ImportError, SystemError):
+ import XmlMaterialValidator # type: ignore # This fixes the tests not being able to import.
## Handles serializing and deserializing material containers from an XML file
@@ -40,11 +44,11 @@ class XmlMaterialProfile(InstanceContainer):
#
# \param xml_version: The version number found in an XML file.
# \return The corresponding setting_version.
- @classmethod
- def xmlVersionToSettingVersion(cls, xml_version: str) -> int:
+ @staticmethod
+ def xmlVersionToSettingVersion(xml_version: str) -> int:
if xml_version == "1.3":
return CuraApplication.SettingVersion
- return 0 #Older than 1.3.
+ return 0 # Older than 1.3.
def getInheritedFiles(self):
return self._inherited_files
@@ -63,26 +67,28 @@ class XmlMaterialProfile(InstanceContainer):
Logger.log("w", "Can't change metadata {key} of material {material_id} because it's read-only.".format(key = key, material_id = self.getId()))
return
- # Prevent recursion
- if not apply_to_all:
- super().setMetaDataEntry(key, value)
- return
+ # Some metadata such as diameter should also be instantiated to be a setting. Go though all values for the
+ # "properties" field and apply the new values to SettingInstances as well.
+ new_setting_values_dict = {}
+ if key == "properties":
+ for k, v in value.items():
+ if k in self.__material_properties_setting_map:
+ new_setting_values_dict[self.__material_properties_setting_map[k]] = v
- # Get the MaterialGroup
- material_manager = CuraApplication.getInstance().getMaterialManager()
- root_material_id = self.getMetaDataEntry("base_file") #if basefile is self.getId, this is a basefile.
- material_group = material_manager.getMaterialGroup(root_material_id)
+ if not apply_to_all: # Historical: If you only want to modify THIS container. We only used that to prevent recursion but with the below code that's no longer necessary.
+ # CURA-6920: This is an optimization, but it also fixes the problem that you can only set metadata for a
+ # material container that can be found in the container registry.
+ container_query = [self]
+ else:
+ container_query = registry.findContainers(base_file = self.getMetaDataEntry("base_file"))
- # Update the root material container
- root_material_container = material_group.root_material_node.getContainer()
- if root_material_container is not None:
- root_material_container.setMetaDataEntry(key, value, apply_to_all = False)
-
- # Update all containers derived from it
- for node in material_group.derived_material_node_list:
- container = node.getContainer()
- if container is not None:
- container.setMetaDataEntry(key, value, apply_to_all = False)
+ for container in container_query:
+ if key not in container.getMetaData() or container.getMetaData()[key] != value:
+ container.getMetaData()[key] = value
+ container.setDirty(True)
+ container.metaDataChanged.emit(container)
+ for k, v in new_setting_values_dict.items():
+ self.setProperty(k, "value", v)
## Overridden from InstanceContainer, similar to setMetaDataEntry.
# without this function the setName would only set the name of the specific nozzle / material / machine combination container
@@ -142,23 +148,13 @@ class XmlMaterialProfile(InstanceContainer):
# setting_version is derived from the "version" tag in the schema, so don't serialize it into a file
if ignored_metadata_keys is None:
ignored_metadata_keys = set()
- ignored_metadata_keys |= {"setting_version"}
+ ignored_metadata_keys |= {"setting_version", "definition", "status", "variant", "type", "base_file", "approximate_diameter", "id", "container_type", "name", "compatible"}
# remove the keys that we want to ignore in the metadata
for key in ignored_metadata_keys:
if key in metadata:
del metadata[key]
properties = metadata.pop("properties", {})
- # Metadata properties that should not be serialized.
- metadata.pop("status", "")
- metadata.pop("variant", "")
- metadata.pop("type", "")
- metadata.pop("base_file", "")
- metadata.pop("approximate_diameter", "")
- metadata.pop("id", "")
- metadata.pop("container_type", "")
- metadata.pop("name", "")
-
## Begin Name Block
builder.start("name") # type: ignore
@@ -182,13 +178,16 @@ class XmlMaterialProfile(InstanceContainer):
## End Name Block
for key, value in metadata.items():
- builder.start(key) # type: ignore
+ key_to_use = key
+ if key in self._metadata_tags_that_have_cura_namespace:
+ key_to_use = "cura:" + key_to_use
+ builder.start(key_to_use) # type: ignore
if value is not None: #Nones get handled well by the builder.
#Otherwise the builder always expects a string.
#Deserialize expects the stringified version.
value = str(value)
builder.data(value)
- builder.end(key)
+ builder.end(key_to_use)
builder.end("metadata")
## End Metadata Block
@@ -211,10 +210,8 @@ class XmlMaterialProfile(InstanceContainer):
for instance in self.findInstances():
self._addSettingElement(builder, instance)
- machine_container_map = {} # type: Dict[str, InstanceContainer]
- machine_variant_map = {} # type: Dict[str, Dict[str, Any]]
-
- variant_manager = CuraApplication.getInstance().getVariantManager()
+ machine_container_map = {} # type: Dict[str, InstanceContainer]
+ machine_variant_map = {} # type: Dict[str, Dict[str, Any]]
root_material_id = self.getMetaDataEntry("base_file") # if basefile is self.getId, this is a basefile.
all_containers = registry.findInstanceContainers(base_file = root_material_id)
@@ -231,13 +228,13 @@ class XmlMaterialProfile(InstanceContainer):
machine_variant_map[definition_id] = {}
variant_name = container.getMetaDataEntry("variant_name")
- if variant_name:
- variant_dict = {"variant_node": variant_manager.getVariantNode(definition_id, variant_name),
- "material_container": container}
- machine_variant_map[definition_id][variant_name] = variant_dict
+ if not variant_name:
+ machine_container_map[definition_id] = container
continue
- machine_container_map[definition_id] = container
+ variant_dict = {"variant_type": container.getMetaDataEntry("hardware_type", "nozzle"),
+ "material_container": container}
+ machine_variant_map[definition_id][variant_name] = variant_dict
# Map machine human-readable names to IDs
product_id_map = self.getProductIdMap()
@@ -270,8 +267,7 @@ class XmlMaterialProfile(InstanceContainer):
# Find all hotend sub-profiles corresponding to this material and machine and add them to this profile.
buildplate_dict = {} # type: Dict[str, Any]
for variant_name, variant_dict in machine_variant_map[definition_id].items():
- variant_type = variant_dict["variant_node"].getMetaDataEntry("hardware_type", str(VariantType.NOZZLE))
- variant_type = VariantType(variant_type)
+ variant_type = VariantType(variant_dict["variant_type"])
if variant_type == VariantType.NOZZLE:
# The hotend identifier is not the containers name, but its "name".
builder.start("hotend", {"id": variant_name})
@@ -334,7 +330,7 @@ class XmlMaterialProfile(InstanceContainer):
stream = io.BytesIO()
tree = ET.ElementTree(root)
# this makes sure that the XML header states encoding="utf-8"
- tree.write(stream, encoding = "utf-8", xml_declaration=True)
+ tree.write(stream, encoding = "utf-8", xml_declaration = True)
return stream.getvalue().decode("utf-8")
@@ -398,7 +394,8 @@ class XmlMaterialProfile(InstanceContainer):
self._combineElement(self._expandMachinesXML(result), self._expandMachinesXML(second))
return result
- def _createKey(self, element):
+ @staticmethod
+ def _createKey(element):
key = element.tag.split("}")[-1]
if "key" in element.attrib:
key += " key:" + element.attrib["key"]
@@ -414,15 +411,15 @@ class XmlMaterialProfile(InstanceContainer):
# Recursively merges XML elements. Updates either the text or children if another element is found in first.
# If it does not exist, copies it from second.
- def _combineElement(self, first, second):
+ @staticmethod
+ def _combineElement(first, second):
# Create a mapping from tag name to element.
-
mapping = {}
for element in first:
- key = self._createKey(element)
+ key = XmlMaterialProfile._createKey(element)
mapping[key] = element
for element in second:
- key = self._createKey(element)
+ key = XmlMaterialProfile._createKey(element)
if len(element): # Check if element has children.
try:
if "setting" in element.tag and not "settings" in element.tag:
@@ -432,7 +429,7 @@ class XmlMaterialProfile(InstanceContainer):
for child in element:
mapping[key].append(child)
else:
- self._combineElement(mapping[key], element) # Multiple elements, handle those.
+ XmlMaterialProfile._combineElement(mapping[key], element) # Multiple elements, handle those.
except KeyError:
mapping[key] = element
first.append(element)
@@ -684,32 +681,6 @@ class XmlMaterialProfile(InstanceContainer):
if is_new_material:
containers_to_add.append(new_material)
- # Find the buildplates compatibility
- buildplates = machine.iterfind("./um:buildplate", self.__namespaces)
- buildplate_map = {}
- buildplate_map["buildplate_compatible"] = {}
- buildplate_map["buildplate_recommended"] = {}
- for buildplate in buildplates:
- buildplate_id = buildplate.get("id")
- if buildplate_id is None:
- continue
-
- variant_manager = CuraApplication.getInstance().getVariantManager()
- variant_node = variant_manager.getVariantNode(machine_id, buildplate_id,
- variant_type = VariantType.BUILD_PLATE)
- if not variant_node:
- continue
-
- _, buildplate_unmapped_settings_dict = self._getSettingsDictForNode(buildplate)
-
- buildplate_compatibility = buildplate_unmapped_settings_dict.get("hardware compatible",
- machine_compatibility)
- buildplate_recommended = buildplate_unmapped_settings_dict.get("hardware recommended",
- machine_compatibility)
-
- buildplate_map["buildplate_compatible"][buildplate_id] = buildplate_compatibility
- buildplate_map["buildplate_recommended"][buildplate_id] = buildplate_recommended
-
hotends = machine.iterfind("./um:hotend", self.__namespaces)
for hotend in hotends:
# The "id" field for hotends in material profiles is actually name
@@ -717,11 +688,6 @@ class XmlMaterialProfile(InstanceContainer):
if hotend_name is None:
continue
- variant_manager = CuraApplication.getInstance().getVariantManager()
- variant_node = variant_manager.getVariantNode(machine_id, hotend_name, VariantType.NOZZLE)
- if not variant_node:
- continue
-
hotend_mapped_settings, hotend_unmapped_settings = self._getSettingsDictForNode(hotend)
hotend_compatibility = hotend_unmapped_settings.get("hardware compatible", machine_compatibility)
@@ -745,9 +711,6 @@ class XmlMaterialProfile(InstanceContainer):
new_hotend_material.getMetaData()["compatible"] = hotend_compatibility
new_hotend_material.getMetaData()["machine_manufacturer"] = machine_manufacturer
new_hotend_material.getMetaData()["definition"] = machine_id
- if buildplate_map["buildplate_compatible"]:
- new_hotend_material.getMetaData()["buildplate_compatible"] = buildplate_map["buildplate_compatible"]
- new_hotend_material.getMetaData()["buildplate_recommended"] = buildplate_map["buildplate_recommended"]
cached_hotend_setting_properties = cached_machine_setting_properties.copy()
cached_hotend_setting_properties.update(hotend_mapped_settings)
@@ -757,63 +720,10 @@ class XmlMaterialProfile(InstanceContainer):
new_hotend_material._dirty = False
if is_new_material:
+ if ContainerRegistry.getInstance().isReadOnly(self.getId()):
+ ContainerRegistry.getInstance().setExplicitReadOnly(new_hotend_material.getId())
containers_to_add.append(new_hotend_material)
- #
- # Build plates in hotend
- #
- buildplates = hotend.iterfind("./um:buildplate", self.__namespaces)
- for buildplate in buildplates:
- # The "id" field for buildplate in material profiles is actually name
- buildplate_name = buildplate.get("id")
- if buildplate_name is None:
- continue
-
- variant_manager = CuraApplication.getInstance().getVariantManager()
- variant_node = variant_manager.getVariantNode(machine_id, buildplate_name, VariantType.BUILD_PLATE)
- if not variant_node:
- continue
-
- buildplate_mapped_settings, buildplate_unmapped_settings = self._getSettingsDictForNode(buildplate)
- buildplate_compatibility = buildplate_unmapped_settings.get("hardware compatible",
- buildplate_map["buildplate_compatible"])
- buildplate_recommended = buildplate_unmapped_settings.get("hardware recommended",
- buildplate_map["buildplate_recommended"])
-
- # Generate container ID for the hotend-and-buildplate-specific material container
- new_hotend_and_buildplate_specific_material_id = new_hotend_specific_material_id + "_" + buildplate_name.replace(" ", "_")
-
- # Same as machine compatibility, keep the derived material containers consistent with the parent material
- if ContainerRegistry.getInstance().isLoaded(new_hotend_and_buildplate_specific_material_id):
- new_hotend_and_buildplate_material = ContainerRegistry.getInstance().findContainers(id = new_hotend_and_buildplate_specific_material_id)[0]
- is_new_material = False
- else:
- new_hotend_and_buildplate_material = XmlMaterialProfile(new_hotend_and_buildplate_specific_material_id)
- is_new_material = True
-
- new_hotend_and_buildplate_material.setMetaData(copy.deepcopy(new_hotend_material.getMetaData()))
- new_hotend_and_buildplate_material.getMetaData()["id"] = new_hotend_and_buildplate_specific_material_id
- new_hotend_and_buildplate_material.getMetaData()["name"] = self.getName()
- new_hotend_and_buildplate_material.getMetaData()["variant_name"] = hotend_name
- new_hotend_and_buildplate_material.getMetaData()["buildplate_name"] = buildplate_name
- new_hotend_and_buildplate_material.setDefinition(machine_id)
- # Don't use setMetadata, as that overrides it for all materials with same base file
- new_hotend_and_buildplate_material.getMetaData()["compatible"] = buildplate_compatibility
- new_hotend_and_buildplate_material.getMetaData()["machine_manufacturer"] = machine_manufacturer
- new_hotend_and_buildplate_material.getMetaData()["definition"] = machine_id
- new_hotend_and_buildplate_material.getMetaData()["buildplate_compatible"] = buildplate_compatibility
- new_hotend_and_buildplate_material.getMetaData()["buildplate_recommended"] = buildplate_recommended
-
- cached_hotend_and_buildplate_setting_properties = cached_hotend_setting_properties.copy()
- cached_hotend_and_buildplate_setting_properties.update(buildplate_mapped_settings)
-
- new_hotend_and_buildplate_material.setCachedValues(cached_hotend_and_buildplate_setting_properties)
-
- new_hotend_and_buildplate_material._dirty = False
-
- if is_new_material:
- containers_to_add.append(new_hotend_and_buildplate_material)
-
# there is only one ID for a machine. Once we have reached here, it means we have already found
# a workable ID for that machine, so there is no need to continue
break
@@ -822,9 +732,9 @@ class XmlMaterialProfile(InstanceContainer):
ContainerRegistry.getInstance().addContainer(container_to_add)
@classmethod
- def _getSettingsDictForNode(cls, node) -> Tuple[dict, dict]:
- node_mapped_settings_dict = dict()
- node_unmapped_settings_dict = dict()
+ def _getSettingsDictForNode(cls, node) -> Tuple[Dict[str, Any], Dict[str, Any]]:
+ node_mapped_settings_dict = dict() # type: Dict[str, Any]
+ node_unmapped_settings_dict = dict() # type: Dict[str, Any]
# Fetch settings in the "um" namespace
um_settings = node.iterfind("./um:setting", cls.__namespaces)
@@ -953,14 +863,12 @@ class XmlMaterialProfile(InstanceContainer):
for machine in data.iterfind("./um:settings/um:machine", cls.__namespaces):
machine_compatibility = common_compatibility
- for entry in machine.iterfind("./um:setting", cls.__namespaces):
- key = entry.get("key")
- if key == "hardware compatible":
- if entry.text is not None:
- machine_compatibility = cls._parseCompatibleValue(entry.text)
+ for entry in machine.iterfind("./um:setting[@key='hardware compatible']", cls.__namespaces):
+ if entry.text is not None:
+ machine_compatibility = cls._parseCompatibleValue(entry.text)
for identifier in machine.iterfind("./um:machine_identifier", cls.__namespaces):
- machine_id_list = product_id_map.get(identifier.get("product"), [])
+ machine_id_list = product_id_map.get(identifier.get("product", ""), [])
if not machine_id_list:
machine_id_list = cls.getPossibleDefinitionIDsFromName(identifier.get("product"))
@@ -992,7 +900,7 @@ class XmlMaterialProfile(InstanceContainer):
result_metadata.append(new_material_metadata)
buildplates = machine.iterfind("./um:buildplate", cls.__namespaces)
- buildplate_map = {} # type: Dict[str, Dict[str, bool]]
+ buildplate_map = {} # type: Dict[str, Dict[str, bool]]
buildplate_map["buildplate_compatible"] = {}
buildplate_map["buildplate_recommended"] = {}
for buildplate in buildplates:
@@ -1028,11 +936,9 @@ class XmlMaterialProfile(InstanceContainer):
continue
hotend_compatibility = machine_compatibility
- for entry in hotend.iterfind("./um:setting", cls.__namespaces):
- key = entry.get("key")
- if key == "hardware compatible":
- if entry.text is not None:
- hotend_compatibility = cls._parseCompatibleValue(entry.text)
+ for entry in hotend.iterfind("./um:setting[@key='hardware compatible']", cls.__namespaces):
+ if entry.text is not None:
+ hotend_compatibility = cls._parseCompatibleValue(entry.text)
new_hotend_specific_material_id = container_id + "_" + machine_id + "_" + hotend_name.replace(" ", "_")
@@ -1123,8 +1029,8 @@ class XmlMaterialProfile(InstanceContainer):
builder.data(data)
builder.end(tag_name)
- @classmethod
- def _profile_name(cls, material_name, color_name):
+ @staticmethod
+ def _profile_name(material_name, color_name):
if material_name is None:
return "Unknown Material"
if color_name != "Generic":
@@ -1132,8 +1038,8 @@ class XmlMaterialProfile(InstanceContainer):
else:
return material_name
- @classmethod
- def getPossibleDefinitionIDsFromName(cls, name):
+ @staticmethod
+ def getPossibleDefinitionIDsFromName(name):
name_parts = name.lower().split(" ")
merged_name_parts = []
for part in name_parts:
@@ -1166,17 +1072,21 @@ class XmlMaterialProfile(InstanceContainer):
with open(product_to_id_file, encoding = "utf-8") as f:
product_to_id_map = json.load(f)
product_to_id_map = {key: [value] for key, value in product_to_id_map.items()}
+ #This also loads "Ultimaker S5" -> "ultimaker_s5" even though that is not strictly necessary with the default to change spaces into underscores.
+ #However it is not always loaded with that default; this mapping is also used in serialize() without that default.
return product_to_id_map
## Parse the value of the "material compatible" property.
- @classmethod
- def _parseCompatibleValue(cls, value: str):
+ @staticmethod
+ def _parseCompatibleValue(value: str):
return value in {"yes", "unknown"}
## Small string representation for debugging.
def __str__(self):
return "".format(my_id = self.getId(), name = self.getName(), base_file = self.getMetaDataEntry("base_file"))
+ _metadata_tags_that_have_cura_namespace = {"pva_compatible", "breakaway_compatible"}
+
# Map XML file setting names to internal names
__material_settings_setting_map = {
"print temperature": "default_material_print_temperature",
@@ -1189,7 +1099,16 @@ class XmlMaterialProfile(InstanceContainer):
"adhesion tendency": "material_adhesion_tendency",
"surface energy": "material_surface_energy",
"shrinkage percentage": "material_shrinkage_percentage",
- }
+ "build volume temperature": "build_volume_temperature",
+ "anti ooze retract position": "material_anti_ooze_retracted_position",
+ "anti ooze retract speed": "material_anti_ooze_retraction_speed",
+ "break preparation position": "material_break_preparation_retracted_position",
+ "break preparation speed": "material_break_preparation_speed",
+ "break preparation temperature": "material_break_preparation_temperature",
+ "break position": "material_break_retracted_position",
+ "break speed": "material_break_speed",
+ "break temperature": "material_break_temperature"
+ } # type: Dict[str, str]
__unmapped_settings = [
"hardware compatible",
"hardware recommended"
diff --git a/plugins/XmlMaterialProfile/plugin.json b/plugins/XmlMaterialProfile/plugin.json
index bb1db82fa4..a8f82d1058 100644
--- a/plugins/XmlMaterialProfile/plugin.json
+++ b/plugins/XmlMaterialProfile/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides capabilities to read and write XML-based material profiles.",
- "api": "6.0",
+ "api": "7.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/XmlMaterialProfile/product_to_id.json b/plugins/XmlMaterialProfile/product_to_id.json
index 3e7ce9311f..a48eb20a18 100644
--- a/plugins/XmlMaterialProfile/product_to_id.json
+++ b/plugins/XmlMaterialProfile/product_to_id.json
@@ -6,6 +6,8 @@
"Ultimaker 2+": "ultimaker2_plus",
"Ultimaker 3": "ultimaker3",
"Ultimaker 3 Extended": "ultimaker3_extended",
+ "Ultimaker S3": "ultimaker_s3",
+ "Ultimaker S5": "ultimaker_s5",
"Ultimaker Original": "ultimaker_original",
"Ultimaker Original+": "ultimaker_original_plus",
"Ultimaker Original Dual Extrusion": "ultimaker_original_dual",
diff --git a/plugins/XmlMaterialProfile/tests/TestXmlMaterialProfile.py b/plugins/XmlMaterialProfile/tests/TestXmlMaterialProfile.py
new file mode 100644
index 0000000000..1bc19f773a
--- /dev/null
+++ b/plugins/XmlMaterialProfile/tests/TestXmlMaterialProfile.py
@@ -0,0 +1,79 @@
+from unittest.mock import patch, MagicMock
+import sys
+import os
+
+# Prevents error: "PyCapsule_GetPointer called with incorrect name" with conflicting SIP configurations between Arcus and PyQt: Import Arcus and Savitar first!
+import Savitar # Dont remove this line
+import Arcus # No really. Don't. It needs to be there!
+from UM.Qt.QtApplication import QtApplication # QtApplication import is required, even though it isn't used.
+
+import pytest
+import XmlMaterialProfile
+
+def createXmlMaterialProfile(material_id):
+ try:
+ return XmlMaterialProfile.XmlMaterialProfile.XmlMaterialProfile(material_id)
+ except AttributeError:
+ return XmlMaterialProfile.XmlMaterialProfile(material_id)
+
+
+def test_setName():
+ material_1 = createXmlMaterialProfile("herpderp")
+ material_2 = createXmlMaterialProfile("OMGZOMG")
+
+ material_1.getMetaData()["base_file"] = "herpderp"
+ material_2.getMetaData()["base_file"] = "herpderp"
+
+ container_registry = MagicMock()
+ container_registry.isReadOnly = MagicMock(return_value = False)
+ container_registry.findInstanceContainers = MagicMock(return_value = [material_1, material_2])
+
+ with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value = container_registry)):
+ material_1.setName("beep!")
+
+ assert material_1.getName() == "beep!"
+ assert material_2.getName() == "beep!"
+
+
+def test_setDirty():
+ material_1 = createXmlMaterialProfile("herpderp")
+ material_2 = createXmlMaterialProfile("OMGZOMG")
+
+ material_1.getMetaData()["base_file"] = "herpderp"
+ material_2.getMetaData()["base_file"] = "herpderp"
+
+ container_registry = MagicMock()
+ container_registry.isReadOnly = MagicMock(return_value=False)
+ container_registry.findContainers = MagicMock(return_value=[material_1, material_2])
+
+ # Sanity check. Since we did a hacky thing to set the metadata, the container should not be dirty.
+ # But this test assumes that it works like that, so we need to validate that.
+ assert not material_1.isDirty()
+ assert not material_2.isDirty()
+
+ with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)):
+ material_2.setDirty(True)
+
+ assert material_1.isDirty()
+ assert material_2.isDirty()
+
+ # Setting the base material dirty does not set it's child as dirty.
+ with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)):
+ material_1.setDirty(False)
+
+ assert not material_1.isDirty()
+ assert material_2.isDirty()
+
+
+def test_serializeNonBaseMaterial():
+ material_1 = createXmlMaterialProfile("herpderp")
+ material_1.getMetaData()["base_file"] = "omgzomg"
+
+ container_registry = MagicMock()
+ container_registry.isReadOnly = MagicMock(return_value=False)
+ container_registry.findContainers = MagicMock(return_value=[material_1])
+
+ with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)):
+ with pytest.raises(NotImplementedError):
+ # This material is not a base material, so it can't be serialized!
+ material_1.serialize()
diff --git a/public_key.pem b/public_key.pem
new file mode 100644
index 0000000000..d07bb5477a
--- /dev/null
+++ b/public_key.pem
@@ -0,0 +1,13 @@
+-----BEGIN RSA PUBLIC KEY-----
+MIICCgKCAgEA8k8IJsNNM097VM2pJ5vxkHcLhHf76JCB0iyvqpUuIgl8Zcp78Go+
+WtVkbVBZPPfSSB8GwjEtxvZeWj3i6e3nfreuuzq2sw6Gh860wMiQbNgL+rYCU3m9
+XxvC0kXgZt+oYs13N5LTePV7BG4goa/JOcN8dsu2ptZKfgH6TPhwshMeOGr/RoGr
+Jw1DrpvVeq/yTkrEHQHdtHr81GDghfK1vzxYQCt94MOFQCeShhtIC/jHelenJA94
+EpXqcWwCzFDfCQ3aXmCNHnMAsTHer7DWDfvsaUFyvJznrxkuQZIOQydGCNWhePTw
+nGiaMydchknr9TT3F+W/yuCs4u5GdZsz7S+1qbG4hblXo6dV6CTzkdKhh/MzONPC
+w6u1QBHUeTWN98zcTdtGIn53jjZEyYTodPnw/p4xLHVCju78a7uwm5U0rahcs6gw
+658glo3uT41mmTrXTBIVTV+4f/dSrwJVpNfTy/E4wi6fiuFeN8ojqXqN+NbIymfJ
+aKar/Jf/nM3QpEYaPz7yyn8PW8MZ7iomqnsPzyQGE1aymuEbw0ipTzMB7Oy/DfuU
+d4JU8FFuVuWJj3zNaXW7U/ggzbt5vkdIP/VNVfNZf741J/yKRbCI0+j4mthbruVQ
+Ka4aB2EVp1ozisHMaALg5tAeUgrQDZjGnVmSQLt+yFUUbG4e0XFQBb8CAwEAAQ==
+-----END RSA PUBLIC KEY-----
diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json
index 21da1d9fdb..22642cd38e 100644
--- a/resources/bundled_packages/cura.json
+++ b/resources/bundled_packages/cura.json
@@ -6,7 +6,7 @@
"display_name": "3MF Reader",
"description": "Provides support for reading 3MF files.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -23,7 +23,7 @@
"display_name": "3MF Writer",
"description": "Provides support for writing 3MF files.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -33,18 +33,18 @@
}
}
},
- "ChangeLogPlugin": {
+ "AMFReader": {
"package_info": {
- "package_id": "ChangeLogPlugin",
+ "package_id": "AMFReader",
"package_type": "plugin",
- "display_name": "Change Log",
- "description": "Shows changes since latest checked version.",
- "package_version": "1.0.1",
- "sdk_version": "6.0",
+ "display_name": "AMF Reader",
+ "description": "Provides support for reading AMF files.",
+ "package_version": "1.0.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
- "author_id": "UltimakerPackages",
- "display_name": "Ultimaker B.V.",
+ "author_id": "fieldOfView",
+ "display_name": "fieldOfView",
"email": "plugins@ultimaker.com",
"website": "https://ultimaker.com"
}
@@ -57,7 +57,7 @@
"display_name": "Cura Backups",
"description": "Backup and restore your configuration.",
"package_version": "1.2.0",
- "sdk_version": 6,
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -74,7 +74,7 @@
"display_name": "CuraEngine Backend",
"description": "Provides the link to the CuraEngine slicing backend.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -91,7 +91,7 @@
"display_name": "Cura Profile Reader",
"description": "Provides support for importing Cura profiles.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -108,7 +108,7 @@
"display_name": "Cura Profile Writer",
"description": "Provides support for exporting Cura profiles.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -125,7 +125,7 @@
"display_name": "Firmware Update Checker",
"description": "Checks for firmware updates.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -142,7 +142,7 @@
"display_name": "Firmware Updater",
"description": "Provides a machine actions for updating firmware.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -159,7 +159,7 @@
"display_name": "Compressed G-code Reader",
"description": "Reads g-code from a compressed archive.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -176,7 +176,7 @@
"display_name": "Compressed G-code Writer",
"description": "Writes g-code to a compressed archive.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -193,7 +193,7 @@
"display_name": "G-Code Profile Reader",
"description": "Provides support for importing profiles from g-code files.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -210,7 +210,7 @@
"display_name": "G-Code Reader",
"description": "Allows loading and displaying G-code files.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "VictorLarchenko",
@@ -227,7 +227,7 @@
"display_name": "G-Code Writer",
"description": "Writes g-code to a file.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -244,7 +244,7 @@
"display_name": "Image Reader",
"description": "Enables ability to generate printable geometry from 2D image files.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -261,7 +261,7 @@
"display_name": "Legacy Cura Profile Reader",
"description": "Provides support for importing profiles from legacy Cura versions.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -278,7 +278,7 @@
"display_name": "Machine Settings Action",
"description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "fieldOfView",
@@ -295,7 +295,7 @@
"display_name": "Model Checker",
"description": "Checks models and print configuration for possible printing issues and give suggestions.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -312,7 +312,7 @@
"display_name": "Monitor Stage",
"description": "Provides a monitor stage in Cura.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -329,7 +329,7 @@
"display_name": "Per-Object Settings Tool",
"description": "Provides the per-model settings.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -346,7 +346,7 @@
"display_name": "Post Processing",
"description": "Extension that allows for user created scripts for post processing.",
"package_version": "2.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -363,7 +363,7 @@
"display_name": "Prepare Stage",
"description": "Provides a prepare stage in Cura.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -380,7 +380,7 @@
"display_name": "Preview Stage",
"description": "Provides a preview stage in Cura.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -397,7 +397,7 @@
"display_name": "Removable Drive Output Device",
"description": "Provides removable drive hotplugging and writing support.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -414,7 +414,7 @@
"display_name": "Simulation View",
"description": "Provides the Simulation view.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -431,7 +431,7 @@
"display_name": "Slice Info",
"description": "Submits anonymous slice info. Can be disabled through preferences.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -448,7 +448,7 @@
"display_name": "Solid View",
"description": "Provides a normal solid mesh view.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -465,7 +465,24 @@
"display_name": "Support Eraser Tool",
"description": "Creates an eraser mesh to block the printing of support in certain places.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
+ "website": "https://ultimaker.com",
+ "author": {
+ "author_id": "UltimakerPackages",
+ "display_name": "Ultimaker B.V.",
+ "email": "plugins@ultimaker.com",
+ "website": "https://ultimaker.com"
+ }
+ }
+ },
+ "TrimeshReader": {
+ "package_info": {
+ "package_id": "TrimeshReader",
+ "package_type": "plugin",
+ "display_name": "Trimesh Reader",
+ "description": "Provides support for reading model files.",
+ "package_version": "1.0.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -482,7 +499,24 @@
"display_name": "Toolbox",
"description": "Find, manage and install new Cura packages.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
+ "website": "https://ultimaker.com",
+ "author": {
+ "author_id": "UltimakerPackages",
+ "display_name": "Ultimaker B.V.",
+ "email": "plugins@ultimaker.com",
+ "website": "https://ultimaker.com"
+ }
+ }
+ },
+ "UFPReader": {
+ "package_info": {
+ "package_id": "UFPReader",
+ "package_type": "plugin",
+ "display_name": "UFP Reader",
+ "description": "Provides support for reading Ultimaker Format Packages.",
+ "package_version": "1.0.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -499,7 +533,7 @@
"display_name": "UFP Writer",
"description": "Provides support for writing Ultimaker Format Packages.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -516,7 +550,7 @@
"display_name": "Ultimaker Machine Actions",
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -533,7 +567,7 @@
"display_name": "UM3 Network Printing",
"description": "Manages network connections to Ultimaker 3 printers.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -550,24 +584,7 @@
"display_name": "USB Printing",
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
"package_version": "1.0.2",
- "sdk_version": "6.0",
- "website": "https://ultimaker.com",
- "author": {
- "author_id": "UltimakerPackages",
- "display_name": "Ultimaker B.V.",
- "email": "plugins@ultimaker.com",
- "website": "https://ultimaker.com"
- }
- }
- },
- "UserAgreement": {
- "package_info": {
- "package_id": "UserAgreement",
- "package_type": "plugin",
- "display_name": "User Agreement",
- "description": "Ask the user once if he/she agrees with our license.",
- "package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -584,7 +601,7 @@
"display_name": "Version Upgrade 2.1 to 2.2",
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -601,7 +618,7 @@
"display_name": "Version Upgrade 2.2 to 2.4",
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -618,7 +635,7 @@
"display_name": "Version Upgrade 2.5 to 2.6",
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -635,7 +652,7 @@
"display_name": "Version Upgrade 2.6 to 2.7",
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -652,7 +669,7 @@
"display_name": "Version Upgrade 2.7 to 3.0",
"description": "Upgrades configurations from Cura 2.7 to Cura 3.0.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -669,7 +686,7 @@
"display_name": "Version Upgrade 3.0 to 3.1",
"description": "Upgrades configurations from Cura 3.0 to Cura 3.1.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -686,7 +703,7 @@
"display_name": "Version Upgrade 3.2 to 3.3",
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -703,7 +720,7 @@
"display_name": "Version Upgrade 3.3 to 3.4",
"description": "Upgrades configurations from Cura 3.3 to Cura 3.4.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -720,7 +737,7 @@
"display_name": "Version Upgrade 3.4 to 3.5",
"description": "Upgrades configurations from Cura 3.4 to Cura 3.5.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -737,7 +754,7 @@
"display_name": "Version Upgrade 3.5 to 4.0",
"description": "Upgrades configurations from Cura 3.5 to Cura 4.0.",
"package_version": "1.0.0",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -754,7 +771,58 @@
"display_name": "Version Upgrade 4.0 to 4.1",
"description": "Upgrades configurations from Cura 4.0 to Cura 4.1.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
+ "website": "https://ultimaker.com",
+ "author": {
+ "author_id": "UltimakerPackages",
+ "display_name": "Ultimaker B.V.",
+ "email": "plugins@ultimaker.com",
+ "website": "https://ultimaker.com"
+ }
+ }
+ },
+ "VersionUpgrade41to42": {
+ "package_info": {
+ "package_id": "VersionUpgrade41to42",
+ "package_type": "plugin",
+ "display_name": "Version Upgrade 4.1 to 4.2",
+ "description": "Upgrades configurations from Cura 4.1 to Cura 4.2.",
+ "package_version": "1.0.0",
+ "sdk_version": "7.0.0",
+ "website": "https://ultimaker.com",
+ "author": {
+ "author_id": "UltimakerPackages",
+ "display_name": "Ultimaker B.V.",
+ "email": "plugins@ultimaker.com",
+ "website": "https://ultimaker.com"
+ }
+ }
+ },
+ "VersionUpgrade42to43": {
+ "package_info": {
+ "package_id": "VersionUpgrade42to43",
+ "package_type": "plugin",
+ "display_name": "Version Upgrade 4.2 to 4.3",
+ "description": "Upgrades configurations from Cura 4.2 to Cura 4.3.",
+ "package_version": "1.0.0",
+ "sdk_version": "7.0.0",
+ "website": "https://ultimaker.com",
+ "author": {
+ "author_id": "UltimakerPackages",
+ "display_name": "Ultimaker B.V.",
+ "email": "plugins@ultimaker.com",
+ "website": "https://ultimaker.com"
+ }
+ }
+ },
+ "VersionUpgrade43to44": {
+ "package_info": {
+ "package_id": "VersionUpgrade43to44",
+ "package_type": "plugin",
+ "display_name": "Version Upgrade 4.3 to 4.4",
+ "description": "Upgrades configurations from Cura 4.3 to Cura 4.4.",
+ "package_version": "1.0.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -771,7 +839,7 @@
"display_name": "X3D Reader",
"description": "Provides support for reading X3D files.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "SevaAlekseyev",
@@ -788,7 +856,7 @@
"display_name": "XML Material Profiles",
"description": "Provides capabilities to read and write XML-based material profiles.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -805,7 +873,7 @@
"display_name": "X-Ray View",
"description": "Provides the X-Ray view.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -822,7 +890,7 @@
"display_name": "Generic ABS",
"description": "The generic ABS profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -840,7 +908,7 @@
"display_name": "Generic BAM",
"description": "The generic BAM profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -858,7 +926,7 @@
"display_name": "Generic CFF CPE",
"description": "The generic CFF CPE profile which other profiles can be based upon.",
"package_version": "1.1.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -876,7 +944,7 @@
"display_name": "Generic CFF PA",
"description": "The generic CFF PA profile which other profiles can be based upon.",
"package_version": "1.1.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -894,7 +962,7 @@
"display_name": "Generic CPE",
"description": "The generic CPE profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -912,7 +980,7 @@
"display_name": "Generic CPE+",
"description": "The generic CPE+ profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -930,7 +998,7 @@
"display_name": "Generic GFF CPE",
"description": "The generic GFF CPE profile which other profiles can be based upon.",
"package_version": "1.1.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -948,7 +1016,7 @@
"display_name": "Generic GFF PA",
"description": "The generic GFF PA profile which other profiles can be based upon.",
"package_version": "1.1.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -966,7 +1034,7 @@
"display_name": "Generic HIPS",
"description": "The generic HIPS profile which other profiles can be based upon.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -984,7 +1052,7 @@
"display_name": "Generic Nylon",
"description": "The generic Nylon profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1002,7 +1070,7 @@
"display_name": "Generic PC",
"description": "The generic PC profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1020,7 +1088,7 @@
"display_name": "Generic PETG",
"description": "The generic PETG profile which other profiles can be based upon.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1038,7 +1106,7 @@
"display_name": "Generic PLA",
"description": "The generic PLA profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1056,7 +1124,7 @@
"display_name": "Generic PP",
"description": "The generic PP profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1074,7 +1142,7 @@
"display_name": "Generic PVA",
"description": "The generic PVA profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1092,7 +1160,7 @@
"display_name": "Generic Tough PLA",
"description": "The generic Tough PLA profile which other profiles can be based upon.",
"package_version": "1.0.2",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1110,7 +1178,7 @@
"display_name": "Generic TPU",
"description": "The generic TPU profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1128,7 +1196,7 @@
"display_name": "Dagoma Chromatik PLA",
"description": "Filament testé et approuvé pour les imprimantes 3D Dagoma. Chromatik est l'idéal pour débuter et suivre les tutoriels premiers pas. Il vous offre qualité et résistance pour chacune de vos impressions.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://dagoma.fr/boutique/filaments.html",
"author": {
"author_id": "Dagoma",
@@ -1145,7 +1213,7 @@
"display_name": "FABtotum ABS",
"description": "This material is easy to be extruded but it is not the simplest to use. It is one of the most used in 3D printing to get very well finished objects. It is not sustainable and its smoke can be dangerous if inhaled. The reason to prefer this filament to PLA is mainly because of its precision and mechanical specs. ABS (for plastic) stands for Acrylonitrile Butadiene Styrene and it is a thermoplastic which is widely used in everyday objects. It can be printed with any FFF 3D printer which can get to high temperatures as it must be extruded in a range between 220° and 245°, so it’s compatible with all versions of the FABtotum Personal fabricator.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=40",
"author": {
"author_id": "FABtotum",
@@ -1162,7 +1230,7 @@
"display_name": "FABtotum Nylon",
"description": "When 3D printing started this material was not listed among the extrudable filaments. It is flexible as well as resistant to tractions. It is well known for its uses in textile but also in industries which require a strong and flexible material. There are different kinds of Nylon: 3D printing mostly uses Nylon 6 and Nylon 6.6, which are the most common. It requires higher temperatures to be printed, so a 3D printer must be able to reach them (around 240°C): the FABtotum, of course, can.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=53",
"author": {
"author_id": "FABtotum",
@@ -1179,7 +1247,7 @@
"display_name": "FABtotum PLA",
"description": "It is the most common filament used for 3D printing. It is studied to be bio-degradable as it comes from corn starch’s sugar mainly. It is completely made of renewable sources and has no footprint on polluting. PLA stands for PolyLactic Acid and it is a thermoplastic that today is still considered the easiest material to be 3D printed. It can be extruded at lower temperatures: the standard range of FABtotum’s one is between 185° and 195°.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=39",
"author": {
"author_id": "FABtotum",
@@ -1196,7 +1264,7 @@
"display_name": "FABtotum TPU Shore 98A",
"description": "",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=66",
"author": {
"author_id": "FABtotum",
@@ -1213,7 +1281,7 @@
"display_name": "Fiberlogy HD PLA",
"description": "With our HD PLA you have many more options. You can use this material in two ways. Choose the one you like best. You can use it as a normal PLA and get prints characterized by a very good adhesion between the layers and high precision. You can also make your prints acquire similar properties to that of ABS – better impact resistance and high temperature resistance. All you need is an oven. Yes, an oven! By annealing our HD PLA in an oven, in accordance with the manual, you will avoid all the inconveniences of printing with ABS, such as unpleasant odour or hazardous fumes.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "http://fiberlogy.com/en/fiberlogy-filaments/filament-hd-pla/",
"author": {
"author_id": "Fiberlogy",
@@ -1230,7 +1298,7 @@
"display_name": "Filo3D PLA",
"description": "Fast, safe and reliable printing. PLA is ideal for the fast and reliable printing of parts and prototypes with a great surface quality.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://dagoma.fr",
"author": {
"author_id": "Dagoma",
@@ -1247,7 +1315,7 @@
"display_name": "IMADE3D JellyBOX PETG",
"description": "",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "http://shop.imade3d.com/filament.html",
"author": {
"author_id": "IMADE3D",
@@ -1264,7 +1332,7 @@
"display_name": "IMADE3D JellyBOX PLA",
"description": "",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "http://shop.imade3d.com/filament.html",
"author": {
"author_id": "IMADE3D",
@@ -1281,7 +1349,7 @@
"display_name": "Octofiber PLA",
"description": "PLA material from Octofiber.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://nl.octofiber.com/3d-printing-filament/pla.html",
"author": {
"author_id": "Octofiber",
@@ -1298,7 +1366,7 @@
"display_name": "PolyFlex™ PLA",
"description": "PolyFlex™ is a highly flexible yet easy to print 3D printing material. Featuring good elasticity and a large strain-to- failure, PolyFlex™ opens up a completely new realm of applications.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "http://www.polymaker.com/shop/polyflex/",
"author": {
"author_id": "Polymaker",
@@ -1315,7 +1383,7 @@
"display_name": "PolyMax™ PLA",
"description": "PolyMax™ PLA is a 3D printing material with excellent mechanical properties and printing quality. PolyMax™ PLA has an impact resistance of up to nine times that of regular PLA, and better overall mechanical properties than ABS.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "http://www.polymaker.com/shop/polymax/",
"author": {
"author_id": "Polymaker",
@@ -1332,7 +1400,7 @@
"display_name": "PolyPlus™ PLA True Colour",
"description": "PolyPlus™ PLA is a premium PLA designed for all desktop FDM/FFF 3D printers. It is produced with our patented Jam-Free™ technology that ensures consistent extrusion and prevents jams.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "http://www.polymaker.com/shop/polyplus-true-colour/",
"author": {
"author_id": "Polymaker",
@@ -1349,7 +1417,7 @@
"display_name": "PolyWood™ PLA",
"description": "PolyWood™ is a wood mimic printing material that contains no actual wood ensuring a clean Jam-Free™ printing experience.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "http://www.polymaker.com/shop/polywood/",
"author": {
"author_id": "Polymaker",
@@ -1365,8 +1433,8 @@
"package_type": "material",
"display_name": "Ultimaker ABS",
"description": "Example package for material and quality profiles for Ultimaker materials.",
- "package_version": "1.2.1",
- "sdk_version": "6.0",
+ "package_version": "1.2.2",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1385,7 +1453,7 @@
"display_name": "Ultimaker Breakaway",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/breakaway",
"author": {
"author_id": "UltimakerPackages",
@@ -1403,8 +1471,8 @@
"package_type": "material",
"display_name": "Ultimaker CPE",
"description": "Example package for material and quality profiles for Ultimaker materials.",
- "package_version": "1.2.1",
- "sdk_version": "6.0",
+ "package_version": "1.2.2",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1422,8 +1490,8 @@
"package_type": "material",
"display_name": "Ultimaker CPE+",
"description": "Example package for material and quality profiles for Ultimaker materials.",
- "package_version": "1.2.1",
- "sdk_version": "6.0",
+ "package_version": "1.2.2",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/cpe",
"author": {
"author_id": "UltimakerPackages",
@@ -1441,8 +1509,8 @@
"package_type": "material",
"display_name": "Ultimaker Nylon",
"description": "Example package for material and quality profiles for Ultimaker materials.",
- "package_version": "1.2.1",
- "sdk_version": "6.0",
+ "package_version": "1.2.2",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1461,7 +1529,7 @@
"display_name": "Ultimaker PC",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.2",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/pc",
"author": {
"author_id": "UltimakerPackages",
@@ -1479,8 +1547,8 @@
"package_type": "material",
"display_name": "Ultimaker PLA",
"description": "Example package for material and quality profiles for Ultimaker materials.",
- "package_version": "1.2.1",
- "sdk_version": "6.0",
+ "package_version": "1.2.2",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1498,8 +1566,8 @@
"package_type": "material",
"display_name": "Ultimaker PP",
"description": "Example package for material and quality profiles for Ultimaker materials.",
- "package_version": "1.2.1",
- "sdk_version": "6.0",
+ "package_version": "1.2.2",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/pp",
"author": {
"author_id": "UltimakerPackages",
@@ -1518,7 +1586,7 @@
"display_name": "Ultimaker PVA",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1536,8 +1604,8 @@
"package_type": "material",
"display_name": "Ultimaker TPU 95A",
"description": "Example package for material and quality profiles for Ultimaker materials.",
- "package_version": "1.2.1",
- "sdk_version": "6.0",
+ "package_version": "1.2.2",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/tpu-95a",
"author": {
"author_id": "UltimakerPackages",
@@ -1556,7 +1624,7 @@
"display_name": "Ultimaker Tough PLA",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.0.3",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://ultimaker.com/products/materials/tough-pla",
"author": {
"author_id": "UltimakerPackages",
@@ -1575,7 +1643,7 @@
"display_name": "Vertex Delta ABS",
"description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://vertex3dprinter.eu",
"author": {
"author_id": "Velleman",
@@ -1592,7 +1660,7 @@
"display_name": "Vertex Delta PET",
"description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://vertex3dprinter.eu",
"author": {
"author_id": "Velleman",
@@ -1609,7 +1677,7 @@
"display_name": "Vertex Delta PLA",
"description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://vertex3dprinter.eu",
"author": {
"author_id": "Velleman",
@@ -1626,7 +1694,7 @@
"display_name": "Vertex Delta TPU",
"description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.1",
- "sdk_version": "6.0",
+ "sdk_version": "7.0.0",
"website": "https://vertex3dprinter.eu",
"author": {
"author_id": "Velleman",
@@ -1636,4 +1704,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/resources/definitions/101Hero.def.json b/resources/definitions/101Hero.def.json
index d77f01fd82..d356d15da9 100644
--- a/resources/definitions/101Hero.def.json
+++ b/resources/definitions/101Hero.def.json
@@ -34,11 +34,10 @@
},
"speed_print": { "default_value": 14 },
"speed_travel": { "value": "speed_print" },
- "speed_infill": { "default_value": 14 },
"speed_wall": { "value": "speed_print * 0.7" },
"speed_topbottom": { "value": "speed_print * 0.7" },
"speed_layer_0": { "value": "speed_print * 0.7" },
- "gantry_height": { "default_value": 0 },
+ "gantry_height": { "value": "0" },
"retraction_speed": { "default_value" : 10 },
"retraction_amount": { "default_value" : 2.5 },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
diff --git a/resources/definitions/3dator.def.json b/resources/definitions/3dator.def.json
index e91c46920b..ac37523379 100644
--- a/resources/definitions/3dator.def.json
+++ b/resources/definitions/3dator.def.json
@@ -17,15 +17,10 @@
"overrides": {
"machine_name": { "default_value": "3Dator" },
- "speed_travel": { "default_value": 120 },
"prime_tower_size": { "default_value": 8.660254037844387 },
"infill_sparse_density": { "default_value": 20 },
- "speed_wall_x": { "default_value": 45 },
- "speed_wall_0": { "default_value": 40 },
- "speed_topbottom": { "default_value": 35 },
"layer_height": { "default_value": 0.2 },
"speed_print": { "default_value": 50 },
- "speed_infill": { "default_value": 60 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
"machine_height": { "default_value": 260 },
@@ -33,8 +28,6 @@
"machine_depth": { "default_value": 170 },
"machine_width": { "default_value": 180 },
"retraction_speed": {"default_value":100},
- "cool_fan_speed_min": {"default_value": 20},
- "cool_fan_speed_max": {"default_value": 70},
"adhesion_type": { "default_value": "none" },
"machine_head_with_fans_polygon": {
"default_value": [
@@ -45,7 +38,7 @@
]
},
"gantry_height": {
- "default_value": 30
+ "value": "30"
},
"machine_start_gcode": {
"default_value": ";Sliced at: {day} {date} {time}\nM104 S{material_print_temperature} ;set temperatures\nM140 S{material_bed_temperature}\nM109 S{material_print_temperature} ;wait for temperatures\nM190 S{material_bed_temperature}\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 Z0 ;move Z to min endstops\nG28 X0 Y0 ;move X/Y to min endstops\nG29 ;Auto Level\nG1 Z0.6 F{speed_travel} ;move the Nozzle near the Bed\nG92 E0\nG1 Y0 ;zero the extruded length\nG1 X10 E30 F500 ;printing a Line from right to left\nG92 E0 ;zero the extruded length again\nG1 Z2\nG1 F{speed_travel}\nM117 Printing...;Put printing message on LCD screen\nM150 R255 U255 B255 P4 ;Change LED Color to white" },
diff --git a/resources/definitions/Mark2_for_Ultimaker2.def.json b/resources/definitions/Mark2_for_Ultimaker2.def.json
new file mode 100644
index 0000000000..1aca2a3844
--- /dev/null
+++ b/resources/definitions/Mark2_for_Ultimaker2.def.json
@@ -0,0 +1,214 @@
+{
+ "version": 2,
+ "name": "Mark2 for Ultimaker2",
+ "inherits": "ultimaker2_plus",
+ "metadata": {
+ "visible": true,
+ "author": "TheUltimakerCommunity",
+ "manufacturer": "Foehnsturm",
+ "category": "Other",
+ "weight": 0,
+ "has_variants": true,
+ "has_materials": true,
+ "has_machine_quality": false,
+ "file_formats": "text/x-gcode",
+ "icon": "icon_ultimaker.png",
+ "platform": "ultimaker2_platform.obj",
+ "platform_texture": "Mark2_for_Ultimaker2_backplate.png",
+ "machine_extruder_trains":
+ {
+ "0": "Mark2_extruder1",
+ "1": "Mark2_extruder2"
+ },
+ "supported_actions": ["MachineSettingsAction", "UpgradeFirmware"]
+ },
+ "overrides": {
+ "machine_name": { "default_value": "Mark2_for_Ultimaker2" },
+ "machine_width": {
+ "default_value": 223
+ },
+ "machine_depth": {
+ "default_value": 223
+ },
+ "machine_height": {
+ "default_value": 203
+ },
+ "gantry_height": {
+ "value": "52"
+ },
+ "machine_center_is_zero": {
+ "default_value": false
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "machine_nozzle_heat_up_speed": {
+ "default_value": 3.5
+ },
+ "machine_nozzle_cool_down_speed": {
+ "default_value": 1.5
+ },
+ "machine_min_cool_heat_time_window":
+ {
+ "default_value": 15.0
+ },
+ "machine_show_variants": {
+ "default_value": true
+ },
+ "machine_nozzle_head_distance": {
+ "default_value": 5
+ },
+ "machine_nozzle_expansion_angle": {
+ "default_value": 45
+ },
+ "machine_heat_zone_length": {
+ "default_value": 20
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "speed_infill": {
+ "value": "speed_print"
+ },
+ "speed_wall_x": {
+ "value": "speed_wall"
+ },
+ "layer_height_0": {
+ "value": "round(machine_nozzle_size / 1.5, 2)"
+ },
+ "line_width": {
+ "value": "round(machine_nozzle_size * 0.875, 2)"
+ },
+ "speed_support": {
+ "value": "speed_wall_0"
+ },
+ "machine_max_feedrate_x": {
+ "default_value": 250
+ },
+ "machine_max_feedrate_y": {
+ "default_value": 250
+ },
+ "machine_max_feedrate_z": {
+ "default_value": 40
+ },
+ "machine_max_feedrate_e": {
+ "default_value": 45
+ },
+ "machine_acceleration": {
+ "default_value": 3000
+ },
+ "retraction_amount": {
+ "default_value": 5.1
+ },
+ "retraction_speed": {
+ "default_value": 25
+ },
+ "switch_extruder_retraction_amount": {
+ "value": "retraction_amount",
+ "enabled": false
+ },
+ "switch_extruder_retraction_speeds": {
+ "value": "retraction_speed",
+ "enabled": false
+ },
+ "switch_extruder_retraction_speed": {
+ "value": "retraction_retract_speed",
+ "enabled": false
+ },
+ "switch_extruder_prime_speed": {
+ "value": "retraction_prime_speed",
+ "enabled": false
+ },
+ "machine_head_with_fans_polygon":
+ {
+ "default_value": [
+ [ -44, 14 ],
+ [ -44, -34 ],
+ [ 64, 14 ],
+ [ 64, -34 ]
+ ]
+ },
+ "machine_use_extruder_offset_to_offset_coords": {
+ "default_value": false
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "machine_start_gcode" : {
+ "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nM200 D0 T0 ;reset filament diameter\\nM200 D0 T1\\nG28 Z0; home all\\nG28 X0 Y0\\nG0 Z20 F2400 ;move the platform to 20mm\\nG92 E0\\nM190 S{material_bed_temperature_layer_0}\\nM109 T0 S{material_standby_temperature, 0}\\nM109 T1 S{material_print_temperature_layer_0, 1}\\nM104 T0 S{material_print_temperature_layer_0, 0}\\nT1 ; move to the 2th head\\nG0 Z20 F2400\\nG92 E-7.0 ;prime distance\\nG1 E0 F45 ;purge nozzle\\nG1 E-5.1 F1500 ; retract\\nG1 X90 Z0.01 F5000 ; move away from the prime poop\\nG1 X50 F9000\\nG0 Z20 F2400\\nT0 ; move to the first head\\nM104 T1 S{material_standby_temperature, 1}\\nG0 Z20 F2400\\nM104 T{initial_extruder_nr} S{material_print_temperature_layer_0, initial_extruder_nr}\\nG92 E-7.0\\nG1 E0 F45 ;purge nozzle\\nG1 X60 Z0.01 F5000 ; move away from the prime poop\\nG1 X20 F9000\\nM400 ;finish all moves\\nG92 E0\\n;end of startup sequence\\n\""
+ },
+ "machine_end_gcode" : {
+ "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G90 ;absolute positioning\\nM104 S0 T0 ;extruder heater off\\nM104 S0 T1\\nM140 S0 ;turn off bed\\nT0 ; move to the first head\\nM107 ;fan off\""
+ },
+ "machine_extruder_count": {
+ "default_value": 2
+ },
+ "acceleration_enabled":
+ {
+ "default_value": true
+ },
+ "acceleration_print":
+ {
+ "value": "2000"
+ },
+ "acceleration_travel":
+ {
+ "value": "acceleration_print if magic_spiralize else 3000"
+ },
+ "acceleration_layer_0": { "value": "acceleration_topbottom" },
+ "acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" },
+ "acceleration_support": { "value": "math.ceil(acceleration_print * 2000 / 4000)" },
+ "acceleration_support_interface": { "value": "acceleration_topbottom" },
+ "acceleration_topbottom": { "value": "math.ceil(acceleration_print * 500 / 4000)" },
+ "acceleration_wall": { "value": "math.ceil(acceleration_print * 1000 / 4000)" },
+ "acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 500 / 1000)" },
+ "jerk_enabled":
+ {
+ "default_value": true
+ },
+ "jerk_print":
+ {
+ "default_value": 12
+ },
+ "jerk_travel":
+ {
+ "value": "jerk_print if magic_spiralize else 20"
+ },
+ "jerk_layer_0": { "value": "jerk_topbottom" },
+ "jerk_prime_tower": { "value": "10 if jerk_print < 16 else math.ceil(jerk_print * 15 / 25)" },
+ "jerk_support": { "value": "10 if jerk_print < 16 else math.ceil(jerk_print * 15 / 25)" },
+ "jerk_support_interface": { "value": "jerk_topbottom" },
+ "jerk_topbottom": { "value": "10 if jerk_print < 25 else math.ceil(jerk_print * 10 / 25)" },
+ "jerk_wall": { "value": "10 if jerk_print < 16 else math.ceil(jerk_print * 15 / 25)" },
+ "jerk_wall_0": { "value": "10 if jerk_wall < 16 else math.ceil(jerk_wall * 6 / 10)" },
+ "jerk_travel_layer_0": { "value": "math.ceil(jerk_layer_0 * jerk_travel / jerk_print)" },
+ "extruder_prime_pos_abs": { "default_value": false },
+ "extruder_prime_pos_x": { "default_value": 0.0, "enabled": false },
+ "extruder_prime_pos_y": { "default_value": 0.0, "enabled": false },
+ "extruder_prime_pos_z": { "default_value": 0.0, "enabled": false },
+ "layer_start_x":
+ {
+ "default_value": 105.0,
+ "enabled": false
+ },
+ "layer_start_y":
+ {
+ "default_value": 27.0,
+ "enabled": false
+ },
+ "prime_tower_position_x": {
+ "value": "185"
+ },
+ "prime_tower_position_y": {
+ "value": "160"
+ },
+ "machine_disallowed_areas": {
+ "default_value": [
+ [[-115, 112.5], [ -10, 112.5], [ -10, 72.5], [-115, 72.5]],
+ [[ 115, 112.5], [ 115, 72.5], [ 15, 72.5], [ 15, 112.5]],
+ [[-115, -112.5], [-115, -87.5], [ 115, -87.5], [ 115, -112.5]],
+ [[-115, 72.5], [-97, 72.5], [-97, -112.5], [-115, -112.5]]
+ ]
+ }
+ }
+}
diff --git a/resources/definitions/abax_pri3.def.json b/resources/definitions/abax_pri3.def.json
index 1ab48b865a..529636be90 100644
--- a/resources/definitions/abax_pri3.def.json
+++ b/resources/definitions/abax_pri3.def.json
@@ -49,33 +49,9 @@
"top_bottom_thickness": {
"default_value": 1
},
- "bottom_thickness": {
- "default_value": 1
- },
- "material_print_temperature": {
- "default_value": 200
- },
- "material_bed_temperature": {
- "default_value": 0
- },
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 70
- },
- "speed_wall": {
- "default_value": 25
- },
- "speed_topbottom": {
- "default_value": 15
- },
- "speed_travel": {
- "default_value": 150
- },
- "speed_layer_0": {
- "default_value": 30
- },
"support_enable": {
"default_value": true
}
diff --git a/resources/definitions/abax_pri5.def.json b/resources/definitions/abax_pri5.def.json
index 46229ce756..9e4e7e3b20 100644
--- a/resources/definitions/abax_pri5.def.json
+++ b/resources/definitions/abax_pri5.def.json
@@ -49,33 +49,9 @@
"top_bottom_thickness": {
"default_value": 1
},
- "bottom_thickness": {
- "default_value": 1
- },
- "material_print_temperature": {
- "default_value": 200
- },
- "material_bed_temperature": {
- "default_value": 0
- },
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 70
- },
- "speed_wall": {
- "default_value": 25
- },
- "speed_topbottom": {
- "default_value": 15
- },
- "speed_travel": {
- "default_value": 150
- },
- "speed_layer_0": {
- "default_value": 30
- },
"support_enable": {
"default_value": true
}
diff --git a/resources/definitions/abax_titan.def.json b/resources/definitions/abax_titan.def.json
index 9f67117d6c..98643df22b 100644
--- a/resources/definitions/abax_titan.def.json
+++ b/resources/definitions/abax_titan.def.json
@@ -49,33 +49,9 @@
"top_bottom_thickness": {
"default_value": 1
},
- "bottom_thickness": {
- "default_value": 1
- },
- "material_print_temperature": {
- "default_value": 200
- },
- "material_bed_temperature": {
- "default_value": 0
- },
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 70
- },
- "speed_wall": {
- "default_value": 25
- },
- "speed_topbottom": {
- "default_value": 15
- },
- "speed_travel": {
- "default_value": 150
- },
- "speed_layer_0": {
- "default_value": 30
- },
"support_enable": {
"default_value": true
}
diff --git a/resources/definitions/alfawise_u20.def.json b/resources/definitions/alfawise_u20.def.json
index 8a6badeca6..4da42fdb1d 100644
--- a/resources/definitions/alfawise_u20.def.json
+++ b/resources/definitions/alfawise_u20.def.json
@@ -39,7 +39,7 @@
"default_value": false
},
"gantry_height": {
- "default_value": 10
+ "value": "10"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
@@ -47,12 +47,6 @@
"material_diameter": {
"default_value": 1.75
},
- "material_print_temperature": {
- "default_value": 210
- },
- "material_bed_temperature": {
- "default_value": 50
- },
"layer_height_0": {
"default_value": 0.2
},
@@ -62,21 +56,6 @@
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 40
- },
- "speed_wall": {
- "default_value": 35
- },
- "speed_topbottom": {
- "default_value": 35
- },
- "speed_travel": {
- "default_value": 120
- },
- "speed_layer_0": {
- "default_value": 20
- },
"support_enable": {
"default_value": true
},
diff --git a/resources/definitions/alfawise_u30.def.json b/resources/definitions/alfawise_u30.def.json
index 65f6adcfe0..e05536f66c 100644
--- a/resources/definitions/alfawise_u30.def.json
+++ b/resources/definitions/alfawise_u30.def.json
@@ -14,80 +14,45 @@
}
},
"overrides": {
- "machine_name": {
- "default_value": "Alfawise U30"
- },
+ "machine_name": { "default_value": "Alfawise U30" },
"machine_start_gcode": {
"default_value": "; -- START GCODE --\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z1 F1000 ;move up slightly\nG1 Y60.0 Z0 E9.0 F1000.0;intro line\nG1 Y100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\nG1 F80\n;Put printing message on LCD screen\nM117 Printing...\n; -- end of START GCODE --"
},
"machine_end_gcode": {
"default_value": "; -- END GCODE --\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F80 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning\nM107 ;turn the fan off; -- end of END GCODE --"
},
- "machine_width": {
- "default_value": 220
- },
- "machine_height": {
- "default_value": 250
- },
- "machine_depth": {
- "default_value": 220
- },
- "machine_heated_bed": {
- "default_value": true
- },
- "machine_center_is_zero": {
- "default_value": false
- },
- "gantry_height": {
- "default_value": 10
- },
- "machine_gcode_flavor": {
- "default_value": "RepRap (Marlin/Sprinter)"
- },
- "material_diameter": {
- "default_value": 1.75
- },
- "material_print_temperature": {
- "default_value": 210
- },
- "material_bed_temperature": {
- "default_value": 50
- },
- "layer_height_0": {
- "default_value": 0.2
- },
- "wall_thickness": {
- "default_value": 1.2
- },
- "speed_print": {
- "default_value": 40
- },
- "speed_infill": {
- "default_value": 40
- },
- "speed_wall": {
- "default_value": 35
- },
- "speed_topbottom": {
- "default_value": 35
- },
- "speed_travel": {
- "default_value": 120
- },
- "speed_layer_0": {
- "default_value": 20
- },
- "support_enable": {
- "default_value": true
- },
- "retraction_enable": {
- "default_value": true
- },
- "retraction_amount": {
- "default_value": 5
- },
- "retraction_speed": {
- "default_value": 45
- }
+ "material_diameter": { "default_value": 1.75 },
+ "layer_height_0": { "default_value": 0.2 },
+ "wall_thickness": { "default_value": 1.2 },
+ "speed_print": { "default_value": 40 },
+ "support_enable": { "default_value": true },
+ "retraction_enable": { "default_value": true },
+ "retraction_amount": { "default_value": 5 },
+ "retraction_speed": { "default_value": 45 },
+ "gantry_height": { "value": "25" },
+ "machine_width": { "default_value": 220 },
+ "machine_height": { "default_value": 250 },
+ "machine_depth": { "default_value": 220 },
+ "machine_center_is_zero": { "default_value": false },
+ "machine_heated_bed": { "default_value": true },
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_max_feedrate_x": { "default_value": 200 },
+ "machine_max_feedrate_y": { "default_value": 200 },
+ "machine_max_feedrate_z": { "default_value": 5 },
+ "machine_max_feedrate_e": { "default_value": 100 },
+ "machine_max_acceleration_x": { "default_value": 500 },
+ "machine_max_acceleration_y": { "default_value": 500 },
+ "machine_max_acceleration_z": { "default_value": 10 },
+ "machine_max_acceleration_e": { "default_value": 3000 },
+ "machine_acceleration": { "default_value": 300 },
+ "machine_max_jerk_xy": { "default_value": 20.0 },
+ "machine_max_jerk_z": { "default_value": 0.4 },
+ "machine_max_jerk_e": { "default_value": 5.0 },
+ "machine_steps_per_mm_x": { "default_value": 80 },
+ "machine_steps_per_mm_y": { "default_value": 80 },
+ "machine_steps_per_mm_z": { "default_value": 400 },
+ "machine_steps_per_mm_e": { "default_value": 93 },
+ "skirt_line_count": { "default_value": 1 },
+ "skirt_brim_minimal_length": { "default_value": 250 }
}
}
diff --git a/resources/definitions/alya3dp.def.json b/resources/definitions/alya3dp.def.json
index e918649097..8de7c79641 100644
--- a/resources/definitions/alya3dp.def.json
+++ b/resources/definitions/alya3dp.def.json
@@ -1,12 +1,22 @@
{
- "name": "ALYA",
"version": 2,
+ "name": "ALYA",
"inherits": "fdmprinter",
- "metadata": {
+ "metadata":
+ {
"visible": true,
"author": "ALYA",
- "manufacturer": "ALYA",
+ "manufacturer": "Kati Hal ARGE",
+ "category": "Other",
"file_formats": "text/x-gcode",
+ "platform": "alya_platform.stl",
+ "platform_offset": [-60, -45, 75 ],
+ "exclude_materials": ["chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu", "fiberlogy_hd_pla", "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red", "generic_abs", "generic_abs_175", "generic_bam", "generic_cpe", "generic_cpe_175", "generic_cpe_plus", "generic_hips", "generic_hips_175", "generic_nylon", "generic_nylon_175", "generic_pc", "generic_pc_175", "generic_petg", "generic_petg_175", "generic_pp", "generic_pva", "generic_pva_175", "generic_tough_pla", "generic_tpu", "generic_tpu_175", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "innofill_innoflex60_175", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "ultimaker_abs_black", "ultimaker_abs_blue", "ultimaker_abs_green", "ultimaker_abs_grey", "ultimaker_abs_orange", "ultimaker_abs_pearl-gold", "ultimaker_abs_red", "ultimaker_abs_silver-metallic", "ultimaker_abs_white", "ultimaker_abs_yellow", "ultimaker_bam", "ultimaker_cpe_black", "ultimaker_cpe_blue", "ultimaker_cpe_dark-grey", "ultimaker_cpe_green", "ultimaker_cpe_light-grey", "ultimaker_cpe_plus_black", "ultimaker_cpe_plus_transparent", "ultimaker_cpe_plus_white", "ultimaker_cpe_red", "ultimaker_cpe_transparent", "ultimaker_cpe_white", "ultimaker_cpe_yellow", "ultimaker_nylon_black", "ultimaker_nylon_transparent", "ultimaker_pc_black", "ultimaker_pc_transparent", "ultimaker_pc_white", "ultimaker_pla_black", "ultimaker_pla_blue", "ultimaker_pla_green", "ultimaker_pla_magenta", "ultimaker_pla_orange", "ultimaker_pla_pearl-white", "ultimaker_pla_red", "ultimaker_pla_silver-metallic", "ultimaker_pla_transparent", "ultimaker_pla_white", "ultimaker_pla_yellow", "ultimaker_pp_transparent", "ultimaker_pva", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "ultimaker_tpu_black", "ultimaker_tpu_blue", "ultimaker_tpu_red", "ultimaker_tpu_white", "verbatim_bvoh_175", "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_TPU", "zyyx_pro_flex", "zyyx_pro_pla","tizyx_pla","tizyx_abs","tizyx_pla_bois" ],
+ "preferred_material": "generic_pla",
+ "has_machine_quality": true,
+ "has_materials": true,
+ "has_variants": false,
+ "supports_usb_connection": false,
"machine_extruder_trains":
{
"0": "alya3dp_extruder_0"
@@ -14,37 +24,27 @@
},
"overrides": {
- "machine_width": {
- "default_value": 100
+ "machine_name": { "default_value": "ALYA 3DP" },
+ "machine_heated_bed": { "default_value": false },
+ "machine_width": { "default_value": 100 },
+ "machine_height": { "default_value": 133 },
+ "machine_depth": { "default_value": 100 },
+ "machine_center_is_zero": { "default_value": false },
+ "gantry_height": { "value": "55"},
+ "retraction_amount": { "default_value": 1.5 },
+ "support_enable": { "default_value": true},
+ "machine_head_with_fans_polygon": {
+ "default_value": [[75, 18],[18, 18],[18, 35],[75, 35]]
},
- "machine_height": {
- "default_value": 133
+ "adhesion_type": {"options": {"raft": "Raft" ,"none": "None", "brim": "Brim"}, "default_value": "raft"},
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_start_gcode":
+ {
+ "default_value": ";Sliced at: {day} {date} {time} \n ;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {fill_density} \n ;Print time: {print_time} \n ;Filament used: {filament_amount}m {filament_weight}g \n ;Filament cost: {filament_cost} \n G28 X0 Y0 ;move X Y to endstops \n G28 Z0 ;move Z to endstops \n ; M190 S{material_bed_temperature} ;bed temp \n M107 ; switch fan off \n M109 S{material_print_temperature} ;extruder temp set \n G1 F3000 \n G1 Z10 \n G92 E0 ;zero the extruded length \n G1 F200 E1 ;extrude 1mm of feed stock \n G92 E0 ;zero the extruded length again \n G4 P7000 ; wait 7000ms \n M117 Printing... ;Put printing message on LCD screen"
},
- "machine_depth": {
- "default_value": 100
- },
- "machine_center_is_zero": {
- "default_value": false
- },
- "machine_head_polygon": {
- "default_value": [
- [75, 18],
- [18, 18],
- [18, 35],
- [75, 35]
- ]
- },
- "gantry_height": {
- "default_value": 55
- },
- "machine_gcode_flavor": {
- "default_value": "RepRap"
- },
- "machine_start_gcode": {
- "default_value": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {fill_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to max endstops\nG1 Z115.0 F{speed_travel} ;move th e platform up 20mm\nG28 Z0 ;move Z to max endstop\nG1 Z15.0 F{speed_travel} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{speed_travel}\nM301 H1 P26.38 I2.57 D67.78\n;Put printing message on LCD screen\nM117 Printing..."
- },
- "machine_end_gcode": {
- "default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}"
+ "machine_end_gcode":
+ {
+ "default_value": ";End GCode\nM104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}"
}
}
}
\ No newline at end of file
diff --git a/resources/definitions/alyanx3dp.def.json b/resources/definitions/alyanx3dp.def.json
new file mode 100644
index 0000000000..07e0a090a9
--- /dev/null
+++ b/resources/definitions/alyanx3dp.def.json
@@ -0,0 +1,50 @@
+{
+ "version": 2,
+ "name": "ALYA NX",
+ "inherits": "fdmprinter",
+ "metadata":
+ {
+ "visible": true,
+ "author": "ALYA",
+ "manufacturer": "Kati Hal ARGE",
+ "category": "Other",
+ "file_formats": "text/x-gcode",
+ "platform": "alya_nx_platform.stl",
+ "platform_offset": [-104, 0, 93 ],
+ "exclude_materials": ["chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu", "fiberlogy_hd_pla", "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red", "generic_abs", "generic_abs_175", "generic_bam", "generic_cpe", "generic_cpe_175", "generic_cpe_plus", "generic_hips", "generic_hips_175", "generic_nylon", "generic_nylon_175", "generic_pc", "generic_pc_175", "generic_petg", "generic_petg_175", "generic_pp", "generic_pva", "generic_pva_175", "generic_tough_pla", "generic_tpu", "generic_tpu_175", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "innofill_innoflex60_175", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "ultimaker_abs_black", "ultimaker_abs_blue", "ultimaker_abs_green", "ultimaker_abs_grey", "ultimaker_abs_orange", "ultimaker_abs_pearl-gold", "ultimaker_abs_red", "ultimaker_abs_silver-metallic", "ultimaker_abs_white", "ultimaker_abs_yellow", "ultimaker_bam", "ultimaker_cpe_black", "ultimaker_cpe_blue", "ultimaker_cpe_dark-grey", "ultimaker_cpe_green", "ultimaker_cpe_light-grey", "ultimaker_cpe_plus_black", "ultimaker_cpe_plus_transparent", "ultimaker_cpe_plus_white", "ultimaker_cpe_red", "ultimaker_cpe_transparent", "ultimaker_cpe_white", "ultimaker_cpe_yellow", "ultimaker_nylon_black", "ultimaker_nylon_transparent", "ultimaker_pc_black", "ultimaker_pc_transparent", "ultimaker_pc_white", "ultimaker_pla_black", "ultimaker_pla_blue", "ultimaker_pla_green", "ultimaker_pla_magenta", "ultimaker_pla_orange", "ultimaker_pla_pearl-white", "ultimaker_pla_red", "ultimaker_pla_silver-metallic", "ultimaker_pla_transparent", "ultimaker_pla_white", "ultimaker_pla_yellow", "ultimaker_pp_transparent", "ultimaker_pva", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "ultimaker_tpu_black", "ultimaker_tpu_blue", "ultimaker_tpu_red", "ultimaker_tpu_white", "verbatim_bvoh_175", "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_TPU", "zyyx_pro_flex", "zyyx_pro_pla","tizyx_pla","tizyx_abs","tizyx_pla_bois" ],
+ "preferred_material": "generic_pla",
+ "has_machine_quality": true,
+ "has_materials": true,
+ "has_variants": false,
+ "supports_usb_connection": false,
+ "machine_extruder_trains":
+ {
+ "0": "alya3dp_extruder_0"
+ }
+ },
+
+ "overrides": {
+ "machine_name": { "default_value": "ALYA NX 3DP" },
+ "machine_heated_bed": { "default_value": false },
+ "machine_width": { "default_value": 180 },
+ "machine_height": { "default_value": 170 },
+ "machine_depth": { "default_value": 160 },
+ "machine_center_is_zero": { "default_value": false },
+ "gantry_height": { "value": "55"},
+ "retraction_amount": { "default_value": 1.5 },
+ "support_enable": { "default_value": true},
+ "machine_head_with_fans_polygon": {
+ "default_value": [[75, 18],[18, 18],[18, 35],[75, 35]]
+ },
+ "adhesion_type": {"options": {"raft": "Raft" ,"none": "None", "brim": "Brim"}, "default_value": "raft"},
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_start_gcode":
+ {
+ "default_value": ";Sliced at: {day} {date} {time} \n ;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {fill_density} \n ;Print time: {print_time} \n ;Filament used: {filament_amount}m {filament_weight}g \n ;Filament cost: {filament_cost} \n G28 X0 Y0 ;move X Y to endstops \n G28 Z0 ;move Z to endstops \n ; M190 S{material_bed_temperature} ;bed temp \n M107 ; switch fan off \n M109 S{material_print_temperature} ;extruder temp set \n G1 F3000 \n G1 Z10 \n G92 E0 ;zero the extruded length \n G1 F200 E1 ;extrude 1mm of feed stock \n G92 E0 ;zero the extruded length again \n G4 P7000 ; wait 7000ms \n M117 Printing... ;Put printing message on LCD screen"
+ },
+ "machine_end_gcode":
+ {
+ "default_value": ";End GCode\nM104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}"
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/anet_a6.def.json b/resources/definitions/anet_a6.def.json
new file mode 100644
index 0000000000..0f5384451e
--- /dev/null
+++ b/resources/definitions/anet_a6.def.json
@@ -0,0 +1,45 @@
+{
+ "version": 2,
+ "name": "Anet A6",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Mark",
+ "manufacturer": "Anet",
+ "file_formats": "text/x-gcode",
+ "platform": "aneta6_platform.stl",
+ "platform_offset": [0, -3.4, 0],
+ "machine_extruder_trains":
+ {
+ "0": "anet_a6_extruder_0"
+ }
+ },
+
+ "overrides": {
+ "machine_name": { "default_value": "Anet A6" },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "machine_width": {
+ "default_value": 220
+ },
+ "machine_height": {
+ "default_value": 250
+ },
+ "machine_depth": {
+ "default_value": 220
+ },
+ "machine_center_is_zero": {
+ "default_value": false
+ },
+ "gantry_height": {
+ "value": "55"
+ },
+ "machine_start_gcode": {
+ "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM84 ;steppers off\nM0 S12 ;wait 12 seconds\nM17 ;turn steppers on\nG1 Z10.0 F300 ;move the platform down 10mm\nG92 E0 ;zero the extruded length\nG1 F200 E8 ;extrude 8mm of feed stock\nG92 E0 ;zero the extruded length again\nM0 S5 ;wait 5 seconds\nG1 F9000\nM117 Printing..."
+ },
+ "machine_end_gcode": {
+ "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+4 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y210 F9000 ;move out to get part off\nM84 ;steppers off\nG90 ;absolute positioning"
+ }
+ }
+}
diff --git a/resources/definitions/anycubic_4max.def.json b/resources/definitions/anycubic_4max.def.json
index c14ce1ac31..05fffcb206 100644
--- a/resources/definitions/anycubic_4max.def.json
+++ b/resources/definitions/anycubic_4max.def.json
@@ -50,7 +50,7 @@
"jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" },
"jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" },
- "gantry_height": { "default_value": 25.0 },
+ "gantry_height": { "value": "25.0" },
"skin_overlap": { "value": "10" },
"acceleration_enabled": { "value": "True" },
@@ -83,6 +83,6 @@
"machine_gcode_flavor":{"default_value": "RepRap (Marlin/Sprinter)"},
"machine_start_gcode":{"default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F{speed_travel} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{speed_travel}\nM117 Printing...\nG5"},
- "machine_end_gcode":{"default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off bed\nM84 ; disable motors\nM107\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle\nto release some of the pressure\nG1 Z+0.5 E-5 ;X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 ;Y0 ;move X/Y to min endstops\nso the head is out of the way\nG1 Y180 F2000\nM84 ;steppers off\nG90\nM300 P300 S4000"}
+ "machine_end_gcode":{"default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off bed\nM84 ; disable motors\nM107\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 ;X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 ;Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y180 F2000\nM84 ;steppers off\nG90\nM300 P300 S4000"}
}
}
diff --git a/resources/definitions/anycubic_chiron.def.json b/resources/definitions/anycubic_chiron.def.json
new file mode 100644
index 0000000000..1b18a936a7
--- /dev/null
+++ b/resources/definitions/anycubic_chiron.def.json
@@ -0,0 +1,80 @@
+{
+ "version": 2,
+ "name": "Anycubic Chiron",
+ "inherits": "fdmprinter",
+ "metadata":
+ {
+ "visible": true,
+ "author": "Patrick Glatt",
+ "manufacturer": "Anycubic",
+ "category": "Other",
+ "file_formats": "text/x-gcode",
+ "icon": "icon_ultimaker2",
+ "platform": "anycubic_chiron_platform.obj",
+ "platform_texture": "anycubic-chiron.png",
+ "has_materials": true,
+ "preferred_material": "generic_pla",
+ "has_machine_quality": true,
+ "quality_definition": "anycubic_chiron",
+ "preferred_quality_type": "normal",
+ "machine_extruder_trains":
+ {
+ "0": "anycubic_chiron_extruder_0"
+ },
+ "firmware_file": "MarlinChiron.hex"
+ },
+
+ "overrides":
+ {
+ "machine_name":
+ {
+ "default_value": "Anycubic Chiron"
+ },
+ "machine_heated_bed":
+ {
+ "default_value": true
+ },
+ "machine_width":
+ {
+ "default_value": 400
+ },
+ "machine_height":
+ {
+ "default_value": 450
+ },
+ "machine_depth":
+ {
+ "default_value": 400
+ },
+ "machine_center_is_zero":
+ {
+ "default_value": false
+ },
+ "gantry_height":
+ {
+ "value": "35"
+ },
+ "machine_head_with_fans_polygon":
+ {
+ "default_value":
+ [
+ [-45, 50],
+ [-45, -45],
+ [45, 50],
+ [45, -45]
+ ]
+ },
+ "machine_gcode_flavor":
+ {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "machine_start_gcode":
+ {
+ "default_value": "M107 ;Start with the fan off\nG21 ;Set units to millimeters\nG91 ;Change to relative positioning mode for retract filament and nozzle lifting\nG1 F200 E-3 ;Retract 3mm filament for a clean start\nG92 E0 ;Zero the extruded length\nG1 F1000 Z5 ;Lift the nozzle 5mm before homing axes\nG90 ;Absolute positioning\nM82 ;Set extruder to absolute mode too\nG28 X0 Y0 ;First move X/Y to min endstops\nG28 Z0 ;Then move Z to min endstops\nG1 F1000 Z15 ;After homing lift the nozzle 15mm before start printing\n"
+ },
+ "machine_end_gcode":
+ {
+ "default_value": "G91 ;Change to relative positioning mode for filament retraction and nozzle lifting\nG1 F200 E-4;Retract the filament a bit before lifting the nozzle\nG1 F1000 Z5;Lift nozzle 5mm\nG90 ;Change to absolute positioning mode to prepare for part rermoval\nG1 X0 Y400 ;Move the print to max y pos for part rermoval\nM104 S0 ; Turn off hotend\nM106 S0 ; Turn off cooling fan\nM140 S0 ; Turn off bed\nM84 ; Disable motors\n"
+ }
+ }
+}
diff --git a/resources/definitions/anycubic_i3_mega.def.json b/resources/definitions/anycubic_i3_mega.def.json
index 8a96d98023..18005f0e12 100644
--- a/resources/definitions/anycubic_i3_mega.def.json
+++ b/resources/definitions/anycubic_i3_mega.def.json
@@ -46,7 +46,7 @@
},
"gantry_height":
{
- "default_value": 0
+ "value": "0"
},
"machine_gcode_flavor":
{
@@ -54,11 +54,11 @@
},
"machine_start_gcode":
{
- "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F{speed_travel} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{speed_travel}\nM117 Printing...\nG5"
+ "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F{speed_travel} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{speed_travel}\nG0 Y20 F{speed_travel}\nM117 Printing...\nG5"
},
"machine_end_gcode":
{
- "default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off bed\nM84 ; disable motors\nM107\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle\nto release some of the pressure\nG1 Z+0.5 E-5 ;X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 ;Y0 ;move X/Y to min endstops\nso the head is out of the way\nG1 Y180 F2000\nM84 ;steppers off\nG90\nM300 P300 S4000"
+ "default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off bed\nM84 ; disable motors\nM107\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 ;X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 ;Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y180 F2000\nM84 ;steppers off\nG90\nM300 P300 S4000"
}
}
}
diff --git a/resources/definitions/bfb.def.json b/resources/definitions/bfb.def.json
index d1dfa9ef1b..e88c8c792b 100644
--- a/resources/definitions/bfb.def.json
+++ b/resources/definitions/bfb.def.json
@@ -15,26 +15,19 @@
},
"overrides": {
- "speed_topbottom": { "default_value": 40 },
"speed_print": { "default_value": 40 },
"machine_extruder_count": { "default_value": 1 },
"prime_tower_size": { "default_value": 7.745966692414834 },
"machine_name": { "default_value": "BFB_Test" },
"machine_heated_bed": { "default_value": false },
- "speed_layer_0": { "default_value": 25 },
"machine_width": { "default_value": 275 },
"machine_gcode_flavor": { "default_value": "BFB" },
"machine_depth": { "default_value": 265 },
- "speed_infill": { "default_value": 30 },
"machine_center_is_zero": { "default_value": true },
"machine_height": { "default_value": 240 },
"layer_height": { "default_value": 0.25 },
- "material_print_temperature": { "default_value": 200 },
"retraction_amount": { "default_value": 0.05 },
- "speed_wall_0": { "default_value": 25 },
- "speed_travel": { "default_value": 50 },
"infill_sparse_density": { "default_value": 10 },
- "layer_height_0": { "default_value": 0.5 },
- "speed_wall_x": { "default_value": 20 }
+ "layer_height_0": { "default_value": 0.5 }
}
}
diff --git a/resources/definitions/bibo2_dual.def.json b/resources/definitions/bibo2_dual.def.json
index 1ae16a49b1..a644185915 100644
--- a/resources/definitions/bibo2_dual.def.json
+++ b/resources/definitions/bibo2_dual.def.json
@@ -1,11 +1,10 @@
{
- "id": "BIBO2 dual",
"version": 2,
"name": "BIBO2 dual",
"inherits": "fdmprinter",
"metadata": {
"visible": true,
- "author": "na",
+ "author": "unknown",
"manufacturer": "BIBO",
"category": "Other",
"file_formats": "text/x-gcode",
@@ -64,7 +63,7 @@
]
},
"gantry_height": {
- "default_value": 12
+ "value": "12"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
@@ -78,14 +77,17 @@
"machine_end_gcode": {
"default_value": ";End GCode\nM104 T0 S0 ;extruder heater off\nM104 T1 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91\nG1 Z1 F100 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-2 X-20 Y-20 F300 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning"
},
+ "speed_print": {
+ "default_value": 40
+ },
"machine_extruder_count": {
"default_value": 2
},
"prime_tower_position_x": {
- "default_value": 50
+ "value": "50"
},
"prime_tower_position_y": {
- "default_value": 50
+ "value": "50"
}
}
}
diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json
index be024cd6fa..d9e84dae87 100644
--- a/resources/definitions/bq_hephestos.def.json
+++ b/resources/definitions/bq_hephestos.def.json
@@ -54,33 +54,9 @@
"top_bottom_thickness": {
"default_value": 1
},
- "bottom_thickness": {
- "default_value": 1
- },
- "material_print_temperature": {
- "default_value": 220
- },
- "material_bed_temperature": {
- "default_value": 0
- },
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 40
- },
- "speed_wall": {
- "default_value": 35
- },
- "speed_topbottom": {
- "default_value": 35
- },
- "speed_travel": {
- "default_value": 120
- },
- "speed_layer_0": {
- "default_value": 20
- },
"support_enable": {
"default_value": true
}
diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json
index 90a86433fb..5c122eb9a4 100644
--- a/resources/definitions/bq_hephestos_2.def.json
+++ b/resources/definitions/bq_hephestos_2.def.json
@@ -24,26 +24,14 @@
"machine_height": { "default_value": 220 },
"machine_heated_bed": { "default_value": false },
"machine_center_is_zero": { "default_value": false },
- "material_print_temperature": { "default_value": 210 },
- "material_bed_temperature": { "default_value": 0 },
"layer_height": { "default_value": 0.2 },
"layer_height_0": { "default_value": 0.2 },
- "wall_line_count": { "default_value": 3 },
"wall_thickness": { "default_value": 1.2 },
"top_bottom_thickness": { "default_value": 1.2 },
"infill_sparse_density": { "default_value": 20 },
- "infill_overlap": { "default_value": 15 },
"speed_print": { "default_value": 60 },
- "speed_travel": { "default_value": 160 },
- "speed_layer_0": { "default_value": 30 },
- "speed_wall_x": { "default_value": 35 },
- "speed_wall_0": { "default_value": 30 },
- "speed_infill": { "default_value": 80 },
- "speed_topbottom": { "default_value": 35 },
- "skirt_brim_speed": { "default_value": 35 },
"skirt_line_count": { "default_value": 4 },
"skirt_brim_minimal_length": { "default_value": 30 },
- "skirt_gap": { "default_value": 6 },
- "cool_fan_full_at_height": { "default_value": 0.4 }
+ "skirt_gap": { "default_value": 6 }
}
}
diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json
index a8d63cbb41..16d0953bf1 100644
--- a/resources/definitions/bq_hephestos_xl.def.json
+++ b/resources/definitions/bq_hephestos_xl.def.json
@@ -53,33 +53,9 @@
"top_bottom_thickness": {
"default_value": 1
},
- "bottom_thickness": {
- "default_value": 1
- },
- "material_print_temperature": {
- "default_value": 220
- },
- "material_bed_temperature": {
- "default_value": 0
- },
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 40
- },
- "speed_wall": {
- "default_value": 35
- },
- "speed_topbottom": {
- "default_value": 35
- },
- "speed_travel": {
- "default_value": 120
- },
- "speed_layer_0": {
- "default_value": 20
- },
"support_enable": {
"default_value": true
}
diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json
index b96da6179c..fce2af9f97 100644
--- a/resources/definitions/bq_witbox.def.json
+++ b/resources/definitions/bq_witbox.def.json
@@ -54,33 +54,9 @@
"top_bottom_thickness": {
"default_value": 1
},
- "bottom_thickness": {
- "default_value": 1
- },
- "material_print_temperature": {
- "default_value": 220
- },
- "material_bed_temperature": {
- "default_value": 0
- },
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 40
- },
- "speed_wall": {
- "default_value": 35
- },
- "speed_topbottom": {
- "default_value": 35
- },
- "speed_travel": {
- "default_value": 120
- },
- "speed_layer_0": {
- "default_value": 20
- },
"support_enable": {
"default_value": true
}
diff --git a/resources/definitions/bq_witbox_2.def.json b/resources/definitions/bq_witbox_2.def.json
index 7412647852..d1114aafd6 100644
--- a/resources/definitions/bq_witbox_2.def.json
+++ b/resources/definitions/bq_witbox_2.def.json
@@ -41,21 +41,12 @@
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
- "material_print_temperature": {
- "default_value": 210
- },
- "material_bed_temperature": {
- "default_value": 0
- },
"layer_height": {
"default_value": 0.2
},
"layer_height_0": {
"default_value": 0.2
},
- "wall_line_count": {
- "default_value": 3
- },
"wall_thickness": {
"default_value": 1.2
},
@@ -65,33 +56,9 @@
"infill_sparse_density": {
"default_value": 20
},
- "infill_overlap": {
- "default_value": 15
- },
"speed_print": {
"default_value": 60
},
- "speed_travel": {
- "default_value": 160
- },
- "speed_layer_0": {
- "default_value": 30
- },
- "speed_wall_x": {
- "default_value": 35
- },
- "speed_wall_0": {
- "default_value": 30
- },
- "speed_infill": {
- "default_value": 80
- },
- "speed_topbottom": {
- "default_value": 35
- },
- "skirt_brim_speed": {
- "default_value": 35
- },
"skirt_line_count": {
"default_value": 4
},
@@ -101,9 +68,6 @@
"skirt_gap": {
"default_value": 6
},
- "cool_fan_full_at_height": {
- "default_value": 0.4
- },
"support_enable": {
"default_value": false
}
diff --git a/resources/definitions/builder_premium_large.def.json b/resources/definitions/builder_premium_large.def.json
index 2e0cd4f839..d19382a591 100644
--- a/resources/definitions/builder_premium_large.def.json
+++ b/resources/definitions/builder_premium_large.def.json
@@ -35,8 +35,6 @@
"material_standby_temperature": { "value": "material_print_temperature" },
"switch_extruder_retraction_speeds": {"default_value": 15 },
- "switch_extruder_retraction_speed": {"default_value": 15 },
- "switch_extruder_prime_speed": {"default_value": 15 },
"switch_extruder_retraction_amount": {"value": 1 },
"speed_travel": { "value": "100" },
@@ -50,8 +48,8 @@
"speed_wall_0": { "value": "math.ceil(speed_wall * 20 / 25)" },
"speed_wall_x": { "value": "speed_wall" },
- "prime_tower_position_x": { "default_value": 175 },
- "prime_tower_position_y": { "default_value": 178 },
+ "prime_tower_position_x": { "value": "175" },
+ "prime_tower_position_y": { "value": "178" },
"prime_tower_wipe_enabled": { "default_value": false },
"prime_tower_min_volume": { "default_value": 50 },
@@ -85,15 +83,13 @@
"retraction_amount": { "default_value": 3 },
"retraction_speed": { "default_value": 15 },
- "retraction_retract_speed": { "default_value": 15 },
- "retraction_prime_speed": { "default_value": 15 },
"travel_retract_before_outer_wall": { "default_value": true },
"skin_overlap": { "value": "15" },
"adhesion_type": { "default_value": "skirt" },
"machine_nozzle_heat_up_speed": { "default_value": 2 },
"machine_nozzle_cool_down_speed": { "default_value": 2 },
- "machine_head_polygon": { "default_value": [[-75, -18],[-75, 35],[18, 35],[18, -18]] },
- "gantry_height": { "default_value": 55 },
+ "machine_head_with_fans_polygon": { "default_value": [[-75, -18],[-75, 35],[18, 35],[18, -18]] },
+ "gantry_height": { "value": "55" },
"machine_max_feedrate_x": { "default_value": 300 },
"machine_max_feedrate_y": { "default_value": 300 },
"machine_max_feedrate_z": { "default_value": 40 },
diff --git a/resources/definitions/builder_premium_medium.def.json b/resources/definitions/builder_premium_medium.def.json
index 58e7c18ed8..e5b8f1785c 100644
--- a/resources/definitions/builder_premium_medium.def.json
+++ b/resources/definitions/builder_premium_medium.def.json
@@ -35,8 +35,6 @@
"material_standby_temperature": { "value": "material_print_temperature" },
"switch_extruder_retraction_speeds": {"default_value": 15 },
- "switch_extruder_retraction_speed": {"default_value": 15 },
- "switch_extruder_prime_speed": {"default_value": 15 },
"switch_extruder_retraction_amount": {"value": 1 },
"speed_travel": { "value": "100" },
@@ -50,8 +48,8 @@
"speed_wall_0": { "value": "math.ceil(speed_wall * 20 / 25)" },
"speed_wall_x": { "value": "speed_wall" },
- "prime_tower_position_x": { "default_value": 175 },
- "prime_tower_position_y": { "default_value": 178 },
+ "prime_tower_position_x": { "value": "175" },
+ "prime_tower_position_y": { "value": "178" },
"prime_tower_wipe_enabled": { "default_value": false },
"prime_tower_min_volume": { "default_value": 50 },
@@ -85,15 +83,13 @@
"retraction_amount": { "default_value": 3 },
"retraction_speed": { "default_value": 15 },
- "retraction_retract_speed": { "default_value": 15 },
- "retraction_prime_speed": { "default_value": 15 },
"travel_retract_before_outer_wall": { "default_value": true },
"skin_overlap": { "value": "15" },
"adhesion_type": { "default_value": "skirt" },
"machine_nozzle_heat_up_speed": { "default_value": 2 },
"machine_nozzle_cool_down_speed": { "default_value": 2 },
- "machine_head_polygon": { "default_value": [[-75, -18],[-75, 35],[18, 35],[18, -18]] },
- "gantry_height": { "default_value": 55 },
+ "machine_head_with_fans_polygon": { "default_value": [[-75, -18],[-75, 35],[18, 35],[18, -18]] },
+ "gantry_height": { "value": "55" },
"machine_max_feedrate_x": { "default_value": 300 },
"machine_max_feedrate_y": { "default_value": 300 },
"machine_max_feedrate_z": { "default_value": 40 },
diff --git a/resources/definitions/builder_premium_small.def.json b/resources/definitions/builder_premium_small.def.json
index 89e172592c..4bcbd7d526 100644
--- a/resources/definitions/builder_premium_small.def.json
+++ b/resources/definitions/builder_premium_small.def.json
@@ -34,8 +34,6 @@
"material_standby_temperature": { "value": "material_print_temperature" },
"switch_extruder_retraction_speeds": {"default_value": 15 },
- "switch_extruder_retraction_speed": {"default_value": 15 },
- "switch_extruder_prime_speed": {"default_value": 15 },
"switch_extruder_retraction_amount": {"value": 1 },
"speed_travel": { "value": "100" },
@@ -49,8 +47,8 @@
"speed_wall_0": { "value": "math.ceil(speed_wall * 20 / 25)" },
"speed_wall_x": { "value": "speed_wall" },
- "prime_tower_position_x": { "default_value": 175 },
- "prime_tower_position_y": { "default_value": 178 },
+ "prime_tower_position_x": { "value": "175" },
+ "prime_tower_position_y": { "value": "178" },
"prime_tower_wipe_enabled": { "default_value": false },
"prime_tower_min_volume": { "default_value": 50 },
@@ -84,15 +82,13 @@
"retraction_amount": { "default_value": 3 },
"retraction_speed": { "default_value": 15 },
- "retraction_retract_speed": { "default_value": 15 },
- "retraction_prime_speed": { "default_value": 15 },
"travel_retract_before_outer_wall": { "default_value": true },
"skin_overlap": { "value": "15" },
"adhesion_type": { "default_value": "skirt" },
"machine_nozzle_heat_up_speed": { "default_value": 2 },
"machine_nozzle_cool_down_speed": { "default_value": 2 },
- "machine_head_polygon": { "default_value": [[-75, -18],[-75, 35],[18, 35],[18, -18]] },
- "gantry_height": { "default_value": 55 },
+ "machine_head_with_fans_polygon": { "default_value": [[-75, -18],[-75, 35],[18, 35],[18, -18]] },
+ "gantry_height": { "value": "55" },
"machine_max_feedrate_x": { "default_value": 300 },
"machine_max_feedrate_y": { "default_value": 300 },
"machine_max_feedrate_z": { "default_value": 40 },
diff --git a/resources/definitions/cartesio.def.json b/resources/definitions/cartesio.def.json
index 9c7a95cceb..e7a005682d 100644
--- a/resources/definitions/cartesio.def.json
+++ b/resources/definitions/cartesio.def.json
@@ -10,7 +10,6 @@
"has_machine_quality": true,
"has_materials": true,
- "has_machine_materials": true,
"has_variants": true,
"variants_name": "Tool",
@@ -35,7 +34,7 @@
"machine_extruder_count": { "default_value": 2 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
- "gantry_height": { "default_value": 35 },
+ "gantry_height": { "value": "35" },
"machine_height": { "default_value": 400 },
"machine_depth": { "default_value": 270 },
"machine_width": { "default_value": 430 },
@@ -45,8 +44,8 @@
"prime_tower_enable": { "default_value": false },
"prime_tower_min_volume": { "value": "0.7" },
"prime_tower_size": { "value": 24.0 },
- "prime_tower_position_x": { "value": 125 },
- "prime_tower_position_y": { "value": 70 },
+ "prime_tower_position_x": { "value": "125" },
+ "prime_tower_position_y": { "value": "70" },
"prime_blob_enable": { "default_value": false },
"machine_max_feedrate_z": { "default_value": 20 },
"machine_disallowed_areas": { "default_value": [
diff --git a/resources/definitions/cocoon_create_modelmaker.def.json b/resources/definitions/cocoon_create_modelmaker.def.json
index 22aa75d09e..b738dc64ff 100644
--- a/resources/definitions/cocoon_create_modelmaker.def.json
+++ b/resources/definitions/cocoon_create_modelmaker.def.json
@@ -39,7 +39,7 @@
"default_value": false
},
"gantry_height": {
- "default_value": 10
+ "value": "10"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
@@ -47,9 +47,6 @@
"material_diameter": {
"default_value": 1.75
},
- "material_print_temperature": {
- "default_value": 220
- },
"layer_height": {
"default_value": 0.10
},
@@ -65,21 +62,6 @@
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 40
- },
- "speed_wall": {
- "default_value": 35
- },
- "speed_topbottom": {
- "default_value": 35
- },
- "speed_travel": {
- "default_value": 70
- },
- "speed_layer_0": {
- "default_value": 20
- },
"support_enable": {
"default_value": true
},
diff --git a/resources/definitions/creality_base.def.json b/resources/definitions/creality_base.def.json
new file mode 100644
index 0000000000..7e91fb4989
--- /dev/null
+++ b/resources/definitions/creality_base.def.json
@@ -0,0 +1,267 @@
+{
+ "name": "Creawsome Base Printer",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": false,
+ "author": "trouch.com",
+ "manufacturer": "Creality3D",
+ "file_formats": "text/x-gcode",
+ "first_start_actions": ["MachineSettingsAction"],
+
+ "machine_extruder_trains": {
+ "0": "creality_base_extruder_0"
+ },
+
+ "has_materials": true,
+ "has_variants": true,
+ "has_machine_quality": true,
+ "variants_name": "Nozzle Size",
+
+ "preferred_variant_name": "0.4mm Nozzle",
+ "preferred_quality_type": "standard",
+ "preferred_material": "generic_pla",
+ "exclude_materials": [
+ "Vertex_Delta_ABS",
+ "Vertex_Delta_PET",
+ "Vertex_Delta_PLA",
+ "Vertex_Delta_TPU",
+ "chromatik_pla",
+ "dsm_arnitel2045_175",
+ "dsm_novamid1070_175",
+ "fabtotum_abs",
+ "fabtotum_nylon",
+ "fabtotum_pla",
+ "fabtotum_tpu",
+ "fiberlogy_hd_pla",
+ "filo3d_pla",
+ "filo3d_pla_green",
+ "filo3d_pla_red",
+ "generic_abs",
+ "generic_bam",
+ "generic_cffcpe",
+ "generic_cffpa",
+ "generic_cpe",
+ "generic_cpe_plus",
+ "generic_gffcpe",
+ "generic_gffpa",
+ "generic_hips",
+ "generic_nylon",
+ "generic_pc",
+ "generic_petg",
+ "generic_pla",
+ "generic_pp",
+ "generic_pva",
+ "generic_tough_pla",
+ "generic_tpu",
+ "imade3d_petg_green",
+ "imade3d_petg_pink",
+ "imade3d_pla_green",
+ "imade3d_pla_pink",
+ "innofill_innoflex60_175",
+ "octofiber_pla",
+ "polyflex_pla",
+ "polymax_pla",
+ "polyplus_pla",
+ "polywood_pla",
+ "structur3d_dap100silicone",
+ "tizyx_abs",
+ "tizyx_pla",
+ "tizyx_pla_bois",
+ "ultimaker_abs_black",
+ "ultimaker_abs_blue",
+ "ultimaker_abs_green",
+ "ultimaker_abs_grey",
+ "ultimaker_abs_orange",
+ "ultimaker_abs_pearl-gold",
+ "ultimaker_abs_red",
+ "ultimaker_abs_silver-metallic",
+ "ultimaker_abs_white",
+ "ultimaker_abs_yellow",
+ "ultimaker_bam",
+ "ultimaker_cpe_black",
+ "ultimaker_cpe_blue",
+ "ultimaker_cpe_dark-grey",
+ "ultimaker_cpe_green",
+ "ultimaker_cpe_light-grey",
+ "ultimaker_cpe_plus_black",
+ "ultimaker_cpe_plus_transparent",
+ "ultimaker_cpe_plus_white",
+ "ultimaker_cpe_red",
+ "ultimaker_cpe_transparent",
+ "ultimaker_cpe_white",
+ "ultimaker_cpe_yellow",
+ "ultimaker_nylon_black",
+ "ultimaker_nylon_transparent",
+ "ultimaker_pc_black",
+ "ultimaker_pc_transparent",
+ "ultimaker_pc_white",
+ "ultimaker_pla_black",
+ "ultimaker_pla_blue",
+ "ultimaker_pla_green",
+ "ultimaker_pla_magenta",
+ "ultimaker_pla_orange",
+ "ultimaker_pla_pearl-white",
+ "ultimaker_pla_red",
+ "ultimaker_pla_silver-metallic",
+ "ultimaker_pla_transparent",
+ "ultimaker_pla_white",
+ "ultimaker_pla_yellow",
+ "ultimaker_pp_transparent",
+ "ultimaker_pva",
+ "ultimaker_tough_pla_black",
+ "ultimaker_tough_pla_green",
+ "ultimaker_tough_pla_red",
+ "ultimaker_tough_pla_white",
+ "ultimaker_tpu_black",
+ "ultimaker_tpu_blue",
+ "ultimaker_tpu_red",
+ "ultimaker_tpu_white",
+ "verbatim_bvoh_175",
+ "zyyx_pro_flex",
+ "zyyx_pro_pla"
+ ]
+ },
+ "overrides": {
+ "machine_name": { "default_value": "Creawsome Base Printer" },
+ "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n" },
+ "machine_end_gcode": { "default_value": "G91 ;Relative positioning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y{machine_depth} ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" },
+
+ "machine_max_feedrate_x": { "value": 500 },
+ "machine_max_feedrate_y": { "value": 500 },
+ "machine_max_feedrate_z": { "value": 10 },
+ "machine_max_feedrate_e": { "value": 50 },
+
+ "machine_max_acceleration_x": { "value": 500 },
+ "machine_max_acceleration_y": { "value": 500 },
+ "machine_max_acceleration_z": { "value": 100 },
+ "machine_max_acceleration_e": { "value": 5000 },
+ "machine_acceleration": { "value": 500 },
+
+ "machine_max_jerk_xy": { "value": 10 },
+ "machine_max_jerk_z": { "value": 0.4 },
+ "machine_max_jerk_e": { "value": 5 },
+
+ "machine_heated_bed": { "default_value": true },
+
+ "material_diameter": { "default_value": 1.75 },
+
+ "acceleration_print": { "value": 500 },
+ "acceleration_travel": { "value": 500 },
+ "acceleration_travel_layer_0": { "value": "acceleration_travel" },
+ "acceleration_roofing": { "enabled": "acceleration_enabled and roofing_layer_count > 0 and top_layers > 0" },
+
+ "jerk_print": { "value": 8 },
+ "jerk_travel": { "value": "jerk_print" },
+ "jerk_travel_layer_0": { "value": "jerk_travel" },
+
+ "acceleration_enabled": { "value": false },
+ "jerk_enabled": { "value": false },
+
+ "speed_print": { "value": 50.0 } ,
+ "speed_infill": { "value": "speed_print" },
+ "speed_wall": { "value": "speed_print / 2" },
+ "speed_wall_0": { "value": "speed_wall" },
+ "speed_wall_x": { "value": "speed_wall" },
+ "speed_topbottom": { "value": "speed_print / 2" },
+ "speed_roofing": { "value": "speed_topbottom" },
+ "speed_travel": { "value": "150.0 if speed_print < 60 else 250.0 if speed_print > 100 else speed_print * 2.5" },
+ "speed_layer_0": { "value": 20.0 },
+ "speed_print_layer_0": { "value": "speed_layer_0" },
+ "speed_travel_layer_0": { "value": "100 if speed_layer_0 < 20 else 150 if speed_layer_0 > 30 else speed_layer_0 * 5" },
+ "speed_prime_tower": { "value": "speed_topbottom" },
+ "speed_support": { "value": "speed_wall_0" },
+ "speed_support_interface": { "value": "speed_topbottom" },
+ "speed_z_hop": { "value": 5 },
+
+ "skirt_brim_speed": { "value": "speed_layer_0" },
+
+ "line_width": { "value": "machine_nozzle_size" },
+
+ "optimize_wall_printing_order": { "value": "True" },
+
+ "material_initial_print_temperature": { "value": "material_print_temperature" },
+ "material_final_print_temperature": { "value": "material_print_temperature" },
+ "material_flow": { "value": 100 },
+ "travel_compensate_overlapping_walls_0_enabled": { "value": "False" },
+
+ "z_seam_type": { "value": "'back'" },
+ "z_seam_corner": { "value": "'z_seam_corner_weighted'" },
+
+ "infill_sparse_density": { "value": "20" },
+ "infill_pattern": { "value": "'lines' if infill_sparse_density > 50 else 'cubic'" },
+ "infill_before_walls": { "value": false },
+ "infill_overlap": { "value": 30.0 },
+ "skin_overlap": { "value": 10.0 },
+ "infill_wipe_dist": { "value": 0.0 },
+ "wall_0_wipe_dist": { "value": 0.0 },
+
+ "fill_perimeter_gaps": { "value": "'everywhere'" },
+ "fill_outline_gaps": { "value": false },
+ "filter_out_tiny_gaps": { "value": false },
+
+ "retraction_speed": {
+ "maximum_value_warning": "machine_max_feedrate_e if retraction_enable else float('inf')",
+ "maximum_value": 200
+ },
+ "retraction_retract_speed": {
+ "maximum_value_warning": "machine_max_feedrate_e if retraction_enable else float('inf')",
+ "maximum_value": 200
+ },
+ "retraction_prime_speed": {
+ "maximum_value_warning": "machine_max_feedrate_e if retraction_enable else float('inf')",
+ "maximum_value": 200
+ },
+
+ "retraction_hop_enabled": { "value": "False" },
+ "retraction_hop": { "value": 0.2 },
+ "retraction_combing": { "value": "'off' if retraction_hop_enabled else 'noskin'" },
+ "retraction_combing_max_distance": { "value": 30 },
+ "travel_avoid_other_parts": { "value": true },
+ "travel_avoid_supports": { "value": true },
+ "travel_retract_before_outer_wall": { "value": true },
+
+ "retraction_enable": { "value": true },
+ "retraction_count_max": { "value": 100 },
+ "retraction_extrusion_window": { "value": 10 },
+ "retraction_min_travel": { "value": 1.5 },
+
+ "cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
+ "cool_fan_enabled": { "value": true },
+ "cool_min_layer_time": { "value": 10 },
+
+ "adhesion_type": { "value": "'skirt'" },
+ "brim_replaces_support": { "value": false },
+ "skirt_gap": { "value": 10.0 },
+ "skirt_line_count": { "value": 3 },
+
+ "adaptive_layer_height_variation": { "value": 0.04 },
+ "adaptive_layer_height_variation_step": { "value": 0.04 },
+
+ "meshfix_maximum_resolution": { "value": "0.05" },
+ "meshfix_maximum_travel_resolution": { "value": "meshfix_maximum_resolution" },
+
+ "support_angle": { "value": "math.floor(math.degrees(math.atan(line_width/2.0/layer_height)))" },
+ "support_pattern": { "value": "'zigzag'" },
+ "support_infill_rate": { "value": "0 if support_tree_enable else 20" },
+ "support_use_towers": { "value": false },
+ "support_xy_distance": { "value": "wall_line_width_0 * 2" },
+ "support_xy_distance_overhang": { "value": "wall_line_width_0" },
+ "support_z_distance": { "value": "layer_height if layer_height >= 0.16 else layer_height*2" },
+ "support_xy_overrides_z": { "value": "'xy_overrides_z'" },
+ "support_wall_count": { "value": 1 },
+ "support_brim_enable": { "value": true },
+ "support_brim_width": { "value": 4 },
+
+ "support_interface_enable": { "value": true },
+ "support_interface_height": { "value": "layer_height * 4" },
+ "support_interface_density": { "value": 33.333 },
+ "support_interface_pattern": { "value": "'grid'" },
+ "support_interface_skip_height": { "value": 0.2 },
+ "minimum_support_area": { "value": 5 },
+ "minimum_interface_area": { "value": 10 },
+ "top_bottom_thickness": {"value": "layer_height_0 + layer_height * 3" },
+ "wall_thickness": {"value": "line_width * 2" }
+
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creality_cr-x.def.json b/resources/definitions/creality_cr-x.def.json
index 94ac20cbb5..13409a7212 100644
--- a/resources/definitions/creality_cr-x.def.json
+++ b/resources/definitions/creality_cr-x.def.json
@@ -1,5 +1,4 @@
{
- "id": "CR-X",
"version": 2,
"name": "Creality CR-X",
"inherits": "fdmprinter",
@@ -30,9 +29,8 @@
"retraction_amount": { "default_value": 3 },
"retraction_speed": { "default_value": 70},
"adhesion_type": { "default_value": "skirt" },
- "gantry_height": { "default_value": 30 },
+ "gantry_height": { "value": "30" },
"speed_print": { "default_value": 60 },
- "speed_travel": { "default_value": 120 },
"machine_max_acceleration_x": { "default_value": 500 },
"machine_max_acceleration_y": { "default_value": 500 },
"machine_max_acceleration_z": { "default_value": 100 },
@@ -43,9 +41,7 @@
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": { "default_value": "G21 ;metric values\nG28 ;home all\nG90 ;absolute positioning\nM107 ;start with the fan off\nG1 F2400 Z15.0 ;raise the nozzle 15mm\nM109 S{material_print_temperature} ;Set Extruder Temperature and Wait\nM190 S{material_bed_temperature}; Wait for bed temperature to reach target temp\nT0 ;Switch to Extruder 1\nG1 F3000 X5 Y10 Z0.2 ;move to prime start position\nG92 E0 ;reset extrusion distance\nG1 F600 X160 E15 ;prime nozzle in a line\nG1 F5000 X180 ;quick wipe\nG92 E0 ;reset extrusion distance" },
"machine_end_gcode": { "default_value": "M104 S0 ;hotend off\nM140 S0 ;bed off\nG92 E0\nG1 F2000 E-100 ;retract filament 100mm\nG92 E0\nG1 F3000 X0 Y270 ;move bed for easy part removal\nM84 ;disable steppers" },
- "material_print_temperature": { "default_value": 200 },
"wall_thickness": { "default_value": 1 },
- "top_bottom_thickness": { "default_value": 1 },
- "bottom_thickness": { "default_value": 1 }
+ "top_bottom_thickness": { "default_value": 1 }
}
}
diff --git a/resources/definitions/creality_cr10.def.json b/resources/definitions/creality_cr10.def.json
index fb63867163..85e0f0a435 100644
--- a/resources/definitions/creality_cr10.def.json
+++ b/resources/definitions/creality_cr10.def.json
@@ -1,95 +1,25 @@
{
"name": "Creality CR-10",
"version": 2,
- "inherits": "fdmprinter",
- "metadata": {
- "visible": true,
- "author": "Michael Wildermuth",
- "manufacturer": "Creality3D",
- "file_formats": "text/x-gcode",
- "preferred_quality_type": "draft",
- "machine_extruder_trains":
- {
- "0": "creality_cr10_extruder_0"
- }
- },
+ "inherits": "creality_base",
"overrides": {
- "machine_width": {
- "default_value": 300
- },
- "machine_height": {
- "default_value": 400
- },
- "machine_depth": {
- "default_value": 300
- },
- "machine_head_polygon": {
- "default_value": [
- [-30, 34],
- [-30, -32],
- [30, -32],
- [30, 34]
+ "machine_name": { "default_value": "Creality CR-10" },
+ "machine_width": { "default_value": 300 },
+ "machine_depth": { "default_value": 300 },
+ "machine_height": { "default_value": 400 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
]
},
- "layer_height_0": {
- "default_value": 0.2
- },
- "top_bottom_thickness": {
- "default_value": 0.6
- },
- "top_bottom_pattern_0": {
- "default_value": "concentric"
- },
- "infill_pattern": {
- "value": "'triangles'"
- },
- "retraction_enable": {
- "default_value": true
- },
- "retraction_amount": {
- "default_value": 5
- },
- "retraction_speed": {
- "default_value": 40
- },
- "cool_min_layer_time": {
- "default_value": 10
- },
- "adhesion_type": {
- "default_value": "skirt"
- },
- "skirt_line_count": {
- "default_value": 4
- },
- "skirt_gap": {
- "default_value": 5
- },
- "machine_end_gcode": {
- "default_value": "G91\nG1 F1800 E-3\nG1 F3000 Z10\nG90\nG28 X0 Y0 ; home x and y axis\nM106 S0 ; turn off cooling fan\nM104 S0 ; turn off extruder\nM140 S0 ; turn off bed\nM84 ; disable motors"
- },
- "machine_heated_bed": {
- "default_value": true
- },
- "gantry_height": {
- "default_value": 30
- },
- "acceleration_enabled": {
- "default_value": true
- },
- "acceleration_print": {
- "default_value": 500
- },
- "acceleration_travel": {
- "default_value": 500
- },
- "jerk_enabled": {
- "default_value": true
- },
- "jerk_print": {
- "default_value": 20
- },
- "jerk_travel": {
- "default_value": 20
- }
+
+ "gantry_height": { "value": 25 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
}
}
\ No newline at end of file
diff --git a/resources/definitions/creality_cr10max.def.json b/resources/definitions/creality_cr10max.def.json
new file mode 100644
index 0000000000..a7e40d5bfc
--- /dev/null
+++ b/resources/definitions/creality_cr10max.def.json
@@ -0,0 +1,26 @@
+{
+ "name": "Creality CR-10 Max",
+ "version": 2,
+ "inherits": "creality_base",
+ "overrides": {
+ "machine_name": { "default_value": "Creality CR-10 Max" },
+ "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nM420 S1 Z2 ;Enable ABL using saved Mesh and Fade Height\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n"},
+ "machine_width": { "default_value": 450 },
+ "machine_depth": { "default_value": 450 },
+ "machine_height": { "default_value": 470 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-44, 34],
+ [-44, -34],
+ [38, -34],
+ [38, 34]
+ ]
+ },
+
+ "gantry_height": { "value": 30 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creality_cr10mini.def.json b/resources/definitions/creality_cr10mini.def.json
new file mode 100644
index 0000000000..621be5f0f3
--- /dev/null
+++ b/resources/definitions/creality_cr10mini.def.json
@@ -0,0 +1,25 @@
+{
+ "name": "Creality CR-10 Mini",
+ "version": 2,
+ "inherits": "creality_base",
+ "overrides": {
+ "machine_name": { "default_value": "Creality CR-10 Mini" },
+ "machine_width": { "default_value": 300 },
+ "machine_depth": { "default_value": 220 },
+ "machine_height": { "default_value": 300 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
+ ]
+ },
+
+ "gantry_height": { "value": 25 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creality_cr10s.def.json b/resources/definitions/creality_cr10s.def.json
index c368269a46..9884b95cb4 100644
--- a/resources/definitions/creality_cr10s.def.json
+++ b/resources/definitions/creality_cr10s.def.json
@@ -1,5 +1,11 @@
{
"name": "Creality CR-10S",
"version": 2,
- "inherits": "creality_cr10"
+ "inherits": "creality_cr10",
+ "overrides": {
+ "machine_name": { "default_value": "Creality CR-10S" }
+ },
+ "metadata": {
+ "quality_definition": "creality_base"
+ }
}
\ No newline at end of file
diff --git a/resources/definitions/creality_cr10s4.def.json b/resources/definitions/creality_cr10s4.def.json
index 7145083674..ccecd41a1d 100644
--- a/resources/definitions/creality_cr10s4.def.json
+++ b/resources/definitions/creality_cr10s4.def.json
@@ -1,26 +1,25 @@
{
- "name": "Creality CR-10 S4",
+ "name": "Creality CR-10S4",
"version": 2,
- "inherits": "creality_cr10",
- "metadata": {
- "visible": true,
- "author": "Michael Wildermuth",
- "manufacturer": "Creality3D",
- "file_formats": "text/x-gcode",
- "machine_extruder_trains":
- {
- "0": "creality_cr10s4_extruder_0"
- }
- },
+ "inherits": "creality_base",
"overrides": {
- "machine_width": {
- "default_value": 400
+ "machine_name": { "default_value": "Creality CR-10S4" },
+ "machine_width": { "default_value": 400 },
+ "machine_depth": { "default_value": 400 },
+ "machine_height": { "default_value": 400 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
+ ]
},
- "machine_height": {
- "default_value": 400
- },
- "machine_depth": {
- "default_value": 400
- }
+
+ "gantry_height": { "value": 25 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
}
}
\ No newline at end of file
diff --git a/resources/definitions/creality_cr10s5.def.json b/resources/definitions/creality_cr10s5.def.json
index b082894a16..105e1d0458 100644
--- a/resources/definitions/creality_cr10s5.def.json
+++ b/resources/definitions/creality_cr10s5.def.json
@@ -1,26 +1,25 @@
{
- "name": "Creality CR-10 S5",
+ "name": "Creality CR-10S5",
"version": 2,
- "inherits": "creality_cr10",
- "metadata": {
- "visible": true,
- "author": "Michael Wildermuth",
- "manufacturer": "Creality3D",
- "file_formats": "text/x-gcode",
- "machine_extruder_trains":
- {
- "0": "creality_cr10s5_extruder_0"
- }
- },
+ "inherits": "creality_base",
"overrides": {
- "machine_width": {
- "default_value": 500
+ "machine_name": { "default_value": "Creality CR-10S5" },
+ "machine_width": { "default_value": 500 },
+ "machine_depth": { "default_value": 500 },
+ "machine_height": { "default_value": 500 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
+ ]
},
- "machine_height": {
- "default_value": 500
- },
- "machine_depth": {
- "default_value": 500
- }
+
+ "gantry_height": { "value": 25 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
}
}
\ No newline at end of file
diff --git a/resources/definitions/creality_cr10spro.def.json b/resources/definitions/creality_cr10spro.def.json
new file mode 100644
index 0000000000..28c8dda0a5
--- /dev/null
+++ b/resources/definitions/creality_cr10spro.def.json
@@ -0,0 +1,24 @@
+{
+ "name": "Creality CR-10S Pro",
+ "version": 2,
+ "inherits": "creality_cr10",
+ "overrides": {
+ "machine_name": { "default_value": "Creality CR-10S Pro" },
+ "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nM420 S1 Z2 ;Enable ABL using saved Mesh and Fade Height\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n"},
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-44, 34],
+ [-44, -34],
+ [38, -34],
+ [38, 34]
+ ]
+ },
+
+ "gantry_height": { "value": 30 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "platform": "creality_cr10spro.stl",
+ "platform_offset": [ -150, 0, 150]
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creality_cr20.def.json b/resources/definitions/creality_cr20.def.json
new file mode 100644
index 0000000000..b18c2709e6
--- /dev/null
+++ b/resources/definitions/creality_cr20.def.json
@@ -0,0 +1,25 @@
+{
+ "name": "Creality CR-20",
+ "version": 2,
+ "inherits": "creality_base",
+ "overrides": {
+ "machine_name": { "default_value": "Creality CR-20" },
+ "machine_width": { "default_value": 220 },
+ "machine_depth": { "default_value": 220 },
+ "machine_height": { "default_value": 250 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
+ ]
+ },
+
+ "gantry_height": { "value": 25 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creality_cr20pro.def.json b/resources/definitions/creality_cr20pro.def.json
new file mode 100644
index 0000000000..4e676bcb74
--- /dev/null
+++ b/resources/definitions/creality_cr20pro.def.json
@@ -0,0 +1,13 @@
+{
+ "name": "Creality CR-20 Pro",
+ "version": 2,
+ "inherits": "creality_cr20",
+ "overrides": {
+ "machine_name": { "default_value": "Creality CR-20 Pro" },
+ "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nM420 S1 Z2 ;Enable ABL using saved Mesh and Fade Height\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n"}
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base"
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creality_ender2.def.json b/resources/definitions/creality_ender2.def.json
new file mode 100644
index 0000000000..2a5e14c828
--- /dev/null
+++ b/resources/definitions/creality_ender2.def.json
@@ -0,0 +1,26 @@
+{
+ "name": "Creality Ender-2",
+ "version": 2,
+ "inherits": "creality_base",
+ "overrides": {
+ "machine_name": { "default_value": "Creality Ender-2" },
+ "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y100.0 Z0.28 F1500.0 E8 ;Draw the first line\nG1 X10.4 Y100.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E15 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n"},
+ "machine_width": { "default_value": 150 },
+ "machine_depth": { "default_value": 150 },
+ "machine_height": { "default_value": 200 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
+ ]
+ },
+
+ "gantry_height": { "value": 25 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creality_ender3.def.json b/resources/definitions/creality_ender3.def.json
old mode 100755
new mode 100644
index 08d8e92b72..37df844560
--- a/resources/definitions/creality_ender3.def.json
+++ b/resources/definitions/creality_ender3.def.json
@@ -1,96 +1,33 @@
{
"name": "Creality Ender-3",
"version": 2,
- "inherits": "fdmprinter",
+ "inherits": "creality_base",
"metadata": {
+ "quality_definition": "creality_base",
"visible": true,
- "author": "Sacha Telgenhof",
- "manufacturer": "Creality3D",
- "file_formats": "text/x-gcode",
- "platform": "creality_ender3_platform.stl",
- "preferred_quality_type": "draft",
- "machine_extruder_trains":
- {
- "0": "creality_ender3_extruder_0"
- }
+ "platform": "creality_ender3.stl"
},
"overrides": {
- "machine_name": {
- "default_value": "Creality Ender-3"
- },
- "machine_width": {
- "default_value": 235
- },
- "machine_height": {
- "default_value": 250
- },
- "machine_depth": {
- "default_value": 235
- },
- "machine_heated_bed": {
- "default_value": true
- },
- "gantry_height": {
- "default_value": 30
- },
- "machine_head_polygon": {
+ "machine_name": { "default_value": "Creality Ender-3" },
+ "machine_width": { "default_value": 235 },
+ "machine_depth": { "default_value": 235 },
+ "machine_height": { "default_value": 250 },
+ "machine_disallowed_areas": {
"default_value": [
- [-30, 34],
- [-30, -32],
- [30, -32],
- [30, 34]
+ [[-117.5, 117.5], [-117.5, 108], [117.5, 108], [117.5, 117.5]],
+ [[-117.5, -108], [-117.5, -117.5], [117.5, -117.5], [117.5, -108]]
+ ]},
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
]
},
- "material_diameter": {
- "default_value": 1.75
- },
- "acceleration_enabled": {
- "default_value": true
- },
- "acceleration_print": {
- "default_value": 500
- },
- "acceleration_travel": {
- "default_value": 500
- },
- "jerk_enabled": {
- "default_value": true
- },
- "jerk_travel": {
- "default_value": 20
- },
- "layer_height": {
- "default_value": 0.10
- },
- "layer_height_0": {
- "default_value": 0.2
- },
- "adhesion_type": {
- "default_value": "skirt"
- },
- "top_bottom_thickness": {
- "default_value": 0.6
- },
- "retraction_amount": {
- "default_value": 5
- },
- "retraction_speed": {
- "default_value": 40
- },
- "cool_min_layer_time": {
- "default_value": 10
- },
- "skirt_line_count": {
- "default_value": 4
- },
- "skirt_gap": {
- "default_value": 5
- },
"machine_start_gcode": {
- "default_value": "; Ender 3 Custom Start G-code\nG28 ; Home all axes\nG92 E0 ; Reset Extruder\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 X0.1 Y20 Z0.3 F5000.0 ; Move to start position\nG1 X0.1 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line\nG1 X0.4 Y200.0 Z0.3 F5000.0 ; Move to side a little\nG1 X0.4 Y20 Z0.3 F1500.0 E30 ; Draw the second line\nG92 E0 ; Reset Extruder\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\n; End of custom start GCode"
+ "default_value": "; Ender 3 Custom Start G-code\nG92 E0 ; Reset Extruder\nG28 ; Home all axes\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 X0.1 Y20 Z0.3 F5000.0 ; Move to start position\nG1 X0.1 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line\nG1 X0.4 Y200.0 Z0.3 F5000.0 ; Move to side a little\nG1 X0.4 Y20 Z0.3 F1500.0 E30 ; Draw the second line\nG92 E0 ; Reset Extruder\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 X5 Y20 Z0.3 F5000.0 ; Move over to prevent blob squish"
},
- "machine_end_gcode": {
- "default_value": "; Ender 3 Custom End G-code\nG4 ; Wait\nM220 S100 ; Reset Speed factor override percentage to default (100%)\nM221 S100 ; Reset Extrude factor override percentage to default (100%)\nG91 ; Set coordinates to relative\nG1 F1800 E-3 ; Retract filament 3 mm to prevent oozing\nG1 F3000 Z20 ; Move Z Axis up 20 mm to allow filament ooze freely\nG90 ; Set coordinates to absolute\nG1 X0 Y{machine_depth} F1000 ; Move Heat Bed to the front for easy print removal\nM84 ; Disable stepper motors\n; End of custom end GCode"
- }
+
+ "gantry_height": { "value": 25 }
}
}
diff --git a/resources/definitions/creality_ender4.def.json b/resources/definitions/creality_ender4.def.json
new file mode 100644
index 0000000000..9c13797c92
--- /dev/null
+++ b/resources/definitions/creality_ender4.def.json
@@ -0,0 +1,27 @@
+{
+ "name": "Creality Ender-4",
+ "version": 2,
+ "inherits": "creality_base",
+ "overrides": {
+ "machine_name": { "default_value": "Creality Ender-4" },
+ "machine_width": { "default_value": 452 },
+ "machine_depth": { "default_value": 468 },
+ "machine_height": { "default_value": 482 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
+ ]
+ },
+
+ "gantry_height": { "value": 25 },
+
+ "speed_print": { "value": 80.0 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creality_ender5.def.json b/resources/definitions/creality_ender5.def.json
new file mode 100644
index 0000000000..1b4be4d71f
--- /dev/null
+++ b/resources/definitions/creality_ender5.def.json
@@ -0,0 +1,28 @@
+{
+ "name": "Creality Ender-5",
+ "version": 2,
+ "inherits": "creality_base",
+ "overrides": {
+ "machine_name": { "default_value": "Creality Ender-5" },
+ "machine_end_gcode": { "default_value": "G91 ;Relative positioning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" },
+ "machine_width": { "default_value": 220 },
+ "machine_depth": { "default_value": 220 },
+ "machine_height": { "default_value": 300 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
+ ]
+ },
+
+ "gantry_height": { "value": 25 },
+
+ "speed_print": { "value": 80.0 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creality_ender5plus.def.json b/resources/definitions/creality_ender5plus.def.json
new file mode 100644
index 0000000000..48ebad61ea
--- /dev/null
+++ b/resources/definitions/creality_ender5plus.def.json
@@ -0,0 +1,28 @@
+{
+ "name": "Creality Ender-5 Plus",
+ "version": 2,
+ "inherits": "creality_base",
+ "overrides": {
+ "machine_name": { "default_value": "Creality Ender-5 Plus" },
+ "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nM420 S1 Z2 ;Enable ABL using saved Mesh and Fade Height\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n"},
+ "machine_width": { "default_value": 350 },
+ "machine_depth": { "default_value": 350 },
+ "machine_height": { "default_value": 400 },
+ "machine_head_with_fans_polygon": { "default_value": [
+ [-26, 34],
+ [-26, -32],
+ [32, -32],
+ [32, 34]
+ ]
+ },
+
+ "gantry_height": { "value": 25 },
+
+ "speed_print": { "value": 80.0 }
+
+ },
+ "metadata": {
+ "quality_definition": "creality_base",
+ "visible": true
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/creatable_d3.def.json b/resources/definitions/creatable_d3.def.json
index 3fb1205ead..f621bcbe97 100644
--- a/resources/definitions/creatable_d3.def.json
+++ b/resources/definitions/creatable_d3.def.json
@@ -24,17 +24,15 @@
"machine_depth": { "default_value": 250 },
"machine_heated_bed": { "default_value": true },
"machine_shape": { "default_value": "elliptic" },
- "machine_max_feedrate_z": { "default_value": 300 },
- "gantry_height": {"default_value": 43},
+ "machine_max_feedrate_z": { "default_value": 300 },
+ "gantry_height": {"value": "43"},
"layer_height": { "default_value": 0.1 },
- "relative_extrusion": { "default_value": false },
+ "relative_extrusion": { "value": "False" },
"retraction_combing": { "default_value": "off" },
- "retraction_hop_enabled": { "default_value": true },
+ "retraction_hop_enabled": { "default_value": true },
"retraction_hop_only_when_collides": { "default_value": false },
- "retraction_retract_speed": { "default_value": 100 },
"retraction_speed": { "default_value": 100 },
"retraction_amount": { "default_value": 4.5 },
- "retraction_prime_speed": { "default_value": 45 },
"machine_start_gcode": {
"default_value": "G21\nG90\nM82\nM106 S255\nG28\nG92 E0\nG1 Z100 F5000\nM190 S50\nM109 S200\nG1 X-135\nG1 Z0.3\nG92 E-32\nG1 E0 F1000\nG1 E50 F200\nG1 F1000\nG1 X-125\nG92 E0"
},
diff --git a/resources/definitions/cubicon_3dp_110f.def.json b/resources/definitions/cubicon_3dp_110f.def.json
index 168b57cd66..eecfdd5911 100644
--- a/resources/definitions/cubicon_3dp_110f.def.json
+++ b/resources/definitions/cubicon_3dp_110f.def.json
@@ -1,5 +1,4 @@
{
- "id": "3DP-110F",
"version": 2,
"name": "Cubicon Single",
"inherits": "cubicon_common",
diff --git a/resources/definitions/cubicon_3dp_210f.def.json b/resources/definitions/cubicon_3dp_210f.def.json
index cc99899f92..5d8ff78487 100644
--- a/resources/definitions/cubicon_3dp_210f.def.json
+++ b/resources/definitions/cubicon_3dp_210f.def.json
@@ -1,5 +1,4 @@
{
- "id": "3DP-210F",
"version": 2,
"name": "Cubicon Style",
"inherits": "cubicon_common",
diff --git a/resources/definitions/cubicon_3dp_310f.def.json b/resources/definitions/cubicon_3dp_310f.def.json
index 90d0e3f25c..1dc78f0ebf 100644
--- a/resources/definitions/cubicon_3dp_310f.def.json
+++ b/resources/definitions/cubicon_3dp_310f.def.json
@@ -1,5 +1,4 @@
{
- "id": "3DP-310F",
"version": 2,
"name": "Cubicon Single Plus",
"inherits": "cubicon_common",
diff --git a/resources/definitions/cubicon_common.def.json b/resources/definitions/cubicon_common.def.json
index ae085c7552..6b1e3d953e 100644
--- a/resources/definitions/cubicon_common.def.json
+++ b/resources/definitions/cubicon_common.def.json
@@ -23,77 +23,34 @@
"travel_compensate_overlapping_walls_enabled": {
"default_value": false
},
- "travel_compensate_overlapping_walls_0_enabled": {
- "default_value": false
- },
- "travel_compensate_overlapping_walls_x_enabled": {
- "default_value": false
- },
"layer_height": {
"default_value": 0.2
},
"layer_height_0": {
"default_value": 0.2
},
- "infill_line_width": {
- "default_value": 0.6
- },
"adhesion_type": {
"default_value": "raft"
},
- "roofing_pattern": { "default_value": "lines" },
"top_bottom_pattern": { "default_value": "lines" },
- "top_bottom_pattern_0": {
- "default_value": "zigzag"
- },
"fill_perimeter_gaps": { "default_value": "everywhere" },
- "infill_pattern": {
- "default_value": "zigzag"
- },
"infill_sparse_density": { "default_value": 20 },
- "infill_overlap": {
- "default_value": 15
- },
"infill_before_walls": { "default_value": false },
- "infill_sparse_thickness": { "default_value": 0.2 },
"top_bottom_thickness": {
"default_value": 1.0
},
- "top_thickness": {
- "default_value": 1.0
- },
"bottom_thickness": {
- "default_value": 0.6,
"value": "top_bottom_thickness * 0.6"
},
- "roofing_layer_count": {
- "default_value": 1
- },
- "skin_preshrink": { "default_value": true },
"material_flow_layer_0": { "default_value": 100 },
- "top_skin_preshrink": { "default_value": 1.2 },
- "bottom_skin_preshrink": { "default_value": 1.2 },
"max_skin_angle_for_expansion": { "default_value": 90 },
- "min_skin_width_for_expansion": { "default_value": 2.7475 },
"skin_angles": { "default_value": "[135,45]" },
- "roofing_angles": { "default_value": "[135,45]" },
"coasting_volume": { "default_value": 0.032 },
"wall_thickness": { "default_value": 1.2 },
- "wall_line_count": { "default_value": 3 },
- "speed_wall_0": { "default_value": 25 },
- "skin_overlap": { "default_value": 5 },
"cool_min_layer_time_fan_speed_max": { "default_value": 15 },
"cool_min_layer_time": { "default_value": 15 },
- "support_roof_pattern": { "default_value": "zigzag" },
- "support_bottom_pattern": { "default_value": "zigzag" },
"support_interface_pattern": { "default_value": "zigzag" },
"support_pattern": { "default_value": "zigzag" },
- "retraction_amount": { "default_value": 1.5 },
- "top_layers": {
- "default_value": 5
- },
- "bottom_layers": {
- "default_value": 3
- }
+ "retraction_amount": { "default_value": 1.5 }
}
}
\ No newline at end of file
diff --git a/resources/definitions/cubicon_dual_pro_a30.def.json b/resources/definitions/cubicon_dual_pro_a30.def.json
new file mode 100644
index 0000000000..6431c917a5
--- /dev/null
+++ b/resources/definitions/cubicon_dual_pro_a30.def.json
@@ -0,0 +1,44 @@
+{
+ "version": 2,
+ "name": "Cubicon Dual Pro-A30",
+ "inherits": "cubicon_common",
+ "metadata": {
+ "author": "Cubicon R&D Center",
+ "manufacturer": "Cubicon",
+ "visible": true,
+ "file_formats": "text/x-gcode",
+ "supports_usb_connection": false,
+ "machine_extruder_trains": {
+ "0": "cubicon_dual_pro_a30_extruder_0",
+ "1": "cubicon_dual_pro_a30_extruder_1"
+ },
+ "platform_offset": [
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "Cubicon Dual Pro-A30"
+ },
+ "machine_start_gcode": {
+ "default_value": "M911 Dual Pro-A30C\nM201 X400 Y400\nM202 X400 Y400\nG28 ; Home\nG1 Z15.0 F6000 ;move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0"
+ },
+ "machine_width": {
+ "default_value": 300
+ },
+ "machine_depth": {
+ "default_value": 300
+ },
+ "machine_height": {
+ "default_value": 300
+ },
+ "material_bed_temp_wait":{
+ "default_value": false
+ },
+ "machine_extruder_count": {
+ "default_value": 2
+ }
+ }
+}
diff --git a/resources/definitions/cubicon_style_plus_a15.def.json b/resources/definitions/cubicon_style_plus_a15.def.json
new file mode 100644
index 0000000000..a55d5aa791
--- /dev/null
+++ b/resources/definitions/cubicon_style_plus_a15.def.json
@@ -0,0 +1,40 @@
+{
+ "version": 2,
+ "name": "Cubicon Style Plus-A15",
+ "inherits": "cubicon_common",
+ "metadata": {
+ "author": "Cubicon R&D Center",
+ "manufacturer": "Cubicon",
+ "visible": true,
+ "file_formats": "text/x-gcode",
+ "supports_usb_connection": false,
+ "machine_extruder_trains": {
+ "0": "cubicon_style_plus_a15_extruder_0"
+ },
+ "platform_offset": [
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "Cubicon Style Plus-A15"
+ },
+ "machine_start_gcode": {
+ "default_value": "M911 Style Plus-A15\nM201 X400 Y400\nM202 X400 Y400\nG28 ; Home\nG1 Z15.0 F6000 ;move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0"
+ },
+ "machine_width": {
+ "default_value": 150
+ },
+ "machine_depth": {
+ "default_value": 150
+ },
+ "machine_height": {
+ "default_value": 150
+ },
+ "material_bed_temp_wait":{
+ "default_value": false
+ }
+ }
+}
diff --git a/resources/definitions/dagoma_discoeasy200.def.json b/resources/definitions/dagoma_discoeasy200.def.json
index 89d94ff6b7..30c0abdab2 100644
--- a/resources/definitions/dagoma_discoeasy200.def.json
+++ b/resources/definitions/dagoma_discoeasy200.def.json
@@ -38,7 +38,7 @@
]
},
"gantry_height": {
- "default_value": 10
+ "value": "10"
},
"machine_start_gcode": {
"default_value": ";Gcode by Cura\nG90\nM106 S255\nG28 X Y\nG1 X50\nM109 R90\nG28\nM104 S{material_print_temperature_layer_0}\nG29\nM107\nG1 X100 Y20 F3000\nG1 Z0.5\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E10\nG92 E0\nG1 Z3\nG1 F6000\n"
@@ -52,9 +52,6 @@
"speed_print": {
"default_value": 60
},
- "speed_travel": {
- "default_value": 100
- },
"retraction_amount": {
"default_value": 3.5
},
diff --git a/resources/definitions/dagoma_magis.def.json b/resources/definitions/dagoma_magis.def.json
index 75e6e449cd..dc5a0f86d2 100644
--- a/resources/definitions/dagoma_magis.def.json
+++ b/resources/definitions/dagoma_magis.def.json
@@ -38,7 +38,7 @@
]
},
"gantry_height": {
- "default_value": 0
+ "value": "0"
},
"machine_shape": {
"default_value": "elliptic"
@@ -55,9 +55,6 @@
"speed_print": {
"default_value": 40
},
- "speed_travel": {
- "default_value": 120
- },
"retraction_amount": {
"default_value": 3.8
},
diff --git a/resources/definitions/dagoma_neva.def.json b/resources/definitions/dagoma_neva.def.json
index 67c8795678..43a3e0c4f1 100644
--- a/resources/definitions/dagoma_neva.def.json
+++ b/resources/definitions/dagoma_neva.def.json
@@ -38,7 +38,7 @@
]
},
"gantry_height": {
- "default_value": 0
+ "value": "0"
},
"machine_shape": {
"default_value": "elliptic"
@@ -55,9 +55,6 @@
"speed_print": {
"default_value": 40
},
- "speed_travel": {
- "default_value": 120
- },
"retraction_amount": {
"default_value": 3.8
},
diff --git a/resources/definitions/delta_go.def.json b/resources/definitions/delta_go.def.json
index cd1fb180c2..04f0580898 100644
--- a/resources/definitions/delta_go.def.json
+++ b/resources/definitions/delta_go.def.json
@@ -16,12 +16,8 @@
"overrides": {
"machine_name": { "default_value": "Delta Go" },
"default_material_print_temperature": { "default_value": 210 },
- "speed_travel": { "default_value": 150 },
"prime_tower_size": { "default_value": 8.66 },
"infill_sparse_density": { "default_value": 10 },
- "speed_wall_x": { "default_value": 30 },
- "speed_wall_0": { "default_value": 30 },
- "speed_topbottom": { "default_value": 20 },
"layer_height": { "default_value": 0.15 },
"speed_print": { "default_value": 30 },
"machine_heated_bed": { "default_value": false },
diff --git a/resources/definitions/deltabot.def.json b/resources/definitions/deltabot.def.json
index 95435f659d..ad6a207bb2 100644
--- a/resources/definitions/deltabot.def.json
+++ b/resources/definitions/deltabot.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "Ultimaker",
- "manufacturer": "Danny Lu",
+ "manufacturer": "Custom",
"file_formats": "text/x-gcode",
"platform_offset": [ 0, 0, 0],
"machine_extruder_trains":
@@ -15,15 +15,10 @@
},
"overrides": {
- "speed_travel": { "default_value": 150 },
"prime_tower_size": { "default_value": 8.660254037844387 },
"infill_sparse_density": { "default_value": 10 },
- "speed_wall_x": { "default_value": 30 },
- "speed_wall_0": { "default_value": 30 },
- "speed_topbottom": { "default_value": 30 },
"layer_height": { "default_value": 0.2 },
"speed_print": { "default_value": 30 },
- "speed_infill": { "default_value": 30 },
"machine_extruder_count": { "default_value": 1 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": true },
diff --git a/resources/definitions/deltacomb.def.json b/resources/definitions/deltacomb.def.json
index 8fec0f8950..ac2ea5abe1 100755
--- a/resources/definitions/deltacomb.def.json
+++ b/resources/definitions/deltacomb.def.json
@@ -1,61 +1,67 @@
{
- "version": 2,
- "name": "Deltacomb 3D",
- "inherits": "fdmprinter",
+ "version": 2,
+ "name": "Deltacomb 3D",
+ "inherits": "fdmprinter",
+
"metadata": {
- "author": "Gabriele Rossetti",
- "visible": true,
- "manufacturer": "Deltacomb 3D",
- "category": "Other",
- "file_formats": "text/x-gcode",
- "platform": "deltacomb.stl",
- "has_machine_quality": true,
- "machine_extruder_trains":
- {
- "0": "deltacomb_extruder_0"
- }
+ "author": "Gabriele Rossetti",
+ "visible": true,
+ "manufacturer": "Deltacomb 3D",
+ "category": "Other",
+ "file_formats": "text/x-gcode",
+ "icon": "icon_ultimaker2",
+ "platform": "deltacomb.stl",
+ "has_machine_quality": true,
+ "has_materials": true,
+ "has_variants": true,
+ "variants_name": "Head",
+ "preferred_variant_name": "E3D 0.40mm",
+ "preferred_material": "generic_pla",
+ "preferred_quality_type": "normal",
+ "machine_extruder_trains": { "0": "deltacomb_extruder_0", "1": "deltacomb_extruder_1" }
},
"overrides": {
- "machine_heated_bed": { "default_value": true },
- "machine_width": { "default_value": 190 },
- "machine_height": { "default_value": 250 },
- "machine_depth": { "default_value": 190 },
- "machine_center_is_zero": { "default_value": true },
- "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
- "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home all axes (max endstops)\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."},
- "machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG28 ;Home all axes (max endstops)\nM84 ;steppers off\nG90 ;absolute positioning" },
- "machine_shape": { "default_value": "elliptic" },
- "retraction_hop_enabled": { "default_value": true },
- "retraction_amount" : { "default_value": 3.5 },
- "retraction_speed" : { "default_value": 50 },
- "material_final_print_temperature": { "value": "material_print_temperature - 5" },
- "material_initial_print_temperature": { "value": "material_print_temperature" },
- "material_print_temperature_layer_0": { "value": "material_print_temperature + 5" },
- "material_diameter": { "default_value": 1.75 },
- "travel_avoid_distance": { "default_value": 1, "value": "1" },
- "speed_print" : { "default_value": 70 },
- "speed_travel": { "value": "150.0" },
- "speed_infill": { "value": "round(speed_print * 1.05, 0)" },
- "speed_topbottom": { "value": "round(speed_print * 0.95, 0)" },
- "speed_wall": { "value": "speed_print" },
- "speed_wall_0": { "value": "20" },
- "speed_wall_x": { "value": "speed_wall" },
- "speed_layer_0": { "value": "min(round(speed_print * 0.75, 0), 45.0)" },
- "speed_travel_layer_0": { "value": "round(speed_travel * 0.7, 0)" },
- "skirt_brim_speed": { "value": "speed_layer_0" },
- "skirt_line_count": { "default_value": 3 },
- "skirt_brim_minimal_length": { "default_value": 150 },
- "infill_sparse_density": { "default_value": 90 },
- "gradual_infill_steps": { "default_value": 2 },
- "infill_before_walls" : { "default_value": false },
- "top_bottom_thickness": { "default_value": 0.6 },
- "support_z_distance": { "value": "layer_height * 2" },
- "support_bottom_distance": { "value": "layer_height" },
- "support_use_towers" : { "default_value": false },
- "jerk_wall_0" : { "value": "30" },
- "jerk_travel" : { "default_value": 20 },
- "acceleration_travel" : { "value": 10000 },
- "machine_max_feedrate_z" : { "default_value": 150 }
+ "machine_extruder_count": { "default_value": 1 },
+ "machine_heated_bed": { "default_value": true },
+ "machine_width": { "default_value": 190 },
+ "machine_height": { "default_value": 250 },
+ "machine_depth": { "default_value": 190 },
+ "machine_center_is_zero": { "default_value": true },
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home all axes (max endstops)\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."},
+ "machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG28 ;Home all axes (max endstops)\nM84 ;steppers off\nG90 ;absolute positioning" },
+ "machine_shape": { "default_value": "elliptic" },
+ "retraction_hop_enabled": { "default_value": true },
+ "retraction_hop": { "default_value": 1 },
+ "retraction_amount" : { "default_value": 3.5 },
+ "retraction_speed" : { "default_value": 30 },
+ "retraction_combing" : { "default_value": "noskin" },
+ "travel_avoid_distance": { "value": "1" },
+ "speed_print" : { "default_value": 80 },
+ "speed_infill": { "value": "round(speed_print * 1.05, 0)" },
+ "speed_topbottom": { "value": "round(speed_print * 0.95, 0)" },
+ "speed_wall": { "value": "speed_print" },
+ "speed_wall_0": { "value": "30" },
+ "speed_wall_x": { "value": "speed_wall" },
+ "speed_layer_0": { "value": "min(round(speed_print * 0.75, 0), 45.0)" },
+ "speed_travel": { "value": 150 },
+ "speed_travel_layer_0": { "value": "round(speed_travel * 0.7, 0)" },
+ "skirt_brim_speed": { "value": "speed_layer_0" },
+ "skirt_line_count": { "default_value": 3 },
+ "skirt_brim_minimal_length": { "default_value": 150 },
+ "infill_sparse_density": { "default_value": 30 },
+ "infill_pattern": { "value": "'cubic'" },
+ "infill_before_walls" : { "default_value": false },
+ "top_bottom_thickness": { "default_value": 0.8 },
+ "support_z_distance": { "value": "layer_height * 2" },
+ "support_bottom_distance": { "value": "layer_height" },
+ "support_use_towers" : { "default_value": false },
+ "jerk_enabled": { "value": "True" },
+ "jerk_infill" : { "value": "5" },
+ "jerk_support" : { "value": "5" },
+ "acceleration_enabled": { "value": "1" },
+ "acceleration_travel" : { "value": 5000 },
+ "machine_max_feedrate_z" : { "default_value": 300 }
}
}
diff --git a/resources/definitions/easyarts_ares.def.json b/resources/definitions/easyarts_ares.def.json
index 5655d0a795..18d73a3531 100644
--- a/resources/definitions/easyarts_ares.def.json
+++ b/resources/definitions/easyarts_ares.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "nliaudat",
- "manufacturer": "EasyArts (discontinued)",
+ "manufacturer": "EasyArts",
"file_formats": "text/x-gcode",
"machine_extruder_trains":
{
@@ -49,27 +49,9 @@
"top_bottom_thickness": {
"default_value": 1
},
- "bottom_thickness": {
- "default_value": 1
- },
"speed_print": {
"default_value": 75
},
- "speed_infill": {
- "default_value": 100
- },
- "speed_wall": {
- "default_value": 25
- },
- "speed_topbottom": {
- "default_value": 15
- },
- "speed_travel": {
- "default_value": 150
- },
- "speed_layer_0": {
- "default_value": 30
- },
"support_enable": {
"default_value": true
}
diff --git a/resources/definitions/erzay3d.def.json b/resources/definitions/erzay3d.def.json
new file mode 100644
index 0000000000..875aea708e
--- /dev/null
+++ b/resources/definitions/erzay3d.def.json
@@ -0,0 +1,81 @@
+{
+ "name": "Erzay3D",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Alexander Kirsanov",
+ "manufacturer": "Robokinetika",
+ "category": "Other",
+ "file_formats": "text/x-gcode",
+ "machine_extruder_trains":
+ {
+ "0": "erzay3d_extruder_0"
+ }
+ },
+
+ "overrides": {
+ "machine_start_gcode" : { "default_value": "G28\nG1 Z15.0 F6000\nG92 E0" },
+ "machine_shape": { "default_value": "elliptic"},
+ "machine_name": { "default_value": "Erzay3D" },
+ "machine_depth": { "default_value": 210 },
+ "machine_width": { "default_value": 210 },
+ "machine_height": { "default_value": 230 },
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_center_is_zero": { "default_value": true },
+ "machine_extruder_count": { "default_value": 1 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_heated_bed": { "default_value": true },
+ "material_bed_temp_wait": { "default_value": true },
+ "material_print_temp_wait": { "default_value": true },
+ "material_print_temp_prepend": { "default_value": true },
+ "machine_buildplate_type": { "default_value": "glass" },
+ "machine_nozzle_head_distance": { "default_value": 2.5 },
+ "machine_heat_zone_length": { "default_value": 12.5 },
+ "machine_max_feedrate_x": { "default_value": 200 },
+ "machine_max_feedrate_y": { "default_value": 200 },
+ "machine_max_feedrate_z": { "default_value": 200 },
+ "machine_max_feedrate_e": { "default_value": 50 },
+ "machine_max_acceleration_x": { "default_value": 3000 },
+ "machine_max_acceleration_y": { "default_value": 3000 },
+ "machine_max_acceleration_z": { "default_value": 3000 },
+ "machine_max_acceleration_e": { "default_value": 3000 },
+ "machine_acceleration": { "default_value": 1000 },
+ "machine_max_jerk_xy": { "default_value": 10 },
+ "machine_max_jerk_z": { "default_value": 10 },
+ "machine_max_jerk_e": { "default_value": 10 },
+ "machine_steps_per_mm_x": { "default_value": 1600 },
+ "machine_steps_per_mm_y": { "default_value": 1600 },
+ "machine_steps_per_mm_z": { "default_value": 1600 },
+ "machine_steps_per_mm_e": { "default_value": 174 },
+ "machine_feeder_wheel_diameter": { "default_value": 12 },
+
+ "layer_height": { "default_value": 0.2 },
+ "layer_height_0": { "default_value": 0.2 },
+
+ "ironing_pattern": { "default_value": "concentric" },
+ "ironing_flow": { "default_value": 7.0 },
+
+ "infill_sparse_density": { "default_value": 20 },
+
+ "default_material_print_temperature": { "default_value": 220 },
+ "retraction_amount": { "default_value": 6.5 },
+
+ "speed_print": { "default_value": 40 },
+ "speed_equalize_flow_enabled": { "default_value": true },
+ "speed_equalize_flow_max": { "default_value": 100 },
+
+ "acceleration_print": { "default_value": 1000 },
+
+ "jerk_print": { "default_value": 10 },
+
+ "support_angle": { "default_value": 65 },
+ "support_brim_enable": { "default_value": true },
+
+ "adhesion_type": { "default_value": "skirt" },
+ "brim_outside_only": { "default_value": false },
+
+ "meshfix_maximum_resolution": { "default_value": 0.05 }
+ }
+}
diff --git a/resources/definitions/fabtotum.def.json b/resources/definitions/fabtotum.def.json
index 10c8f68844..355f6a1434 100644
--- a/resources/definitions/fabtotum.def.json
+++ b/resources/definitions/fabtotum.def.json
@@ -28,7 +28,7 @@
"machine_end_gcode": {
"default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-3 X+5 Y+5 F5000 ;move Z up a bit and retract filament even more\n;end of the print\nM84 ;steppers off\nG90 ;absolute positioning\nM300 S2 ;FAB bep bep (end print)"
},
- "gantry_height": { "default_value": 55 },
+ "gantry_height": { "value": "55" },
"machine_width": { "default_value": 214 },
"machine_height": { "default_value": 241.5 },
"machine_depth": { "default_value": 234 },
@@ -50,8 +50,8 @@
"retraction_hop_enabled": { "default_value": false },
"material_final_print_temperature": { "value": "material_print_temperature - 5" },
"material_initial_print_temperature": { "value": "material_print_temperature" },
- "travel_avoid_distance": { "default_value": 1, "value": 1 },
- "speed_travel": { "default_value": 200, "value": 200 },
+ "travel_avoid_distance": { "value": 1 },
+ "speed_travel": { "value": 200 },
"speed_infill": { "value": "round(speed_print * 1.05, 0)" },
"speed_topbottom": { "value": "round(speed_print * 0.95, 0)" },
"speed_wall": { "value": "speed_print" },
diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json
index 0af1e68075..9d1e3c305e 100644
--- a/resources/definitions/fdmextruder.def.json
+++ b/resources/definitions/fdmextruder.def.json
@@ -6,7 +6,7 @@
"type": "extruder",
"author": "Ultimaker",
"manufacturer": "Unknown",
- "setting_version": 1,
+ "setting_version": 11,
"visible": false,
"position": "0"
},
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index 677fbf565d..1c84e99d24 100644
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -7,17 +7,20 @@
"author": "Ultimaker",
"category": "Other",
"manufacturer": "Unknown",
- "setting_version": 1,
+ "setting_version": 11,
"file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g",
"visible": false,
"has_materials": true,
+ "has_variants": false,
+ "has_machine_quality": false,
"preferred_material": "generic_pla",
"preferred_quality_type": "normal",
"machine_extruder_trains":
{
"0": "fdmextruder"
},
- "supports_usb_connection": true
+ "supports_usb_connection": true,
+ "supports_network_connection": false
},
"settings":
{
@@ -203,6 +206,16 @@
"settable_per_extruder": false,
"settable_per_meshgroup": false
},
+ "machine_heated_build_volume":
+ {
+ "label": "Has Build Volume Temperature Stabilization",
+ "description": "Whether the machine is able to stabilize the build volume temperature.",
+ "default_value": false,
+ "type": "bool",
+ "settable_per_mesh": false,
+ "settable_per_extruder": false,
+ "settable_per_meshgroup": false
+ },
"machine_center_is_zero":
{
"label": "Is Center Origin",
@@ -227,7 +240,7 @@
},
"extruders_enabled_count":
{
- "label": "Number of Extruders that are enabled",
+ "label": "Number of Extruders That Are Enabled",
"description": "Number of extruder trains that are enabled; automatically set in software",
"value": "machine_extruder_count",
"default_value": 1,
@@ -240,7 +253,7 @@
},
"machine_nozzle_tip_outer_diameter":
{
- "label": "Outer nozzle diameter",
+ "label": "Outer Nozzle Diameter",
"description": "The outer diameter of the tip of the nozzle.",
"unit": "mm",
"default_value": 1,
@@ -252,7 +265,7 @@
},
"machine_nozzle_head_distance":
{
- "label": "Nozzle length",
+ "label": "Nozzle Length",
"description": "The height difference between the tip of the nozzle and the lowest part of the print head.",
"unit": "mm",
"default_value": 3,
@@ -263,7 +276,7 @@
},
"machine_nozzle_expansion_angle":
{
- "label": "Nozzle angle",
+ "label": "Nozzle Angle",
"description": "The angle between the horizontal plane and the conical part right above the tip of the nozzle.",
"unit": "°",
"type": "int",
@@ -276,7 +289,7 @@
},
"machine_heat_zone_length":
{
- "label": "Heat zone length",
+ "label": "Heat Zone Length",
"description": "The distance from the tip of the nozzle in which heat from the nozzle is transferred to the filament.",
"unit": "mm",
"default_value": 16,
@@ -310,7 +323,7 @@
},
"machine_nozzle_heat_up_speed":
{
- "label": "Heat up speed",
+ "label": "Heat Up Speed",
"description": "The speed (°C/s) by which the nozzle heats up averaged over the window of normal printing temperatures and the standby temperature.",
"default_value": 2.0,
"unit": "°C/s",
@@ -321,7 +334,7 @@
},
"machine_nozzle_cool_down_speed":
{
- "label": "Cool down speed",
+ "label": "Cool Down Speed",
"description": "The speed (°C/s) by which the nozzle cools down averaged over the window of normal printing temperatures and the standby temperature.",
"default_value": 2.0,
"unit": "°C/s",
@@ -343,7 +356,7 @@
},
"machine_gcode_flavor":
{
- "label": "G-code flavour",
+ "label": "G-code Flavor",
"description": "The type of g-code to be generated.",
"type": "enum",
"options":
@@ -374,9 +387,19 @@
"settable_per_extruder": false,
"settable_per_meshgroup": false
},
+ "machine_extruders_share_heater":
+ {
+ "label": "Extruders Share Heater",
+ "description": "Whether the extruders share a single heater rather than each extruder having its own heater.",
+ "type": "bool",
+ "default_value": false,
+ "settable_per_mesh": false,
+ "settable_per_extruder": false,
+ "settable_per_meshgroup": false
+ },
"machine_disallowed_areas":
{
- "label": "Disallowed areas",
+ "label": "Disallowed Areas",
"description": "A list of polygons with areas the print head is not allowed to enter.",
"type": "polygons",
"default_value":
@@ -398,37 +421,9 @@
"settable_per_extruder": false,
"settable_per_meshgroup": false
},
- "machine_head_polygon":
- {
- "label": "Machine head polygon",
- "description": "A 2D silhouette of the print head (fan caps excluded).",
- "type": "polygon",
- "default_value":
- [
- [
- -1,
- 1
- ],
- [
- -1,
- -1
- ],
- [
- 1,
- -1
- ],
- [
- 1,
- 1
- ]
- ],
- "settable_per_mesh": false,
- "settable_per_extruder": false,
- "settable_per_meshgroup": false
- },
"machine_head_with_fans_polygon":
{
- "label": "Machine head & Fan polygon",
+ "label": "Machine Head & Fan Polygon",
"description": "A 2D silhouette of the print head (fan caps included).",
"type": "polygon",
"default_value":
@@ -456,9 +451,10 @@
},
"gantry_height":
{
- "label": "Gantry height",
+ "label": "Gantry Height",
"description": "The height difference between the tip of the nozzle and the gantry system (X and Y axes).",
"default_value": 99999999999,
+ "value": "machine_height",
"type": "float",
"settable_per_mesh": false,
"settable_per_extruder": false,
@@ -487,7 +483,7 @@
},
"machine_use_extruder_offset_to_offset_coords":
{
- "label": "Offset With Extruder",
+ "label": "Offset with Extruder",
"description": "Apply the extruder offset to the coordinate system.",
"type": "bool",
"default_value": true,
@@ -522,7 +518,7 @@
"description": "The maximum speed for the motor of the X-direction.",
"unit": "mm/s",
"type": "float",
- "default_value": 500,
+ "default_value": 299792458000,
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -533,7 +529,7 @@
"description": "The maximum speed for the motor of the Y-direction.",
"unit": "mm/s",
"type": "float",
- "default_value": 500,
+ "default_value": 299792458000,
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -544,7 +540,7 @@
"description": "The maximum speed for the motor of the Z-direction.",
"unit": "mm/s",
"type": "float",
- "default_value": 5,
+ "default_value": 299792458000,
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -890,7 +886,7 @@
"maximum_value_warning": "3 * machine_nozzle_size",
"default_value": 0.4,
"type": "float",
- "enabled": "support_enable",
+ "enabled": "(support_enable or support_tree_enable)",
"value": "line_width",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
@@ -906,7 +902,7 @@
"minimum_value_warning": "0.1 + 0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size",
"type": "float",
- "enabled": "support_enable and support_interface_enable",
+ "enabled": "(support_enable or support_tree_enable) and support_interface_enable",
"limit_to_extruder": "support_interface_extruder_nr",
"value": "line_width",
"settable_per_mesh": false,
@@ -923,7 +919,7 @@
"minimum_value_warning": "0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size",
"type": "float",
- "enabled": "support_enable and support_roof_enable",
+ "enabled": "(support_enable or support_tree_enable) and support_roof_enable",
"limit_to_extruder": "support_roof_extruder_nr",
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_line_width')",
"settable_per_mesh": false,
@@ -939,7 +935,7 @@
"minimum_value_warning": "0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size",
"type": "float",
- "enabled": "support_enable and support_bottom_enable",
+ "enabled": "(support_enable or support_tree_enable) and support_bottom_enable",
"limit_to_extruder": "support_bottom_extruder_nr",
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_line_width')",
"settable_per_mesh": false,
@@ -961,20 +957,20 @@
"maximum_value_warning": "2 * machine_nozzle_size",
"settable_per_mesh": false,
"settable_per_extruder": true
- },
- "initial_layer_line_width_factor":
- {
- "label": "Initial Layer Line Width",
- "description": "Multiplier of the line width on the first layer. Increasing this could improve bed adhesion.",
- "type": "float",
- "unit": "%",
- "default_value": 100.0,
- "minimum_value": "0.001",
- "maximum_value_warning": "150",
- "settable_per_mesh": false,
- "settable_per_extruder": true
}
}
+ },
+ "initial_layer_line_width_factor":
+ {
+ "label": "Initial Layer Line Width",
+ "description": "Multiplier of the line width on the first layer. Increasing this could improve bed adhesion.",
+ "type": "float",
+ "unit": "%",
+ "default_value": 100.0,
+ "minimum_value": "0.001",
+ "maximum_value_warning": "150",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
}
}
},
@@ -1176,6 +1172,18 @@
"value": "999999 if infill_sparse_density == 100 else math.ceil(round(bottom_thickness / resolveOrValue('layer_height'), 4))",
"limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true
+ },
+ "initial_bottom_layers":
+ {
+ "label": "Initial Bottom Layers",
+ "description": "The number of initial bottom layers, from the build-plate upwards. When calculated by the bottom thickness, this value is rounded to a whole number.",
+ "minimum_value": "0",
+ "minimum_value_warning": "2",
+ "default_value": 6,
+ "type": "int",
+ "value": "bottom_layers",
+ "limit_to_extruder": "top_bottom_extruder_nr",
+ "settable_per_mesh": true
}
}
}
@@ -1315,8 +1323,7 @@
"default_value": 0,
"type": "float",
"enabled": "travel_compensate_overlapping_walls_0_enabled or travel_compensate_overlapping_walls_x_enabled",
- "settable_per_mesh": true,
- "settable_per_extruder": false
+ "settable_per_mesh": true
},
"wall_min_flow_retract":
{
@@ -1325,8 +1332,7 @@
"type": "bool",
"default_value": false,
"enabled": "(travel_compensate_overlapping_walls_0_enabled or travel_compensate_overlapping_walls_x_enabled) and wall_min_flow > 0",
- "settable_per_mesh": true,
- "settable_per_extruder": false
+ "settable_per_mesh": true
},
"fill_perimeter_gaps":
{
@@ -1399,41 +1405,66 @@
"limit_to_extruder": "wall_0_extruder_nr",
"settable_per_mesh": true
},
- "z_seam_x":
+ "z_seam_position":
{
- "label": "Z Seam X",
- "description": "The X coordinate of the position near where to start printing each part in a layer.",
- "unit": "mm",
- "type": "float",
- "default_value": 100.0,
- "value": "machine_width / 2",
+ "label": "Z Seam Position",
+ "description": "The position near where to start printing each part in a layer.",
+ "type": "enum",
+ "options":
+ {
+ "backleft": "Back Left",
+ "back": "Back",
+ "backright": "Back Right",
+ "right": "Right",
+ "frontright": "Front Right",
+ "front": "Front",
+ "frontleft": "Front Left",
+ "left": "Left"
+ },
"enabled": "z_seam_type == 'back'",
+ "default_value": "back",
"limit_to_extruder": "wall_0_extruder_nr",
- "settable_per_mesh": true
- },
- "z_seam_y":
- {
- "label": "Z Seam Y",
- "description": "The Y coordinate of the position near where to start printing each part in a layer.",
- "unit": "mm",
- "type": "float",
- "default_value": 100.0,
- "value": "machine_depth * 3",
- "enabled": "z_seam_type == 'back'",
- "limit_to_extruder": "wall_0_extruder_nr",
- "settable_per_mesh": true
+ "settable_per_mesh": true,
+ "children":
+ {
+ "z_seam_x":
+ {
+ "label": "Z Seam X",
+ "description": "The X coordinate of the position near where to start printing each part in a layer.",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 100.0,
+ "value": "(0 if (z_seam_position == 'frontleft' or z_seam_position == 'left' or z_seam_position == 'backleft') else machine_width / 2 if (z_seam_position == 'front' or z_seam_position == 'back') else machine_width) - (machine_width / 2 if z_seam_relative or machine_center_is_zero else 0)",
+ "enabled": "z_seam_type == 'back'",
+ "limit_to_extruder": "wall_0_extruder_nr",
+ "settable_per_mesh": true
+ },
+ "z_seam_y":
+ {
+ "label": "Z Seam Y",
+ "description": "The Y coordinate of the position near where to start printing each part in a layer.",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 100.0,
+ "value": "(0 if (z_seam_position == 'frontleft' or z_seam_position == 'front' or z_seam_position == 'frontright') else machine_depth / 2 if (z_seam_position == 'left' or z_seam_position == 'right') else machine_depth) - (machine_depth / 2 if z_seam_relative or machine_center_is_zero else 0)",
+ "enabled": "z_seam_type == 'back'",
+ "limit_to_extruder": "wall_0_extruder_nr",
+ "settable_per_mesh": true
+ }
+ }
},
"z_seam_corner":
{
"label": "Seam Corner Preference",
- "description": "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner.",
+ "description": "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner. Smart Hiding allows both inside and outside corners, but chooses inside corners more frequently, if appropriate.",
"type": "enum",
"options":
{
- "z_seam_corner_none": "None",
- "z_seam_corner_inner": "Hide Seam",
- "z_seam_corner_outer": "Expose Seam",
- "z_seam_corner_any": "Hide or Expose Seam"
+ "z_seam_corner_none": "None",
+ "z_seam_corner_inner": "Hide Seam",
+ "z_seam_corner_outer": "Expose Seam",
+ "z_seam_corner_any": "Hide or Expose Seam",
+ "z_seam_corner_weighted": "Smart Hiding"
},
"default_value": "z_seam_corner_inner",
"enabled": "z_seam_type != 'random'",
@@ -1453,8 +1484,8 @@
},
"skin_no_small_gaps_heuristic":
{
- "label": "Ignore Small Z Gaps",
- "description": "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting.",
+ "label": "No Skin in Z Gaps",
+ "description": "When the model has small vertical gaps of only a few layers, there should normally be skin around those layers in the narrow space. Enable this setting to not generate skin if the vertical gap is very small. This improves printing time and slicing time, but technically leaves infill exposed to the air.",
"type": "bool",
"default_value": false,
"enabled": "top_layers > 0 or bottom_layers > 0",
@@ -1476,7 +1507,7 @@
"ironing_enabled":
{
"label": "Enable Ironing",
- "description": "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface.",
+ "description": "Go over the top surface one additional time, but this time extruding very little material. This is meant to melt the plastic on top further, creating a smoother surface. The pressure in the nozzle chamber is kept high so that the creases in the surface are filled with material.",
"type": "bool",
"default_value": false,
"limit_to_extruder": "top_bottom_extruder_nr",
@@ -1590,6 +1621,36 @@
"enabled": "resolveOrValue('jerk_enabled') and ironing_enabled",
"limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true
+ },
+ "skin_overlap":
+ {
+ "label": "Skin Overlap Percentage",
+ "description": "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines, as a percentage of the line widths of the skin lines and the innermost wall. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any percentage over 50% may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 5,
+ "minimum_value_warning": "-50",
+ "maximum_value_warning": "100",
+ "value": "5 if top_bottom_pattern != 'concentric' else 0",
+ "enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'",
+ "limit_to_extruder": "top_bottom_extruder_nr",
+ "settable_per_mesh": true,
+ "children":
+ {
+ "skin_overlap_mm":
+ {
+ "label": "Skin Overlap",
+ "description": "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any value over half the width of the wall may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall.",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 0.02,
+ "minimum_value_warning": "-0.5 * machine_nozzle_size",
+ "maximum_value_warning": "machine_nozzle_size",
+ "value": "0.5 * (skin_line_width + (wall_line_width_x if wall_line_count > 1 else wall_line_width_0)) * skin_overlap / 100 if top_bottom_pattern != 'concentric' else 0",
+ "enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'",
+ "settable_per_mesh": true
+ }
+ }
}
}
},
@@ -1722,6 +1783,17 @@
"limit_to_extruder": "infill_extruder_nr",
"settable_per_mesh": true
},
+ "infill_randomize_start_location":
+ {
+ "label": "Randomize Infill Start",
+ "description": "Randomize which infill line is printed first. This prevents one segment becoming the strongest, but it does so at the cost of an additional travel move.",
+ "type": "bool",
+ "default_value": false,
+ "warning_value": "True if infill_pattern not in ('grid', 'triangles', 'trihexagon', 'cubic', 'cubicsubdiv', 'tetrahedral', 'quarter_cubic') else None",
+ "enabled": "not ((infill_pattern == 'cross' and connect_infill_polygons) or infill_pattern == 'concentric')",
+ "limit_to_extruder": "infill_extruder_nr",
+ "settable_per_mesh": true
+ },
"infill_multiplier":
{
"label": "Infill Line Multiplier",
@@ -1789,36 +1861,6 @@
}
}
},
- "skin_overlap":
- {
- "label": "Skin Overlap Percentage",
- "description": "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall.",
- "unit": "%",
- "type": "float",
- "default_value": 5,
- "minimum_value_warning": "-50",
- "maximum_value_warning": "100",
- "value": "5 if top_bottom_pattern != 'concentric' else 0",
- "enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'",
- "limit_to_extruder": "top_bottom_extruder_nr",
- "settable_per_mesh": true,
- "children":
- {
- "skin_overlap_mm":
- {
- "label": "Skin Overlap",
- "description": "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin.",
- "unit": "mm",
- "type": "float",
- "default_value": 0.02,
- "minimum_value_warning": "-0.5 * machine_nozzle_size",
- "maximum_value_warning": "machine_nozzle_size",
- "value": "0.5 * (skin_line_width + (wall_line_width_x if wall_line_count > 1 else wall_line_width_0)) * skin_overlap / 100 if top_bottom_pattern != 'concentric' else 0",
- "enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'",
- "settable_per_mesh": true
- }
- }
- },
"infill_wipe_dist":
{
"label": "Infill Wipe Distance",
@@ -1840,7 +1882,7 @@
"unit": "mm",
"type": "float",
"default_value": 0.1,
- "minimum_value": "resolveOrValue('layer_height') if infill_line_distance > 0 else -999999",
+ "minimum_value": "resolveOrValue('layer_height') / 2 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) if infill_line_distance > 0 else 999999",
"value": "resolveOrValue('layer_height')",
@@ -1924,7 +1966,7 @@
"description": "The largest width of skin areas which are to be removed. Every skin area smaller than this value will disappear. This can help in limiting the amount of time and material spent on printing top/bottom skin at slanted surfaces in the model.",
"unit": "mm",
"type": "float",
- "default_value": 0,
+ "default_value": 1,
"value": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
"minimum_value": "0",
"enabled": "top_layers > 0 or bottom_layers > 0",
@@ -1938,7 +1980,7 @@
"description": "The largest width of top skin areas which are to be removed. Every skin area smaller than this value will disappear. This can help in limiting the amount of time and material spent on printing top skin at slanted surfaces in the model.",
"unit": "mm",
"type": "float",
- "default_value": 0,
+ "default_value": 1,
"value": "skin_preshrink",
"minimum_value": "0",
"enabled": "top_layers > 0 or bottom_layers > 0",
@@ -1951,7 +1993,7 @@
"description": "The largest width of bottom skin areas which are to be removed. Every skin area smaller than this value will disappear. This can help in limiting the amount of time and material spent on printing bottom skin at slanted surfaces in the model.",
"unit": "mm",
"type": "float",
- "default_value": 0,
+ "default_value": 1,
"value": "skin_preshrink",
"minimum_value": "0",
"enabled": "top_layers > 0 or bottom_layers > 0",
@@ -1966,7 +2008,7 @@
"description": "The distance the skins are expanded into the infill. Higher values makes the skin attach better to the infill pattern and makes the walls on neighboring layers adhere better to the skin. Lower values save amount of material used.",
"unit": "mm",
"type": "float",
- "default_value": 2.8,
+ "default_value": 1,
"value": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
"minimum_value": "-skin_preshrink",
"limit_to_extruder": "top_bottom_extruder_nr",
@@ -1980,7 +2022,7 @@
"description": "The distance the top skins are expanded into the infill. Higher values makes the skin attach better to the infill pattern and makes the walls on the layer above adhere better to the skin. Lower values save amount of material used.",
"unit": "mm",
"type": "float",
- "default_value": 2.8,
+ "default_value": 1,
"value": "expand_skins_expand_distance",
"minimum_value": "-top_skin_preshrink",
"enabled": "top_layers > 0 or bottom_layers > 0",
@@ -1993,7 +2035,7 @@
"description": "The distance the bottom skins are expanded into the infill. Higher values makes the skin attach better to the infill pattern and makes the skin adhere better to the walls on the layer below. Lower values save amount of material used.",
"unit": "mm",
"type": "float",
- "default_value": 2.8,
+ "default_value": 1,
"value": "expand_skins_expand_distance",
"minimum_value": "-bottom_skin_preshrink",
"enabled": "top_layers > 0 or bottom_layers > 0",
@@ -2051,11 +2093,26 @@
"default_value": 210,
"minimum_value_warning": "0",
"maximum_value_warning": "285",
- "enabled": "machine_nozzle_temp_enabled",
+ "enabled": false,
"settable_per_extruder": true,
"settable_per_mesh": false,
"minimum_value": "-273.15"
},
+ "build_volume_temperature":
+ {
+ "label": "Build Volume Temperature",
+ "description": "The temperature of the environment to print in. If this is 0, the build volume temperature will not be adjusted.",
+ "unit": "°C",
+ "type": "float",
+ "default_value": 0,
+ "resolve": "min(extruderValues('build_volume_temperature'))",
+ "minimum_value": "-273.15",
+ "minimum_value_warning": "0",
+ "maximum_value_warning": "285",
+ "enabled": "machine_heated_build_volume",
+ "settable_per_mesh": false,
+ "settable_per_extruder": false
+ },
"material_print_temperature":
{
"label": "Printing Temperature",
@@ -2097,7 +2154,7 @@
"minimum_value": "-273.15",
"minimum_value_warning": "material_standby_temperature",
"maximum_value_warning": "material_print_temperature",
- "enabled": "machine_nozzle_temp_enabled",
+ "enabled": "machine_nozzle_temp_enabled and not machine_extruders_share_heater",
"settable_per_mesh": false,
"settable_per_extruder": true
},
@@ -2112,7 +2169,7 @@
"minimum_value": "-273.15",
"minimum_value_warning": "material_standby_temperature",
"maximum_value_warning": "material_print_temperature",
- "enabled": "machine_nozzle_temp_enabled",
+ "enabled": "machine_nozzle_temp_enabled and not machine_extruders_share_heater",
"settable_per_mesh": false,
"settable_per_extruder": true
},
@@ -2139,9 +2196,9 @@
"resolve": "max(extruderValues('default_material_bed_temperature'))",
"default_value": 60,
"minimum_value": "-273.15",
- "minimum_value_warning": "0",
+ "minimum_value_warning": "build_volume_temperature",
"maximum_value_warning": "130",
- "enabled": "machine_heated_bed and machine_gcode_flavor != \"UltiGCode\"",
+ "enabled": false,
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -2156,7 +2213,7 @@
"value": "default_material_bed_temperature",
"resolve": "max(extruderValues('material_bed_temperature'))",
"minimum_value": "-273.15",
- "minimum_value_warning": "0",
+ "minimum_value_warning": "build_volume_temperature",
"maximum_value_warning": "130",
"enabled": "machine_heated_bed and machine_gcode_flavor != \"UltiGCode\"",
"settable_per_mesh": false,
@@ -2173,7 +2230,7 @@
"default_value": 60,
"value": "resolveOrValue('material_bed_temperature')",
"minimum_value": "-273.15",
- "minimum_value_warning": "max(extruderValues('material_bed_temperature'))",
+ "minimum_value_warning": "max(build_volume_temperature, max(extruderValues('material_bed_temperature')))",
"maximum_value_warning": "130",
"enabled": "machine_heated_bed and machine_gcode_flavor != \"UltiGCode\"",
"settable_per_mesh": false,
@@ -2218,6 +2275,121 @@
"settable_per_mesh": false,
"settable_per_extruder": true
},
+ "material_crystallinity":
+ {
+ "label": "Crystalline Material",
+ "description": "Is this material the type that breaks off cleanly when heated (crystalline), or is it the type that produces long intertwined polymer chains (non-crystalline)?",
+ "type": "bool",
+ "default_value": false,
+ "enabled": false,
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "material_anti_ooze_retracted_position":
+ {
+ "label": "Anti-ooze Retracted Position",
+ "description": "How far the material needs to be retracted before it stops oozing.",
+ "type": "float",
+ "unit": "mm",
+ "default_value": -4,
+ "enabled": false,
+ "minimum_value_warning": "-retraction_amount",
+ "maximum_value_warning": "0",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "material_anti_ooze_retraction_speed":
+ {
+ "label": "Anti-ooze Retraction Speed",
+ "description": "How fast the material needs to be retracted during a filament switch to prevent oozing.",
+ "type": "float",
+ "unit": "mm/s",
+ "default_value": 5,
+ "enabled": false,
+ "minimum_value": "0",
+ "maximum_value": "machine_max_feedrate_e",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "material_break_preparation_retracted_position":
+ {
+ "label": "Break Preparation Retracted Position",
+ "description": "How far the filament can be stretched before it breaks, while heated.",
+ "type": "float",
+ "unit": "mm",
+ "default_value": -16,
+ "enabled": false,
+ "minimum_value_warning": "-retraction_amount * 4",
+ "maximum_value_warning": "0",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "material_break_preparation_speed":
+ {
+ "label": "Break Preparation Retraction Speed",
+ "description": "How fast the filament needs to be retracted just before breaking it off in a retraction.",
+ "type": "float",
+ "unit": "mm/s",
+ "default_value": 2,
+ "enabled": false,
+ "minimum_value": "0",
+ "maximum_value": "machine_max_feedrate_e",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "material_break_preparation_temperature":
+ {
+ "label": "Break Preparation Temperature",
+ "description": "The temperature used to purge material, should be roughly equal to the highest possible printing temperature.",
+ "type": "float",
+ "unit": "°C",
+ "default_value": 50,
+ "value": "material_print_temperature",
+ "enabled": false,
+ "minimum_value": "-273.15",
+ "maximum_value_warning": "300",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "material_break_retracted_position":
+ {
+ "label": "Break Retracted Position",
+ "description": "How far to retract the filament in order to break it cleanly.",
+ "type": "float",
+ "unit": "mm",
+ "default_value": -50,
+ "enabled": false,
+ "minimum_value_warning": "-100",
+ "maximum_value_warning": "0",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "material_break_speed":
+ {
+ "label": "Break Retraction Speed",
+ "description": "The speed at which to retract the filament in order to break it cleanly.",
+ "type": "float",
+ "unit": "mm/s",
+ "default_value": 25,
+ "enabled": false,
+ "minimum_value": "0",
+ "maximum_value": "machine_max_feedrate_e",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "material_break_temperature":
+ {
+ "label": "Break Temperature",
+ "description": "The temperature at which the filament is broken for a clean break.",
+ "type": "float",
+ "unit": "°C",
+ "default_value": 50,
+ "enabled": false,
+ "minimum_value": "-273.15",
+ "maximum_value_warning": "300",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
"material_flow":
{
"label": "Flow",
@@ -2229,7 +2401,196 @@
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"enabled": "machine_gcode_flavor != \"UltiGCode\"",
- "settable_per_mesh": true
+ "settable_per_mesh": true,
+ "children":
+ {
+ "wall_material_flow":
+ {
+ "label": "Wall Flow",
+ "description": "Flow compensation on wall lines.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "limit_to_extruder": "wall_0_extruder_nr if wall_x_extruder_nr == wall_0_extruder_nr else -1",
+ "settable_per_mesh": true,
+ "children":
+ {
+ "wall_0_material_flow":
+ {
+ "label": "Outer Wall Flow",
+ "description": "Flow compensation on the outermost wall line.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "wall_material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "limit_to_extruder": "wall_0_extruder_nr",
+ "settable_per_mesh": true
+ },
+ "wall_x_material_flow":
+ {
+ "label": "Inner Wall(s) Flow",
+ "description": "Flow compensation on wall lines for all wall lines except the outermost one.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "wall_material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "limit_to_extruder": "wall_x_extruder_nr",
+ "settable_per_mesh": true
+ }
+ }
+ },
+ "skin_material_flow":
+ {
+ "label": "Top/Bottom Flow",
+ "description": "Flow compensation on top/bottom lines.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "top_layers > 0 or bottom_layers > 0",
+ "limit_to_extruder": "top_bottom_extruder_nr",
+ "settable_per_mesh": true
+ },
+ "roofing_material_flow":
+ {
+ "label": "Top Surface Skin Flow",
+ "description": "Flow compensation on lines of the areas at the top of the print.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "skin_material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "limit_to_extruder": "roofing_extruder_nr",
+ "settable_per_mesh": true,
+ "enabled": "roofing_layer_count > 0 and top_layers > 0"
+ },
+ "infill_material_flow":
+ {
+ "label": "Infill Flow",
+ "description": "Flow compensation on infill lines.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "infill_sparse_density > 0",
+ "limit_to_extruder": "infill_extruder_nr",
+ "settable_per_mesh": true
+ },
+ "skirt_brim_material_flow":
+ {
+ "label": "Skirt/Brim Flow",
+ "description": "Flow compensation on skirt or brim lines.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "resolveOrValue('adhesion_type') == 'skirt' or resolveOrValue('adhesion_type') == 'brim'",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "support_material_flow":
+ {
+ "label": "Support Flow",
+ "description": "Flow compensation on support structure lines.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "support_enable",
+ "limit_to_extruder": "support_infill_extruder_nr",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "support_interface_material_flow":
+ {
+ "label": "Support Interface Flow",
+ "description": "Flow compensation on lines of support roof or floor.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "support_enable and support_interface_enable",
+ "limit_to_extruder": "support_interface_extruder_nr",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "children":
+ {
+ "support_roof_material_flow":
+ {
+ "label": "Support Roof Flow",
+ "description": "Flow compensation on support roof lines.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "extruderValue(support_roof_extruder_nr, 'support_interface_material_flow')",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "support_enable and support_roof_enable",
+ "limit_to_extruder": "support_roof_extruder_nr",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "support_bottom_material_flow":
+ {
+ "label": "Support Floor Flow",
+ "description": "Flow compensation on support floor lines.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "extruderValue(support_bottom_extruder_nr, 'support_interface_material_flow')",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "support_enable and support_bottom_enable",
+ "limit_to_extruder": "support_bottom_extruder_nr",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ }
+ }
+ },
+ "prime_tower_flow":
+ {
+ "label": "Prime Tower Flow",
+ "description": "Flow compensation on prime tower lines.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 100,
+ "value": "material_flow",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ }
+ }
},
"material_flow_layer_0":
{
@@ -2237,7 +2598,6 @@
"description": "Flow compensation for the first layer: the amount of material extruded on the initial layer is multiplied by this value.",
"unit": "%",
"default_value": 100,
- "value": "material_flow",
"type": "float",
"minimum_value": "0.0001",
"minimum_value_warning": "50",
@@ -2349,7 +2709,6 @@
"minimum_value": "0",
"minimum_value_warning": "line_width * 1.5",
"maximum_value_warning": "10",
- "enabled": "retraction_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
},
@@ -2382,10 +2741,10 @@
"limit_support_retractions":
{
"label": "Limit Support Retractions",
- "description": "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure.",
+ "description": "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excessive stringing within the support structure.",
"type": "bool",
"default_value": true,
- "enabled": "retraction_enable and support_enable",
+ "enabled": "retraction_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": false,
"settable_per_extruder": true
},
@@ -2466,6 +2825,19 @@
"settable_per_extruder": true
}
}
+ },
+ "switch_extruder_extra_prime_amount":
+ {
+ "label": "Nozzle Switch Extra Prime Amount",
+ "description": "Extra material to prime after nozzle switching.",
+ "type": "float",
+ "unit": "mm³",
+ "default_value": 0,
+ "minimum_value_warning": "0",
+ "maximum_value_warning": "100",
+ "enabled": "retraction_enable",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
}
}
},
@@ -2590,7 +2962,7 @@
"maximum_value_warning": "150",
"default_value": 60,
"value": "speed_print",
- "enabled": "support_enable",
+ "enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false,
"limit_to_extruder": "support_extruder_nr",
"settable_per_extruder": true,
@@ -2607,7 +2979,7 @@
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "150",
"value": "speed_support",
- "enabled": "support_enable",
+ "enabled": "support_enable or support_tree_enable",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -2622,7 +2994,7 @@
"minimum_value": "0.1",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "150",
- "enabled": "support_interface_enable and support_enable",
+ "enabled": "support_interface_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_interface_extruder_nr",
"value": "speed_support / 1.5",
"settable_per_mesh": false,
@@ -2639,7 +3011,7 @@
"minimum_value": "0.1",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "150",
- "enabled": "support_roof_enable and support_enable",
+ "enabled": "support_roof_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_roof_extruder_nr",
"value": "extruderValue(support_roof_extruder_nr, 'speed_support_interface')",
"settable_per_mesh": false,
@@ -2655,7 +3027,7 @@
"minimum_value": "0.1",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "150",
- "enabled": "support_bottom_enable and support_enable",
+ "enabled": "support_bottom_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_bottom_extruder_nr",
"value": "extruderValue(support_bottom_extruder_nr, 'speed_support_interface')",
"settable_per_mesh": false,
@@ -2750,21 +3122,21 @@
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "300",
"value": "speed_layer_0",
- "enabled": "resolveOrValue('adhesion_type') == 'skirt' or resolveOrValue('adhesion_type') == 'brim'",
+ "enabled": "resolveOrValue('adhesion_type') == 'skirt' or resolveOrValue('adhesion_type') == 'brim' or resolveOrValue('draft_shield_enabled') or resolveOrValue('ooze_shield_enabled')",
"settable_per_mesh": false,
"settable_per_extruder": true,
"limit_to_extruder": "adhesion_extruder_nr"
},
- "max_feedrate_z_override":
+ "speed_z_hop":
{
- "label": "Maximum Z Speed",
- "description": "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed.",
+ "label": "Z Hop Speed",
+ "description": "The speed at which the vertical Z movement is made for Z Hops. This is typically lower than the print speed since the build plate or machine's gantry is harder to move.",
"unit": "mm/s",
"type": "float",
- "default_value": 0,
+ "default_value": 10,
"minimum_value": "0",
- "maximum_value": "299792458000",
- "maximum_value_warning": "machine_max_feedrate_z",
+ "maximum_value": "machine_max_feedrate_z",
+ "enabled": "retraction_enable and retraction_hop_enabled",
"settable_per_mesh": false,
"settable_per_extruder": true
},
@@ -2901,7 +3273,6 @@
"default_value": 3000,
"value": "acceleration_topbottom",
"enabled": "resolveOrValue('acceleration_enabled') and roofing_layer_count > 0 and top_layers > 0",
- "enabled": "top_layers > 0 or bottom_layers > 0",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true
},
@@ -2931,7 +3302,7 @@
"maximum_value_warning": "10000",
"default_value": 3000,
"value": "acceleration_print",
- "enabled": "resolveOrValue('acceleration_enabled') and support_enable",
+ "enabled": "resolveOrValue('acceleration_enabled') and (support_enable or support_tree_enable)",
"settable_per_mesh": false,
"limit_to_extruder": "support_extruder_nr",
"settable_per_extruder": true,
@@ -2948,7 +3319,7 @@
"minimum_value": "0.1",
"minimum_value_warning": "100",
"maximum_value_warning": "10000",
- "enabled": "resolveOrValue('acceleration_enabled') and support_enable",
+ "enabled": "resolveOrValue('acceleration_enabled') and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -2964,7 +3335,7 @@
"minimum_value": "0.1",
"minimum_value_warning": "100",
"maximum_value_warning": "10000",
- "enabled": "resolveOrValue('acceleration_enabled') and support_interface_enable and support_enable",
+ "enabled": "resolveOrValue('acceleration_enabled') and support_interface_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_interface_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true,
@@ -2981,7 +3352,7 @@
"minimum_value": "0.1",
"minimum_value_warning": "100",
"maximum_value_warning": "10000",
- "enabled": "acceleration_enabled and support_roof_enable and support_enable",
+ "enabled": "acceleration_enabled and support_roof_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_roof_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -2997,7 +3368,7 @@
"minimum_value": "0.1",
"minimum_value_warning": "100",
"maximum_value_warning": "10000",
- "enabled": "acceleration_enabled and support_bottom_enable and support_enable",
+ "enabled": "acceleration_enabled and support_bottom_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_bottom_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -3093,7 +3464,7 @@
"minimum_value": "0.1",
"minimum_value_warning": "100",
"maximum_value_warning": "10000",
- "enabled": "resolveOrValue('acceleration_enabled')",
+ "enabled": "resolveOrValue('acceleration_enabled') and (resolveOrValue('adhesion_type') == 'skirt' or resolveOrValue('adhesion_type') == 'brim' or resolveOrValue('draft_shield_enabled') or resolveOrValue('ooze_shield_enabled'))",
"settable_per_mesh": false,
"limit_to_extruder": "adhesion_extruder_nr"
},
@@ -3216,7 +3587,7 @@
"maximum_value_warning": "50",
"default_value": 20,
"value": "jerk_print",
- "enabled": "resolveOrValue('jerk_enabled') and support_enable",
+ "enabled": "resolveOrValue('jerk_enabled') and (support_enable or support_tree_enable)",
"settable_per_mesh": false,
"settable_per_extruder": true,
"limit_to_extruder": "support_extruder_nr",
@@ -3232,7 +3603,7 @@
"value": "jerk_support",
"minimum_value": "0",
"maximum_value_warning": "50",
- "enabled": "resolveOrValue('jerk_enabled') and support_enable",
+ "enabled": "resolveOrValue('jerk_enabled') and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -3247,7 +3618,7 @@
"value": "jerk_support",
"minimum_value": "0",
"maximum_value_warning": "50",
- "enabled": "resolveOrValue('jerk_enabled') and support_interface_enable and support_enable",
+ "enabled": "resolveOrValue('jerk_enabled') and support_interface_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_interface_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true,
@@ -3263,7 +3634,7 @@
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
"minimum_value": "0",
"maximum_value_warning": "50",
- "enabled": "resolveOrValue('jerk_enabled') and support_roof_enable and support_enable",
+ "enabled": "resolveOrValue('jerk_enabled') and support_roof_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_roof_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -3278,7 +3649,7 @@
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
"minimum_value": "0",
"maximum_value_warning": "50",
- "enabled": "resolveOrValue('jerk_enabled') and support_bottom_enable and support_enable",
+ "enabled": "resolveOrValue('jerk_enabled') and support_bottom_enable and (support_enable or support_tree_enable)",
"limit_to_extruder": "support_bottom_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -3368,7 +3739,7 @@
"minimum_value": "0",
"maximum_value_warning": "50",
"value": "jerk_layer_0",
- "enabled": "resolveOrValue('jerk_enabled')",
+ "enabled": "resolveOrValue('jerk_enabled') and (resolveOrValue('adhesion_type') == 'skirt' or resolveOrValue('adhesion_type') == 'brim' or resolveOrValue('draft_shield_enabled') or resolveOrValue('ooze_shield_enabled'))",
"settable_per_mesh": false,
"limit_to_extruder": "adhesion_extruder_nr"
}
@@ -3456,17 +3827,6 @@
"settable_per_mesh": false,
"settable_per_extruder": true
},
- "start_layers_at_same_position":
- {
- "label": "Start Layers with the Same Part",
- "description": "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time.",
- "type": "bool",
- "default_value": false,
- "enabled": false,
- "settable_per_mesh": false,
- "settable_per_extruder": false,
- "settable_per_meshgroup": true
- },
"layer_start_x":
{
"label": "Layer Start X",
@@ -3529,6 +3889,20 @@
"enabled": "retraction_hop_enabled and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": true
+ },
+ "retraction_hop_after_extruder_switch_height":
+ {
+ "label": "Z Hop After Extruder Switch Height",
+ "description": "The height difference when performing a Z Hop after extruder switch.",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 1,
+ "value": "retraction_hop",
+ "minimum_value_warning": "0",
+ "maximum_value_warning": "10",
+ "enabled": "retraction_enable and retraction_hop_after_extruder_switch and extruders_enabled_count > 1",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
}
}
},
@@ -3704,7 +4078,7 @@
"description": "The extruder train to use for printing the support. This is used in multi-extrusion.",
"type": "extruder",
"default_value": "0",
- "value": "defaultExtruderPosition()",
+ "value": "int(defaultExtruderPosition())",
"enabled": "(support_enable or support_tree_enable) and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false,
@@ -3842,7 +4216,7 @@
"type": "bool",
"default_value": false,
"value": "support_pattern == 'cross' or support_pattern == 'gyroid'",
- "enabled": "support_pattern == 'grid' or support_pattern == 'triangles' or support_pattern == 'cross' or support_pattern == 'gyroid'",
+ "enabled": "(support_enable or support_tree_enable) and (support_pattern == 'grid' or support_pattern == 'triangles' or support_pattern == 'cross' or support_pattern == 'gyroid')",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -3906,16 +4280,14 @@
}
}
},
- "support_infill_angle":
+ "support_infill_angles":
{
- "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",
+ "label": "Support Infill Line Directions",
+ "description": "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angle 0 degrees.",
+ "type": "[int]",
+ "default_value": "[ ]",
+ "enabled": "(support_enable or support_tree_enable) and support_pattern != 'concentric' and support_infill_rate > 0",
+ "limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
},
@@ -3939,7 +4311,7 @@
"default_value": 8.0,
"minimum_value": "0.0",
"maximum_value_warning": "50.0",
- "enabled": "support_enable",
+ "enabled": "(support_enable or support_tree_enable) and support_brim_enable",
"settable_per_mesh": false,
"settable_per_extruder": true,
"limit_to_extruder": "support_infill_extruder_nr",
@@ -3954,7 +4326,7 @@
"minimum_value": "0",
"maximum_value_warning": "50 / skirt_brim_line_width",
"value": "math.ceil(support_brim_width / (skirt_brim_line_width * initial_layer_line_width_factor / 100.0))",
- "enabled": "support_enable",
+ "enabled": "(support_enable or support_tree_enable) and support_brim_enable",
"settable_per_mesh": false,
"settable_per_extruder": true,
"limit_to_extruder": "support_infill_extruder_nr"
@@ -4040,6 +4412,7 @@
"unit": "mm",
"type": "float",
"minimum_value": "0",
+ "minimum_value_warning": "support_xy_distance - support_line_width * 2",
"maximum_value_warning": "support_xy_distance",
"default_value": 0.2,
"value": "machine_nozzle_size / 2",
@@ -4076,7 +4449,7 @@
"support_join_distance":
{
"label": "Support Join Distance",
- "description": "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one.",
+ "description": "The maximum distance between support structures in the X/Y directions. When separate structures are closer together than this value, the structures merge into one.",
"unit": "mm",
"type": "float",
"default_value": 2.0,
@@ -4092,7 +4465,7 @@
"description": "Amount of offset applied to all support polygons in each layer. Positive values can smooth out the support areas and result in more sturdy support.",
"unit": "mm",
"type": "float",
- "default_value": 0.2,
+ "default_value": 0,
"limit_to_extruder": "support_infill_extruder_nr",
"minimum_value_warning": "-1 * machine_nozzle_size",
"maximum_value_warning": "10 * machine_nozzle_size",
@@ -4243,7 +4616,7 @@
"minimum_value": "0",
"maximum_value_warning": "support_interface_height",
"limit_to_extruder": "support_interface_extruder_nr",
- "enabled": "support_interface_enable and support_enable",
+ "enabled": "support_interface_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": true
},
"support_interface_density":
@@ -4394,21 +4767,21 @@
"minimum_interface_area":
{
"label": "Minimum Support Interface Area",
- "description": "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will not be generated.",
+ "description": "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will be printed as normal support.",
"unit": "mm²",
"type": "float",
"default_value": 1.0,
"minimum_value": "0",
"minimum_value_warning": "minimum_support_area",
"limit_to_extruder": "support_interface_extruder_nr",
- "enabled": "support_interface_enable and support_enable",
+ "enabled": "support_interface_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": true,
"children":
{
"minimum_roof_area":
{
"label": "Minimum Support Roof Area",
- "description": "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will not be generated.",
+ "description": "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will be printed as normal support.",
"unit": "mm²",
"type": "float",
"default_value": 1.0,
@@ -4416,13 +4789,13 @@
"minimum_value": "0",
"minimum_value_warning": "minimum_support_area",
"limit_to_extruder": "support_roof_extruder_nr",
- "enabled": "support_roof_enable and support_enable",
+ "enabled": "support_roof_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": true
},
"minimum_bottom_area":
{
"label": "Minimum Support Floor Area",
- "description": "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will not be generated.",
+ "description": "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will be printed as normal support.",
"unit": "mm²",
"type": "float",
"default_value": 1.0,
@@ -4430,7 +4803,7 @@
"minimum_value": "0",
"minimum_value_warning": "minimum_support_area",
"limit_to_extruder": "support_bottom_extruder_nr",
- "enabled": "support_bottom_enable and support_enable",
+ "enabled": "support_bottom_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": true
}
}
@@ -4479,13 +4852,51 @@
}
}
},
+ "support_interface_angles":
+ {
+ "label": "Support Interface Line Directions",
+ "description": "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees).",
+ "type": "[int]",
+ "default_value": "[ ]",
+ "limit_to_extruder": "support_interface_extruder_nr",
+ "enabled": "(support_enable or support_tree_enable) and support_interface_enable and support_interface_pattern != 'concentric'",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "children":
+ {
+ "support_roof_angles":
+ {
+ "label": "Support Roof Line Directions",
+ "description": "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees).",
+ "type": "[int]",
+ "default_value": "[ ]",
+ "value": "support_interface_angles",
+ "limit_to_extruder": "support_roof_extruder_nr",
+ "enabled": "(support_enable or support_tree_enable) and support_roof_enable and support_roof_pattern != 'concentric'",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "support_bottom_angles":
+ {
+ "label": "Support Floor Line Directions",
+ "description": "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees).",
+ "type": "[int]",
+ "default_value": "[ ]",
+ "value": "support_interface_angles",
+ "limit_to_extruder": "support_bottom_extruder_nr",
+ "enabled": "(support_enable or support_tree_enable) and support_bottom_enable and support_bottom_pattern != 'concentric'",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ }
+ }
+ },
"support_fan_enable":
{
"label": "Fan Speed Override",
"description": "When enabled, the print cooling fan speed is altered for the skin regions immediately above the support.",
"type": "bool",
"default_value": false,
- "enabled": "support_enable",
+ "enabled": "support_enable or support_tree_enable",
"settable_per_mesh": false
},
"support_supported_skin_fan_speed":
@@ -4497,7 +4908,7 @@
"maximum_value": "100",
"default_value": 100,
"type": "float",
- "enabled": "support_enable and support_fan_enable",
+ "enabled": "(support_enable or support_tree_enable) and support_fan_enable",
"settable_per_mesh": false
},
"support_use_towers":
@@ -4524,10 +4935,10 @@
"enabled": "support_enable and support_use_towers",
"settable_per_mesh": true
},
- "support_minimal_diameter":
+ "support_tower_maximum_supported_diameter":
{
- "label": "Minimum Diameter",
- "description": "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.",
+ "label": "Maximum Tower-Supported Diameter",
+ "description": "Maximum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.",
"unit": "mm",
"type": "float",
"default_value": 3.0,
@@ -4579,11 +4990,11 @@
"label": "Enable Prime Blob",
"description": "Whether to prime the filament with a blob before printing. Turning this setting on will ensure that the extruder will have material ready at the nozzle before printing. Printing Brim or Skirt can act like priming too, in which case turning this setting off saves some time.",
"type": "bool",
- "resolve": "any(extruderValues('prime_blob_enable'))",
- "default_value": true,
+ "default_value": false,
"settable_per_mesh": false,
"settable_per_extruder": true,
- "enabled": false
+ "enabled": false,
+ "warning_value": "True if resolveOrValue('print_sequence') == 'one_at_a_time' else None"
},
"extruder_prime_pos_x":
{
@@ -4634,7 +5045,7 @@
"description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.",
"type": "extruder",
"default_value": "0",
- "value": "defaultExtruderPosition()",
+ "value": "int(defaultExtruderPosition())",
"enabled": "extruders_enabled_count > 1 and (resolveOrValue('adhesion_type') != 'none' or resolveOrValue('prime_tower_brim_enable'))",
"settable_per_mesh": false,
"settable_per_extruder": false
@@ -4719,7 +5130,7 @@
"description": "Enforce brim to be printed around the model even if that space would otherwise be occupied by support. This replaces some regions of the first layer of support by brim regions.",
"type": "bool",
"default_value": true,
- "enabled": "resolveOrValue('adhesion_type') == 'brim' and support_enable",
+ "enabled": "resolveOrValue('adhesion_type') == 'brim' and (support_enable or support_tree_enable)",
"settable_per_mesh": false,
"settable_per_extruder": true,
"limit_to_extruder": "support_infill_extruder_nr"
@@ -5221,18 +5632,7 @@
"type": "bool",
"enabled": "extruders_enabled_count > 1",
"default_value": false,
- "resolve": "any(extruderValues('prime_tower_enable'))",
- "settable_per_mesh": false,
- "settable_per_extruder": false
- },
- "prime_tower_circular":
- {
- "label": "Circular Prime Tower",
- "description": "Make the prime tower as a circular shape.",
- "type": "bool",
- "enabled": "resolveOrValue('prime_tower_enable')",
- "default_value": true,
- "resolve": "any(extruderValues('prime_tower_circular'))",
+ "resolve": "(extruders_enabled_count > 1) and any(extruderValues('prime_tower_enable'))",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -5260,7 +5660,7 @@
"type": "float",
"default_value": 6,
"minimum_value": "0",
- "maximum_value_warning": "((resolveOrValue('prime_tower_size') * 0.5) ** 2 * 3.14159 * resolveOrValue('layer_height') if prime_tower_circular else resolveOrValue('prime_tower_size') ** 2 * resolveOrValue('layer_height')) - sum(extruderValues('prime_tower_min_volume')) + prime_tower_min_volume",
+ "maximum_value_warning": "(resolveOrValue('prime_tower_size') * 0.5) ** 2 * 3.14159 * resolveOrValue('layer_height')",
"enabled": "resolveOrValue('prime_tower_enable')",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -5273,7 +5673,7 @@
"unit": "mm",
"enabled": "resolveOrValue('prime_tower_enable')",
"default_value": 200,
- "value": "machine_width - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' or (prime_tower_brim_enable and adhesion_type != 'raft') else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enable') else 0) - 1",
+ "value": "machine_width - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' or (prime_tower_brim_enable and adhesion_type != 'raft') else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - 1",
"maximum_value": "machine_width / 2 if machine_center_is_zero else machine_width",
"minimum_value": "resolveOrValue('prime_tower_size') - machine_width / 2 if machine_center_is_zero else resolveOrValue('prime_tower_size')",
"settable_per_mesh": false,
@@ -5287,27 +5687,12 @@
"unit": "mm",
"enabled": "resolveOrValue('prime_tower_enable')",
"default_value": 200,
- "value": "machine_depth - prime_tower_size - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' or (prime_tower_brim_enable and adhesion_type != 'raft') else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enable') else 0) - 1",
+ "value": "machine_depth - prime_tower_size - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' or (prime_tower_brim_enable and adhesion_type != 'raft') else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - 1",
"maximum_value": "machine_depth / 2 - resolveOrValue('prime_tower_size') if machine_center_is_zero else machine_depth - resolveOrValue('prime_tower_size')",
"minimum_value": "machine_depth / -2 if machine_center_is_zero else 0",
"settable_per_mesh": false,
"settable_per_extruder": false
},
- "prime_tower_flow":
- {
- "label": "Prime Tower Flow",
- "description": "Flow compensation: the amount of material extruded is multiplied by this value.",
- "type": "float",
- "unit": "%",
- "enabled": "resolveOrValue('prime_tower_enable')",
- "default_value": 100,
- "value": "material_flow",
- "minimum_value": "0.0001",
- "minimum_value_warning": "50",
- "maximum_value_warning": "150",
- "settable_per_mesh": false,
- "settable_per_extruder": true
- },
"prime_tower_wipe_enabled":
{
"label": "Wipe Inactive Nozzle on Prime Tower",
@@ -5324,6 +5709,7 @@
"description": "Prime-towers might need the extra adhesion afforded by a brim even if the model doesn't. Presently can't be used with the 'Raft' adhesion-type.",
"type": "bool",
"enabled": "resolveOrValue('prime_tower_enable') and (resolveOrValue('adhesion_type') != 'raft')",
+ "resolve": "resolveOrValue('prime_tower_enable') and (resolveOrValue('adhesion_type') in ('none', 'skirt'))",
"default_value": false,
"settable_per_mesh": false,
"settable_per_extruder": false
@@ -5450,9 +5836,47 @@
"description": "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle.",
"type": "bool",
"default_value": true,
- "enabled": "not support_enable",
+ "enabled": "not (support_enable or support_tree_enable)",
"settable_per_mesh": false,
"settable_per_extruder": false
+ },
+ "meshfix_maximum_resolution":
+ {
+ "label": "Maximum Resolution",
+ "description": "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway.",
+ "type": "float",
+ "unit": "mm",
+ "default_value": 0.5,
+ "minimum_value": "0.001",
+ "minimum_value_warning": "0.01",
+ "maximum_value_warning": "3",
+ "settable_per_mesh": true
+ },
+ "meshfix_maximum_travel_resolution":
+ {
+ "label": "Maximum Travel Resolution",
+ "description": "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate.",
+ "type": "float",
+ "unit": "mm",
+ "default_value": 1.0,
+ "value": "min(meshfix_maximum_resolution * speed_travel / speed_print, 2 * line_width)",
+ "minimum_value": "0.001",
+ "minimum_value_warning": "0.05",
+ "maximum_value_warning": "10",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "meshfix_maximum_deviation":
+ {
+ "label": "Maximum Deviation",
+ "description": "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution, so if the two conflict the Maximum Deviation will always be held true.",
+ "type": "float",
+ "unit": "mm",
+ "default_value": 0.05,
+ "minimum_value": "0.001",
+ "minimum_value_warning": "0.01",
+ "maximum_value_warning": "0.3",
+ "settable_per_mesh": true
}
}
},
@@ -5610,7 +6034,7 @@
"smooth_spiralized_contours":
{
"label": "Smooth Spiralized Contours",
- "description": "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details.",
+ "description": "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details.",
"type": "bool",
"default_value": true,
"enabled": "magic_spiralize",
@@ -5812,6 +6236,7 @@
"label": "Infill Travel Optimization",
"description": "When enabled, the order in which the infill lines are printed is optimized to reduce the distance travelled. The reduction in travel time achieved very much depends on the model being sliced, infill pattern, density, etc. Note that, for some models that have many small areas of infill, the time to slice the model may be greatly increased.",
"type": "bool",
+ "enabled": "resolveOrValue('retraction_combing') != 'off'",
"default_value": false,
"settable_per_mesh": true
},
@@ -5843,38 +6268,12 @@
"unit": "mm",
"type": "float",
"default_value": 1.0,
- "minimum_value": "0.001",
+ "minimum_value": "0",
"minimum_value_warning": "0.05",
"maximum_value_warning": "1.0",
"settable_per_mesh": true,
"settable_per_extruder": false
},
- "meshfix_maximum_resolution":
- {
- "label": "Maximum Resolution",
- "description": "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway.",
- "type": "float",
- "unit": "mm",
- "default_value": 0.01,
- "minimum_value": "0.001",
- "minimum_value_warning": "0.005",
- "maximum_value_warning": "0.1",
- "settable_per_mesh": true
- },
- "meshfix_maximum_travel_resolution":
- {
- "label": "Maximum Travel Resolution",
- "description": "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate.",
- "type": "float",
- "unit": "mm",
- "default_value": 0.02,
- "value": "meshfix_maximum_resolution * speed_travel / speed_print",
- "minimum_value": "0.001",
- "minimum_value_warning": "0.005",
- "maximum_value_warning": "1",
- "settable_per_mesh": false,
- "settable_per_extruder": true
- },
"support_skip_some_zags":
{
"label": "Break Up Support In Chunks",
@@ -6037,16 +6436,6 @@
"settable_per_mesh": false,
"settable_per_extruder": true
},
- "skin_alternate_rotation":
- {
- "label": "Alternate Skin Rotation",
- "description": "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions.",
- "type": "bool",
- "default_value": false,
- "enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'",
- "limit_to_extruder": "top_bottom_extruder_nr",
- "settable_per_mesh": true
- },
"cross_infill_pocket_size":
{
"label": "Cross 3D Pocket Size",
@@ -6171,7 +6560,7 @@
"support_conical_enabled":
{
"label": "Enable Conical Support",
- "description": "Experimental feature: Make support areas smaller at the bottom than at the overhang.",
+ "description": "Make support areas smaller at the bottom than at the overhang.",
"type": "bool",
"default_value": false,
"enabled": "support_enable",
@@ -6203,7 +6592,7 @@
"minimum_value_warning": "machine_nozzle_size * 3",
"maximum_value_warning": "100.0",
"type": "float",
- "enabled": "support_conical_enabled and support_enable",
+ "enabled": "support_conical_enabled and support_enable and support_conical_angle > 0",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": true
},
@@ -6264,30 +6653,26 @@
},
"flow_rate_max_extrusion_offset":
{
- "label": "Flow rate compensation max extrusion offset",
- "description": "The maximum distance in mm to compensate.",
+ "label": "Flow Rate Compensation Max Extrusion Offset",
+ "description": "The maximum distance in mm to move the filament to compensate for changes in flow rate.",
"unit": "mm",
"type": "float",
"minimum_value": "0",
"maximum_value_warning": "10",
"default_value": 0,
- "value": "0",
- "enabled": true,
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
},
"flow_rate_extrusion_offset_factor":
{
- "label": "Flow rate compensation factor",
- "description": "The multiplication factor for the flow rate -> distance translation.",
+ "label": "Flow Rate Compensation Factor",
+ "description": "How far to move the filament in order to compensate for changes in flow rate, as a percentage of how far the filament would move in one second of extrusion.",
"unit": "%",
"type": "float",
"minimum_value": "0",
"maximum_value_warning": "100",
"default_value": 100,
- "value": "100",
- "enabled": true,
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -6310,7 +6695,7 @@
"unit": "mm",
"default_value": 3,
"value": "machine_nozzle_head_distance",
- "minimum_value": "0.0001",
+ "minimum_value": "0.001",
"maximum_value_warning": "20",
"enabled": "wireframe_enabled",
"settable_per_mesh": false,
@@ -6340,8 +6725,8 @@
"unit": "mm/s",
"type": "float",
"default_value": 5,
- "minimum_value": "0.1",
- "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + max(max_feedrate_z_override, machine_max_feedrate_z) ** 2)",
+ "minimum_value": "0.05",
+ "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + machine_max_feedrate_z ** 2)",
"maximum_value_warning": "50",
"enabled": "wireframe_enabled",
"settable_per_mesh": false,
@@ -6356,11 +6741,11 @@
"unit": "mm/s",
"type": "float",
"default_value": 5,
- "minimum_value": "0.1",
+ "minimum_value": "0.05",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "50",
"enabled": "wireframe_enabled",
- "value": "wireframe_printspeed",
+ "value": "wireframe_printspeed_flat",
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -6372,8 +6757,8 @@
"unit": "mm/s",
"type": "float",
"default_value": 5,
- "minimum_value": "0.1",
- "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + max(max_feedrate_z_override, machine_max_feedrate_z) ** 2)",
+ "minimum_value": "0.05",
+ "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + machine_max_feedrate_z ** 2)",
"maximum_value_warning": "50",
"enabled": "wireframe_enabled",
"value": "wireframe_printspeed",
@@ -6388,8 +6773,8 @@
"unit": "mm/s",
"type": "float",
"default_value": 5,
- "minimum_value": "0.1",
- "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + max(max_feedrate_z_override, machine_max_feedrate_z) ** 2)",
+ "minimum_value": "0.05",
+ "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + machine_max_feedrate_z ** 2)",
"maximum_value_warning": "50",
"enabled": "wireframe_enabled",
"value": "wireframe_printspeed",
@@ -6404,7 +6789,7 @@
"unit": "mm/s",
"type": "float",
"default_value": 5,
- "minimum_value": "0.1",
+ "minimum_value": "0.05",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "100",
"value": "wireframe_printspeed",
@@ -6527,7 +6912,7 @@
"default_value": 0.6,
"minimum_value": "0",
"maximum_value_warning": "2.0",
- "enabled": "wireframe_enabled",
+ "enabled": "wireframe_enabled and wireframe_strategy == 'knot'",
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -6541,7 +6926,7 @@
"default_value": 0.5,
"minimum_value": "0",
"maximum_value_warning": "wireframe_height",
- "enabled": "wireframe_enabled",
+ "enabled": "wireframe_enabled and wireframe_strategy == 'compensate'",
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -6555,7 +6940,7 @@
"default_value": 0.6,
"minimum_value": "0",
"maximum_value_warning": "wireframe_height",
- "enabled": "wireframe_enabled",
+ "enabled": "wireframe_enabled and wireframe_strategy == 'compensate'",
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -6649,7 +7034,7 @@
},
"adaptive_layer_height_enabled":
{
- "label": "Use adaptive layers",
+ "label": "Use Adaptive Layers",
"description": "Adaptive layers computes the layer heights depending on the shape of the model.",
"type": "bool",
"default_value": false,
@@ -6659,7 +7044,7 @@
},
"adaptive_layer_height_variation":
{
- "label": "Adaptive layers maximum variation",
+ "label": "Adaptive Layers Maximum Variation",
"description": "The maximum allowed height different from the base layer height.",
"type": "float",
"enabled": "adaptive_layer_height_enabled",
@@ -6671,23 +7056,25 @@
},
"adaptive_layer_height_variation_step":
{
- "label": "Adaptive layers variation step size",
+ "label": "Adaptive Layers Variation Step Size",
"description": "The difference in height of the next layer height compared to the previous one.",
"type": "float",
"enabled": "adaptive_layer_height_enabled",
"default_value": 0.01,
"unit": "mm",
"settable_per_mesh": false,
+ "minimum_value": "0.001",
"settable_per_extruder": false,
"settable_per_meshgroup": false
},
"adaptive_layer_height_threshold":
{
- "label": "Adaptive layers threshold",
- "description": "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer.",
+ "label": "Adaptive Layers Topography Size",
+ "description": "Target horizontal distance between two adjacent layers. Reducing this setting causes thinner layers to be used to bring the edges of the layers closer together.",
"type": "float",
"enabled": "adaptive_layer_height_enabled",
- "default_value": 200.0,
+ "default_value": 0.2,
+ "unit": "mm",
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -6695,7 +7082,7 @@
"wall_overhang_angle":
{
"label": "Overhanging Wall Angle",
- "description": "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging.",
+ "description": "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging. Overhang that gets supported by support will not be treated as overhang either.",
"unit": "°",
"type": "float",
"minimum_value": "0",
@@ -6749,6 +7136,17 @@
"enabled": "bridge_settings_enabled",
"settable_per_mesh": true
},
+ "bridge_sparse_infill_max_density":
+ {
+ "label": "Bridge Sparse Infill Max Density",
+ "description": "Maximum density of infill considered to be sparse. Skin over sparse infill is considered to be unsupported and so may be treated as a bridge skin.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 0,
+ "minimum_value": "0",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
"bridge_wall_coast":
{
"label": "Bridge Wall Coasting",
@@ -6954,44 +7352,303 @@
"type": "float",
"enabled": "bridge_settings_enabled and bridge_enable_more_layers",
"settable_per_mesh": true
+ },
+ "clean_between_layers":
+ {
+ "label": "Wipe Nozzle Between Layers",
+ "description": "Whether to include nozzle wipe G-Code between layers. Enabling this setting could influence behavior of retract at layer change. Please use Wipe Retraction settings to control retraction at layers where the wipe script will be working.",
+ "default_value": false,
+ "type": "bool",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "max_extrusion_before_wipe":
+ {
+ "label": "Material Volume Between Wipes",
+ "description": "Maximum material, that can be extruded before another nozzle wipe is initiated.",
+ "default_value": 10,
+ "type": "float",
+ "unit": "mm³",
+ "enabled": "clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "wipe_retraction_enable":
+ {
+ "label": "Wipe Retraction Enable",
+ "description": "Retract the filament when the nozzle is moving over a non-printed area.",
+ "type": "bool",
+ "default_value": true,
+ "value": "retraction_enable",
+ "enabled": "clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "wipe_retraction_amount":
+ {
+ "label": "Wipe Retraction Distance",
+ "description": "Amount to retract the filament so it does not ooze during the wipe sequence.",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 1,
+ "value": "retraction_amount",
+ "minimum_value_warning": "-0.0001",
+ "maximum_value_warning": "10.0",
+ "enabled": "wipe_retraction_enable and clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "wipe_retraction_extra_prime_amount":
+ {
+ "label": "Wipe Retraction Extra Prime Amount",
+ "description": "Some material can ooze away during a wipe travel moves, which can be compensated for here.",
+ "unit": "mm³",
+ "type": "float",
+ "default_value": 0,
+ "value": "retraction_extra_prime_amount",
+ "minimum_value_warning": "-0.0001",
+ "maximum_value_warning": "10.0",
+ "enabled": "wipe_retraction_enable and clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "wipe_retraction_speed":
+ {
+ "label": "Wipe Retraction Speed",
+ "description": "The speed at which the filament is retracted and primed during a wipe retraction move.",
+ "unit": "mm/s",
+ "type": "float",
+ "default_value": 5,
+ "value": "retraction_speed",
+ "minimum_value": "0",
+ "minimum_value_warning": "1",
+ "maximum_value": "machine_max_feedrate_e",
+ "maximum_value_warning": "70",
+ "enabled": "wipe_retraction_enable and clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "children":
+ {
+ "wipe_retraction_retract_speed":
+ {
+ "label": "Wipe Retraction Retract Speed",
+ "description": "The speed at which the filament is retracted during a wipe retraction move.",
+ "unit": "mm/s",
+ "type": "float",
+ "default_value": 3,
+ "minimum_value": "0",
+ "maximum_value": "machine_max_feedrate_e",
+ "minimum_value_warning": "1",
+ "maximum_value_warning": "70",
+ "enabled": "wipe_retraction_enable and clean_between_layers",
+ "value": "wipe_retraction_speed",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "wipe_retraction_prime_speed":
+ {
+ "label": "Wipe Retraction Prime Speed",
+ "description": "The speed at which the filament is primed during a wipe retraction move.",
+ "unit": "mm/s",
+ "type": "float",
+ "default_value": 2,
+ "minimum_value": "0",
+ "maximum_value": "machine_max_feedrate_e",
+ "minimum_value_warning": "1",
+ "maximum_value_warning": "70",
+ "enabled": "wipe_retraction_enable and clean_between_layers",
+ "value": "wipe_retraction_speed",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ }
+ }
+ },
+ "wipe_pause":
+ {
+ "label": "Wipe Pause",
+ "description": "Pause after the unretract.",
+ "unit": "s",
+ "type": "float",
+ "default_value": 0,
+ "minimum_value": "0",
+ "enabled": "clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "wipe_hop_enable":
+ {
+ "label": "Wipe Z Hop",
+ "description": "When wiping, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate.",
+ "type": "bool",
+ "default_value": true,
+ "value": "retraction_hop_enabled",
+ "enabled": "clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "wipe_hop_amount":
+ {
+ "label": "Wipe Z Hop Height",
+ "description": "The height difference when performing a Z Hop.",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 1,
+ "value": "retraction_hop",
+ "enabled": "wipe_hop_enable and clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "wipe_hop_speed":
+ {
+ "label": "Wipe Hop Speed",
+ "description": "Speed to move the z-axis during the hop.",
+ "unit": "mm/s",
+ "type": "float",
+ "default_value": 10,
+ "value": "speed_z_hop",
+ "minimum_value": "0",
+ "minimum_value_warning": "1",
+ "enabled": "wipe_hop_enable and clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "wipe_brush_pos_x":
+ {
+ "label": "Wipe Brush X Position",
+ "description": "X location where wipe script will start.",
+ "type": "float",
+ "unit": "mm",
+ "default_value": 100,
+ "minimum_value_warning": "0",
+ "enabled": "clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "wipe_repeat_count":
+ {
+ "label": "Wipe Repeat Count",
+ "description": "Number of times to move the nozzle across the brush.",
+ "type": "int",
+ "minimum_value": "0",
+ "default_value": 5,
+ "enabled": "clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "wipe_move_distance":
+ {
+ "label": "Wipe Move Distance",
+ "description": "The distance to move the head back and forth across the brush.",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 20,
+ "enabled": "clean_between_layers",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true,
+ "settable_per_meshgroup": false
+ },
+ "small_hole_max_size":
+ {
+ "label": "Small Hole Max Size",
+ "description": "Holes and part outlines with a diameter smaller than this will be printed using Small Feature Speed.",
+ "unit": "mm",
+ "type": "float",
+ "minimum_value": "0",
+ "default_value": 0,
+ "settable_per_mesh": true,
+ "children":
+ {
+ "small_feature_max_length":
+ {
+ "label": "Small Feature Max Length",
+ "description": "Feature outlines that are shorter than this length will be printed using Small Feature Speed.",
+ "unit": "mm",
+ "type": "float",
+ "minimum_value": "0",
+ "default_value": 0,
+ "value": "small_hole_max_size * math.pi",
+ "settable_per_mesh": true
+ }
+ }
+ },
+ "small_feature_speed_factor":
+ {
+ "label": "Small Feature Speed",
+ "description": "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 50,
+ "minimum_value": "1",
+ "minimum_value_warning": "25",
+ "maximum_value": "100",
+ "settable_per_mesh": true
+ },
+ "small_feature_speed_factor_0":
+ {
+ "label": "Small Feature Initial Layer Speed",
+ "description": "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy.",
+ "unit": "%",
+ "type": "float",
+ "default_value": 50,
+ "value": "small_feature_speed_factor",
+ "minimum_value": "1",
+ "minimum_value_warning": "25",
+ "maximum_value": "100",
+ "settable_per_mesh": true
}
}
},
- "command_line_settings": {
+ "command_line_settings":
+ {
"label": "Command Line Settings",
"description": "Settings which are only used if CuraEngine isn't called from the Cura frontend.",
"type": "category",
"enabled": false,
"children": {
- "center_object": {
+ "center_object":
+ {
"description": "Whether to center the object on the middle of the build platform (0,0), instead of using the coordinate system in which the object was saved.",
"type": "bool",
"label": "Center Object",
"default_value": false,
"enabled": false
},
- "mesh_position_x": {
+ "mesh_position_x":
+ {
"description": "Offset applied to the object in the x direction.",
"type": "float",
"label": "Mesh Position X",
"default_value": 0,
"enabled": false
},
- "mesh_position_y": {
+ "mesh_position_y":
+ {
"description": "Offset applied to the object in the y direction.",
"type": "float",
"label": "Mesh Position Y",
"default_value": 0,
"enabled": false
},
- "mesh_position_z": {
+ "mesh_position_z":
+ {
"description": "Offset applied to the object in the z direction. With this you can perform what was used to be called 'Object Sink'.",
"type": "float",
"label": "Mesh Position Z",
"default_value": 0,
"enabled": false
},
- "mesh_rotation_matrix": {
+ "mesh_rotation_matrix":
+ {
"label": "Mesh Rotation Matrix",
"description": "Transformation matrix to be applied to the model when loading it from file.",
"type": "str",
diff --git a/resources/definitions/felixpro2dual.def.json b/resources/definitions/felixpro2dual.def.json
new file mode 100644
index 0000000000..fdd8a1b694
--- /dev/null
+++ b/resources/definitions/felixpro2dual.def.json
@@ -0,0 +1,71 @@
+{
+ "version": 2,
+ "name": "Felix Pro 2 Dual",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "pnks",
+ "manufacturer": "Felix",
+ "platform": "FelixPro2_platform.obj",
+ "platform_offset": [-135, -0.5, 130],
+ "machine_extruder_trains":
+ {
+ "0": "felixpro2_dual_extruder_0",
+ "1": "felixpro2_dual_extruder_1"
+ },
+ "file_formats": "text/x-gcode",
+ "has_variants": true,
+ "has_materials": true,
+ "preferred_variant_name": "0.35 mm",
+ "variants_name": "Nozzle diameter"
+ },
+ "overrides": {
+ "machine_name": { "default_value": "FelixPro2Dual" },
+
+ "layer_height": { "default_value": 0.15 },
+ "layer_height_0": { "default_value": 0.2 },
+
+ "infill_sparse_density": { "default_value": 20 },
+ "wall_thickness": { "default_value": 1 },
+ "top_bottom_thickness": { "default_value": 1 },
+
+ "machine_width": { "default_value": 240 },
+ "machine_depth": { "default_value": 225 },
+ "machine_height": { "default_value": 245 },
+
+ "machine_head_with_fans_polygon":
+ {
+ "default_value": [
+ [ -60, 50 ],
+ [ -60, -50 ],
+ [ 70, 50 ],
+ [ 70, -50 ]
+ ]
+ },
+ "gantry_height": { "value": "0" },
+ "machine_extruder_count": { "default_value": 2 },
+ "prime_tower_position_x": { "value": "250" },
+ "prime_tower_position_y": { "value": "200" },
+
+ "machine_heated_bed": { "default_value": true },
+ "machine_gcode_flavor": { "default_value": "Repetier" },
+ "machine_center_is_zero": { "default_value": false },
+
+ "speed_print": { "default_value": 80 },
+
+ "retraction_amount": { "default_value": 1 },
+ "retraction_speed": { "default_value": 50},
+ "material_flow": { "default_value": 100 },
+ "material_flow_layer_0": { "default_value" : 110, "value": "material_flow * 1.1" },
+ "adhesion_type": { "default_value": "skirt" },
+ "skirt_brim_minimal_length": { "default_value": 130 },
+ "skirt_line_count": { "default_value": 3 },
+
+ "machine_start_gcode": {
+ "default_value": "G90 ;absolute positioning\r\nM82 ;set extruder to absolute mode\r\nM107 ;start with the fan off\r\nG28 X0 Y0 ;move X\/Y to min endstops\r\nG28 Z0 ;move Z to min endstops\r\nG1 Z15.0 F9000 ;move the platform down 15mm\r\n\r\nT0 ;Switch to the 1st extruder\r\nG92 E0 ;zero the extruded length\r\nG1 F200 E6 ;extrude 6 mm of feed stock\r\nG92 E0 ;zero the extruded length again\r\n;G1 F9000\r\nM117 FPro2 printing...\r\n"
+ },
+ "machine_end_gcode": {
+ "default_value": "; Endcode FELIXprinters Pro series\r\n; =================================\t; Move extruder to park position\r\nG91 \t\t\t\t\t; Make coordinates relative\r\nG1 Z2 F5000 \t\t\t\t; Move z 2mm up\r\nG90 \t\t\t\t\t; Use absolute coordinates again\t\t\r\nG1 X220 Y243 F7800 \t\t\t; Move bed and printhead to ergonomic position\r\n\r\n; =================================\t; Turn off heaters\r\nT0\t\t\t\t\t; Select left extruder\r\nM104 T0 S0\t\t\t\t; Turn off heater and continue\t\t\t\t\r\nG92 E0\t\t\t\t\t; Reset extruder position\r\nG1 E-8\t\t\t\t\t; Retract filament 8mm\r\nG1 E-5\t\t\t\t\t; Push back filament 3mm\r\nG92 E0\t\t\t\t\t; Reset extruder position\r\n\r\nT1\t\t\t\t\t; Select right extruder\r\nM104 T1 S0\t\t\t\t; Turn off heater and continu\r\nG92 E0\t\t\t\t\t; Reset extruder position\r\nG1 E-8\t\t\t\t\t; Retract filament 8mm\r\nG1 E-5\t\t\t\t\t; Push back filament 3mm\r\nG92 E0\t\t\t\t\t; Reset extruder position\r\nT0\t\t\t\t\t; Select left extruder\r\nM140 S0\t\t\t\t\t; Turn off bed heater\r\n\r\n; =================================\t; Turn the rest off\r\nM107 \t\t\t\t; Turn off fan\r\nM84\t\t\t\t\t; Disable steppers\r\nM117 Print Complete"
+ }
+ }
+}
diff --git a/resources/definitions/felixtec4dual.def.json b/resources/definitions/felixtec4dual.def.json
index ba612d4e3c..efc13c1759 100644
--- a/resources/definitions/felixtec4dual.def.json
+++ b/resources/definitions/felixtec4dual.def.json
@@ -39,19 +39,18 @@
"machine_center_is_zero": { "default_value": false },
"speed_print": { "default_value": 60 },
- "speed_travel": { "default_value": 200 },
"retraction_amount": { "default_value": 1 },
"retraction_speed": { "default_value": 50},
- "material_flow": { "default_value": 87 },
+ "material_flow": { "default_value": 95 },
"adhesion_type": { "default_value": "skirt" },
"skirt_brim_minimal_length": { "default_value": 130},
- "machine_start_gcode": {
- "default_value": "; FELIXprinters | www.FELIXprinters.com | Zeemanlaan 15 3401 MV IJsselstein The Netherlands\n; FELIX Tec 4 | Start Code Dual Extruders v1.0\n; Modified by kerog777@gmail.com\n;================================ \n;Initializing\nM80 ; Turn on the power supply\nM107 ; Turn off fans\nM117 Heating up\nM104 T0 S120\nM104 T1 S120\nM140 S{print_bed_temperature} ; Heatup Bed and continue\nG28 ; Home all\nM109 T0 S{print_temperature} ; Heatup hot-end and continue\nM117 Purging\nT0 ; Select extruder 1\nG92 E0 ; Reset extruder\nG1 X10.0 Y1.1 Z5.0 F15240 ; Move to start-line position\nG1 Z0.3 F15240 ; Move z up\nG1 X127.0 Y1.1 Z0.3 F1500.0 E15 ; Purge 1st line\nG92 E0 ; Reset extruder\n\n;================================ ; Initializing done\nM117 FELIXprinting"
+ "machine_start_gcode": {
+ "default_value": "; FELIXprinters | www.FELIXprinters.com | Zeemanlaan 15 3401 MV IJsselstein The Netherlands\n; FELIX Tec 4 | Start Code Dual Extruders v1.0\n; Modified by kerog777@gmail.com\n;================================ \n;Initializing\nM80 ; Turn on the power supply\nM107 ; Turn off fans\nM117 Heating up\nM190 S{material_bed_temperature} ; Heatup Bed\nM104 T0 S120\nM104 T1 S120\nG28 ; Home all\nM109 T0 S{material_print_temperature_layer_0} ; Heatup hot-end\nM117 Purging\nT0 ; Select extruder 1\nG92 E0 ; Reset extruder\nG1 X10.0 Y1.1 Z5.0 F15240 ; Move to start-line position\nG1 Z0.3 F15240 ; Move z up\nG1 X127.0 Y1.1 Z0.3 F1500.0 E15 ; Purge 1st line\nG92 E0 ; Reset extruder\n\n;================================ ; Initializing done\nM117 FELIXprinting"
},
"machine_end_gcode": {
- "default_value": "; FELIXprinters End Code Tec Series v1.0\n; Modified by kerog777@gmail.com\n; ================================= \n; Move extruder to park position\nG91 ; Make coordinates relative\nG1 Z2 F1000 ; Move z 2mm up\nG90 ; Use absolute coordinates again\n G1 X0 Y0 F15240 ; Move bed and printhead to ergonomic position\n\n; ================================= ; Turn off heaters\nM140 S0 ; Turn off bed heater\nT0 ; Select left extruder\nM104 T0 S0 ; Turn off heater and continue\n G92 E0 ; Reset extruder position\nG1 E-6 ; Retract filament 8mm\nG92 E0 ; Reset extruder position\nT1 ; Select right extruder\nM104 T1 S0 ; Turn off heater and continue\nG92 E0 ; Reset extruder position\nG1 E-6 ; Retract filament 8mm\nG92 E0 ; Reset extruder position\nT0 ; Select left extruder\n\n; ================================= ; Turn the rest off\nM107 ; Turn off fan\nM84 ; Disable steppers\nM117 Finished Printing!"
+ "default_value": "; FELIXprinters End Code Tec Series v1.0\n; Modified by kerog777@gmail.com\n; ================================= \n; Move extruder to park position\nG91 ; Make coordinates relative\nG1 Z2 F1000 ; Move z 2mm up\nG90 ; Use absolute coordinates again\nG1 X0 Y0 F15240 ; Move bed and printhead to ergonomic position\n\n; ================================= ; Turn off heaters\nM140 S0 ; Turn off bed heater\nT0 ; Select left extruder\nM104 T0 S0 ; Turn off heater and continue\nG92 E0 ; Reset extruder position\nG1 E-6 ; Retract filament 8mm\nG92 E0 ; Reset extruder position\nT1 ; Select right extruder\nM104 T1 S0 ; Turn off heater and continue\nG92 E0 ; Reset extruder position\nG1 E-6 ; Retract filament 8mm\nG92 E0 ; Reset extruder position\nT0 ; Select left extruder\n\n; ================================= ; Turn the rest off\nM107 ; Turn off fan\nM84 ; Disable steppers\nM117 Finished Printing!"
}
}
}
diff --git a/resources/definitions/flsun_qq.def.json b/resources/definitions/flsun_qq.def.json
new file mode 100644
index 0000000000..02b3849c12
--- /dev/null
+++ b/resources/definitions/flsun_qq.def.json
@@ -0,0 +1,46 @@
+{
+ "version": 2,
+ "name": "FLSUN QQ",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "manufacturer": "FLSUN",
+ "author": "Daniel Green",
+ "file_formats": "text/x-gcode",
+ "machine_extruder_trains": {
+ "0": "flsun_qq_extruder"
+ }
+ },
+ "overrides": {
+ "machine_extruder_count": {
+ "default_value": 1
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "machine_width": {
+ "default_value": 260
+ },
+ "machine_height": {
+ "default_value": 285
+ },
+ "machine_depth": {
+ "default_value": 260
+ },
+ "machine_center_is_zero": {
+ "default_value": true
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "machine_start_gcode": {
+ "default_value": "G28 ;Home\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0"
+ },
+ "machine_end_gcode": {
+ "default_value": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84"
+ },
+ "machine_shape": {
+ "default_value": "elliptic"
+ }
+ }
+}
diff --git a/resources/definitions/flsun_qq_s.def.json b/resources/definitions/flsun_qq_s.def.json
new file mode 100644
index 0000000000..9c3bf571ae
--- /dev/null
+++ b/resources/definitions/flsun_qq_s.def.json
@@ -0,0 +1,71 @@
+{
+ "version": 2,
+ "name": "FLSUN QQ-S",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Cataldo URSO",
+ "manufacturer": "FLSUN",
+ "file_formats": "text/x-gcode",
+ "has_materials": true,
+ "preferred_quality_type": "draft",
+ "machine_extruder_trains": {
+ "0": "flsun_qq_s_extruder_0"
+ }
+ },
+ "overrides": {
+ "machine_center_is_zero": {
+ "default_value": true
+ },
+ "machine_shape": {
+ "default_value": "elliptic"
+ },
+ "machine_width": {
+ "default_value": 260
+ },
+ "machine_depth": {
+ "default_value": 260
+ },
+ "machine_height": {
+ "default_value": 370
+ },
+ "z_seam_type": {
+ "default_value": "back"
+ },
+ "gantry_height": {
+ "value": "0"
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "machine_start_gcode": {
+ "default_value": "G21\nG90\nM82\nM107 T0\nM190 S{material_bed_temperature}\nM109 S{material_print_temperature} T0\nG28\nG92 E0\nG0 E3 F200\nG92 E0\n"
+ },
+ "machine_end_gcode": {
+ "default_value": "M107 T0\nM104 S0\nM104 S0 T1\nM140 S0\nG92 E0\nG91\nG1 E-1 F300 \nG1 Z+0.5 E-5 X-20 Y-20 F9000\nG28 X0 Y0\nM84 ;steppers off\nG90 ;absolute positioning\n"
+ },
+ "infill_sparse_density": {
+ "default_value": 10
+ },
+ "machine_head_with_fans_polygon": {
+ "default_value": [
+ [0, 0],
+ [0, 0],
+ [0, 0],
+ [0, 0]
+ ]
+ },
+ "retraction_enable": {
+ "default_value": true
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "machine_gcode_flavor": {
+ "default_value": "Repetier"
+ }
+ }
+}
diff --git a/resources/definitions/folgertech_FT-5.def.json b/resources/definitions/folgertech_FT-5.def.json
index d3d00a9b25..7ede40a025 100644
--- a/resources/definitions/folgertech_FT-5.def.json
+++ b/resources/definitions/folgertech_FT-5.def.json
@@ -18,7 +18,7 @@
"machine_width": { "default_value": 300 },
"machine_height": { "default_value": 400 },
"machine_depth": { "default_value": 300 },
- "gantry_height": { "default_value": 55 },
+ "gantry_height": { "value": "55" },
"machine_start_gcode": {
"default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."
diff --git a/resources/definitions/geeetech_a30.def.json b/resources/definitions/geeetech_a30.def.json
new file mode 100644
index 0000000000..1f08d37445
--- /dev/null
+++ b/resources/definitions/geeetech_a30.def.json
@@ -0,0 +1,113 @@
+{
+ "version": 2,
+ "name": "Geeetech A30",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "author": "William & Cataldo URSO",
+ "manufacturer": "Shenzhen Geeetech Technology",
+ "file_formats": "text/x-gcode",
+ "visible": true,
+ "has_materials": true,
+ "preferred_quality_type": "draft",
+ "machine_extruder_trains": {
+ "0": "geeetech_a30_extruder_0"
+ }
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "Geeetech A30"
+ },
+ "machine_start_gcode": {
+ "default_value": "G28 ;Home\nM190 S{material_bed_temperature}\nM109 S{material_print_temperature} T0\nG1 Z15.0 F6000 ;Move the platform down 15mm\nG92 E0\nG1 F200 E3\nG92 E0"
+ },
+ "machine_end_gcode": {
+ "default_value": "M104 S0;Cooling the heat end\nM140 S0;Cooling the heat bed\nG92 E1\nG1 E-1 F300\nG28 X0 Y0;Home X axis and Y axis\nM84"
+ },
+ "machine_width": {
+ "default_value": 320
+ },
+ "machine_height": {
+ "default_value": 420
+ },
+ "machine_depth": {
+ "default_value": 320
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "machine_center_is_zero": {
+ "default_value": false
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "layer_height": {
+ "default_value": 0.1
+ },
+ "layer_height_0": {
+ "default_value": 0.3
+ },
+ "retraction_amount": {
+ "default_value": 2
+ },
+ "retraction_speed": {
+ "default_value": 25
+ },
+ "adhesion_type": {
+ "default_value": "skirt"
+ },
+ "machine_head_with_fans_polygon": {
+ "default_value": [
+ [-75, 35],
+ [18, 35],
+ [18, -18],
+ [-75, -18]
+ ]
+ },
+ "gantry_height": {
+ "value": "55"
+ },
+ "machine_max_feedrate_x": {
+ "default_value": 300
+ },
+ "machine_max_feedrate_y": {
+ "default_value": 300
+ },
+ "machine_max_feedrate_z": {
+ "default_value": 7
+ },
+ "machine_max_feedrate_e": {
+ "default_value": 50
+ },
+ "machine_max_acceleration_x": {
+ "default_value": 2000
+ },
+ "machine_max_acceleration_y": {
+ "default_value": 2000
+ },
+ "machine_max_acceleration_z": {
+ "default_value": 100
+ },
+ "machine_max_acceleration_e": {
+ "default_value": 10000
+ },
+ "machine_acceleration": {
+ "default_value": 2000
+ },
+ "machine_max_jerk_xy": {
+ "default_value": 10
+ },
+ "machine_max_jerk_z": {
+ "default_value": 1
+ },
+ "machine_max_jerk_e": {
+ "default_value": 5
+ },
+ "machine_gcode_flavor": {
+ "default_value": "Repetier"
+ }
+ }
+}
diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json
index 069b8be999..e98d6c02fe 100644
--- a/resources/definitions/gmax15plus.def.json
+++ b/resources/definitions/gmax15plus.def.json
@@ -1,5 +1,4 @@
{
- "id": "gmax15plus",
"version": 2,
"name": "gMax 1.5 Plus",
"inherits": "fdmprinter",
@@ -37,9 +36,8 @@
"retraction_amount": { "default_value": 1 },
"retraction_speed": { "default_value": 70},
"adhesion_type": { "default_value": "skirt" },
- "gantry_height": { "default_value": 50 },
+ "gantry_height": { "value": "50" },
"speed_print": { "default_value": 50 },
- "speed_travel": { "default_value": 70 },
"machine_max_acceleration_x": { "default_value": 600 },
"machine_max_acceleration_y": { "default_value": 600 },
"machine_max_acceleration_z": { "default_value": 30 },
@@ -50,9 +48,7 @@
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} ; Preheat\nM109 S{material_print_temperature} ; Preheat\nG91 ;relative positioning\nG90 ;absolute positioning\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." },
"machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" },
- "material_print_temperature": { "default_value": 202 },
"wall_thickness": { "default_value": 1 },
- "top_bottom_thickness": { "default_value": 1 },
- "bottom_thickness": { "default_value": 1 }
+ "top_bottom_thickness": { "default_value": 1 }
}
}
diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json
index 0264ef5977..aaba2cc55b 100644
--- a/resources/definitions/gmax15plus_dual.def.json
+++ b/resources/definitions/gmax15plus_dual.def.json
@@ -1,5 +1,4 @@
{
- "id": "gmax15plus_dual",
"version": 2,
"name": "gMax 1.5 Plus Dual Extruder",
"inherits": "fdmprinter",
@@ -35,9 +34,8 @@
"retraction_amount": { "default_value": 1 },
"retraction_speed": { "default_value": 70},
"adhesion_type": { "default_value": "skirt" },
- "gantry_height": { "default_value": 50 },
+ "gantry_height": { "value": "50" },
"speed_print": { "default_value": 50 },
- "speed_travel": { "default_value": 70 },
"machine_max_acceleration_x": { "default_value": 600 },
"machine_max_acceleration_y": { "default_value": 600 },
"machine_max_acceleration_z": { "default_value": 30 },
@@ -48,9 +46,7 @@
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} T0 ; Preheat Left Extruder\nM104 S{material_print_temperature} T1 ; Preheat Right Extruder\nM109 S{material_print_temperature} T0 ; Preheat Left Extruder\nM109 S{material_print_temperature} T1 ; Preheat Right Extruder\nG91 ;relative positioning\nG90 ;absolute positioning\nM218 T1 X34.3 Y0; Set 2nd extruder offset. This can be changed later if needed\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." },
"machine_end_gcode": { "default_value": "M104 S0 T0;Left extruder off\nM104 S0 T1; Right extruder off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" },
- "material_print_temperature": { "default_value": 202 },
"wall_thickness": { "default_value": 1 },
- "top_bottom_thickness": { "default_value": 1 },
- "bottom_thickness": { "default_value": 1 }
+ "top_bottom_thickness": { "default_value": 1 }
}
}
diff --git a/resources/definitions/grr_neo.def.json b/resources/definitions/grr_neo.def.json
index 67d6a92023..774a3e614c 100644
--- a/resources/definitions/grr_neo.def.json
+++ b/resources/definitions/grr_neo.def.json
@@ -28,7 +28,7 @@
"machine_center_is_zero": {
"default_value": false
},
- "machine_head_polygon": {
+ "machine_head_with_fans_polygon": {
"default_value": [
[-75, -18],
[-75, 35],
@@ -37,7 +37,7 @@
]
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/hellbot_adonis.def.json b/resources/definitions/hellbot_adonis.def.json
new file mode 100644
index 0000000000..a73c66a611
--- /dev/null
+++ b/resources/definitions/hellbot_adonis.def.json
@@ -0,0 +1,32 @@
+{
+ "version": 2,
+ "name": "Hellbot Adonis",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "MUX team",
+ "manufacturer": "Hellbot",
+ "file_formats": "text/x-gcode",
+ "platform": "hellbot_adonis.obj",
+ "platform_texture": "hellbot.png",
+ "platform_offset": [0, -1, 0],
+ "has_materials": true,
+ "machine_extruder_trains": {
+ "0": "hellbot_adonis_extruder"
+ }
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "Hellbot Adonis"
+ },
+ "machine_width": {
+ "default_value": 160
+ },
+ "machine_depth": {
+ "default_value": 160
+ },
+ "machine_height": {
+ "default_value": 160
+ }
+ }
+}
diff --git a/resources/definitions/hellbot_magna_I.def.json b/resources/definitions/hellbot_magna_I.def.json
new file mode 100644
index 0000000000..453dcef718
--- /dev/null
+++ b/resources/definitions/hellbot_magna_I.def.json
@@ -0,0 +1,32 @@
+{
+ "version": 2,
+ "name": "Hellbot Magna 1",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "MUX team",
+ "manufacturer": "Hellbot",
+ "file_formats": "text/x-gcode",
+ "platform": "hellbot_magna.obj",
+ "platform_texture": "hellbot.png",
+ "platform_offset": [0, -1, 0],
+ "has_materials": true,
+ "machine_extruder_trains": {
+ "0": "hellbot_magna_i_extruder"
+ }
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "Hellbot Magna 1"
+ },
+ "machine_width": {
+ "default_value": 220
+ },
+ "machine_depth": {
+ "default_value": 220
+ },
+ "machine_height": {
+ "default_value": 260
+ }
+ }
+}
diff --git a/resources/definitions/hellbot_magna_dual.def.json b/resources/definitions/hellbot_magna_dual.def.json
new file mode 100644
index 0000000000..5ee36e0749
--- /dev/null
+++ b/resources/definitions/hellbot_magna_dual.def.json
@@ -0,0 +1,36 @@
+{
+ "version": 2,
+ "name": "Hellbot Magna DUAL",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "MUX team",
+ "manufacturer": "Hellbot",
+ "file_formats": "text/x-gcode",
+ "platform": "hellbot_magna.obj",
+ "platform_texture": "hellbot.png",
+ "platform_offset": [0, -1, 0],
+ "has_materials": true,
+ "machine_extruder_trains": {
+ "0": "hellbot_magna_dual_extruder_1",
+ "1": "hellbot_magna_dual_extruder_2"
+ }
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "Hellbot Magna DUAL"
+ },
+ "machine_width": {
+ "default_value": 220
+ },
+ "machine_depth": {
+ "default_value": 220
+ },
+ "machine_height": {
+ "default_value": 260
+ },
+ "machine_extruder_count": {
+ "default_value": 2
+ }
+ }
+}
diff --git a/resources/definitions/helloBEEprusa.def.json b/resources/definitions/helloBEEprusa.def.json
index 65716ac175..2c8c4839d0 100644
--- a/resources/definitions/helloBEEprusa.def.json
+++ b/resources/definitions/helloBEEprusa.def.json
@@ -26,28 +26,15 @@
"machine_height": { "default_value": 190 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
- "material_print_temperature": { "default_value": 200 },
- "material_bed_temperature": { "default_value": 60 },
- "line_width": { "default_value": 0.48 },
"layer_height": { "default_value": 0.2 },
"layer_height_0": { "default_value": 0.2 },
- "wall_line_count": { "default_value": 3 },
"wall_thickness": { "default_value": 1.2 },
"top_bottom_thickness": { "default_value": 1.2 },
"infill_sparse_density": { "default_value": 20 },
- "infill_overlap": { "default_value": 15 },
"speed_print": { "default_value": 60 },
- "speed_travel": { "default_value": 160 },
- "speed_layer_0": { "default_value": 30 },
- "speed_wall_x": { "default_value": 35 },
- "speed_wall_0": { "default_value": 30 },
- "speed_infill": { "default_value": 60 },
- "speed_topbottom": { "default_value": 20 },
- "skirt_brim_speed": { "default_value": 35 },
"skirt_line_count": { "default_value": 4 },
"skirt_brim_minimal_length": { "default_value": 30 },
"skirt_gap": { "default_value": 6 },
- "cool_fan_full_at_height": { "default_value": 0.4 },
"retraction_speed": { "default_value": 15.0},
"retraction_amount": { "default_value": 1.5}
}
diff --git a/resources/definitions/hms434.def.json b/resources/definitions/hms434.def.json
new file mode 100644
index 0000000000..ca031f26bf
--- /dev/null
+++ b/resources/definitions/hms434.def.json
@@ -0,0 +1,187 @@
+{
+ "name": "HMS434",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Scheepers",
+ "manufacturer": "Hybrid AM Systems",
+ "file_formats": "text/x-gcode",
+
+ "has_materials": true,
+ "preferred_material": "generic_pla",
+ "exclude_materials": [
+ "chromatik_pla",
+ "dsm_arnitel2045_175", "dsm_novamid1070_175",
+ "emotiontech_abs", "emotiontech_petg", "emotiontech_pla", "emotiontech_pva-m", "emotiontech_pva-oks", "emotiontech_pva-s", "emotiontech_tpu98a",
+ "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu",
+ "fiberlogy_hd_pla",
+ "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red",
+ "generic_abs_175", "generic_cpe_175", "generic_hips_175", "generic_nylon_175", "generic_pc_175", "generic_petg_175", "generic_pva_175", "generic_tpu_175",
+ "imade3d_petg_175", "imade3d_pla_175",
+ "innofill_innoflex60_175",
+ "octofiber_pla",
+ "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla",
+ "verbatim_bvoh_175",
+ "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_PLA_Glitter", "Vertex_Delta_PLA_Mat", "Vertex_Delta_PLA_Satin", "Vertex_Delta_PLA_Wood", "Vertex_Delta_TPU",
+ "tizyx_abs", "tizyx_flex", "tizyx_petg", "tizyx_pla", "tizyx_pla_bois", "tizyx_pva",
+ "zyyx_pro_flex", "zyyx_pro_pla"
+ ],
+
+ "has_variants": true,
+ "variants_name": "Tool",
+ "preferred_variant_name": "0.4mm TP extruder",
+
+ "has_machine_quality": true,
+ "preferred_quality_type": "normal",
+
+ "machine_extruder_trains":
+ {
+ "0": "hms434_tool_1",
+ "1": "hms434_tool_2",
+ "2": "hms434_tool_3",
+ "3": "hms434_tool_4",
+ "4": "hms434_tool_5",
+ "5": "hms434_tool_6",
+ "6": "hms434_tool_7",
+ "7": "hms434_tool_8"
+ },
+ "platform": "hms_platform.obj",
+ "platform_offset": [ 26, -13.2, 162.5],
+ "platform_texture": "hms434.png",
+ "first_start_actions": ["MachineSettingsAction"],
+ "supported_actions": ["MachineSettingsAction"]
+ },
+
+ "overrides": {
+ "machine_extruder_count": {"default_value": 2 },
+ "material_diameter": {"default_value": 1.75 },
+ "machine_heated_bed": {"default_value": true },
+ "machine_heated_build_volume":{"default_value": true },
+ "machine_center_is_zero": {"default_value": false },
+ "gantry_height": {"value": "35" },
+ "machine_height": {"default_value": 400 },
+ "machine_depth": {"default_value": 325 },
+ "machine_width": {"default_value": 450 },
+ "machine_gcode_flavor": {"default_value": "RepRap (RepRap)" },
+ "material_print_temp_wait": {"default_value": false },
+ "material_bed_temp_wait": {"default_value": false },
+ "machine_max_feedrate_z": {"default_value": 10 },
+ "machine_acceleration": {"default_value": 1000 },
+ "machine_start_gcode": {"default_value": "\n;Neither Hybrid AM Systems nor any of Hybrid AM Systems representatives has any liabilities or gives any warranties on this .gcode file, or on any or all objects made with this .gcode file.\n\nM117 Homing Y ......\nG28 Y\nM117 Homing X ......\nG28 X\nM117 Homing Z ......\nG28 Z F100\n\nG1 X-44 Y-100 F9000;go to wipe point\nG1 Z0 F900\nG1 Z0.2 F900\nM117 HMS434 Printing ...\n\n" },
+ "machine_end_gcode": {"default_value": "" },
+
+ "retraction_extra_prime_amount": {"minimum_value_warning": "-2.0" },
+ "optimize_wall_printing_order": {"default_value": true },
+ "machine_nozzle_heat_up_speed": {"default_value": 12},
+ "machine_nozzle_cool_down_speed": {"default_value": 20},
+ "machine_min_cool_heat_time_window": {"default_value": 5},
+
+ "layer_height": {"maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
+ "layer_height_0": {"maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
+ "line_width": {"value": "(machine_nozzle_size + layer_height)" },
+ "infill_line_width": {"value": "(line_width)" },
+ "initial_layer_line_width_factor": {"value": 110 },
+
+ "wall_thickness": {"value": "(line_width * 3) if infill_sparse_density < 95 else line_width" },
+ "roofing_layer_count": {"value": "4" },
+ "top_bottom_thickness": {"value": "(layer_height_0 + (layer_height * 3))" },
+ "top_layers": {"value": "4" },
+ "bottom_layers": {"value": "(top_layers)" },
+ "wall_0_inset": {"value": "0" },
+ "outer_inset_first": {"value": true },
+ "alternate_extra_perimeter": {"value": false },
+ "filter_out_tiny_gaps": {"value": false },
+ "fill_outline_gaps": {"value": true },
+ "skin_outline_count": {"value": "0"},
+ "ironing_enabled": {"value": true },
+ "ironing_line_spacing": {"value": "line_width"},
+ "ironing_flow": {"value": "0"},
+ "ironing_inset": {"value": "line_width"},
+ "speed_ironing": {"value": "150"},
+
+ "infill_sparse_density": {"value": 30},
+ "infill_pattern": {"value": "'lines'"},
+ "infill_overlap": {"value": 5},
+ "skin_overlap": {"value": 5},
+ "infill_wipe_dist": {"value": 0.0},
+ "infill_before_walls": {"value": false},
+
+ "material_print_temperature_layer_0": {"value": "material_print_temperature + 5"},
+ "material_initial_print_temperature": {"value": "material_print_temperature",
+ "maximum_value_warning": "material_print_temperature + 15"},
+ "material_final_print_temperature": {"value": "material_print_temperature"},
+ "material_bed_temperature_layer_0": {"value": "material_bed_temperature + 1"},
+ "material_flow": {"value": "100"},
+ "retraction_amount": {"value": "1"},
+ "retraction_speed": {"value": "20"},
+ "retraction_prime_speed": {"value": "8"},
+ "retraction_min_travel": {"value": "(round(line_width * 10))"},
+ "switch_extruder_retraction_amount": {"value": 2},
+ "switch_extruder_retraction_speeds": {"value": "(retraction_speed)"},
+ "switch_extruder_prime_speed": {"value": "(retraction_prime_speed)"},
+
+ "speed_print": {"value": "50"},
+ "speed_infill": {"value": "speed_print"},
+ "speed_wall": {"value": "(speed_print/5*3) if speed_print < 51 else speed_print"},
+ "speed_wall_x": {"value": "speed_wall"},
+ "speed_layer_0": {"value": "(speed_print/5*4) if speed_print < 51 else speed_print"},
+ "speed_topbottom": {"value": "speed_layer_0"},
+ "speed_travel": {"value": "150"},
+ "speed_travel_layer_0": {"value": "speed_travel"},
+ "speed_support_interface": {"value": "speed_topbottom"},
+ "speed_z_hop": {"value": 10},
+ "speed_slowdown_layers": {"value": 1},
+ "acceleration_print": {"value": 1000},
+ "acceleration_travel": {"value": 1000},
+ "jerk_print": {"value": 10},
+ "jerk_travel": {"value": 10},
+
+ "retraction_hop_enabled": {"value": false},
+ "retraction_hop": {"value": 1},
+ "retraction_combing": {"value": "'off'"},
+
+ "cool_fan_speed": {"value": 0},
+ "cool_fan_enabled": {"value": true},
+ "cool_min_layer_time_fan_speed_max": {"value": "cool_min_layer_time"},
+ "cool_min_layer_time": {"value": 20},
+ "cool_min_speed": {"value": "10"},
+ "cool_lift_head": {"value": false},
+
+ "support_z_distance": {"value": 0},
+ "support_xy_distance": {"value": 1},
+ "support_join_distance": {"value": 10},
+ "support_interface_enable": {"value": true},
+ "support_interface_height": {"value": 0.5},
+ "support_interface_pattern": {"value": "'lines'"},
+
+ "adhesion_type": {"value": "'none'"},
+ "skirt_gap": {"value": 1},
+ "skirt_brim_minimal_length": {"value": 50},
+
+ "prime_tower_enable": {"value": false },
+ "prime_tower_size": {"value": 20.6 },
+ "prime_tower_position_x": {"value": 125 },
+ "prime_tower_position_y": {"value": 70 },
+ "prime_blob_enable": {"default_value": false },
+
+ "coasting_enable": {"value": true},
+ "coasting_volume": {"value": 0.1},
+ "coasting_min_volume": {"value": 0.17},
+ "coasting_speed": {"value": 90},
+ "bridge_settings_enabled": {"value": true},
+ "bridge_wall_min_length": {"value": 3},
+ "bridge_skin_support_threshold": {"value": 90},
+ "bridge_wall_speed": {"value": 15},
+ "bridge_wall_material_flow": {"value": 130},
+ "bridge_skin_speed": {"value": 15},
+ "bridge_skin_material_flow": {"value": 130},
+ "bridge_fan_speed": {"value": 0},
+ "bridge_skin_density_2": {"value": 100},
+ "bridge_skin_density_3": {"value": 100},
+ "bridge_skin_material_flow_2": {"value": 110},
+ "bridge_skin_material_flow_3": {"value": 100},
+ "bridge_skin_speed_2": {"value": 20},
+ "bridge_skin_speed_3": {"value": 30}
+ }
+}
diff --git a/resources/definitions/imade3d_jellybox.def.json b/resources/definitions/imade3d_jellybox.def.json
index ae9ca176f5..635cb1fdd0 100644
--- a/resources/definitions/imade3d_jellybox.def.json
+++ b/resources/definitions/imade3d_jellybox.def.json
@@ -1,19 +1,16 @@
{
"version": 2,
- "name": "IMADE3D JellyBOX",
- "inherits": "fdmprinter",
+ "name": "IMADE3D JellyBOX Original",
+ "inherits": "imade3d_jellybox_root",
"metadata": {
"visible": true,
"author": "IMADE3D",
- "manufacturer": "IMADE3D",
"platform": "imade3d_jellybox_platform.stl",
"platform_offset": [ 0, -0.3, 0],
- "file_formats": "text/x-gcode",
"preferred_variant_name": "0.4 mm",
"preferred_quality_type": "fast",
"has_materials": true,
"has_variants": true,
- "has_machine_materials": true,
"has_machine_quality": true,
"machine_extruder_trains": {
"0": "imade3d_jellybox_extruder_0"
@@ -22,18 +19,15 @@
"overrides": {
"machine_head_with_fans_polygon": { "default_value": [[ 0, 0 ],[ 0, 0 ],[ 0, 0 ],[ 0, 0 ]]},
- "machine_name": { "default_value": "IMADE3D JellyBOX" },
+ "machine_name": { "default_value": "IMADE3D JellyBOX Original" },
"machine_width": { "default_value": 170 },
"machine_height": { "default_value": 145 },
"machine_depth": { "default_value": 160 },
- "machine_heated_bed": { "default_value": true },
- "machine_center_is_zero": { "default_value": false },
- "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": {
- "default_value": ";---------------------------------------\n; ; ; Jellybox Start Script Begin ; ; ;\n;_______________________________________\n; M92 E140 ;optionally adjust steps per mm for your filament\n\n; Print Settings Summary\n; (leave these alone: this is only a list of the slicing settings)\n; (overwriting these values will NOT change your printer's behavior)\n; sliced for : {machine_name}\n; nozzle diameter : {machine_nozzle_size}\n; filament diameter : {material_diameter}\n; layer height : {layer_height}\n; 1st layer height : {layer_height_0}\n; line width : {line_width}\n; outer wall wipe dist. : {wall_0_wipe_dist}\n; infill line width : {infill_line_width}\n; wall thickness : {wall_thickness}\n; top thickness : {top_thickness}\n; bottom thickness : {bottom_thickness}\n; infill density : {infill_sparse_density}\n; infill pattern : {infill_pattern}\n; print temperature : {material_print_temperature}\n; 1st layer print temp. : {material_print_temperature_layer_0}\n; heated bed temperature : {material_bed_temperature}\n; 1st layer bed temp. : {material_bed_temperature_layer_0}\n; regular fan speed : {cool_fan_speed_min}\n; max fan speed : {cool_fan_speed_max}\n; retraction amount : {retraction_amount}\n; retr. retract speed : {retraction_retract_speed}\n; retr. prime speed : {retraction_prime_speed}\n; build plate adhesion : {adhesion_type}\n; support ? {support_enable}\n; spiralized ? {magic_spiralize}\n\nM117 Preparing ;write Preparing\nM140 S{material_bed_temperature_layer_0} ;set bed temperature and move on\nM109 S{material_print_temperature} ; wait for the extruder to reach desired temperature\nM206 X10.0 Y0.0 ;set x homing offset for default bed leveling\nG21 ;metric values\nG90 ;absolute positioning\nM107 ;start with the fan off\nM82 ;set extruder to absolute mode\nG28 ;home all axes\nM203 Z4 ;slow Z speed down for greater accuracy when probing\nG29 ;auto bed leveling procedure\nM203 Z7 ;pick up z speed again for printing\nM190 S{material_bed_temperature_layer_0} ;wait for the bed to reach desired temperature\nM109 S{material_print_temperature_layer_0} ;wait for the extruder to reach desired temperature\nG92 E0 ;reset the extruder position\nG1 F1500 E15 ;extrude 15mm of feed stock\nG92 E0 ;reset the extruder position again\nM117 Print starting ;write Print starting\n;---------------------------------------------\n; ; ; Jellybox Printer Start Script End ; ; ;\n;_____________________________________________\n"
+ "default_value": ";---------------------------------------\n; ; ; Jellybox Start Script Begin ; ; ;\n;_______________________________________\n; for slicer: CURA 3\n; start gcode last modified Jun 1, 2019\n\n; Print Settings Summary\n; (leave these alone: this is only a list of the slicing settings)\n; (overwriting these values will NOT change your printer's behavior)\n; sliced for : {machine_name}\n; jobname : {jobname}\n; gcode generated : {day}, {date}, {time}\n; est. print time : {print_time}\n; nozzle diameter : {machine_nozzle_size}\n; filament diameter : {material_diameter}\n; layer height : {layer_height}\n; 1st layer height : {layer_height_0}\n; line width : {line_width} \n; outer wall wipe dist. : {wall_0_wipe_dist}\n; infill line width : {infill_line_width}\n; wall thickness : {wall_thickness}\n; top thickness : {top_thickness}\n; bottom thickness : {bottom_thickness}\n; infill density : {infill_sparse_density}\n; infill pattern : {infill_pattern}\n; print temperature : {material_print_temperature}\n; 1st layer print temp. : {material_print_temperature_layer_0}\n; heated bed temperature : {material_bed_temperature}\n; 1st layer bed temp. : {material_bed_temperature_layer_0}\n; regular fan speed : {cool_fan_speed_min}\n; max fan speed : {cool_fan_speed_max}\n; retraction amount : {retraction_amount}\n; retr. retract speed : {retraction_retract_speed}\n; retr. prime speed : {retraction_prime_speed}\n; build plate adhesion : {adhesion_type}\n; support ? {support_enable}\n; spiralized ? {magic_spiralize}\n\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nM117 Preparing ;write Preparing\nM190 S{material_bed_temperature_layer_0} ;wait for the bed to reach desired temperature\nM109 S180 ;wait for the extruder to reach 180C\nG28 ;home all axes\nM203 Z4 ;slow Z speed down for greater accuracy when probing\nG29 O ;run auto bed leveling procedure IF leveling not active already\n; M500 ;optionally save the mesh\nM203 Z7 ;pick up z speed again for printing\nG28 X ;home x to get as far from the plate as possible\nM420 S1 ;(re) enable bed leveling if turned off by the G28\nG0 Y0 F5000 ;position Y in front\nG0 Z15 F3000 ;position Z\nM109 S{material_print_temperature_layer_0} ;wait for the extruder to reach desired temperature\nM300 S440 P300 ;play a tone\n; M0 Ready! Click to start ; optionally, stop and wait for user to continue\nM420 S1 ;(re) enable bed leveling to make iron-sure\nM117 Print starting ;write Print starting\n;================ ;PRINT:LINE start\nG90 ;absolute positioning\nG92 E0 ;reset the extruder position\nM420 S1 ;(re) enable bed leveling to make iron-sure\nG0 Z0 ;get Z down\nM83 ;relative extrusion mode\nM420 S1 ;(re) enable bed leveling to make iron-sure\nG1 E20 F300 ;extrude __mm of feed stock\nG1 E18 F250 ;extrude __mm of feed stock\nG1 E10 F250 ;extrude __mm of feed stock\nG4 S2 ;pause for ooze\nM400 ;make sure all is finished\nM420 S1 ;(re) enable bed leveling to make iron-sure\nG0 F500 X3 Y0 Z0.3;get to the start of the LINE\nG1 E2 F300 ;extrude __mm of feed stock\nG1 F1000 X152 E7 ;print a thick LINE extruding __mm along the way\nG92 E0 ;reset the extruder position\n;---------------------------------------------\n; ; ; Jellybox Printer Start Script End ; ; ;\n;_____________________________________________\n"
},
"machine_end_gcode": {
- "default_value": "\n;---------------------------------\n;;; Jellybox End Script Begin ;;;\n;_________________________________\nM117 Finishing Up ;write Finishing Up\n\nM104 S0 ;extruder heater off\nM140 S0 ;bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG90 ;absolute positioning\nG28 X ;home x, so the head is out of the way\nG1 Y100 ;move Y forward, so the print is more accessible\nM84 ;steppers off\n\nM117 Print finished ;write Print finished\n;---------------------------------------\n;;; Jellybox End Script End ;;;\n;_______________________________________"
+ "default_value": "\n;---------------------------------\n;;; Jellybox End Script Begin ;;;\n;_________________________________\n; end gcode last modified Nov 30, 2018\nM117 Finishing Up ;write Finishing Up\n\nM107 ;turn the fan off\nM104 S0 ;extruder heater off\nM140 S0 ;bed heater off (if you have it)\nG91 ;relative positioning (includes extruder)\nG1 E-1 F2500 ;retract the filament a bit before lifting the nozzle to release some of the pressure\nG1 Z0.5 E-4 X-10 F9000 ;get out and retract filament even more\nG1 E-25 F2500 ;retract even more\nG90 ;absolute positioning (includes extruder)\nG28 X ;home X so the head is out of the way\nG1 Y140 ;move Y forward, so the print is more accessible\nM84 ;steppers off\n\nM117 Print finished ;write Print finished\n;---------------------------------------\n;;; Jellybox End Script End ;;;\n;_______________________________________"
}
}
}
diff --git a/resources/definitions/imade3d_jellybox_2.def.json b/resources/definitions/imade3d_jellybox_2.def.json
new file mode 100644
index 0000000000..7d7b82e194
--- /dev/null
+++ b/resources/definitions/imade3d_jellybox_2.def.json
@@ -0,0 +1,36 @@
+{
+ "version": 2,
+ "name": "IMADE3D JellyBOX 2",
+ "inherits": "imade3d_jellybox_root",
+ "metadata": {
+ "visible": true,
+ "author": "IMADE3D",
+ "platform": "imade3d_jellybox_2_platform.stl",
+ "platform_offset": [ 0, -10, 0],
+ "preferred_variant_name": "0.4 mm",
+ "preferred_quality_type": "fast",
+ "has_materials": true,
+ "has_variants": true,
+ "has_machine_quality": true,
+ "machine_extruder_trains": {
+ "0": "imade3d_jellybox_2_extruder_0"
+ }
+ },
+
+ "overrides": {
+ "gradual_infill_steps":{"default_value": 0},
+ "gradual_infill_step_height": {"default_value": 3},
+ "machine_head_with_fans_polygon": { "default_value": [[ 0, 0 ],[ 0, 0 ],[ 0, 0 ],[ 0, 0 ]]},
+ "machine_name": { "default_value": "IMADE3D JellyBOX 2" },
+ "machine_width": { "default_value": 180 },
+ "machine_height": { "default_value": 145 },
+ "machine_depth": { "default_value": 165 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "machine_start_gcode": {
+ "default_value": ";---------------------------------------\n; ; ; Jellybox Start Script Begin ; ; ;\n;_______________________________________\n; for slicer: CURA 3\n; start gcode last modified Jun 1, 2019\n\n; Print Settings Summary\n; (leave these alone: this is only a list of the slicing settings)\n; (overwriting these values will NOT change your printer's behavior)\n; sliced for : {machine_name}\n; jobname : {jobname}\n; gcode generated : {day}, {date}, {time}\n; est. print time : {print_time}\n; nozzle diameter : {machine_nozzle_size}\n; filament diameter : {material_diameter}\n; layer height : {layer_height}\n; 1st layer height : {layer_height_0}\n; line width : {line_width} \n; outer wall wipe dist. : {wall_0_wipe_dist}\n; infill line width : {infill_line_width}\n; wall thickness : {wall_thickness}\n; top thickness : {top_thickness}\n; bottom thickness : {bottom_thickness}\n; infill density : {infill_sparse_density}\n; infill pattern : {infill_pattern}\n; print temperature : {material_print_temperature}\n; 1st layer print temp. : {material_print_temperature_layer_0}\n; heated bed temperature : {material_bed_temperature}\n; 1st layer bed temp. : {material_bed_temperature_layer_0}\n; regular fan speed : {cool_fan_speed_min}\n; max fan speed : {cool_fan_speed_max}\n; retraction amount : {retraction_amount}\n; retr. retract speed : {retraction_retract_speed}\n; retr. prime speed : {retraction_prime_speed}\n; build plate adhesion : {adhesion_type}\n; support ? {support_enable}\n; spiralized ? {magic_spiralize}\n\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nM117 Preparing ;write Preparing\nM190 S{material_bed_temperature_layer_0} ;wait for the bed to reach desired temperature\nM109 S180 ;wait for the extruder to reach 180C\nG28 ;home all axes\nM203 Z4 ;slow Z speed down for greater accuracy when probing\nG29 O ;run auto bed leveling procedure IF leveling not active already\n; M500 ;optionally save the mesh\nM203 Z7 ;pick up z speed again for printing\nG28 X ;home x to get as far from the plate as possible\nM420 S1 ;(re) enable bed leveling if turned off by the G28\nG0 Y0 F5000 ;position Y in front\nG0 Z15 F3000 ;position Z\nM109 S{material_print_temperature_layer_0} ;wait for the extruder to reach desired temperature\nM300 S440 P300 ;play a tone\n; M0 Ready! Click to start ; optionally, stop and wait for user to continue\nM420 S1 ;(re) enable bed leveling to make iron-sure\nM117 Print starting ;write Print starting\n;================ ;PRINT:LINE start\nG90 ;absolute positioning\nG92 E0 ;reset the extruder position\nM420 S1 ;(re) enable bed leveling to make iron-sure\nG0 Z0 ;get Z down\nM83 ;relative extrusion mode\nM420 S1 ;(re) enable bed leveling to make iron-sure\nG1 E20 F300 ;extrude __mm of feed stock\nG1 E18 F250 ;extrude __mm of feed stock\nG1 E10 F250 ;extrude __mm of feed stock\nG4 S2 ;pause for ooze\nM400 ;make sure all is finished\nM420 S1 ;(re) enable bed leveling to make iron-sure\nG0 F500 X3 Y0 Z0.3;get to the start of the LINE\nG1 E2 F300 ;extrude __mm of feed stock\nG1 F1000 X152 E7 ;print a thick LINE extruding __mm along the way\nG92 E0 ;reset the extruder position\n;---------------------------------------------\n; ; ; Jellybox Printer Start Script End ; ; ;\n;_____________________________________________\n"
+ },
+ "machine_end_gcode": {
+ "default_value": "\n;---------------------------------\n;;; Jellybox End Script Begin ;;;\n;_________________________________\n; end gcode last modified Nov 30, 2018\nM117 Finishing Up ;write Finishing Up\n\nM107 ;turn the fan off\nM104 S0 ;extruder heater off\nM140 S0 ;bed heater off (if you have it)\nG91 ;relative positioning (includes extruder)\nG1 E-1 F2500 ;retract the filament a bit before lifting the nozzle to release some of the pressure\nG1 Z0.5 E-4 X-10 F9000 ;get out and retract filament even more\nG1 E-25 F2500 ;retract even more\nG90 ;absolute positioning (includes extruder)\nG28 X ;home X so the head is out of the way\nG1 Y140 ;move Y forward, so the print is more accessible\nM84 ;steppers off\n\nM117 Print finished ;write Print finished\n;---------------------------------------\n;;; Jellybox End Script End ;;;\n;_______________________________________"
+ }
+ }
+}
diff --git a/resources/definitions/imade3d_jellybox_root.def.json b/resources/definitions/imade3d_jellybox_root.def.json
new file mode 100644
index 0000000000..52f541f1d4
--- /dev/null
+++ b/resources/definitions/imade3d_jellybox_root.def.json
@@ -0,0 +1,143 @@
+{
+ "version": 2,
+ "name": "imade3d_jellybox_root",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "author": "IMADE3D",
+ "manufacturer": "IMADE3D",
+ "category": "Ultimaker",
+ "visible": false,
+ "file_formats": "text/x-gcode",
+ "exclude_materials": [
+ "chromatik_pla",
+ "dsm_arnitel2045_175",
+ "dsm_novamid1070_175",
+ "fabtotum_abs",
+ "fabtotum_nylon",
+ "fabtotum_pla",
+ "fabtotum_tpu",
+ "fiberlogy_hd_pla",
+ "filo3d_pla_green",
+ "filo3d_pla_red",
+ "filo3d_pla",
+ "generic_abs_175",
+ "generic_abs",
+ "generic_bam",
+ "generic_cpe_175",
+ "generic_cpe_plus",
+ "generic_cpe",
+ "generic_hips_175",
+ "generic_hips",
+ "generic_nylon_175",
+ "generic_nylon",
+ "generic_pc_175",
+ "generic_pc",
+ "generic_petg",
+ "generic_petg_175",
+ "generic_pla",
+ "generic_pla_175",
+ "generic_pp",
+ "generic_pva_175",
+ "generic_pva",
+ "generic_tough_pla",
+ "generic_tpu",
+ "imade3d_petg_green",
+ "imade3d_petg_pink",
+ "imade3d_pla_green",
+ "imade3d_pla_pink",
+ "innofill_innoflex60_175",
+ "octofiber_pla",
+ "polyflex_pla",
+ "polymax_pla",
+ "polyplus_pla",
+ "polywood_pla",
+ "tizyx_abs",
+ "tizyx_pla_bois",
+ "tizyx_pla",
+ "ultimaker_abs_black",
+ "ultimaker_abs_blue",
+ "ultimaker_abs_green",
+ "ultimaker_abs_grey",
+ "ultimaker_abs_orange",
+ "ultimaker_abs_pearl-gold",
+ "ultimaker_abs_red",
+ "ultimaker_abs_silver-metallic",
+ "ultimaker_abs_white",
+ "ultimaker_abs_yellow",
+ "ultimaker_bam",
+ "ultimaker_cpe_black",
+ "ultimaker_cpe_blue",
+ "ultimaker_cpe_dark-grey",
+ "ultimaker_cpe_green",
+ "ultimaker_cpe_light-grey",
+ "ultimaker_cpe_plus_black",
+ "ultimaker_cpe_plus_transparent",
+ "ultimaker_cpe_plus_white",
+ "ultimaker_cpe_red",
+ "ultimaker_cpe_transparent",
+ "ultimaker_cpe_white",
+ "ultimaker_cpe_yellow",
+ "ultimaker_nylon_black",
+ "ultimaker_nylon_transparent",
+ "ultimaker_pc_black",
+ "ultimaker_pc_transparent",
+ "ultimaker_pc_white",
+ "ultimaker_pla_black",
+ "ultimaker_pla_blue",
+ "ultimaker_pla_green",
+ "ultimaker_pla_magenta",
+ "ultimaker_pla_orange",
+ "ultimaker_pla_pearl-white",
+ "ultimaker_pla_red",
+ "ultimaker_pla_silver-metallic",
+ "ultimaker_pla_transparent",
+ "ultimaker_pla_white",
+ "ultimaker_pla_yellow",
+ "ultimaker_pp_transparent",
+ "ultimaker_pva",
+ "ultimaker_tough_pla_black",
+ "ultimaker_tough_pla_green",
+ "ultimaker_tough_pla_red",
+ "ultimaker_tough_pla_white",
+ "ultimaker_tpu_black",
+ "ultimaker_tpu_blue",
+ "ultimaker_tpu_red",
+ "ultimaker_tpu_white",
+ "verbatim_bvoh_175",
+ "Vertex_Delta_ABS",
+ "Vertex_Delta_PET",
+ "Vertex_Delta_PLA",
+ "Vertex_Delta_TPU",
+ "zyyx_pro_flex",
+ "zyyx_pro_pla"
+ ]
+ },
+ "overrides": {
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "material_print_temperature": {
+ "minimum_value": "0"
+ },
+ "machine_center_is_zero": {
+ "default_value": false
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "material_bed_temperature": {
+ "minimum_value": "0"
+ },
+ "material_standby_temperature": {
+ "minimum_value": "0"
+ },
+ "relative_extrusion":
+ {
+ "value": true,
+ "enabled": true
+ }
+ }
+}
diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json
index 91a6d8365b..df839b0fe4 100644
--- a/resources/definitions/innovo_inventor.def.json
+++ b/resources/definitions/innovo_inventor.def.json
@@ -32,7 +32,7 @@
"machine_center_is_zero": {
"default_value": true
},
- "machine_head_polygon": {
+ "machine_head_with_fans_polygon": {
"default_value": [
[-43.7, -19.2],
[-43.7, 55],
@@ -41,7 +41,7 @@
]
},
"gantry_height": {
- "default_value": 82.3
+ "value": "82.3"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
@@ -61,36 +61,10 @@
"top_bottom_thickness": {
"default_value": 1.2
},
- "material_print_temperature": {
- "default_value": 205
- },
- "material_bed_temperature": {
- "default_value": 60
- },
"speed_print": {
"default_value": 50
},
- "speed_wall_0": {
- "default_value": 25
- },
- "speed_wall_x": {
- "default_value": 40
- },
- "speed_infill": {
- "default_value": 80
- },
- "speed_topbottom": {
- "default_value": 30
- },
- "speed_support_interface":
- {
- "default_value": 20
- },
- "speed_travel": {
- "default_value": 150
- },
"speed_layer_0": {
- "default_value": 30.0,
"minimum_value": 0.1
}
}
diff --git a/resources/definitions/jgaurora_a1.def.json b/resources/definitions/jgaurora_a1.def.json
index b9a921c311..1c910f0d95 100644
--- a/resources/definitions/jgaurora_a1.def.json
+++ b/resources/definitions/jgaurora_a1.def.json
@@ -39,7 +39,7 @@
"default_value": false
},
"gantry_height": {
- "default_value": 10
+ "value": "10"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
@@ -47,12 +47,6 @@
"material_diameter": {
"default_value": 1.75
},
- "material_print_temperature": {
- "default_value": 215
- },
- "material_bed_temperature": {
- "default_value": 67
- },
"layer_height_0": {
"default_value": 0.12
},
@@ -62,21 +56,6 @@
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 40
- },
- "speed_wall": {
- "default_value": 35
- },
- "speed_topbottom": {
- "default_value": 35
- },
- "speed_travel": {
- "default_value": 120
- },
- "speed_layer_0": {
- "default_value": 12
- },
"support_enable": {
"default_value": true
},
diff --git a/resources/definitions/jgaurora_a3s.def.json b/resources/definitions/jgaurora_a3s.def.json
new file mode 100644
index 0000000000..ead0a5f9e7
--- /dev/null
+++ b/resources/definitions/jgaurora_a3s.def.json
@@ -0,0 +1,72 @@
+{
+ "name": "JGAurora A3S",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Samuel Pinches",
+ "manufacturer": "JGAurora",
+ "file_formats": "text/x-gcode",
+ "preferred_quality_type": "normal",
+ "machine_extruder_trains":
+ {
+ "0": "jgaurora_a3s_extruder_0"
+ }
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "JGAurora A3S"
+ },
+ "machine_start_gcode": {
+ "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --"
+ },
+ "machine_end_gcode": {
+ "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y200 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --"
+ },
+ "machine_width": {
+ "default_value": 205
+ },
+ "machine_height": {
+ "default_value": 205
+ },
+ "machine_depth": {
+ "default_value": 205
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "machine_center_is_zero": {
+ "default_value": false
+ },
+ "gantry_height": {
+ "value": "10"
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "layer_height_0": {
+ "default_value": 0.12
+ },
+ "wall_thickness": {
+ "default_value": 1.2
+ },
+ "speed_print": {
+ "default_value": 35
+ },
+ "support_enable": {
+ "default_value": true
+ },
+ "retraction_enable": {
+ "default_value": true
+ },
+ "retraction_amount": {
+ "default_value": 8
+ },
+ "retraction_speed": {
+ "default_value": 45
+ }
+ }
+}
diff --git a/resources/definitions/jgaurora_a5.def.json b/resources/definitions/jgaurora_a5.def.json
index d84a8440e6..b9f179d38e 100644
--- a/resources/definitions/jgaurora_a5.def.json
+++ b/resources/definitions/jgaurora_a5.def.json
@@ -41,7 +41,7 @@
"default_value": false
},
"gantry_height": {
- "default_value": 10
+ "value": "10"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
@@ -49,12 +49,6 @@
"material_diameter": {
"default_value": 1.75
},
- "material_print_temperature": {
- "default_value": 215
- },
- "material_bed_temperature": {
- "default_value": 67
- },
"layer_height_0": {
"default_value": 0.12
},
@@ -64,21 +58,6 @@
"speed_print": {
"default_value": 40
},
- "speed_infill": {
- "default_value": 40
- },
- "speed_wall": {
- "default_value": 35
- },
- "speed_topbottom": {
- "default_value": 35
- },
- "speed_travel": {
- "default_value": 120
- },
- "speed_layer_0": {
- "default_value": 12
- },
"support_enable": {
"default_value": true
},
diff --git a/resources/definitions/jgaurora_jgmaker_magic.def.json b/resources/definitions/jgaurora_jgmaker_magic.def.json
new file mode 100644
index 0000000000..8d0349a48c
--- /dev/null
+++ b/resources/definitions/jgaurora_jgmaker_magic.def.json
@@ -0,0 +1,72 @@
+{
+ "name": "JGAurora JGMaker Magic",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Samuel Pinches",
+ "manufacturer": "JGAurora",
+ "file_formats": "text/x-gcode",
+ "preferred_quality_type": "fast",
+ "machine_extruder_trains":
+ {
+ "0": "jgaurora_jgmaker_magic_extruder_0"
+ }
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "JGAurora JGMaker Magic"
+ },
+ "machine_start_gcode": {
+ "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nM420 S1 ;turn on mesh bed levelling if enabled in firmware\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --"
+ },
+ "machine_end_gcode": {
+ "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --"
+ },
+ "machine_width": {
+ "default_value": 220
+ },
+ "machine_height": {
+ "default_value": 250
+ },
+ "machine_depth": {
+ "default_value": 220
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "machine_center_is_zero": {
+ "default_value": false
+ },
+ "gantry_height": {
+ "value": "10"
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "layer_height_0": {
+ "default_value": 0.2
+ },
+ "wall_thickness": {
+ "default_value": 1.2
+ },
+ "speed_print": {
+ "default_value": 60
+ },
+ "support_enable": {
+ "default_value": true
+ },
+ "retraction_enable": {
+ "default_value": true
+ },
+ "retraction_amount": {
+ "default_value": 5
+ },
+ "retraction_speed": {
+ "default_value": 50
+ }
+ }
+}
diff --git a/resources/definitions/jgaurora_z_603s.def.json b/resources/definitions/jgaurora_z_603s.def.json
index 3a78585240..8dbf5a82bb 100644
--- a/resources/definitions/jgaurora_z_603s.def.json
+++ b/resources/definitions/jgaurora_z_603s.def.json
@@ -21,8 +21,8 @@
"default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 ;home all axis\nM420 S1 ;turn on mesh bed levelling if enabled in firmware\nG92 E0 ;zero the extruded length\nG1 Z1 F1000 ;move up slightly\nG1 X60.0 Z0 E9.0 F1000.0;intro line\nG1 X100.0 E21.5 F1000.0 ;continue line\nG92 E0 ;zero the extruded length again\n; -- end of START GCODE --"
},
"machine_end_gcode": {
- "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 ;move to the X-axis origin (Home)\nG0 Y280 F600 ;bring the bed to the front for easy print removal\nM84 ;turn off stepper motors\n; -- end of END GCODE --"
- },
+ "default_value": "; -- END GCODE --\nM104 S0 ;turn off nozzle heater\nM140 S0 ;turn off bed heater\nG91 ;set to relative positioning\nG1 E-10 F300 ;retract the filament slightly\nG90 ;set to absolute positioning\nG28 X0 Y0 F600 ;move to the X/Y-axis origin (Home)\nM84 ;turn off stepper motors\n; -- end of END GCODE --"
+ },
"machine_width": {
"default_value": 280
},
@@ -39,7 +39,7 @@
"default_value": false
},
"gantry_height": {
- "default_value": 10
+ "value": "10"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
@@ -47,12 +47,6 @@
"material_diameter": {
"default_value": 1.75
},
- "material_print_temperature": {
- "default_value": 210
- },
- "material_bed_temperature": {
- "default_value": 55
- },
"layer_height_0": {
"default_value": 0.2
},
@@ -62,21 +56,6 @@
"speed_print": {
"default_value": 60
},
- "speed_infill": {
- "default_value": 60
- },
- "speed_wall": {
- "default_value": 30
- },
- "speed_topbottom": {
- "default_value": 45
- },
- "speed_travel": {
- "default_value": 125
- },
- "speed_layer_0": {
- "default_value": 20
- },
"support_enable": {
"default_value": true
},
diff --git a/resources/definitions/julia.def.json b/resources/definitions/julia.def.json
index 62e4170c1f..15e5057a55 100644
--- a/resources/definitions/julia.def.json
+++ b/resources/definitions/julia.def.json
@@ -21,25 +21,14 @@
"machine_end_gcode": {
"default_value": " M104 S0 ;extruder heater off\n M140 S0 ;heated bed heater off (if you have it)\n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning\n"
},
- "material_bed_temperature": { "default_value": 100 },
"layer_height": { "default_value": 0.2 },
"support_angle": { "default_value": 30 },
- "infill_overlap": { "default_value": 30 },
"layer_height_0": { "default_value": 0.2 },
"speed_print": { "default_value": 80 },
- "speed_wall_0": { "default_value": 30 },
- "speed_travel": { "default_value": 150 },
- "brim_line_count": { "default_value": 15 },
- "skin_overlap": { "default_value": 30 },
"prime_tower_size": { "default_value": 8.660254037844387 },
- "bottom_thickness": { "default_value": 0.8 },
"retraction_amount": { "default_value": 3 },
- "speed_topbottom": { "default_value": 80 },
- "material_print_temperature": { "default_value": 230 },
"support_pattern": { "default_value": "grid" },
- "speed_infill": { "default_value": 80 },
"infill_sparse_density": { "default_value": 10 },
- "top_thickness": { "default_value": 0.8 },
"machine_extruder_count": { "default_value": 1 },
"retraction_combing": { "default_value": "off" },
"machine_heated_bed": { "default_value": true },
diff --git a/resources/definitions/kemiq_q2_beta.def.json b/resources/definitions/kemiq_q2_beta.def.json
index 387818565e..f0ae009419 100644
--- a/resources/definitions/kemiq_q2_beta.def.json
+++ b/resources/definitions/kemiq_q2_beta.def.json
@@ -41,7 +41,7 @@
"default_value": 2
},
"gantry_height": {
- "default_value": 0
+ "value": "0"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/kemiq_q2_gama.def.json b/resources/definitions/kemiq_q2_gama.def.json
index fd6f2d54aa..07ff6dcbf7 100644
--- a/resources/definitions/kemiq_q2_gama.def.json
+++ b/resources/definitions/kemiq_q2_gama.def.json
@@ -42,7 +42,7 @@
"default_value": 2
},
"gantry_height": {
- "default_value": 0
+ "value": "0"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/key3d_tyro.def.json b/resources/definitions/key3d_tyro.def.json
new file mode 100644
index 0000000000..0bfc78c115
--- /dev/null
+++ b/resources/definitions/key3d_tyro.def.json
@@ -0,0 +1,65 @@
+{
+ "name": "Tyro",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "DragonJe",
+ "manufacturer": "Key3D",
+ "file_formats": "text/x-gcode",
+ "platform_offset": [0, 0, 0],
+ "has_materials": true,
+ "has_variants": false,
+ "preferred_quality_type": "normal",
+ "has_machine_quality": true,
+ "preferred_material": "generic_pla",
+ "machine_extruder_trains":
+ {
+ "0": "key3d_tyro_extruder_0"
+ }
+ },
+
+ "overrides": {
+ "machine_name": {
+ "default_value": "Tyro"
+ },
+ "machine_width": {
+ "default_value": 150
+ },
+ "machine_height": {
+ "default_value": 150
+ },
+ "machine_depth": {
+ "default_value": 150
+ },
+ "machine_head_with_fans_polygon": {
+ "default_value": [
+ [-30, 34],
+ [-30, -32],
+ [30, -32],
+ [30, 34]
+ ]
+ },
+ "gantry_height": {
+ "value": "30"
+ },
+ "machine_heated_bed": {
+ "default_value": false
+ },
+ "machine_heated_build_volume": {
+ "default_value": false
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "machine_start_gcode": {
+ "default_value": "G28 ; Home\nG1 Z15.0 F6000 ; Move Z axis up 15mm\n ; Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0"
+ },
+ "machine_end_gcode": {
+ "default_value": "M104 S0\nM140 S0\n ; Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84"
+ }
+ }
+}
diff --git a/resources/definitions/kossel_mini.def.json b/resources/definitions/kossel_mini.def.json
index 91f374fb6d..d9c3b3d37f 100644
--- a/resources/definitions/kossel_mini.def.json
+++ b/resources/definitions/kossel_mini.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "Claudio Sampaio (Patola)",
- "manufacturer": "Other",
+ "manufacturer": "Johann",
"file_formats": "text/x-gcode",
"platform": "kossel_platform.stl",
"platform_offset": [0, -0.25, 0],
diff --git a/resources/definitions/kossel_pro.def.json b/resources/definitions/kossel_pro.def.json
index e104538b2c..f26c6ed068 100644
--- a/resources/definitions/kossel_pro.def.json
+++ b/resources/definitions/kossel_pro.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "Chris Petersen",
- "manufacturer": "OpenBeam",
+ "manufacturer": "Johann",
"file_formats": "text/x-gcode",
"platform": "kossel_pro_build_platform.stl",
"platform_offset": [0, -0.25, 0],
diff --git a/resources/definitions/kupido.def.json b/resources/definitions/kupido.def.json
index 412fe979b8..ad0182a5f6 100644
--- a/resources/definitions/kupido.def.json
+++ b/resources/definitions/kupido.def.json
@@ -1,13 +1,21 @@
{
- "name": "Kupido",
"version": 2,
+ "name": "KUPIDO",
"inherits": "fdmprinter",
- "metadata": {
+ "metadata":
+ {
"visible": true,
- "author": "Ultimaker",
- "manufacturer": "Kupido",
+ "author": "ALYA",
+ "manufacturer": "Kati Hal ARGE",
+ "category": "Other",
"file_formats": "text/x-gcode",
"platform_offset": [ 0, 0, 0],
+ "exclude_materials": ["chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu", "fiberlogy_hd_pla", "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red", "generic_bam", "generic_cpe", "generic_cpe_175", "generic_cpe_plus", "generic_hips", "generic_hips_175", "generic_nylon", "generic_nylon_175", "generic_pc", "generic_pc_175", "generic_petg", "generic_petg_175", "generic_pp", "generic_pva", "generic_pva_175", "generic_tough_pla", "generic_tpu", "generic_tpu_175", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "innofill_innoflex60_175", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "ultimaker_abs_black", "ultimaker_abs_blue", "ultimaker_abs_green", "ultimaker_abs_grey", "ultimaker_abs_orange", "ultimaker_abs_pearl-gold", "ultimaker_abs_red", "ultimaker_abs_silver-metallic", "ultimaker_abs_white", "ultimaker_abs_yellow", "ultimaker_bam", "ultimaker_cpe_black", "ultimaker_cpe_blue", "ultimaker_cpe_dark-grey", "ultimaker_cpe_green", "ultimaker_cpe_light-grey", "ultimaker_cpe_plus_black", "ultimaker_cpe_plus_transparent", "ultimaker_cpe_plus_white", "ultimaker_cpe_red", "ultimaker_cpe_transparent", "ultimaker_cpe_white", "ultimaker_cpe_yellow", "ultimaker_nylon_black", "ultimaker_nylon_transparent", "ultimaker_pc_black", "ultimaker_pc_transparent", "ultimaker_pc_white", "ultimaker_pla_black", "ultimaker_pla_blue", "ultimaker_pla_green", "ultimaker_pla_magenta", "ultimaker_pla_orange", "ultimaker_pla_pearl-white", "ultimaker_pla_red", "ultimaker_pla_silver-metallic", "ultimaker_pla_transparent", "ultimaker_pla_white", "ultimaker_pla_yellow", "ultimaker_pp_transparent", "ultimaker_pva", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "ultimaker_tpu_black", "ultimaker_tpu_blue", "ultimaker_tpu_red", "ultimaker_tpu_white", "verbatim_bvoh_175", "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_TPU", "zyyx_pro_flex", "zyyx_pro_pla","tizyx_pla","tizyx_abs","tizyx_pla_bois" ],
+ "preferred_material": "generic_pla",
+ "has_machine_quality": true,
+ "has_materials": true,
+ "has_variants": false,
+ "supports_usb_connection": false,
"machine_extruder_trains":
{
"0": "kupido_extruder_0"
@@ -15,26 +23,27 @@
},
"overrides": {
- "machine_name": { "default_value": "Kupido" },
- "machine_start_gcode": {
- "default_value": " ;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n ;M190 S{material_bed_temperature} ;Uncomment to add your own bed temperature line\n ;M109 S{material_print_temperature} ;Uncomment to add your own temperature line\n G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X Y to endstops\n G28 Z0 ;move Z to endstops\n G1 Z20.0 F40 ;move the platform down 20mm\n G1 Y0 X170 F{speed_travel}\n G92 E0 ;zero the extruded length\n G1 F200 E10 ;extrude 3mm of feed stock\n G92 E0 ;zero the extruded length again\n G4 P7000\n G1 F{speed_travel}\n ;Put printing message on LCD screen\n M117 Printing...\n"
+ "machine_name": { "default_value": "KUPIDO" },
+ "machine_heated_bed": { "default_value": true },
+ "machine_width": { "default_value": 195 },
+ "machine_height": { "default_value": 190 },
+ "machine_depth": { "default_value": 195 },
+ "machine_center_is_zero": { "default_value": false },
+ "gantry_height": { "value": "55" },
+ "retraction_amount": { "default_value": 1 },
+ "support_enable": { "default_value": true},
+ "machine_head_with_fans_polygon": {
+ "default_value": [[75, 18],[18, 18],[18, 35],[75, 35]]
},
- "machine_end_gcode": {
- "default_value": " M104 S0 ;extruder heater off\n M140 S0 ;heated bed heater off (if you have it)\n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning\n"
+ "adhesion_type": {"options": {"raft": "Raft" ,"none": "None", "brim": "Brim"}, "default_value": "raft"},
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_start_gcode":
+ {
+ "default_value": ";Sliced at: {day} {date} {time} \n ;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {fill_density} \n ;Print time: {print_time} \n ;Filament used: {filament_amount}m {filament_weight}g \n ;Filament cost: {filament_cost} \n G28 X0 Y0 ;move X Y to endstops \n G28 Z0 ;move Z to endstops \n M190 S{material_bed_temperature} ;bed temp \n M107 ; switch fan off \n M109 S{material_print_temperature} ;extruder temp set \n G1 F3000 \n G1 Z10 \n G92 E0 ;zero the extruded length \n G1 F200 E1 ;extrude 1mm of feed stock \n G92 E0 ;zero the extruded length again \n G4 P7000 ; wait 7000ms \n M117 Printing... ;Put printing message on LCD screen"
},
- "prime_tower_size": { "default_value": 8.660254037844387 },
- "retraction_speed": { "default_value": 60 },
- "material_bed_temperature": { "default_value": 60 },
- "speed_wall_x": { "default_value": 40 },
- "skirt_line_count": { "default_value": 2 },
- "retraction_min_travel": { "default_value": 2 },
- "speed_wall_0": { "default_value": 30 },
- "material_print_temperature": { "default_value": 220 },
- "brim_line_count": { "default_value": 15 },
- "retraction_amount": { "default_value": 3.6 },
- "speed_topbottom": { "default_value": 20 },
- "layer_height": { "default_value": 0.2 },
- "speed_print": { "default_value": 30 },
- "speed_infill": { "default_value": 30 }
+ "machine_end_gcode":
+ {
+ "default_value": ";End GCode\nM104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG28 Z0\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}"
+ }
}
-}
+}
\ No newline at end of file
diff --git a/resources/definitions/leapfrog_bolt_pro.def.json b/resources/definitions/leapfrog_bolt_pro.def.json
new file mode 100644
index 0000000000..09b9ecded5
--- /dev/null
+++ b/resources/definitions/leapfrog_bolt_pro.def.json
@@ -0,0 +1,115 @@
+{
+ "version": 2,
+ "name": "Leapfrog Bolt Pro",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Karan and Vincent 20191104",
+ "manufacturer": "Leapfrog B.V.",
+ "category": "Other",
+ "platform": "leapfrog_bolt_pro_platform.stl",
+ "platform_offset": [0, 0, -14],
+ "file_formats": "text/x-gcode",
+ "supports_usb_connection": false,
+ "supports_network_connection": false,
+ "has_materials": true,
+ "has_machine_quality": true,
+ "has_variants": true,
+ "preferred_variant_name": "Brass 0.4",
+ "preferred_material": "leapfrog_epla_natural",
+ "variants_name": "Hot end",
+ "exclude_materials": [
+ "generic_pla_175",
+ "generic_abs_175",
+ "generic_cpe_175",
+ "generic_hips_175",
+ "generic_nylon_175",
+ "generic_pc_175",
+ "generic_petg_175",
+ "generic_pva_175",
+ "generic_tpu_175",
+ "chromatik_pla",
+ "dsm_arnitel2045_175",
+ "dsm_novamid1070_175",
+ "emotiontech_abs",
+ "emotiontech_petg",
+ "emotiontech_pla",
+ "emotiontech_pva-m",
+ "emotiontech_pva-oks",
+ "emotiontech_pva-s",
+ "emotiontech_tpu98a",
+ "fabtotum_abs",
+ "fabtotum_nylon",
+ "fabtotum_pla",
+ "fabtotum_tpu",
+ "fiberlogy_hd_pla",
+ "filo3d_pla",
+ "filo3d_pla_green",
+ "filo3d_pla_red",
+ "imade3d_petg_175",
+ "imade3d_pla_175",
+ "innofill_innoflex60_175",
+ "octofiber_pla",
+ "polyflex_pla",
+ "polymax_pla",
+ "polyplus_pla",
+ "polywood_pla",
+ "tizyx_abs",
+ "tizyx_pla",
+ "tizyx_flex",
+ "tizyx_petg",
+ "tizyx_pva",
+ "tizyx_pla_bois",
+ "verbatim_bvoh_175",
+ "Vertex_Delta_ABS",
+ "Vertex_Delta_PET",
+ "Vertex_Delta_PLA_Glitter",
+ "Vertex_Delta_PLA_Mat",
+ "Vertex_Delta_PLA_Satin",
+ "Vertex_Delta_PLA_Wood",
+ "Vertex_Delta_PLA",
+ "Vertex_Delta_TPU",
+ "zyyx_pro_flex",
+ "zyyx_pro_pla"
+ ],
+ "machine_extruder_trains":
+ {
+ "0": "leapfrog_bolt_pro_extruder_right",
+ "1": "leapfrog_bolt_pro_extruder_left"
+ }
+ },
+ "overrides": {
+ "machine_name": {"default_value": "Leapfrog Bolt Pro" },
+ "machine_extruder_count": {"default_value": 2},
+ "machine_center_is_zero": {"default_value": false},
+ "machine_width": {"default_value": 302},
+ "machine_height": {"default_value": 205},
+ "machine_depth": {"default_value": 322},
+ "machine_heated_bed": {"default_value": true},
+ "machine_head_with_fans_polygon": {"default_value": [[-60, 110 ], [-60, -45], [60, -45 ], [60, 110]]},
+ "machine_max_feedrate_z": {"default_value": 16.7 },
+ "machine_max_feedrate_e": {"default_value": 50 },
+ "machine_max_acceleration_z": {"default_value": 100 },
+ "machine_acceleration": {"default_value": 400 },
+ "machine_max_jerk_xy": {"default_value": 20 },
+ "machine_max_jerk_z": {"default_value": 0.4 },
+ "machine_max_jerk_e": {"default_value": 5 },
+ "machine_gcode_flavor": {"default_value": "RepRap (Marlin/Sprinter)"},
+ "material_final_print_temperature": {"value": "default_material_print_temperature" },
+ "material_initial_print_temperature": {"value": "default_material_print_temperature" },
+ "gantry_height": {"value": "20"},
+ "retraction_combing": { "default_value": "all" },
+ "retraction_amount": {"default_value": 2},
+ "adhesion_type": {"default_value": "skirt"},
+ "skirt_line_count": {"default_value": 3},
+ "machine_use_extruder_offset_to_offset_coords": {"default_value": true},
+ "machine_start_gcode": {"default_value": "G90\nG28 X0 Y0 Z0\nG1 Z5 F1000\nG92 E0\nG1 Y-32 F12000\nG1 E15 F1000\nG1 E45 F150\nG4 S5"},
+ "machine_end_gcode": {"default_value": "G92 E0\nG1 E-3 F300\nM104 S0 T0\nM104 S0 T1\nM140 S0\nG28 X0 Y0\nM84"},
+ "prime_tower_enable": { "resolve": "extruders_enabled_count > 1"},
+ "prime_tower_position_x": {"value": "169" },
+ "prime_tower_position_y": {"value": "25" },
+ "speed_travel": { "value": "200" },
+ "build_volume_temperature": {"enabled": false},
+ "material_standby_temperature": {"enabled": false }
+ }
+}
diff --git a/resources/definitions/makeR_pegasus.def.json b/resources/definitions/makeR_pegasus.def.json
index ac09aa01ac..63f76194a4 100644
--- a/resources/definitions/makeR_pegasus.def.json
+++ b/resources/definitions/makeR_pegasus.def.json
@@ -32,7 +32,7 @@
"machine_center_is_zero": {
"default_value": false
},
- "machine_head_polygon": {
+ "machine_head_with_fans_polygon": {
"default_value": [
[-75, -18],
[-75, 35],
@@ -41,7 +41,7 @@
]
},
"gantry_height": {
- "default_value": -25
+ "value": "25"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/makeR_prusa_tairona_i3.def.json b/resources/definitions/makeR_prusa_tairona_i3.def.json
index 0e59874978..3c57c0cbc8 100644
--- a/resources/definitions/makeR_prusa_tairona_i3.def.json
+++ b/resources/definitions/makeR_prusa_tairona_i3.def.json
@@ -32,7 +32,7 @@
"machine_center_is_zero": {
"default_value": false
},
- "machine_head_polygon": {
+ "machine_head_with_fans_polygon": {
"default_value": [
[-75, -18],
[-75, 35],
@@ -41,7 +41,7 @@
]
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/makeblock_mcreate.def.json b/resources/definitions/makeblock_mcreate.def.json
new file mode 100644
index 0000000000..7a2d575395
--- /dev/null
+++ b/resources/definitions/makeblock_mcreate.def.json
@@ -0,0 +1,68 @@
+{
+ "version": 2,
+ "name": "Makeblock mCreate",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "author": "Makeblock",
+ "manufacturer": "Makeblock",
+ "visible": true,
+ "file_formats": "application/gzip;text/x-gcode",
+ "has_machine_quality": true,
+ "preferred_quality_type": "normal",
+ "machine_extruder_trains": {
+ "0": "makeblock_mcreate_extruder_0"
+ }
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "Makeblock mCreate"
+ },
+ "machine_width": {
+ "default_value": 225
+ },
+ "machine_depth": {
+ "default_value": 225
+ },
+ "machine_height": {
+ "default_value": 300
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "machine_head_with_fans_polygon": {
+ "default_value": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ]
+ },
+ "machine_gcode_flavor": {
+ "default_value": "Marlin"
+ },
+ "gantry_height": {
+ "value": 15.0
+ },
+ "machine_extruder_count": {
+ "default_value": 1
+ },
+ "machine_start_gcode": {
+ "default_value": "; Mcreate Start Gcode \nG28 ; Home all axes \nG92 E0 ; Reset Extruder\nG1 X0 Y0 Z15 F3000.0 ; Move to start position \nG1 E10 F400 ;load filament \nG1 E2 F400 ;retarct filament \nG92 E0 ; Reset Extruder \nG1 X0 Y130 Z15 F3000.0 \nG12 ; clean nozzle \nG1 X0 Y0 Z0.3 F3000.0 ; Move to start position \nG1 E9.0 F400 ;loadsome filament \nG92 E0 ; Reset Extruder \n; End of start GCode"
+ },
+ "machine_end_gcode": {
+ "default_value": "; Mcreate end Gcode \nG4 ; Wait command in buffer have finished \nG92 E0 \nG1 E-2 F300; retract filament \nG28 X Z; home x z axis \nG1 F3000 Y220;Move Heat Bed to the front for easy print removal \nM104 S0; Turn off the nozzle heat \nM140 S0; Turn off the bed heat \nM107 ; Turn off the Fan \nM84 ; Disable stepper motors \n; End of GCode"
+ }
+ }
+}
diff --git a/resources/definitions/makeit_pro_l.def.json b/resources/definitions/makeit_pro_l.def.json
index d40d63f97b..d601a5c309 100644
--- a/resources/definitions/makeit_pro_l.def.json
+++ b/resources/definitions/makeit_pro_l.def.json
@@ -4,8 +4,8 @@
"inherits": "fdmprinter",
"metadata": {
"visible": true,
- "author": "NA",
- "manufacturer": "NA",
+ "author": "unknown",
+ "manufacturer": "MAKEiT 3D",
"file_formats": "text/x-gcode",
"has_materials": false,
"machine_extruder_trains":
@@ -39,7 +39,7 @@
]
},
"gantry_height": {
- "default_value": 330
+ "value": "330"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
@@ -77,27 +77,12 @@
"retraction_amount": {
"default_value": 6
},
- "retraction_min_travel": {
- "default_value": 1.5
- },
- "speed_travel": {
- "default_value": 150
- },
"speed_print": {
"default_value": 60
},
"wall_thickness": {
"default_value": 1.2
},
- "bottom_thickness": {
- "default_value": 0.2
- },
- "speed_layer_0": {
- "default_value": 20
- },
- "speed_print_layer_0": {
- "default_value": 20
- },
"cool_min_layer_time_fan_speed_max": {
"default_value": 5
},
diff --git a/resources/definitions/makeit_pro_m.def.json b/resources/definitions/makeit_pro_m.def.json
index 1f0381df86..267646b647 100644
--- a/resources/definitions/makeit_pro_m.def.json
+++ b/resources/definitions/makeit_pro_m.def.json
@@ -4,8 +4,8 @@
"inherits": "fdmprinter",
"metadata": {
"visible": true,
- "author": "NA",
- "manufacturer": "NA",
+ "author": "unknown",
+ "manufacturer": "MAKEiT 3D",
"file_formats": "text/x-gcode",
"has_materials": false,
"machine_extruder_trains":
@@ -39,7 +39,7 @@
]
},
"gantry_height": {
- "default_value": 200
+ "value": "200"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
@@ -77,27 +77,12 @@
"retraction_amount": {
"default_value": 6
},
- "retraction_min_travel": {
- "default_value": 1.5
- },
- "speed_travel": {
- "default_value": 150
- },
"speed_print": {
"default_value": 60
},
"wall_thickness": {
"default_value": 1.2
},
- "bottom_thickness": {
- "default_value": 0.2
- },
- "speed_layer_0": {
- "default_value": 20
- },
- "speed_print_layer_0": {
- "default_value": 20
- },
"cool_min_layer_time_fan_speed_max": {
"default_value": 5
},
diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json
index be85e54967..96dca118af 100644
--- a/resources/definitions/maker_starter.def.json
+++ b/resources/definitions/maker_starter.def.json
@@ -33,7 +33,7 @@
"default_value": false
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
@@ -53,57 +53,15 @@
"layer_height_0": {
"default_value": 0.2
},
- "wall_line_count": {
- "default_value": 2
- },
- "top_layers": {
- "default_value": 4
- },
- "bottom_layers": {
- "default_value": 4
- },
"speed_print": {
"default_value": 50
},
- "speed_wall": {
- "default_value": 30
- },
- "speed_wall_0": {
- "default_value": 30
- },
- "speed_wall_x": {
- "default_value": 30
- },
- "speed_topbottom": {
- "default_value": 50
- },
- "speed_support": {
- "default_value": 50
- },
- "speed_travel": {
- "default_value": 120
- },
- "speed_layer_0": {
- "default_value": 20
- },
- "skirt_brim_speed": {
- "default_value": 15
- },
"speed_slowdown_layers": {
"default_value": 4
},
"infill_sparse_density": {
"default_value": 20
},
- "cool_fan_speed_min": {
- "default_value": 50
- },
- "cool_fan_speed_max": {
- "default_value": 100
- },
- "cool_fan_full_layer": {
- "default_value": 4
- },
"cool_min_layer_time": {
"default_value": 5
},
@@ -122,17 +80,11 @@
"support_z_distance": {
"default_value": 0.2
},
- "support_top_distance": {
- "default_value": 0.2
- },
- "support_bottom_distance": {
- "default_value": 0.24
- },
"support_pattern": {
"default_value": "ZigZag"
},
"support_infill_rate": {
- "default_value": 15
+ "value": "15 if support_enable else 0 if support_tree_enable else 15"
},
"adhesion_type": {
"default_value": "raft"
@@ -140,24 +92,6 @@
"skirt_brim_minimal_length": {
"default_value": 100
},
- "raft_base_line_spacing": {
- "default_value": 2
- },
- "raft_base_thickness": {
- "default_value": 0.3
- },
- "raft_base_line_width": {
- "default_value": 2
- },
- "raft_base_speed": {
- "default_value": 15
- },
- "raft_interface_thickness": {
- "default_value": 0.24
- },
- "raft_interface_line_width": {
- "default_value": 0.6
- },
"raft_airgap": {
"default_value": 0.2
},
diff --git a/resources/definitions/makerbotreplicator.def.json b/resources/definitions/makerbotreplicator.def.json
index 3b02215e74..24b556e1ee 100644
--- a/resources/definitions/makerbotreplicator.def.json
+++ b/resources/definitions/makerbotreplicator.def.json
@@ -18,9 +18,7 @@
"overrides": {
"prime_tower_size": { "default_value": 10.0 },
"infill_sparse_density": { "default_value": 10 },
- "speed_travel": { "default_value": 150 },
"layer_height": { "default_value": 0.15 },
- "material_print_temperature": { "default_value": 220 },
"machine_extruder_count": { "default_value": 1 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
diff --git a/resources/definitions/malyan_m180.def.json b/resources/definitions/malyan_m180.def.json
index 53864dabae..bb812b6dd6 100644
--- a/resources/definitions/malyan_m180.def.json
+++ b/resources/definitions/malyan_m180.def.json
@@ -1,5 +1,4 @@
{
- "id": "malyan_m180",
"version": 2,
"name": "Malyan M180",
"inherits": "fdmprinter",
@@ -53,7 +52,7 @@
"default_value": 92
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/malyan_m200.def.json b/resources/definitions/malyan_m200.def.json
index f2c01b3831..fc8756ff6a 100644
--- a/resources/definitions/malyan_m200.def.json
+++ b/resources/definitions/malyan_m200.def.json
@@ -1,5 +1,4 @@
{
- "id": "malyan_m200",
"version": 2,
"name": "Malyan M200",
"inherits": "fdmprinter",
@@ -30,8 +29,6 @@
"speed_wall_x": { "value": "speed_print" },
"speed_support": { "value": "speed_wall_0" },
"speed_layer_0": { "value": "round(speed_print / 2.0, 2)" },
- "speed_travel": { "default_value": 50 },
- "speed_travel_layer_0": { "default_value": 40 },
"speed_infill": { "value": "speed_print" },
"speed_topbottom": {"value": "speed_print / 2"},
@@ -80,7 +77,6 @@
"raft_surface_layers": { "default_value": 1 },
"skirt_line_count": { "default_value": 2},
"brim_width" : { "default_value": 5},
- "start_layers_at_same_position": { "default_value": true},
"retraction_combing": { "default_value": "noskin" },
"retraction_amount" : { "default_value": 4.5},
"retraction_speed" : { "default_value": 40},
diff --git a/resources/definitions/mankati_fullscale_xt_plus.def.json b/resources/definitions/mankati_fullscale_xt_plus.def.json
index 507e5209b2..b6fa040750 100644
--- a/resources/definitions/mankati_fullscale_xt_plus.def.json
+++ b/resources/definitions/mankati_fullscale_xt_plus.def.json
@@ -28,7 +28,7 @@
[ 3, 3 ]
]
},
- "gantry_height": { "default_value": 0 },
+ "gantry_height": { "value": "0" },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": {
@@ -41,23 +41,15 @@
"layer_height": { "default_value": 0.2 },
"wall_thickness": { "default_value": 0.8 },
"top_bottom_thickness": { "default_value": 0.3 },
- "material_print_temperature": { "default_value": 195 },
- "material_bed_temperature": { "default_value": 60 },
"retraction_enable": { "default_value": true },
"retraction_speed": { "default_value": 50 },
"retraction_amount": { "default_value": 0.8 },
"retraction_hop": { "default_value": 0.075 },
"speed_print": { "default_value": 60 },
- "speed_infill": { "default_value": 100 },
- "speed_topbottom": { "default_value": 15 },
- "speed_travel": { "default_value": 150 },
"speed_layer_0": {
- "minimum_value": "0.1",
- "default_value": 15.0
+ "minimum_value": "0.1"
},
- "infill_overlap": { "default_value": 10 },
"cool_fan_enabled": { "default_value": false },
- "cool_fan_speed": { "default_value": 0 },
"skirt_line_count": { "default_value": 3 },
"skirt_gap": { "default_value": 4 },
"skirt_brim_minimal_length": { "default_value": 200 }
diff --git a/resources/definitions/mendel90.def.json b/resources/definitions/mendel90.def.json
index 104ca7f42f..39cb4de8d3 100644
--- a/resources/definitions/mendel90.def.json
+++ b/resources/definitions/mendel90.def.json
@@ -5,7 +5,7 @@
"metadata":
{
"visible": true,
- "author": "Bo Herrmannsen",
+ "author": "Wilmer Gaona",
"manufacturer": "Nophead",
"file_formats": "text/x-gcode",
"platform": "mendel90_platform.stl",
@@ -23,10 +23,10 @@
"overrides": {
"machine_name": { "default_value": "Mendel90" },
"machine_start_gcode": {
- "default_value": "G21 ;metric values\nG90 ;absolute positioning\nG92 E0 ;zero the extruded length\nM107 ;start with the fan off\nG1 X90 Y200 F6000 ;go to the middle of the front\nG1 Z0.05 ;close to the bed\nG1 Z0.3 ;lift Z\n"
+ "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;absolute extrusion\nM107 ;start with the fan off\nG28 ;home\nG92 E0 ;zero the extruded length\nM140 S{material_bed_temperature_layer_0} ; set the bed temperature and continue on\nG1 X-50 Y98 F9000 ;go to the left of the top\nG1 Z0.05 ; close to the bed\nM104 S{material_print_temperature_layer_0}; pre-heat the extruder continue on\nM190 S{material_bed_temperature_layer_0} ;set the bed temp & wait\nM109 S{material_print_temperature_layer_0};set the extruder temp for layer 0 & wait\nG92 E0 ;zero the extruded length\nG1 X50 E10 F300 ; make a thick line to prime extruder\nG92 E0 ; reset extruder\nG1 E-4 F1800\nG1 Z0.3 ;lift Z\n"
},
"machine_end_gcode": {
- "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nM107 ;carriage fan off\nG91 ;relative positioning\nG1 Z10 ;Move up Z 10mm\nG90 ;back to absolute mode\nG1 E-1 F1200 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG92 E0 ;zero the extruded length\nG1 Y200 F5000 ;Move Y to middle of bed cooling fan\nM42 P42 S255 ;Turn on Bed cooling fan on\nG4 S420 ;Wait 7 mins\nM42 P42 S0 ;Turn off bed cooling fan\nG1 Y10 F5000 ;Move Y to front\nM84 ;steppers off\n"
+ "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nM107 ;carriage fan off\nG91 ;relative positioning\nG1 Z10 ;Move up Z 10mm\nG90 ;back to absolute mode\nG1 E-1 F1200 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG92 E0 ;zero the extruded length\nG1 Z200 X-100 F9000 ; go to top\nG1 Y100 F5000 ;Move Y to back\nM42 P42 S255 ;Turn on Bed cooling fan on\nG4 S10 ;Wait 10 seconds\nM42 P42 S0 ;Turn off bed cooling fan\nM84 ;steppers off\n"
},
"material_bed_temp_wait": {
"default_value": true
@@ -47,7 +47,7 @@
"default_value": true
},
"machine_center_is_zero": {
- "default_value": false
+ "default_value": true
},
"machine_extruder_count": {
"default_value": 1
@@ -68,7 +68,7 @@
"default_value": "RepRap (Marlin/Sprinter)"
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_head_with_fans_polygon":
{
diff --git a/resources/definitions/monoprice_select_mini_v1.def.json b/resources/definitions/monoprice_select_mini_v1.def.json
index a516d54b18..4fe67fc92e 100644
--- a/resources/definitions/monoprice_select_mini_v1.def.json
+++ b/resources/definitions/monoprice_select_mini_v1.def.json
@@ -1,5 +1,4 @@
{
- "id": "monoprice_select_mini_v1",
"version": 2,
"name": "Monoprice Select Mini V1",
"inherits": "malyan_m200",
diff --git a/resources/definitions/monoprice_select_mini_v2.def.json b/resources/definitions/monoprice_select_mini_v2.def.json
index bed4fb1adb..2364e49383 100644
--- a/resources/definitions/monoprice_select_mini_v2.def.json
+++ b/resources/definitions/monoprice_select_mini_v2.def.json
@@ -1,5 +1,4 @@
{
- "id": "monoprice_select_mini_v2",
"version": 2,
"name": "Monoprice Select Mini V2 (E3D)",
"inherits": "malyan_m200",
diff --git a/resources/definitions/monoprice_ultimate.def.json b/resources/definitions/monoprice_ultimate.def.json
index 48290f0941..445347b54e 100644
--- a/resources/definitions/monoprice_ultimate.def.json
+++ b/resources/definitions/monoprice_ultimate.def.json
@@ -1,52 +1,48 @@
{
- "version": 2,
- "name": "Monoprice Ultimate",
- "inherits": "wanhao_d6",
- "metadata": {
- "visible": true,
- "author": "Danny Tuppeny",
- "manufacturer": "monoprice",
- "file_formats": "text/x-gcode",
- "icon": "wanhao-icon.png",
- "has_materials": true,
- "platform": "wanhao_200_200_platform.obj",
- "platform_texture": "Wanhaobackplate.png",
- "machine_extruder_trains": {
- "0": "wanhao_d6_extruder_0"
+ "version": 2,
+ "name": "Monoprice Ultimate",
+ "inherits": "wanhao_d6",
+ "metadata": {
+ "visible": true,
+ "author": "Danny Tuppeny",
+ "manufacturer": "Monoprice",
+ "file_formats": "text/x-gcode",
+ "icon": "wanhao-icon.png",
+ "has_materials": true,
+ "platform": "wanhao_200_200_platform.obj",
+ "platform_texture": "Wanhaobackplate.png",
+ "machine_extruder_trains": {
+ "0": "wanhao_d6_extruder_0"
+ },
+ "platform_offset": [0, -28, 0]
},
- "platform_offset": [
- 0,
- -28,
- 0
- ]
- },
- "overrides": {
- "machine_name": {
- "default_value": "Monoprice Ultimate"
- },
- "machine_max_acceleration_x": {
- "default_value": 3000
- },
- "machine_max_acceleration_y": {
- "default_value": 3000
- },
- "machine_max_acceleration_z": {
- "default_value": 100
- },
- "machine_max_acceleration_e": {
- "default_value": 500
- },
- "machine_acceleration": {
- "default_value": 800
- },
- "machine_max_jerk_xy": {
- "default_value": 10.0
- },
- "machine_max_jerk_z": {
- "default_value": 0.4
- },
- "machine_max_jerk_e": {
- "default_value": 1.0
+ "overrides": {
+ "machine_name": {
+ "default_value": "Monoprice Ultimate"
+ },
+ "machine_max_acceleration_x": {
+ "default_value": 3000
+ },
+ "machine_max_acceleration_y": {
+ "default_value": 3000
+ },
+ "machine_max_acceleration_z": {
+ "default_value": 100
+ },
+ "machine_max_acceleration_e": {
+ "default_value": 500
+ },
+ "machine_acceleration": {
+ "default_value": 800
+ },
+ "machine_max_jerk_xy": {
+ "default_value": 10.0
+ },
+ "machine_max_jerk_z": {
+ "default_value": 0.4
+ },
+ "machine_max_jerk_e": {
+ "default_value": 1.0
+ }
}
- }
}
diff --git a/resources/definitions/nwa3d_a31.def.json b/resources/definitions/nwa3d_a31.def.json
new file mode 100644
index 0000000000..1cfd02fe7f
--- /dev/null
+++ b/resources/definitions/nwa3d_a31.def.json
@@ -0,0 +1,64 @@
+{
+ "name": "NWA3D A31",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "DragonJe",
+ "manufacturer": "NWA 3D LLC",
+ "file_formats": "text/x-gcode",
+ "platform_offset": [0, 0, 0],
+ "has_materials": true,
+ "has_variants": true,
+ "variants_name": "Nozzle Size",
+ "preferred_variant_name": "Standard 0.4mm",
+ "preferred_quality_type": "normal",
+ "has_machine_quality": true,
+ "preferred_material": "generic_pla",
+ "machine_extruder_trains":
+ {
+ "0": "nwa3d_a31_extruder_0"
+ }
+ },
+
+ "overrides": {
+ "machine_name": {
+ "default_value": "NWA3D A31"
+ },
+ "machine_width": {
+ "default_value": 300
+ },
+ "machine_height": {
+ "default_value": 400
+ },
+ "machine_depth": {
+ "default_value": 300
+ },
+ "machine_head_with_fans_polygon": {
+ "default_value": [
+ [-30, 34],
+ [-30, -32],
+ [30, -32],
+ [30, 34]
+ ]
+ },
+ "gantry_height": {
+ "value": "30"
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "machine_start_gcode": {
+ "default_value": "G28 ; Home\nG1 Z15.0 F6000 ; Move Z axis up 15mm\n ; Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0"
+ },
+ "machine_end_gcode": {
+ "default_value": "M104 S0\nM140 S0\n ; Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84"
+ }
+ }
+}
diff --git a/resources/definitions/nwa3d_a5.def.json b/resources/definitions/nwa3d_a5.def.json
index 3deb0027fd..1631860d47 100644
--- a/resources/definitions/nwa3d_a5.def.json
+++ b/resources/definitions/nwa3d_a5.def.json
@@ -10,55 +10,53 @@
"platform_offset": [0, 0, 0],
"has_materials": true,
"has_variants": false,
- "has_machine_materials": true,
- "has_variant_materials": false,
"preferred_quality_type": "normal",
"has_machine_quality": true,
"preferred_material": "generic_pla",
- "machine_extruder_trains":
+ "machine_extruder_trains":
{
"0": "nwa3d_a5_extruder_0"
}
},
-
+
"overrides": {
- "machine_name": {
- "default_value": "NWA3D A5"
+ "machine_name": {
+ "default_value": "NWA3D A5"
},
- "machine_width": {
- "default_value": 125
+ "machine_width": {
+ "default_value": 125
},
- "machine_height": {
- "default_value": 100
+ "machine_height": {
+ "default_value": 100
},
- "machine_depth": {
- "default_value": 150
+ "machine_depth": {
+ "default_value": 150
},
- "machine_head_polygon": {
+ "machine_head_with_fans_polygon": {
"default_value": [
- [-30, 34],
- [-30, -32],
- [30, -32],
+ [-30, 34],
+ [-30, -32],
+ [30, -32],
[30, 34]
- ]
+ ]
},
- "gantry_height": {
- "default_value": 30
+ "gantry_height": {
+ "value": "30"
},
- "machine_heated_bed": {
- "default_value": false
+ "machine_heated_bed": {
+ "default_value": false
},
"material_diameter": {
"default_value": 1.75
},
- "machine_gcode_flavor": {
- "default_value": "RepRap (RepRap)"
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (RepRap)"
},
- "machine_start_gcode": {
- "default_value": "G28 ; Home\nG1 Z15.0 F6000 ; Move Z axis up 15mm\n ; Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0"
+ "machine_start_gcode": {
+ "default_value": "G28 ; Home\nG1 Z15.0 F6000 ; Move Z axis up 15mm\n ; Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0"
},
- "machine_end_gcode": {
- "default_value": "M104 S0\nM140 S0\n ; Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84"
+ "machine_end_gcode": {
+ "default_value": "M104 S0\nM140 S0\n ; Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84"
}
}
}
diff --git a/resources/definitions/ord.def.json b/resources/definitions/ord.def.json
index de410b0d58..4a550602f2 100644
--- a/resources/definitions/ord.def.json
+++ b/resources/definitions/ord.def.json
@@ -19,12 +19,9 @@
},
"overrides": {
- "material_bed_temperature": { "default_value": 60 },
"prime_tower_size": { "default_value": 7.0710678118654755 },
"infill_sparse_density": { "default_value": 15 },
- "speed_travel": { "default_value": 150 },
"layer_height": { "default_value": 0.3 },
- "material_print_temperature": { "default_value": 240 },
"machine_extruder_count": { "default_value": 5 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
diff --git a/resources/definitions/peopoly_moai.def.json b/resources/definitions/peopoly_moai.def.json
index a578cc4240..8d7754a9ef 100644
--- a/resources/definitions/peopoly_moai.def.json
+++ b/resources/definitions/peopoly_moai.def.json
@@ -126,9 +126,6 @@
"adhesion_type": {
"value": "'none'"
},
- "acceleration_enabled": {
- "value": "False"
- },
"print_sequence": {
"enabled": false
},
@@ -173,8 +170,8 @@
"minimum_polygon_circumference": {
"value": "0.1"
},
- "meshfix_maximum_resolution": {
- "value": "0.005"
+ "meshfix_maximum_deviation": {
+ "value": "0.003"
},
"skin_outline_count": {
"value": 0
@@ -251,10 +248,6 @@
"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
},
diff --git a/resources/definitions/printrbot_play.def.json b/resources/definitions/printrbot_play.def.json
index e3a18a4eee..bf52363800 100644
--- a/resources/definitions/printrbot_play.def.json
+++ b/resources/definitions/printrbot_play.def.json
@@ -27,9 +27,8 @@
"retraction_speed": { "default_value": 45},
"adhesion_type": { "default_value": "skirt" },
"machine_head_with_fans_polygon": { "default_value": [[-32,999],[37,999],[37,-32],[-32,-32]] },
- "gantry_height": { "default_value": 55 },
+ "gantry_height": { "value": "55" },
"speed_print": { "default_value": 50 },
- "speed_travel": { "default_value": 55 },
"machine_max_feedrate_x": {"default_value": 125},
"machine_max_feedrate_y": {"default_value": 125},
"machine_max_feedrate_z": { "default_value": 5 },
diff --git a/resources/definitions/printrbot_simple.def.json b/resources/definitions/printrbot_simple.def.json
index fb65b77fa5..760ff383d1 100644
--- a/resources/definitions/printrbot_simple.def.json
+++ b/resources/definitions/printrbot_simple.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "Calvindog717",
- "manufacturer": "PrintrBot",
+ "manufacturer": "Printrbot",
"platform": "printrbot_simple_metal_platform.stl",
"platform_offset": [0, -3.45, 0],
"file_formats": "text/x-gcode",
@@ -30,7 +30,6 @@
[55, -99999]
]
},
- "gantry_height": { "default_value": 99999 },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": {
diff --git a/resources/definitions/printrbot_simple_extended.def.json b/resources/definitions/printrbot_simple_extended.def.json
index 1e004a8ca3..06c639f024 100644
--- a/resources/definitions/printrbot_simple_extended.def.json
+++ b/resources/definitions/printrbot_simple_extended.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "samsector",
- "manufacturer": "PrintrBot",
+ "manufacturer": "Printrbot",
"platform": "printrbot_simple_metal_upgrade.stl",
"platform_offset": [0, -0.3, 0],
"file_formats": "text/x-gcode",
@@ -30,7 +30,7 @@
[ -49, -20 ]
]
},
- "gantry_height": { "default_value": 99999 },
+ "gantry_height": { "value": "99999" },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": {
diff --git a/resources/definitions/printrbot_simple_makers_kit.def.json b/resources/definitions/printrbot_simple_makers_kit.def.json
index ad6ecee21e..1223f2a4d9 100644
--- a/resources/definitions/printrbot_simple_makers_kit.def.json
+++ b/resources/definitions/printrbot_simple_makers_kit.def.json
@@ -27,7 +27,7 @@
[60, -10]
]
},
- "gantry_height": { "default_value": 1000 },
+ "gantry_height": { "value": "1000" },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": {
diff --git a/resources/definitions/prusa_i3.def.json b/resources/definitions/prusa_i3.def.json
index 1f0eb37aec..267a7ba4e6 100644
--- a/resources/definitions/prusa_i3.def.json
+++ b/resources/definitions/prusa_i3.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "Quillford",
- "manufacturer": "Prusajr",
+ "manufacturer": "Prusa3D",
"file_formats": "text/x-gcode",
"platform": "prusai3_platform.stl",
"machine_extruder_trains":
@@ -31,14 +31,6 @@
"machine_center_is_zero": {
"default_value": false
},
- "machine_head_polygon": {
- "default_value": [
- [-75, -18],
- [-75, 35],
- [18, 35],
- [18, -18]
- ]
- },
"machine_head_with_fans_polygon": {
"default_value": [
[-75, -18],
@@ -48,7 +40,7 @@
]
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/prusa_i3_mk2.def.json b/resources/definitions/prusa_i3_mk2.def.json
index 5c5583b56f..5ae541049d 100644
--- a/resources/definitions/prusa_i3_mk2.def.json
+++ b/resources/definitions/prusa_i3_mk2.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "Apsu, Nounours2099",
- "manufacturer": "Prusa Research",
+ "manufacturer": "Prusa3D",
"file_formats": "text/x-gcode",
"platform": "prusai3_platform.stl",
"has_materials": true,
@@ -22,16 +22,13 @@
"machine_height": { "default_value": 200 },
"machine_depth": { "default_value": 210 },
"machine_center_is_zero": { "default_value": false },
- "material_bed_temperature": { "default_value": 55 },
"layer_height": { "default_value": 0.1 },
"layer_height_0": { "default_value": 0.15 },
"retraction_amount": { "default_value": 0.8 },
"retraction_speed": { "default_value": 35 },
- "retraction_retract_speed": { "default_value": 35 },
- "retraction_prime_speed": { "default_value": 35 },
"adhesion_type": { "default_value": "skirt" },
"machine_head_with_fans_polygon": { "default_value": [[-31,31],[34,31],[34,-40],[-31,-40]] },
- "gantry_height": { "default_value": 28 },
+ "gantry_height": { "value": "28" },
"machine_max_feedrate_z": { "default_value": 12 },
"machine_max_feedrate_e": { "default_value": 120 },
"machine_max_acceleration_z": { "default_value": 500 },
diff --git a/resources/definitions/prusa_i3_mk3.def.json b/resources/definitions/prusa_i3_mk3.def.json
new file mode 100644
index 0000000000..eddc1d88df
--- /dev/null
+++ b/resources/definitions/prusa_i3_mk3.def.json
@@ -0,0 +1,50 @@
+{
+ "version": 2,
+ "name": "Prusa i3 Mk3/Mk3s",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Prusa Research",
+ "manufacturer": "Prusa3D",
+ "file_formats": "text/x-gcode",
+ "icon": "icon_ultimaker2",
+ "platform": "Original_Prusa_i3_MK3S_MK3_platform.stl",
+ "has_materials": true,
+ "machine_extruder_trains":
+ {
+ "0": "prusa_i3_mk3_extruder_0"
+ }
+ },
+
+ "overrides": {
+ "machine_name": { "default_value": "Prusa i3 Mk3/Mk3s" },
+ "machine_heated_bed": { "default_value": true },
+ "machine_width": { "default_value": 250 },
+ "machine_height": { "default_value": 210 },
+ "machine_depth": { "default_value": 210 },
+ "machine_center_is_zero": { "default_value": false },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "layer_height": { "default_value": 0.15 },
+ "layer_height_0": { "default_value": 0.2 },
+ "retraction_amount": { "default_value": 0.8 },
+ "retraction_speed": { "default_value": 35 },
+ "adhesion_type": { "default_value": "skirt" },
+ "machine_head_with_fans_polygon": { "default_value": [[-31,31],[34,31],[34,-40],[-31,-40]] },
+ "gantry_height": { "value": 28 },
+ "machine_max_feedrate_z": { "default_value": 12 },
+ "machine_max_feedrate_e": { "default_value": 120 },
+ "machine_max_acceleration_z": { "default_value": 500 },
+ "machine_acceleration": { "default_value": 1000 },
+ "machine_max_jerk_xy": { "default_value": 10 },
+ "machine_max_jerk_z": { "default_value": 0.2 },
+ "machine_max_jerk_e": { "default_value": 2.5 },
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_start_gcode": {
+ "default_value": "G21 ; set units to millimeters\nG90 ; use absolute positioning\nM82 ; absolute extrusion mode\nM104 S{material_print_temperature_layer_0} ; set extruder temp\nM140 S{material_bed_temperature_layer_0} ; set bed temp\nM190 S{material_bed_temperature_layer_0} ; wait for bed temp\nM109 S{material_print_temperature_layer_0} ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG92 E0.0 ; reset extruder distance position\nG1 Y-3.0 F1000.0 ; go outside print area\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E21.5 F1000.0 ; intro line\nG92 E0.0 ; reset extruder distance position"
+ },
+ "machine_end_gcode": {
+ "default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y210; home X axis and push Y forward\nM84 ; disable motors"
+ }
+ }
+}
diff --git a/resources/definitions/prusa_i3_xl.def.json b/resources/definitions/prusa_i3_xl.def.json
index 9931be5c72..dae1bdce4f 100644
--- a/resources/definitions/prusa_i3_xl.def.json
+++ b/resources/definitions/prusa_i3_xl.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "guigashm",
- "manufacturer": "Prusajr",
+ "manufacturer": "Prusa3D",
"file_formats": "text/x-gcode",
"platform": "prusai3_xl_platform.stl",
"machine_extruder_trains":
@@ -31,7 +31,7 @@
"machine_center_is_zero": {
"default_value": false
},
- "machine_head_polygon": {
+ "machine_head_with_fans_polygon": {
"default_value": [
[-75, -18],
[-75, 35],
@@ -40,7 +40,7 @@
]
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/punchtec_connect_xl.def.json b/resources/definitions/punchtec_connect_xl.def.json
index 1efdd226fd..9bae80b0ac 100644
--- a/resources/definitions/punchtec_connect_xl.def.json
+++ b/resources/definitions/punchtec_connect_xl.def.json
@@ -16,16 +16,10 @@
},
"overrides": {
- "machine_head_polygon": { "default_value": [[ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0]] },
- "speed_travel": { "default_value": 150 },
+ "machine_head_with_fans_polygon": { "default_value": [[ 0, 0], [ 0, 0], [ 0, 0], [ 0, 0]] },
"prime_tower_size": { "default_value": 8.660254037844387 },
- "speed_wall_x": { "default_value": 40 },
- "speed_wall_0": { "default_value": 40 },
- "speed_topbottom": { "default_value": 40 },
"layer_height": { "default_value": 0.2 },
- "material_print_temperature": { "default_value": 195 },
"speed_print": { "default_value": 40 },
- "speed_infill": { "default_value": 40 },
"machine_extruder_count": { "default_value": 2 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
diff --git a/resources/definitions/raise3D_N2_dual.def.json b/resources/definitions/raise3D_N2_dual.def.json
index eff5884da8..530ad79d19 100644
--- a/resources/definitions/raise3D_N2_dual.def.json
+++ b/resources/definitions/raise3D_N2_dual.def.json
@@ -58,7 +58,7 @@
"default_value": "skirt"
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
@@ -67,7 +67,7 @@
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
- "default_value": "G90\nG21\n; home all axes\nG28\nG92 X0 Y0 Z0\n; move heatbed into position\nG1 X20.0 Y20.0 Z1.0 F1000\n; zero extruders\nG92 E0 E1\nT0; right tool\n; set extruder steps per mm\nM92 E140\nT1; left tool\n; set extruder steps per mm\nM92 E140\nT0; left tool\nG92 E0 E1\n; purge nozzle\nG1 E25 F250\nT1; left tool\nG92 E0 E1\n; purge nozzle\nG1 E25 F250\n; zero extruders\nG92 E0 E1\n; move heatbed down a little more\nG1 Z5.0 F20\n; wait 600ms\nG4 600\n; move to tack down the strands\nG1 X20.0 Y30.0 Z0 F9000\n; wait 600ms\nG4 600\n;move up a bit\nG1 Z5.0 F9000\n; wait 300ms\nG4 300\n;fast move to center\nG1 X152.5 Y152.5 F9000\nT0\n;Raise3D Job Start\nM117 Printing…\nM1001\n"
+ "default_value": "G90\nG21\n; home all axes\nG28\nG92 X0 Y0 Z0\n; move heatbed into position\nG1 X20.0 Y20.0 Z1.0 F1000\n; zero extruders\nG92 E0 E1\nT0; right tool\n; set extruder steps per mm\nM92 E140\nT1; left tool\n; set extruder steps per mm\nM92 E140\nT0; left tool\nG92 E0 E1\n; purge nozzle\nG1 E25 F250\nT1; left tool\nG92 E0 E1\n; purge nozzle\nG1 E25 F250\n; zero extruders\nG92 E0 E1\n; move heatbed down a little more\nG1 Z5.0 F20\n; wait 600ms\nG4 600\n; move to tack down the strands\nG1 X20.0 Y30.0 Z0 F9000\n; wait 600ms\nG4 600\n;move up a bit\nG1 Z5.0 F9000\n; wait 300ms\nG4 300\n;fast move to center\nG1 X152.5 Y152.5 F9000\nT0\n;Raise3D Job Start\nM117 Printing...\nM1001\n"
},
"machine_end_gcode": {
"default_value": "M107\nM1002\nM104 S0 T1\nM104 S0 T0\nM140 S0\nM117 Print Complete.\nG28 X0 Y0\nG91\nG1 Z10\nG90\nM84"
@@ -76,10 +76,10 @@
"default_value": 2
},
"prime_tower_position_x": {
- "default_value": 195
+ "value": "195"
},
"prime_tower_position_y": {
- "default_value": 149
+ "value": "149"
}
}
}
diff --git a/resources/definitions/raise3D_N2_plus_dual.def.json b/resources/definitions/raise3D_N2_plus_dual.def.json
index 06de52321a..ffc4afec16 100644
--- a/resources/definitions/raise3D_N2_plus_dual.def.json
+++ b/resources/definitions/raise3D_N2_plus_dual.def.json
@@ -58,7 +58,7 @@
"default_value": "skirt"
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
@@ -67,7 +67,7 @@
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
- "default_value": "G90\nG21\n; home all axes\nG28\nG92 X0 Y0 Z0\n; move heatbed into position\nG1 X20.0 Y20.0 Z1.0 F1000\n; zero extruders\nG92 E0 E1\nT0; right tool\n; set extruder steps per mm\nM92 E140\nT1; left tool\n; set extruder steps per mm\nM92 E140\nT0; left tool\nG92 E0 E1\n; purge nozzle\nG1 E25 F250\nT1; left tool\nG92 E0 E1\n; purge nozzle\nG1 E25 F250\n; zero extruders\nG92 E0 E1\n; move heatbed down a little more\nG1 Z5.0 F20\n; wait 600ms\nG4 600\n; move to tack down the strands\nG1 X20.0 Y30.0 Z0 F9000\n; wait 600ms\nG4 600\n;move up a bit\nG1 Z5.0 F9000\n; wait 300ms\nG4 300\n;fast move to center\nG1 X152.5 Y152.5 F9000\nT0\n;Raise3D Job Start\nM117 Printing…\nM1001\n"
+ "default_value": "G90\nG21\n; home all axes\nG28\nG92 X0 Y0 Z0\n; move heatbed into position\nG1 X20.0 Y20.0 Z1.0 F1000\n; zero extruders\nG92 E0 E1\nT0; right tool\n; set extruder steps per mm\nM92 E140\nT1; left tool\n; set extruder steps per mm\nM92 E140\nT0; left tool\nG92 E0 E1\n; purge nozzle\nG1 E25 F250\nT1; left tool\nG92 E0 E1\n; purge nozzle\nG1 E25 F250\n; zero extruders\nG92 E0 E1\n; move heatbed down a little more\nG1 Z5.0 F20\n; wait 600ms\nG4 600\n; move to tack down the strands\nG1 X20.0 Y30.0 Z0 F9000\n; wait 600ms\nG4 600\n;move up a bit\nG1 Z5.0 F9000\n; wait 300ms\nG4 300\n;fast move to center\nG1 X152.5 Y152.5 F9000\nT0\n;Raise3D Job Start\nM117 Printing...\nM1001\n"
},
"machine_end_gcode": {
"default_value": "M107\nM1002\nM104 S0 T1\nM104 S0 T0\nM140 S0\nM117 Print Complete.\nG28 X0 Y0\nG91\nG1 Z10\nG90\nM84"
@@ -76,10 +76,10 @@
"default_value": 2
},
"prime_tower_position_x": {
- "default_value": 195
+ "value": "195"
},
"prime_tower_position_y": {
- "default_value": 149
+ "value": "149"
}
}
}
diff --git a/resources/definitions/raise3D_N2_plus_single.def.json b/resources/definitions/raise3D_N2_plus_single.def.json
index b829147160..ccb169efb1 100644
--- a/resources/definitions/raise3D_N2_plus_single.def.json
+++ b/resources/definitions/raise3D_N2_plus_single.def.json
@@ -57,7 +57,7 @@
"default_value": "skirt"
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
@@ -66,16 +66,16 @@
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
- "default_value": "G90\nG21\n; home all axes\nG28\nG92 X0 Y0 Z0\n; move heatbed into position\nG1 X20.0 Y20.0 Z1.0 F1000\n; zero extruders\nG92 E0 E1\nT0; right tool\n; set extruder steps per mm\nM92 E140\n; purge nozzle\nG1 E25 F250\n; zero extruders\nG92 E0 E1\n; move heatbed down a little more\nG1 Z5.0 F20\n; wait 600ms\nG4 600\n; move to tack down the strands\nG1 X20.0 Y30.0 Z0 F9000\n; wait 600ms\nG4 600\n;move up a bit\nG1 Z5.0 F9000\n; wait 300ms\nG4 300\n;fast move to center\nG1 X152.5 Y152.5 F9000\nT0\n;Raise3D Job Start\nM117 Printing…\nM1001\n"
+ "default_value": "G90\nG21\n; home all axes\nG28\nG92 X0 Y0 Z0\n; move heatbed into position\nG1 X20.0 Y20.0 Z1.0 F1000\n; zero extruders\nG92 E0 E1\nT0; right tool\n; set extruder steps per mm\nM92 E140\n; purge nozzle\nG1 E25 F250\n; zero extruders\nG92 E0 E1\n; move heatbed down a little more\nG1 Z5.0 F20\n; wait 600ms\nG4 600\n; move to tack down the strands\nG1 X20.0 Y30.0 Z0 F9000\n; wait 600ms\nG4 600\n;move up a bit\nG1 Z5.0 F9000\n; wait 300ms\nG4 300\n;fast move to center\nG1 X152.5 Y152.5 F9000\nT0\n;Raise3D Job Start\nM117 Printing...\nM1001\n"
},
"machine_end_gcode": {
"default_value": "M107\nM1002\nM104 S0 T1\nM104 S0 T0\nM140 S0\nM117 Print Complete.\nG28 X0 Y0\nG91\nG1 Z10\nG90\nM84"
},
"prime_tower_position_x": {
- "default_value": 195
+ "value": "195"
},
"prime_tower_position_y": {
- "default_value": 149
+ "value": "149"
}
}
}
diff --git a/resources/definitions/raise3D_N2_single.def.json b/resources/definitions/raise3D_N2_single.def.json
index 899da5188f..f0915d1a31 100644
--- a/resources/definitions/raise3D_N2_single.def.json
+++ b/resources/definitions/raise3D_N2_single.def.json
@@ -57,7 +57,7 @@
"default_value": "skirt"
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
@@ -66,16 +66,16 @@
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
- "default_value": "G90\nG21\n; home all axes\nG28\nG92 X0 Y0 Z0\n; move heatbed into position\nG1 X20.0 Y20.0 Z1.0 F1000\n; zero extruders\nG92 E0 E1\nT0; right tool\n; set extruder steps per mm\nM92 E140\n; purge nozzle\nG1 E25 F250\n; zero extruders\nG92 E0 E1\n; move heatbed down a little more\nG1 Z5.0 F20\n; wait 600ms\nG4 600\n; move to tack down the strands\nG1 X20.0 Y30.0 Z0 F9000\n; wait 600ms\nG4 600\n;move up a bit\nG1 Z5.0 F9000\n; wait 300ms\nG4 300\n;fast move to center\nG1 X152.5 Y152.5 F9000\nT0\n;Raise3D Job Start\nM117 Printing…\nM1001\n"
+ "default_value": "G90\nG21\n; home all axes\nG28\nG92 X0 Y0 Z0\n; move heatbed into position\nG1 X20.0 Y20.0 Z1.0 F1000\n; zero extruders\nG92 E0 E1\nT0; right tool\n; set extruder steps per mm\nM92 E140\n; purge nozzle\nG1 E25 F250\n; zero extruders\nG92 E0 E1\n; move heatbed down a little more\nG1 Z5.0 F20\n; wait 600ms\nG4 600\n; move to tack down the strands\nG1 X20.0 Y30.0 Z0 F9000\n; wait 600ms\nG4 600\n;move up a bit\nG1 Z5.0 F9000\n; wait 300ms\nG4 300\n;fast move to center\nG1 X152.5 Y152.5 F9000\nT0\n;Raise3D Job Start\nM117 Printing...\nM1001\n"
},
"machine_end_gcode": {
"default_value": "M107\nM1002\nM104 S0 T1\nM104 S0 T0\nM140 S0\nM117 Print Complete.\nG28 X0 Y0\nG91\nG1 Z10\nG90\nM84"
},
"prime_tower_position_x": {
- "default_value": 195
+ "value": "195"
},
"prime_tower_position_y": {
- "default_value": 149
+ "value": "149"
}
}
}
diff --git a/resources/definitions/renkforce_rf100.def.json b/resources/definitions/renkforce_rf100.def.json
index 41549fb531..2ff34a7519 100644
--- a/resources/definitions/renkforce_rf100.def.json
+++ b/resources/definitions/renkforce_rf100.def.json
@@ -183,7 +183,7 @@
"value": "False"
},
"support_infill_rate": {
- "value": "15.0"
+ "value": "15 if support_enable else 0 if support_tree_enable else 15"
},
"support_pattern": {
"default_value": "lines"
diff --git a/resources/definitions/rigid3d.def.json b/resources/definitions/rigid3d.def.json
index 43ffd6924a..ba90894f7d 100644
--- a/resources/definitions/rigid3d.def.json
+++ b/resources/definitions/rigid3d.def.json
@@ -21,27 +21,17 @@
"machine_end_gcode": {
"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn ectruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"
},
- "machine_head_polygon": { "default_value": [[ 22, 67], [ 22, 51], [ 36, 51], [ 36, 67]] },
+ "machine_head_with_fans_polygon": { "default_value": [[ 22, 67], [ 22, 51], [ 36, 51], [ 36, 67]] },
"skirt_gap": { "default_value": 5.0 },
"cool_min_layer_time": { "default_value": 10 },
"prime_tower_size": { "default_value": 7.745966692414834 },
- "speed_wall_x": { "default_value": 40 },
- "speed_travel": { "default_value": 100 },
- "bottom_thickness": { "default_value": 0.75 },
"layer_height_0": { "default_value": 0.25 },
"support_angle": { "default_value": 45 },
- "material_bed_temperature": { "default_value": 100 },
- "top_thickness": { "default_value": 0.75 },
- "material_print_temperature": { "default_value": 235 },
"retraction_speed": { "default_value": 60.0 },
"wall_thickness": { "default_value": 0.8 },
- "retraction_min_travel": { "default_value": 2 },
- "speed_wall_0": { "default_value": 30 },
"retraction_amount": { "default_value": 1 },
- "speed_topbottom": { "default_value": 30 },
"layer_height": { "default_value": 0.25 },
"speed_print": { "default_value": 40 },
- "speed_infill": { "default_value": 40 },
"machine_extruder_count": { "default_value": 1 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
diff --git a/resources/definitions/rigid3d_3rdgen.def.json b/resources/definitions/rigid3d_3rdgen.def.json
index bb3414b75d..6e1a93fb40 100644
--- a/resources/definitions/rigid3d_3rdgen.def.json
+++ b/resources/definitions/rigid3d_3rdgen.def.json
@@ -21,24 +21,16 @@
"machine_end_gcode": {
"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn extruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"
},
- "machine_head_polygon": { "default_value": [[ 18, 0], [ 18, 65], [ 32, 65], [ 32, 0]] },
+ "machine_head_with_fans_polygon": { "default_value": [[ 18, 0], [ 18, 65], [ 32, 65], [ 32, 0]] },
"cool_min_layer_time": { "default_value": 10 },
"prime_tower_size": { "default_value": 7.745966692414834 },
"skirt_gap": { "default_value": 5.0 },
- "speed_travel": { "default_value": 120 },
- "bottom_thickness": { "default_value": 0.75 },
"layer_height_0": { "default_value": 0.25 },
"support_angle": { "default_value": 45 },
- "material_bed_temperature": { "default_value": 100 },
- "retraction_min_travel": { "default_value": 2 },
- "speed_wall_0": { "default_value": 30 },
"retraction_speed": { "default_value": 60.0 },
"wall_thickness": { "default_value": 0.8 },
- "material_print_temperature": { "default_value": 235 },
"retraction_amount": { "default_value": 1 },
- "speed_topbottom": { "default_value": 25 },
"layer_height": { "default_value": 0.25 },
- "top_thickness": { "default_value": 0.75 },
"machine_extruder_count": { "default_value": 1 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
diff --git a/resources/definitions/rigid3d_hobby.def.json b/resources/definitions/rigid3d_hobby.def.json
index db48195fe0..d89c1aeaff 100644
--- a/resources/definitions/rigid3d_hobby.def.json
+++ b/resources/definitions/rigid3d_hobby.def.json
@@ -15,27 +15,19 @@
},
"overrides": {
- "machine_head_polygon": { "default_value": [[ 16, 30], [ 16, 45], [ 16, 45], [ 16, 30]] },
+ "machine_head_with_fans_polygon": { "default_value": [[ 16, 30], [ 16, 45], [ 16, 45], [ 16, 30]] },
"prime_tower_size": { "default_value": 8.660254037844387 },
- "speed_travel": { "default_value": 40 },
"skirt_gap": { "default_value": 5.0 },
"cool_min_layer_time": { "default_value": 15 },
"support_pattern": { "default_value": "grid" },
"layer_height_0": { "default_value": 0.25 },
- "speed_wall_x": { "default_value": 30 },
"skirt_line_count": { "default_value": 2 },
"support_angle": { "default_value": 45 },
- "speed_topbottom": { "default_value": 20 },
- "material_print_temperature": { "default_value": 205 },
"retraction_speed": { "default_value": 80 },
"wall_thickness": { "default_value": 0.8 },
- "retraction_min_travel": { "default_value": 2 },
- "speed_wall_0": { "default_value": 20 },
"retraction_amount": { "default_value": 2 },
- "speed_layer_0": { "default_value": 15 },
"layer_height": { "default_value": 0.2 },
"speed_print": { "default_value": 30 },
- "speed_infill": { "default_value": 30 },
"machine_extruder_count": { "default_value": 1 },
"machine_heated_bed": { "default_value": false },
"machine_center_is_zero": { "default_value": false },
diff --git a/resources/definitions/rigid3d_mucit.def.json b/resources/definitions/rigid3d_mucit.def.json
index 42cd99a3bd..75853fab8b 100644
--- a/resources/definitions/rigid3d_mucit.def.json
+++ b/resources/definitions/rigid3d_mucit.def.json
@@ -76,14 +76,9 @@
"default_value": true
},
"cool_fan_speed": {
- "default_value": 100,
"value": "100"
},
- "cool_fan_speed_min": {
- "default_value": 0
- },
"cool_fan_full_at_height": {
- "default_value": 0.5,
"value": "0.5"
},
"support_z_distance": {
diff --git a/resources/definitions/rigid3d_zero.def.json b/resources/definitions/rigid3d_zero.def.json
index f55f913a56..54bd2c3dca 100644
--- a/resources/definitions/rigid3d_zero.def.json
+++ b/resources/definitions/rigid3d_zero.def.json
@@ -21,24 +21,14 @@
"machine_end_gcode": {
"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn ectruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"
},
- "machine_head_polygon": { "default_value": [[ 40, 15], [ 40, 60], [ 30, 60], [ 30, 15]] },
+ "machine_head_with_fans_polygon": { "default_value": [[ 40, 15], [ 40, 60], [ 30, 60], [ 30, 15]] },
"support_pattern": { "default_value": "grid" },
"cool_min_layer_time": { "default_value": 10 },
- "speed_travel": { "default_value": 80 },
"support_angle": { "default_value": 45 },
- "retraction_min_travel": { "default_value": 2 },
- "speed_wall_0": { "default_value": 20 },
- "speed_layer_0": { "default_value": 15 },
- "speed_infill": { "default_value": 30 },
- "speed_topbottom": { "default_value": 30 },
"prime_tower_size": { "default_value": 7.745966692414834 },
"skirt_line_count": { "default_value": 2 },
- "speed_wall_x": { "default_value": 30 },
- "bottom_thickness": { "default_value": 0.75 },
"layer_height_0": { "default_value": 0.25 },
- "top_thickness": { "default_value": 0.75 },
"wall_thickness": { "default_value": 0.8 },
- "material_print_temperature": { "default_value": 195 },
"retraction_amount": { "default_value": 1.5 },
"skirt_gap": { "default_value": 5.0 },
"layer_height": { "default_value": 0.25 },
diff --git a/resources/definitions/rigid3d_zero2.def.json b/resources/definitions/rigid3d_zero2.def.json
index 09390ed8b5..cc922769f7 100644
--- a/resources/definitions/rigid3d_zero2.def.json
+++ b/resources/definitions/rigid3d_zero2.def.json
@@ -44,9 +44,6 @@
"material_print_temperature": {
"value": 235
},
- "material_bed_temperature": {
- "default_value": 100
- },
"speed_print": {
"default_value": 40
},
@@ -55,7 +52,7 @@
},
"speed_travel": {
"value": 100
- },
+ },
"support_enable": {
"default_value": false
},
@@ -81,7 +78,7 @@
"default_value": false
},
"gantry_height": {
- "default_value": 25
+ "value": "25"
},
"machine_gcode_flavor": {
"default_value": "RepRap"
@@ -90,14 +87,9 @@
"default_value": false
},
"cool_fan_speed": {
- "default_value": 50,
"value": 50
},
- "cool_fan_speed_min": {
- "default_value": 0
- },
"cool_fan_full_at_height": {
- "default_value": 1.0,
"value": 1.0
},
"support_z_distance": {
diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json
index 5eb346c7ca..d6fb4f1651 100644
--- a/resources/definitions/rigidbot.def.json
+++ b/resources/definitions/rigidbot.def.json
@@ -29,7 +29,7 @@
"default_value": true
},
"gantry_height": {
- "default_value": 0
+ "value": "0"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
@@ -49,37 +49,15 @@
"top_bottom_thickness": {
"default_value": 0.3
},
- "material_print_temperature": {
- "default_value": 195
- },
- "material_bed_temperature": {
- "default_value": 60
- },
"speed_print": {
"default_value": 60
},
- "speed_infill": {
- "default_value": 100
- },
- "speed_topbottom": {
- "default_value": 15
- },
- "speed_travel": {
- "default_value": 150
- },
"speed_layer_0": {
- "default_value": 15,
"minimum_value": "0.1"
},
- "infill_overlap": {
- "default_value": 10
- },
"cool_fan_enabled": {
"default_value": false
},
- "cool_fan_speed": {
- "default_value": 0
- },
"skirt_line_count": {
"default_value": 3
},
diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json
index 581b6144a0..9568417acc 100644
--- a/resources/definitions/rigidbot_big.def.json
+++ b/resources/definitions/rigidbot_big.def.json
@@ -29,7 +29,7 @@
"default_value": true
},
"gantry_height": {
- "default_value": 0
+ "value": "0"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
@@ -49,37 +49,15 @@
"top_bottom_thickness": {
"default_value": 0.3
},
- "material_print_temperature": {
- "default_value": 195
- },
- "material_bed_temperature": {
- "default_value": 60
- },
"speed_print": {
"default_value": 60
},
- "speed_infill": {
- "default_value": 100
- },
- "speed_topbottom": {
- "default_value": 15
- },
- "speed_travel": {
- "default_value": 150
- },
"speed_layer_0": {
- "default_value": 15,
"minimum_value": "0.1"
},
- "infill_overlap": {
- "default_value": 10
- },
"cool_fan_enabled": {
"default_value": false
},
- "cool_fan_speed": {
- "default_value": 0
- },
"skirt_line_count": {
"default_value": 3
},
diff --git a/resources/definitions/robo_3d_r1.def.json b/resources/definitions/robo_3d_r1.def.json
index 8d7698e198..36b8addd27 100644
--- a/resources/definitions/robo_3d_r1.def.json
+++ b/resources/definitions/robo_3d_r1.def.json
@@ -22,28 +22,16 @@
"default_value": " M104 S0 ;extruder heater off\n M140 S0 ;heated bed heater off (if you have it)\n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning\n"
},
"cool_min_layer_time": { "default_value": 7 },
- "speed_topbottom": { "default_value": 40 },
"retraction_speed": { "default_value": 50 },
- "layer_0_z_overlap": { "default_value": 0.2 },
"cool_min_speed": { "default_value": 19 },
- "material_bed_temperature": { "default_value": 60 },
"support_angle": { "default_value": 50 },
- "speed_layer_0": { "default_value": 30 },
- "line_width": { "default_value": 0.4 },
- "speed_infill": { "default_value": 60 },
"prime_tower_size": { "default_value": 8.660254037844387 },
"support_enable": { "default_value": true },
- "cool_fan_full_at_height": { "default_value": 0.1 },
- "bottom_thickness": { "default_value": 1.2 },
"raft_airgap": { "default_value": 0.2 },
"layer_height_0": { "default_value": 0.15 },
- "top_thickness": { "default_value": 1.2 },
- "speed_wall_0": { "default_value": 40 },
- "retraction_min_travel": { "default_value": 5 },
"material_flow": { "default_value": 100 },
"infill_sparse_density": { "default_value": 10 },
"wall_thickness": { "default_value": 1.2 },
- "material_print_temperature": { "default_value": 190 },
"retraction_amount": { "default_value": 3 },
"layer_height": { "default_value": 0.2 },
"speed_print": { "default_value": 40 },
diff --git a/resources/definitions/seemecnc_artemis.def.json b/resources/definitions/seemecnc_artemis.def.json
index ec92f528d7..88c1d84b3d 100644
--- a/resources/definitions/seemecnc_artemis.def.json
+++ b/resources/definitions/seemecnc_artemis.def.json
@@ -27,13 +27,11 @@
"machine_name": { "default_value": "Artemis" },
"machine_shape": { "default_value": "elliptic" },
"machine_width": { "default_value": 290 },
- "relative_extrusion": { "default_value": false },
+ "relative_extrusion": { "value": "False" },
"retraction_amount": { "default_value": 3.2 },
"retraction_combing": { "default_value": "off" },
"retraction_hop_enabled": { "default_value": true },
"retraction_hop_only_when_collides": { "default_value": false },
- "retraction_prime_speed": { "default_value": 45 },
- "retraction_retract_speed": { "default_value": 45 },
"retraction_speed": { "default_value": 45 },
"machine_start_gcode": {
"default_value": "G28\nG1 Z15.0 F10000\nG92 E0"
diff --git a/resources/definitions/seemecnc_v32.def.json b/resources/definitions/seemecnc_v32.def.json
index d4316c25d9..0f49410116 100644
--- a/resources/definitions/seemecnc_v32.def.json
+++ b/resources/definitions/seemecnc_v32.def.json
@@ -27,13 +27,11 @@
"machine_name": { "default_value": "Rostock Max V3.2" },
"machine_shape": { "default_value": "elliptic" },
"machine_width": { "default_value": 265 },
- "relative_extrusion": { "default_value": false },
+ "relative_extrusion": { "value": "False" },
"retraction_amount": { "default_value": 3.2 },
"retraction_combing": { "default_value": "off" },
"retraction_hop_enabled": { "default_value": true },
"retraction_hop_only_when_collides": { "default_value": false },
- "retraction_prime_speed": { "default_value": 45 },
- "retraction_retract_speed": { "default_value": 45 },
"retraction_speed": { "default_value": 45 },
"machine_start_gcode": {
"default_value": "G28\nG1 Z15.0 F10000\nG92 E0"
diff --git a/resources/definitions/skriware_2.def.json b/resources/definitions/skriware_2.def.json
new file mode 100644
index 0000000000..584cdd1708
--- /dev/null
+++ b/resources/definitions/skriware_2.def.json
@@ -0,0 +1,598 @@
+{
+ "name": "Skriware 2",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Skriware",
+ "manufacturer": "Skriware",
+ "category": "Other",
+ "file_formats": "text/x-gcode",
+ "platform_offset": [
+ 0,
+ 0,
+ 0
+ ],
+ "supports_usb_connection": false,
+ "platform": "skriware_2_platform.stl",
+ "machine_extruder_trains": {
+ "0": "skriware_2_extruder_0",
+ "1": "skriware_2_extruder_1"
+ }
+ },
+ "overrides": {
+ "jerk_print_layer_0": {
+ "value": "5"
+ },
+ "jerk_prime_tower": {
+ "value": "5"
+ },
+ "expand_skins_expand_distance": {
+ "value": "1.2"
+ },
+ "jerk_support_interface": {
+ "value": "5"
+ },
+ "jerk_travel_layer_0": {
+ "value": "5.0"
+ },
+ "wipe_retraction_prime_speed": {
+ "value": "30"
+ },
+ "material_standby_temperature": {
+ "default_value": 195
+ },
+ "acceleration_support_bottom": {
+ "value": "250"
+ },
+ "raft_base_line_width": {
+ "value": "0.5"
+ },
+ "raft_speed": {
+ "value": "30.0"
+ },
+ "jerk_topbottom": {
+ "value": "5"
+ },
+ "ironing_inset": {
+ "value": "0.2"
+ },
+ "acceleration_wall": {
+ "value": "250"
+ },
+ "cross_infill_pocket_size": {
+ "value": "5.333333333333333"
+ },
+ "jerk_support_roof": {
+ "value": "5"
+ },
+ "acceleration_print": {
+ "default_value": 250
+ },
+ "meshfix_maximum_travel_resolution": {
+ "value": "0.8"
+ },
+ "support_top_distance": {
+ "value": "0.22"
+ },
+ "acceleration_enabled": {
+ "default_value": true
+ },
+ "optimize_wall_printing_order": {
+ "default_value": true
+ },
+ "jerk_layer_0": {
+ "value": "5"
+ },
+ "infill_line_distance": {
+ "value": "5.333333333333333"
+ },
+ "acceleration_ironing": {
+ "value": "250"
+ },
+ "material_print_temperature_layer_0": {
+ "value": "195"
+ },
+ "bridge_skin_speed_2": {
+ "value": "15"
+ },
+ "acceleration_travel": {
+ "value": "250"
+ },
+ "switch_extruder_retraction_speed": {
+ "value": "30"
+ },
+ "jerk_print": {
+ "default_value": 5
+ },
+ "material_guid": {
+ "default_value": "0ff92885-617b-4144-a03c-9989872454bc"
+ },
+ "raft_interface_acceleration": {
+ "value": "250"
+ },
+ "acceleration_support_interface": {
+ "value": "250"
+ },
+ "cool_fan_full_layer": {
+ "value": "1"
+ },
+ "skirt_brim_minimal_length": {
+ "default_value": 50
+ },
+ "material_bed_temperature": {
+ "value": "50"
+ },
+ "speed_slowdown_layers": {
+ "default_value": 1
+ },
+ "speed_travel": {
+ "value": "150"
+ },
+ "skin_overlap": {
+ "value": "15"
+ },
+ "acceleration_infill": {
+ "value": "250"
+ },
+ "support_roof_material_flow": {
+ "value": "99"
+ },
+ "raft_base_jerk": {
+ "value": "5"
+ },
+ "retraction_retract_speed": {
+ "value": "30"
+ },
+ "infill_wipe_dist": {
+ "value": "0.1"
+ },
+ "jerk_wall_x": {
+ "value": "5"
+ },
+ "layer_height": {
+ "default_value": 0.2
+ },
+ "bottom_skin_expand_distance": {
+ "value": "1.2000000000000002"
+ },
+ "machine_start_gcode": {
+ "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nG28 X0 Y0;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM420 S1 Z0.9 ;enable bed levelling\nG1 Z10 F250 ;move the platform down 10mm\nM107 ;fan off\nM42 P11 S255 ;turn on front fan\nM140 S{material_bed_temperature}\nM104 T0 S{material_print_temperature}\nM104 T1 S{material_print_temperature}\nG1 F2500 Y260\nM190 S{material_bed_temperature}\nM109 T0 S{material_print_temperature}\nM109 T1 S{material_print_temperature}\nM60 ;enable E-FADE Algorithm\nM62 A ;filament sensor off\nG92 E0 ;zero the extruded length\nT1\nG92 E0;zero the extruded length\nG1 F300 Z0.3\nG1 F1200 X20\nG1 F1200 X180 E21 ;extrude 21 mm of feed stock\nG1 F1200 E15 ;retracting 6 mm\nG1 F2000 E21\nG1 F2000 E15\nG1 F300 Z1.5\nG92 E0 ;zero the extruded length again\nT0\nG92 E0 ;zero the extruded length\nG1 F1200 Y258\nG1 F300 Z0.3\nG1 F1200 X40 E21 ;extrude 21 mm of feed stock\nG1 F1200 E15 ;retracting 6 mm\nG1 F2000 E21\nG1 F2000 E15\nG1 Z1.5\nM61 A\nM63 A ;filament sensor on\nG92 E0 ;zero the extruded length again\nM58 ;end of Start G-Code and signal retract management"
+ },
+ "travel_retract_before_outer_wall": {
+ "default_value": true
+ },
+ "xy_offset_layer_0": {
+ "value": "-0.16"
+ },
+ "adhesion_type": {
+ "default_value": "raft"
+ },
+ "min_skin_width_for_expansion": {
+ "value": "0.671279704941824"
+ },
+ "support_bottom_material_flow": {
+ "value": "99"
+ },
+ "prime_tower_position_x": {
+ "value": "1"
+ },
+ "machine_depth": {
+ "default_value": 260
+ },
+ "retraction_speed": {
+ "default_value": 30
+ },
+ "support_skip_some_zags": {
+ "default_value": true
+ },
+ "remove_empty_first_layers": {
+ "default_value": false
+ },
+ "z_seam_x": {
+ "value": "115"
+ },
+ "support_xy_distance_overhang": {
+ "value": "0.5"
+ },
+ "support_tree_wall_thickness": {
+ "value": "0.4"
+ },
+ "acceleration_print_layer_0": {
+ "value": "250"
+ },
+ "support_xy_distance": {
+ "default_value": 0.8
+ },
+ "support_roof_line_distance": {
+ "value": "0.5714285714285714"
+ },
+ "jerk_enabled": {
+ "default_value": true
+ },
+ "min_infill_area": {
+ "default_value": 1
+ },
+ "travel_avoid_supports": {
+ "default_value": true
+ },
+ "bottom_layers": {
+ "value": "3"
+ },
+ "multiple_mesh_overlap": {
+ "default_value": 0
+ },
+ "retraction_hop_enabled": {
+ "default_value": true
+ },
+ "acceleration_topbottom": {
+ "value": "250"
+ },
+ "jerk_wall": {
+ "value": "5"
+ },
+ "jerk_wall_0": {
+ "value": "5"
+ },
+ "skin_overlap_mm": {
+ "value": "0.06"
+ },
+ "retraction_min_travel": {
+ "value": "1"
+ },
+ "support_interface_material_flow": {
+ "value": "99"
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "speed_roofing": {
+ "value": "30.0"
+ },
+ "skin_outline_count": {
+ "default_value": 0
+ },
+ "skin_no_small_gaps_heuristic": {
+ "default_value": true
+ },
+ "top_bottom_pattern_0": {
+ "value": "'zigzag'"
+ },
+ "top_skin_expand_distance": {
+ "value": "1.2000000000000002"
+ },
+ "acceleration_travel_layer_0": {
+ "value": "250.0"
+ },
+ "prime_tower_min_volume": {
+ "default_value": 4
+ },
+ "switch_extruder_retraction_speeds": {
+ "default_value": 30
+ },
+ "skin_preshrink": {
+ "value": "1.2000000000000002"
+ },
+ "material_bed_temperature_layer_0": {
+ "value": "50"
+ },
+ "support_tree_collision_resolution": {
+ "value": "0.2"
+ },
+ "machine_height": {
+ "default_value": 210
+ },
+ "raft_acceleration": {
+ "value": "250"
+ },
+ "fill_outline_gaps": {
+ "default_value": true
+ },
+ "wall_x_material_flow": {
+ "value": "99"
+ },
+ "jerk_support_bottom": {
+ "value": "5"
+ },
+ "machine_end_gcode": {
+ "default_value": "M59\nG92 E1\nG1 E-1 F300\nM104 T0 S0\nM104 T1 S0\nM140 S0\nG28 X0 Y0\nM84\nM106 S0\nM107"
+ },
+ "infill_sparse_density": {
+ "default_value": 15
+ },
+ "meshfix_maximum_deviation": {
+ "default_value": 0.005
+ },
+ "wall_0_material_flow": {
+ "value": "99"
+ },
+ "material_adhesion_tendency": {
+ "default_value": 0
+ },
+ "prime_tower_flow": {
+ "value": "99"
+ },
+ "prime_tower_position_y": {
+ "value": "1"
+ },
+ "support_material_flow": {
+ "value": "99"
+ },
+ "retract_at_layer_change": {
+ "default_value": true
+ },
+ "machine_extruder_count": {
+ "default_value": 2
+ },
+ "wall_thickness": {
+ "default_value": 1.2
+ },
+ "support_infill_sparse_thickness": {
+ "value": "0.2"
+ },
+ "raft_surface_acceleration": {
+ "value": "250"
+ },
+ "roofing_layer_count": {
+ "value": "1"
+ },
+ "skirt_brim_line_width": {
+ "value": "0.5"
+ },
+ "jerk_support": {
+ "value": "5"
+ },
+ "raft_surface_jerk": {
+ "value": "5"
+ },
+ "speed_equalize_flow_max": {
+ "default_value": 40
+ },
+ "raft_surface_speed": {
+ "value": "30.0"
+ },
+ "jerk_travel": {
+ "value": "5"
+ },
+ "support_zag_skip_count": {
+ "value": "8"
+ },
+ "retraction_combing": {
+ "default_value": "infill"
+ },
+ "raft_interface_line_spacing": {
+ "value": "0.4"
+ },
+ "layer_height_0": {
+ "default_value": 0.2
+ },
+ "extruders_enabled_count": {
+ "value": "2"
+ },
+ "support_line_distance": {
+ "value": "1.3333333333333333"
+ },
+ "support_roof_density": {
+ "value": "70"
+ },
+ "raft_base_line_spacing": {
+ "value": "0.8"
+ },
+ "acceleration_prime_tower": {
+ "value": "250"
+ },
+ "skin_material_flow": {
+ "value": "99"
+ },
+ "support_z_distance": {
+ "default_value": 0.22
+ },
+ "bottom_skin_preshrink": {
+ "value": "1.2000000000000002"
+ },
+ "jerk_skirt_brim": {
+ "value": "5"
+ },
+ "z_seam_y": {
+ "value": "180"
+ },
+ "skirt_line_count": {
+ "default_value": 2
+ },
+ "raft_margin": {
+ "default_value": 4
+ },
+ "infill_material_flow": {
+ "value": "99"
+ },
+ "wipe_retraction_retract_speed": {
+ "value": "30"
+ },
+ "z_seam_corner": {
+ "default_value": "z_seam_corner_weighted"
+ },
+ "support_roof_height": {
+ "value": "0.4"
+ },
+ "top_layers": {
+ "value": "4"
+ },
+ "support_infill_rate": {
+ "value": "30"
+ },
+ "raft_interface_speed": {
+ "value": "35"
+ },
+ "default_material_print_temperature": {
+ "default_value": 195
+ },
+ "acceleration_layer_0": {
+ "value": "250"
+ },
+ "support_skip_zag_per_mm": {
+ "default_value": 10
+ },
+ "material_initial_print_temperature": {
+ "value": "195"
+ },
+ "raft_interface_jerk": {
+ "value": "5"
+ },
+ "machine_width": {
+ "default_value": 210
+ },
+ "wall_line_count": {
+ "value": "3"
+ },
+ "retraction_amount": {
+ "default_value": 3
+ },
+ "infill_sparse_thickness": {
+ "value": "0.2"
+ },
+ "support_initial_layer_line_distance": {
+ "value": "1.3333333333333333"
+ },
+ "jerk_support_infill": {
+ "value": "5"
+ },
+ "acceleration_roofing": {
+ "value": "250"
+ },
+ "retraction_extrusion_window": {
+ "value": "3"
+ },
+ "raft_interface_line_width": {
+ "value": "0.4"
+ },
+ "acceleration_support_roof": {
+ "value": "250"
+ },
+ "support_brim_line_count": {
+ "value": "16"
+ },
+ "layer_0_z_overlap": {
+ "value": "0.1"
+ },
+ "support_angle": {
+ "default_value": 60
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "raft_surface_thickness": {
+ "value": "0.2"
+ },
+ "cool_min_layer_time": {
+ "default_value": 10
+ },
+ "gantry_height": {
+ "value": "210"
+ },
+ "raft_airgap": {
+ "default_value": 0.2
+ },
+ "acceleration_skirt_brim": {
+ "value": "250"
+ },
+ "skirt_brim_material_flow": {
+ "value": "99"
+ },
+ "jerk_infill": {
+ "value": "5"
+ },
+ "roofing_material_flow": {
+ "value": "99"
+ },
+ "support_use_towers": {
+ "default_value": false
+ },
+ "ooze_shield_angle": {
+ "default_value": 50
+ },
+ "material_flow": {
+ "default_value": 99
+ },
+ "speed_travel_layer_0": {
+ "value": "75.0"
+ },
+ "raft_base_acceleration": {
+ "value": "250"
+ },
+ "retraction_count_max": {
+ "default_value": 40
+ },
+ "ooze_shield_dist": {
+ "default_value": 4
+ },
+ "acceleration_support": {
+ "value": "250"
+ },
+ "max_skin_angle_for_expansion": {
+ "default_value": 50
+ },
+ "coasting_enable": {
+ "default_value": true
+ },
+ "brim_width": {
+ "default_value": 10
+ },
+ "acceleration_support_infill": {
+ "value": "250"
+ },
+ "retraction_prime_speed": {
+ "value": "30"
+ },
+ "raft_base_speed": {
+ "value": "35"
+ },
+ "acceleration_wall_0": {
+ "value": "250"
+ },
+ "xy_offset": {
+ "default_value": -0.16
+ },
+ "prime_tower_size": {
+ "default_value": 1
+ },
+ "jerk_ironing": {
+ "value": "5"
+ },
+ "switch_extruder_prime_speed": {
+ "value": "30"
+ },
+ "raft_jerk": {
+ "value": "5"
+ },
+ "top_skin_preshrink": {
+ "value": "1.2000000000000002"
+ },
+ "material_print_temperature": {
+ "value": "195"
+ },
+ "wall_material_flow": {
+ "value": "99"
+ },
+ "jerk_roofing": {
+ "value": "5"
+ },
+ "cool_fan_full_at_height": {
+ "value": "0"
+ },
+ "acceleration_wall_x": {
+ "value": "250"
+ },
+ "support_bottom_distance": {
+ "value": "0.23"
+ },
+ "cool_min_speed": {
+ "default_value": 15
+ },
+ "default_material_bed_temperature": {
+ "default_value": 50
+ },
+ "raft_interface_thickness": {
+ "value": "0.2"
+ }
+ }
+}
diff --git a/resources/definitions/stereotech_start.def.json b/resources/definitions/stereotech_start.def.json
new file mode 100644
index 0000000000..e85893d811
--- /dev/null
+++ b/resources/definitions/stereotech_start.def.json
@@ -0,0 +1,45 @@
+{
+ "version": 2,
+ "name": "Stereotech START",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Stereotech",
+ "manufacturer": "Stereotech LLC.",
+ "file_formats": "text/x-gcode",
+ "platform": "stereotech_start.stl",
+ "icon": "icon_ultimaker2",
+ "platform_offset": [0, 0, 0],
+ "machine_extruder_trains":
+ {
+ "0": "stereotech_start_extruder_0"
+ }
+ },
+
+ "overrides": {
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "machine_width": {
+ "default_value": 190
+ },
+ "machine_height": {
+ "default_value": 190
+ },
+ "machine_depth": {
+ "default_value": 190
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "machine_start_gcode": {
+ "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home all axes (max endstops)\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."
+ },
+ "machine_end_gcode": {
+ "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG28 ;Home all axes (max endstops)\nM84 ;steppers off\nG90 ;absolute positioning"
+ },
+ "machine_shape": {
+ "default_value": "rectangular"
+ }
+ }
+}
diff --git a/resources/definitions/stereotech_ste320.def.json b/resources/definitions/stereotech_ste320.def.json
new file mode 100644
index 0000000000..3eb114324b
--- /dev/null
+++ b/resources/definitions/stereotech_ste320.def.json
@@ -0,0 +1,89 @@
+{
+ "version": 2,
+ "name": "Stereotech STE320",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Stereotech",
+ "manufacturer": "Stereotech LLC.",
+ "category": "Other",
+ "platform": "stereotech_ste320_platform.obj",
+ "platform_texture": "StereotechSte320backplate.png",
+ "platform_offset": [
+ 0,
+ 0,
+ -14
+ ],
+ "file_formats": "text/x-gcode",
+ "has_materials": true,
+ "supports_usb_connection": false,
+ "machine_extruder_trains": {
+ "0": "stereotech_ste320_1st",
+ "1": "stereotech_ste320_2nd"
+ }
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "Stereotech STE320"
+ },
+ "machine_width": {
+ "default_value": 218
+ },
+ "machine_height": {
+ "default_value": 200
+ },
+ "machine_depth": {
+ "default_value": 210
+ },
+ "machine_center_is_zero": {
+ "default_value": false
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "machine_head_with_fans_polygon": {
+ "default_value": [
+ [
+ -29,
+ 22
+ ],
+ [
+ -29,
+ -20
+ ],
+ [
+ 27,
+ 22
+ ],
+ [
+ 27,
+ -20
+ ]
+ ]
+ },
+ "gantry_height": {
+ "value": "25"
+ },
+ "machine_use_extruder_offset_to_offset_coords": {
+ "default_value": true
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "machine_start_gcode": {
+ "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;homing\nG1 Z15.0 F9000 ;move the platform down 15mm\nT1 ;Switch to the 2nd extruder\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F200 E-{switch_extruder_retraction_amount}\nT0 ;Switch to the 1st extruder\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."
+ },
+ "machine_end_gcode": {
+ "default_value": "M104 T0 S0 ;1st extruder heater off\nM104 T1 S0 ;2nd extruder heater off\nM140 S0 ;heated bed heater off\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning"
+ },
+ "machine_extruder_count": {
+ "default_value": 2
+ },
+ "prime_tower_position_x": {
+ "value": "195"
+ },
+ "prime_tower_position_y": {
+ "value": "149"
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/strateo3d.def.json b/resources/definitions/strateo3d.def.json
new file mode 100644
index 0000000000..2ee3650404
--- /dev/null
+++ b/resources/definitions/strateo3d.def.json
@@ -0,0 +1,138 @@
+{
+ "version": 2,
+ "name": "Strateo3D",
+ "inherits": "fdmprinter",
+ "metadata":
+ {
+ "author": "M.K",
+ "manufacturer": "eMotionTech",
+ "category": "Other",
+ "visible": true,
+ "file_formats": "text/x-gcode",
+ "has_machine_quality": true,
+ "has_materials": true,
+ "has_variants": true,
+ "preferred_variant_name": "Standard 0.6",
+ "preferred_material": "emotiontech_pla",
+ "preferred_quality_type": "c",
+ "variants_name": "Print Head",
+ "machine_extruder_trains":
+ {
+ "0": "strateo3d_right_extruder",
+ "1": "strateo3d_left_extruder"
+ }
+ },
+
+ "overrides":
+ {
+ "machine_name": { "default_value": "Strateo3D" },
+ "machine_width": { "default_value": 600 },
+ "machine_depth": { "default_value": 420 },
+ "machine_height": { "default_value": 495 },
+ "machine_heated_bed": { "default_value": true },
+ "machine_heated_build_volume": { "default_value": true },
+ "machine_center_is_zero": { "default_value": false },
+ "machine_head_with_fans_polygon": { "default_value": [ [ -76, -51.8 ] , [ 25, -51.8 ] , [ 25, 38.2 ] , [ -76, 38.2 ] ] },
+ "gantry_height": { "value": "40" },
+ "machine_extruder_count": { "default_value": 2 },
+ "machine_gcode_flavor": { "default_value": "Marlin" },
+ "machine_start_gcode": { "default_value": "G28 \nG90 G1 X300 Y210 Z15 F6000 \nG92 E0" },
+ "machine_end_gcode": { "default_value": "T1 \nM104 S0 \nT0 \nM104 S0 \nM140 S0 \nM141 S0 \nG91 \nG0 z1 \nG90 \nG28 \nM801.0 \nM84 \nM192" },
+ "extruder_prime_pos_y": {"minimum_value": "0", "maximum_value": "machine_depth"},
+ "extruder_prime_pos_x": {"minimum_value": "0", "maximum_value": "machine_width"},
+ "machine_heat_zone_length": { "default_value": 7 },
+ "default_material_print_temperature": { "maximum_value_warning": "350" },
+ "material_print_temperature": { "maximum_value_warning": "350" },
+ "material_print_temperature_layer_0": { "maximum_value_warning": "350" },
+ "material_bed_temperature": { "maximum_value": "130" },
+ "material_bed_temperature_layer_0": { "maximum_value": "130" },
+ "extruder_prime_pos_abs": { "default_value": true },
+ "machine_acceleration": { "default_value": 1500 },
+
+ "acceleration_enabled": { "value": false },
+ "acceleration_print": { "value": "machine_acceleration" },
+ "acceleration_wall": { "value": "math.ceil(acceleration_print * 1250 / acceleration_print)" },
+ "acceleration_wall_0": { "value": "math.ceil(acceleration_print * 1000 / acceleration_print)" },
+ "acceleration_topbottom": { "value": "math.ceil(acceleration_print * 1250 / acceleration_print)" },
+ "acceleration_support": { "value": "acceleration_print" },
+ "acceleration_support_interface": { "value": "acceleration_topbottom" },
+ "acceleration_travel": { "value": "acceleration_print" },
+ "acceleration_layer_0": { "value": "acceleration_topbottom" },
+ "adaptive_layer_height_variation": { "default_value": 0.1 },
+ "adaptive_layer_height_variation_step": { "default_value": 0.05 },
+ "adhesion_type": { "default_value": "skirt" },
+ "expand_skins_expand_distance": { "value": "wall_line_width_0 + wall_line_count * wall_line_width_x" },
+ "gradual_infill_step_height": { "value": "layer_height*10" },
+ "gradual_support_infill_step_height": { "value": "layer_height*7" },
+ "infill_before_walls": { "default_value": false },
+ "infill_overlap": { "value": "0" },
+ "infill_wipe_dist": { "value": "0" },
+ "jerk_enabled": { "value": "False" },
+ "jerk_layer_0": { "value": "jerk_topbottom" },
+ "jerk_prime_tower": { "value": "math.ceil(jerk_print * 15 / 25)" },
+ "jerk_print": { "value": "25" },
+ "jerk_support": { "value": "math.ceil(jerk_print * 15 / 25)" },
+ "jerk_support_interface": { "value": "jerk_topbottom" },
+ "jerk_topbottom": { "value": "math.ceil(jerk_print * 5 / 25)" },
+ "jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" },
+ "jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" },
+ "layer_start_x": { "value": "sum(extruderValues('machine_extruder_start_pos_x')) / len(extruderValues('machine_extruder_start_pos_x'))" },
+ "layer_start_y": { "value": "sum(extruderValues('machine_extruder_start_pos_y')) / len(extruderValues('machine_extruder_start_pos_y'))" },
+ "machine_min_cool_heat_time_window": { "value": "15" },
+ "machine_nozzle_cool_down_speed": { "default_value": 0.50 },
+ "machine_nozzle_heat_up_speed": { "default_value": 2.25 },
+ "material_final_print_temperature": { "value": "material_print_temperature - 10" },
+ "material_flow": { "default_value": 93 },
+ "material_flow_layer_0": { "value": "math.ceil(material_flow*1)" },
+ "material_initial_print_temperature": { "value": "material_print_temperature - 5" },
+ "meshfix_maximum_resolution": { "value": "0.03" },
+ "optimize_wall_printing_order": { "value": "True" },
+ "prime_blob_enable": { "enabled": false, "default_value": false },
+ "prime_tower_min_volume": { "default_value": 35 },
+ "prime_tower_position_x": { "value": "machine_width/2 - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - 1" },
+ "prime_tower_position_y": { "value": "machine_depth - prime_tower_size - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - 1" },
+ "retraction_amount": { "default_value": 1.5 },
+ "retraction_combing": { "default_value": "all" },
+ "retraction_combing_max_distance": { "default_value": 5 },
+ "retraction_count_max": { "default_value": 15 },
+ "retraction_hop": { "value": "2" },
+ "retraction_hop_enabled": { "value": "extruders_enabled_count > 1" },
+ "retraction_hop_only_when_collides": { "value": "True" },
+ "retraction_min_travel": { "value": "3*line_width" },
+ "retraction_prime_speed": { "value": "retraction_speed-10" },
+ "retraction_speed": { "default_value": 25 },
+ "skin_overlap": { "value": "10" },
+ "skirt_brim_minimal_length": { "default_value": 333 },
+ "speed_layer_0": { "value": "20" },
+ "speed_travel_layer_0": { "value": "100" },
+ "speed_prime_tower": { "value": "speed_topbottom" },
+ "speed_print": { "value": "50" },
+ "speed_support": { "value": "speed_wall" },
+ "speed_support_interface": { "value": "speed_topbottom" },
+ "speed_topbottom": { "value": "math.ceil(speed_print * 20/35)" },
+ "speed_travel": { "value": "150" },
+ "speed_wall": { "value": "math.ceil(speed_print * 3/4)" },
+ "speed_wall_0": { "value": "math.ceil(speed_wall * 2/3)" },
+ "speed_wall_x": { "value": "speed_wall" },
+ "support_angle": { "value": "50" },
+ "support_bottom_distance": {"value": "extruderValue(support_bottom_extruder_nr if support_bottom_enable else support_infill_extruder_nr, 'support_z_distance/2') if support_type == 'everywhere' else 0", "maximum_value_warning": "machine_nozzle_size*1.5" },
+ "support_interface_enable": { "default_value": true },
+ "support_interface_height": { "value": "layer_height*3" },
+ "support_interface_offset": { "value": "support_offset" },
+ "support_top_distance": {"value": "extruderValue(support_roof_extruder_nr if support_roof_enable else support_infill_extruder_nr, 'support_z_distance')", "maximum_value_warning": "machine_nozzle_size*1.5" },
+ "support_use_towers": { "default_value": true },
+ "support_xy_distance": { "value": "line_width * 1.7" },
+ "support_xy_distance_overhang": { "value": "wall_line_width_0" },
+ "support_z_distance": { "value": "layer_height*2", "maximum_value_warning": "machine_nozzle_size*1.5" },
+ "switch_extruder_prime_speed": { "value": "retraction_prime_speed" },
+ "switch_extruder_retraction_amount": { "value": "7" },
+ "switch_extruder_retraction_speeds": {"value": "retraction_retract_speed"},
+ "top_bottom_thickness": { "value": "3*layer_height", "minimum_value_warning": "layer_height*2" },
+ "top_thickness": { "value": "top_bottom_thickness" },
+ "top_layers": { "value": "0 if infill_sparse_density == 100 else math.ceil(round(top_thickness / resolveOrValue('layer_height'), 4))"},
+ "bottom_thickness": { "value": "top_bottom_thickness-2*layer_height+layer_height_0" },
+ "bottom_layers": { "value": "999999 if infill_sparse_density == 100 else math.ceil(round(((bottom_thickness-resolveOrValue('layer_height_0')) / resolveOrValue('layer_height'))+1, 4))"},
+ "travel_avoid_distance": { "value": "3 if extruders_enabled_count > 1 else machine_nozzle_tip_outer_diameter / 2 * 1.5" },
+ "wall_thickness": { "value": "wall_line_width_0 + wall_line_width_x" }
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/structur3d_discov3ry1_complete_um2plus.def.json b/resources/definitions/structur3d_discov3ry1_complete_um2plus.def.json
new file mode 100644
index 0000000000..e4893cacac
--- /dev/null
+++ b/resources/definitions/structur3d_discov3ry1_complete_um2plus.def.json
@@ -0,0 +1,113 @@
+{
+ "version": 2,
+ "name": "Discov3ry Complete",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "author": "Andrew Finkle, CTO",
+ "manufacturer": "Structur3d.io",
+ "visible": true,
+ "file_formats": "text/x-gcode",
+ "platform": "ultimaker2_platform.obj",
+ "platform_texture": "Ultimaker2Plusbackplate.png",
+ "platform_offset": [0, 0, 0],
+ "has_materials": true,
+ "has_variants": true,
+ "variants_name": "Print core",
+ "preferred_variant_name": "0.84mm (Green)",
+ "preferred_material": "structur3d_dap100silicone",
+ "has_machine_quality": false,
+ "preferred_quality_type": "extra_fast",
+ "first_start_actions": [],
+ "supported_actions": [],
+ "machine_extruder_trains":
+ {
+ "0": "structur3d_discov3ry1_complete_um2plus_extruder_0"
+ },
+ "firmware_file": "MarlinUltimaker2plus.hex"
+ },
+
+ "overrides": {
+ "machine_name": { "default_value": "Discov3ry Complete (Ultimaker 2+)" },
+ "speed_infill": {
+ "value": "speed_print"
+ },
+ "infill_sparse_density": {
+ "value": 100
+ },
+ "retraction_hop_enabled": {
+ "value": true
+ },
+ "adhesion_type": {
+ "default_value": "skirt"
+ },
+ "skirt_brim_minimal_length": {
+ "value": 1500
+ },
+ "speed_print": {
+ "value": 15
+ },
+ "speed_wall_x": {
+ "value": "speed_wall"
+ },
+ "layer_height_0": {
+ "value": "round(machine_nozzle_size / 1.5, 2)"
+ },
+ "line_width": {
+ "value": "round(machine_nozzle_size * 0.875, 2)"
+ },
+ "speed_support": {
+ "value": "speed_wall_0"
+ },
+ "machine_height": {
+ "default_value": 205
+ },
+ "machine_width": {
+ "default_value": 205
+ },
+ "machine_depth": {
+ "default_value": 205
+ },
+ "machine_show_variants": {
+ "default_value": true
+ },
+ "gantry_height": {
+ "value": "52"
+ },
+ "machine_nozzle_head_distance": {
+ "default_value": 5
+ },
+ "machine_nozzle_expansion_angle": {
+ "default_value": 45
+ },
+ "machine_heat_zone_length": {
+ "default_value": 20
+ },
+ "machine_head_with_fans_polygon":
+ {
+ "default_value": [
+ [ -44, 14 ],
+ [ -44, -34 ],
+ [ 64, 14 ],
+ [ 64, -34 ]
+ ]
+ },
+ "machine_disallowed_areas": {
+ "default_value": [
+ [[-115, 112.5], [ -78, 112.5], [ -80, 102.5], [-115, 102.5]],
+ [[ 115, 112.5], [ 115, 102.5], [ 105, 102.5], [ 103, 112.5]],
+ [[-115, -112.5], [-115, -104.5], [ -84, -104.5], [ -82, -112.5]],
+ [[ 115, -112.5], [ 108, -112.5], [ 110, -104.5], [ 115, -104.5]]
+ ]
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "machine_start_gcode": {
+ "default_value": "\n;Updated Firmware (.hex and Marlin .ino) for \n;Ultimaker 2+ with Discov3ry Extruder available at: \n;https://github.com/Structur3d/UM2.1Discov3ry-Firmware-beta \n;**Learn more at https://www.structur3d.io** \n \nM104 S{material_print_temperature} ;Start heating extruder \nM140 S{material_bed_temperature} ;Start heating bed \nG21 ;metric values \nG90 ;absolute positioning \nM82 ;set extruder to absolute mode \nM107 ;start with the fan off \nM302 ;allow cold extrusion \nM92 E2589 ;set extruder EEPROM steps/mm for paste \nG28 Z0 ;move Z to bottom endstops \nG28 X0 Y0 ;move X/Y to endstops \nG1 X15 Y0 F4000 ;move X/Y to front of printer \nG1 Z15.0 F9000 ;move the platform to 15mm \nG92 E0 ;zero the extruded length \nG1 F200 E10 ;extrude 10 mm of feed stock \nG92 E0 ;zero the extruded length again \nG1 F9000 \n;Put printing message on LCD screen \nM117 Printing..."
+ },
+ "machine_end_gcode": {
+ "default_value": "M104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it) \nM92 E282 ;reset extruder EEPROM steps/mm for plastic filament \nG91 ;relative positioning \nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure \nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more \nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way \nM84 ;steppers off\nG90 ;absolute positioning"
+ }
+
+ }
+}
diff --git a/resources/definitions/tam.def.json b/resources/definitions/tam.def.json
index 0ed8d657a2..211049ca3d 100644
--- a/resources/definitions/tam.def.json
+++ b/resources/definitions/tam.def.json
@@ -1,6 +1,6 @@
{
"version": 2,
- "name": "Type A Machines Series 1 2014",
+ "name": "Series 1 2014",
"inherits": "fdmprinter",
"metadata": {
"visible": true,
@@ -32,12 +32,11 @@
"machine_heated_bed": { "default_value": true },
"machine_head_with_fans_polygon": { "default_value": [ [ -35, 65 ], [ -35, -55 ], [ 55, 65 ], [ 55, -55 ] ] },
- "gantry_height": { "default_value": 35 },
- "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "gantry_height": { "value": "35" },
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_center_is_zero": { "default_value": false },
"speed_print": { "default_value": 60 },
- "speed_travel": { "default_value": 200 },
"retraction_amount": { "default_value": 0.4 },
"retraction_speed": { "default_value": 35},
diff --git a/resources/definitions/tevo_blackwidow.def.json b/resources/definitions/tevo_blackwidow.def.json
index 25e7a2620d..9e450067fb 100644
--- a/resources/definitions/tevo_blackwidow.def.json
+++ b/resources/definitions/tevo_blackwidow.def.json
@@ -44,7 +44,7 @@
},
"gantry_height":
{
- "default_value": 0
+ "value": "0"
},
"machine_gcode_flavor":
{
diff --git a/resources/definitions/tevo_tarantula.def.json b/resources/definitions/tevo_tarantula.def.json
index ec4ae667d5..f4bf2b901e 100644
--- a/resources/definitions/tevo_tarantula.def.json
+++ b/resources/definitions/tevo_tarantula.def.json
@@ -23,7 +23,7 @@
"machine_height": { "default_value": 200 },
"machine_depth": { "default_value": 200 },
"machine_center_is_zero": { "default_value": false },
- "machine_head_polygon":
+ "machine_head_with_fans_polygon":
{
"default_value":
[
@@ -33,7 +33,7 @@
[18, -18]
]
},
- "gantry_height": { "default_value": 55 },
+ "gantry_height": { "value": "55" },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_acceleration": { "default_value": 2650 },
"machine_max_jerk_xy": { "default_value": 15.0 },
diff --git a/resources/definitions/tevo_tornado.def.json b/resources/definitions/tevo_tornado.def.json
index cb3a6c45bd..3b6c431feb 100644
--- a/resources/definitions/tevo_tornado.def.json
+++ b/resources/definitions/tevo_tornado.def.json
@@ -13,7 +13,7 @@
}
},
"overrides": {
- "machine_name": {
+ "machine_name": {
"default_value": "Tevo Tornado"
},
"machine_width": {
@@ -25,10 +25,10 @@
"machine_depth": {
"default_value": 300
},
- "machine_center_is_zero": {
- "default_value": false
+ "machine_center_is_zero": {
+ "default_value": false
},
- "machine_head_polygon": {
+ "machine_head_with_fans_polygon": {
"default_value": [
[-30, 34],
[-30, -32],
@@ -70,25 +70,43 @@
"default_value": true
},
"gantry_height": {
- "default_value": 30
+ "value": "30"
},
"acceleration_enabled": {
- "default_value": false
+ "default_value": true
},
- "machine_acceleration": {
- "default_value": 1500
+ "acceleration_print": {
+ "default_value": 500
+ },
+ "acceleration_travel": {
+ "value": 500
+ },
+ "acceleration_travel_layer_0": {
+ "value": 500
+ },
+ "machine_acceleration": {
+ "default_value": 1500
},
"jerk_enabled": {
- "default_value": false
+ "default_value": true
},
- "machine_max_jerk_xy": {
- "default_value": 6
+ "jerk_print": {
+ "default_value": 8
},
- "machine_gcode_flavor": {
+ "jerk_travel": {
+ "value": 8
+ },
+ "jerk_travel_layer_0": {
+ "value": 8
+ },
+ "machine_max_jerk_xy": {
+ "default_value": 6
+ },
+ "machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
- "default_value": "; start_gcode\nM117 Start Clean ; Indicate nozzle clean in progress on LCD\n;\nM104 S[extruder0_temperature] \nM109 S[extruder0_temperature] \nM109 R[extruder0_temperature] \n;\nM107 ; Turn layer fan off\nG21 ; Set to metric [change to G20 if you want Imperial]\nG90 ; Force coordinates to be absolute relative to the origin\nG28 ; Home X/Y/Z axis\n;\nG1 X3 Y1 Z15 F9000 ; Move safe Z height to shear strings\nG0 X1 Y1 Z0.2 F9000 ; Move in 1mm from edge and up [z] 0.2mm\nG92 E0 ; Set extruder to [0] zero\nG1 X100 E12 F500 ; Extrude 30mm filiment along X axis 100mm long to prime and clean the nozzle\nG92 E0 ; Reset extruder to [0] zero end of cleaning run\nG1 E-1 F500 ; Retract filiment by 1 mm to reduce string effect\nG1 X180 F4000 ; quick wipe away from the filament line / purge\nM117 End Clean ; Indicate nozzle clean in progress on LCD\n;\nM117 Printing...\n; Begin printing with sliced GCode after here\n;"
+ "default_value": "; start_gcode\nM117 Start Clean ; Indicate nozzle clean in progress on LCD\n;\nM104 S{material_print_temperature_layer_0} \nM109 S{material_print_temperature_layer_0} \nM109 R{material_print_temperature_layer_0} \n;\nM107 ; Turn layer fan off\nG21 ; Set to metric [change to G20 if you want Imperial]\nG90 ; Force coordinates to be absolute relative to the origin\nG28 ; Home X/Y/Z axis\n;\nG1 X3 Y1 Z15 F9000 ; Move safe Z height to shear strings\nG0 X1 Y1 Z0.2 F9000 ; Move in 1mm from edge and up [z] 0.2mm\nG92 E0 ; Set extruder to [0] zero\nG1 X100 E12 F500 ; Extrude 30mm filiment along X axis 100mm long to prime and clean the nozzle\nG92 E0 ; Reset extruder to [0] zero end of cleaning run\nG1 E-1 F500 ; Retract filiment by 1 mm to reduce string effect\nG1 X180 F4000 ; quick wipe away from the filament line / purge\nM117 End Clean ; Indicate nozzle clean in progress on LCD\n;\nM117 Printing...\n; Begin printing with sliced GCode after here\n;"
},
"machine_end_gcode": {
"default_value": ";\n; end_gcode\nG92 E0 ; zero the extruded length\nG1 E-5 F9000 ; retract\nM104 S0 ; turn off temperature\nM140 S0 ; turn off bed\nG91 ; relative positioning\nG1 E-1 F300 ; retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+20 E-5 X-20 Y-20 F7200 ; move Z up a bit and retract filament even more\nG1 X320 Y150 F10000 ; move right mid\nM107 ; turn off layer fan\nM84 ; disable motors\nG90 ; absolute positioning\n;\n;EOF"
diff --git a/resources/definitions/tizyx_evy.def.json b/resources/definitions/tizyx_evy.def.json
index fe9a02a31c..57c7337196 100644
--- a/resources/definitions/tizyx_evy.def.json
+++ b/resources/definitions/tizyx_evy.def.json
@@ -10,13 +10,12 @@
"has_machine_quality": true,
"has_materials": true,
- "has_machine_materials": true,
"has_variants": true,
"preferred_variant_name": "0.4mm",
"preferred_material": "tizyx_pla",
"preferred_quality_type": "normal",
- "exclude_materials": ["chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu", "fiberlogy_hd_pla", "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red", "generic_bam", "generic_cpe", "generic_cpe_175", "generic_cpe_plus", "generic_hips", "generic_hips_175", "generic_nylon", "generic_nylon_175", "generic_pc", "generic_pc_175","generic_pp", "generic_pva", "generic_pva_175", "generic_tpu", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "innofill_innoflex60_175", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "ultimaker_abs_black", "ultimaker_abs_blue", "ultimaker_abs_green", "ultimaker_abs_grey", "ultimaker_abs_orange", "ultimaker_abs_pearl-gold", "ultimaker_abs_red", "ultimaker_abs_silver-metallic", "ultimaker_abs_white", "ultimaker_abs_yellow", "ultimaker_bam", "ultimaker_cpe_black", "ultimaker_cpe_blue", "ultimaker_cpe_dark-grey", "ultimaker_cpe_green", "ultimaker_cpe_light-grey", "ultimaker_cpe_plus_black", "ultimaker_cpe_plus_transparent", "ultimaker_cpe_plus_white", "ultimaker_cpe_red", "ultimaker_cpe_transparent", "ultimaker_cpe_white", "ultimaker_cpe_yellow", "ultimaker_nylon_black", "ultimaker_nylon_transparent", "ultimaker_pc_black", "ultimaker_pc_transparent", "ultimaker_pc_white", "ultimaker_pla_black", "ultimaker_pla_blue", "ultimaker_pla_green", "ultimaker_pla_magenta", "ultimaker_pla_orange", "ultimaker_pla_pearl-white", "ultimaker_pla_red", "ultimaker_pla_silver-metallic", "ultimaker_pla_transparent", "ultimaker_pla_white", "ultimaker_pla_yellow", "ultimaker_pp_transparent", "ultimaker_pva", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "ultimaker_tpu_black", "ultimaker_tpu_blue", "ultimaker_tpu_red", "ultimaker_tpu_white", "verbatim_bvoh_175", "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_TPU", "zyyx_pro_flex", "zyyx_pro_pla" ],
+ "exclude_materials": ["chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu", "fiberlogy_hd_pla", "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red", "generic_bam", "generic_cpe", "generic_cpe_175", "generic_cpe_plus", "generic_hips", "generic_hips_175", "generic_nylon", "generic_nylon_175", "generic_pc", "generic_pc_175","generic_pp", "generic_pva", "generic_pva_175", "generic_tpu", "generic_tpu_175", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "innofill_innoflex60_175", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "ultimaker_abs_black", "ultimaker_abs_blue", "ultimaker_abs_green", "ultimaker_abs_grey", "ultimaker_abs_orange", "ultimaker_abs_pearl-gold", "ultimaker_abs_red", "ultimaker_abs_silver-metallic", "ultimaker_abs_white", "ultimaker_abs_yellow", "ultimaker_bam", "ultimaker_cpe_black", "ultimaker_cpe_blue", "ultimaker_cpe_dark-grey", "ultimaker_cpe_green", "ultimaker_cpe_light-grey", "ultimaker_cpe_plus_black", "ultimaker_cpe_plus_transparent", "ultimaker_cpe_plus_white", "ultimaker_cpe_red", "ultimaker_cpe_transparent", "ultimaker_cpe_white", "ultimaker_cpe_yellow", "ultimaker_nylon_black", "ultimaker_nylon_transparent", "ultimaker_pc_black", "ultimaker_pc_transparent", "ultimaker_pc_white", "ultimaker_pla_black", "ultimaker_pla_blue", "ultimaker_pla_green", "ultimaker_pla_magenta", "ultimaker_pla_orange", "ultimaker_pla_pearl-white", "ultimaker_pla_red", "ultimaker_pla_silver-metallic", "ultimaker_pla_transparent", "ultimaker_pla_white", "ultimaker_pla_yellow", "ultimaker_pp_transparent", "ultimaker_pva", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "ultimaker_tpu_black", "ultimaker_tpu_blue", "ultimaker_tpu_red", "ultimaker_tpu_white", "verbatim_bvoh_175", "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_TPU", "zyyx_pro_flex", "zyyx_pro_pla" ],
"machine_extruder_trains":
{
@@ -32,7 +31,7 @@
"machine_extruder_count": { "default_value": 1 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
- "gantry_height": { "default_value": 500 },
+ "gantry_height": { "value": "500" },
"machine_height": { "default_value": 255 },
"machine_depth": { "default_value": 255 },
"machine_width": { "default_value": 255 },
@@ -51,13 +50,8 @@
"fill_outline_gaps": { "default_value": true},
"infill_sparse_density": { "default_value": 15},
"retraction_amount": { "default_value": 2.5},
- "retraction_min_travel": { "default_value": 2},
"retraction_speed": { "default_value": 30},
"speed_print": { "default_value": 60},
- "speed_topbottom": { "default_value": 50},
- "speed_wall_0": { "default_value": 40},
- "top_layers": { "default_value": 4},
- "wall_line_count": { "default_value": 2},
"cool_min_layer_time": { "default_value": 11},
"layer_height": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
"layer_height_0": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
@@ -69,6 +63,13 @@
"machine_end_gcode":
{
"default_value": "M104 S0\nM140 S0\nG91\nG1 E-5 F300\nG1 Z+3 F3000\nG1 Y245 F3000\nM84"
- }
+ },
+
+ "acceleration_enabled": {"value": "False"},
+ "acceleration_print": {"value": "1500"},
+ "z_seam_type": {"default_value": "back"},
+ "z_seam_x": {"value": "127.5"},
+ "z_seam_y": {"value": "250"},
+ "retraction_combing": {"default_value": "off"}
}
}
diff --git a/resources/definitions/tizyx_evy_dual.def.json b/resources/definitions/tizyx_evy_dual.def.json
new file mode 100644
index 0000000000..e06894139e
--- /dev/null
+++ b/resources/definitions/tizyx_evy_dual.def.json
@@ -0,0 +1,63 @@
+{
+ "name": "TiZYX EVY Dual",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "TiZYX",
+ "manufacturer": "TiZYX",
+ "file_formats": "text/x-gcode",
+
+ "has_machine_quality": true,
+ "has_materials": true,
+ "has_variants": true,
+ "preferred_variant_name": "Classic Extruder",
+
+ "preferred_material": "tizyx_pla",
+ "preferred_quality_type": "normal",
+ "exclude_materials": ["chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu", "fiberlogy_hd_pla", "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red", "generic_cpe_175", "generic_cpe_plus","generic_hips_175","generic_nylon_175", "generic_pc_175", "generic_pva_175", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "innofill_innoflex60_175", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "verbatim_bvoh_175", "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_TPU", "zyyx_pro_flex", "zyyx_pro_pla" ],
+
+ "machine_extruder_trains":
+ {
+ "0": "tizyx_evy_dual_extruder_0",
+ "1": "tizyx_evy_dual_extruder_1"
+ },
+ "platform": "tizyx_k25_platform.stl",
+ "platform_offset": [0, -4, 0],
+ "first_start_actions": ["MachineSettingsAction"],
+ "supported_actions": ["MachineSettingsAction"]
+ },
+
+ "overrides": {
+ "machine_extruder_count": { "default_value": 2 },
+ "machine_heated_bed": { "default_value": true },
+ "machine_center_is_zero": { "default_value": false },
+ "gantry_height": { "value": "500" },
+ "machine_height": { "default_value": 255 },
+ "machine_depth": { "default_value": 255 },
+ "machine_width": { "default_value": 255 },
+ "machine_head_with_fans_polygon": {
+ "default_value": [
+ [25, 49],
+ [25, -49],
+ [-25, -49],
+ [25, 49]
+ ]
+ },
+ "machine_start_gcode":
+ {
+ "default_value": "M82\nG90\nG28 X\nG28 Y\nG28 Z\nG29\nG91\nG1 Z0\nG90\nM82\nG92 E0\nG1 X125 Y245 F3000\nG1 Z0"
+ },
+ "machine_end_gcode":
+ {
+ "default_value": "M104 S0\nM140 S0\nG91\nG1 E-5 F300\nG1 Z+3 F3000\nG1 Y245 F3000\nM84"
+ },
+
+ "acceleration_enabled": {"value": "False"},
+ "acceleration_print": {"value": "1500"},
+ "z_seam_type": {"default_value": "back"},
+ "z_seam_x": {"value": "127.5"},
+ "z_seam_y": {"value": "250"},
+ "retraction_combing": {"default_value": "off"}
+ }
+}
diff --git a/resources/definitions/tizyx_k25.def.json b/resources/definitions/tizyx_k25.def.json
index d6a5ff5ecd..32fa9b331d 100644
--- a/resources/definitions/tizyx_k25.def.json
+++ b/resources/definitions/tizyx_k25.def.json
@@ -1,52 +1,60 @@
-{
- "version": 2,
- "name": "TiZYX K25",
- "inherits": "fdmprinter",
- "metadata":
- {
- "visible": true,
- "author": "TiZYX",
- "manufacturer": "TiZYX",
- "file_formats": "text/x-gcode",
- "platform": "tizyx_k25_platform.stl",
- "platform_offset": [0, -4, 0],
- "exclude_materials": ["chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu", "fiberlogy_hd_pla", "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red", "generic_abs", "generic_abs_175", "generic_bam", "generic_cpe", "generic_cpe_175", "generic_cpe_plus", "generic_hips", "generic_hips_175", "generic_nylon", "generic_nylon_175", "generic_pc", "generic_pc_175", "generic_petg", "generic_petg_175", "generic_pla", "generic_pla_175", "generic_pp", "generic_pva", "generic_pva_175", "generic_tough_pla", "generic_tpu", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "innofill_innoflex60_175", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "ultimaker_abs_black", "ultimaker_abs_blue", "ultimaker_abs_green", "ultimaker_abs_grey", "ultimaker_abs_orange", "ultimaker_abs_pearl-gold", "ultimaker_abs_red", "ultimaker_abs_silver-metallic", "ultimaker_abs_white", "ultimaker_abs_yellow", "ultimaker_bam", "ultimaker_cpe_black", "ultimaker_cpe_blue", "ultimaker_cpe_dark-grey", "ultimaker_cpe_green", "ultimaker_cpe_light-grey", "ultimaker_cpe_plus_black", "ultimaker_cpe_plus_transparent", "ultimaker_cpe_plus_white", "ultimaker_cpe_red", "ultimaker_cpe_transparent", "ultimaker_cpe_white", "ultimaker_cpe_yellow", "ultimaker_nylon_black", "ultimaker_nylon_transparent", "ultimaker_pc_black", "ultimaker_pc_transparent", "ultimaker_pc_white", "ultimaker_pla_black", "ultimaker_pla_blue", "ultimaker_pla_green", "ultimaker_pla_magenta", "ultimaker_pla_orange", "ultimaker_pla_pearl-white", "ultimaker_pla_red", "ultimaker_pla_silver-metallic", "ultimaker_pla_transparent", "ultimaker_pla_white", "ultimaker_pla_yellow", "ultimaker_pp_transparent", "ultimaker_pva", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "ultimaker_tpu_black", "ultimaker_tpu_blue", "ultimaker_tpu_red", "ultimaker_tpu_white", "verbatim_bvoh_175", "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_TPU", "zyyx_pro_flex", "zyyx_pro_pla" ],
- "preferred_material": "tizyx_pla",
- "has_machine_quality": true,
- "has_materials": true,
- "has_variants": true,
- "preferred_variant_name": "0.4 mm",
- "machine_extruder_trains":
- {
- "0": "tizyx_k25_extruder_0"
- }
- },
-
- "overrides":
- {
- "machine_name": { "default_value": "TiZYX K25" },
- "machine_heated_bed": { "default_value": true },
- "machine_width": { "default_value": 255 },
- "machine_height": { "default_value": 255 },
- "machine_depth": { "default_value": 255 },
- "machine_center_is_zero": { "default_value": false },
- "gantry_height": { "default_value": 500 },
- "machine_head_with_fans_polygon": {
- "default_value": [
- [25, 49],
- [25, -49],
- [-25, -49],
- [25, 49]
- ]
- },
- "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
- "machine_start_gcode":
- {
- "default_value": "M82\nG90\nG28 X\nG28 Y\nG28 Z\nG29\nG91\nG1 Z0\nG90\nM82\nG92 E0\nG1 X125 Y245 F3000\nG1 Z0"
- },
- "machine_end_gcode":
- {
- "default_value": "M104 S0\nM140 S0\nG91\nG1 E-5 F300\nG1 Z+3 F3000\nG1 Y245 F3000\nM84"
- }
- }
-}
+{
+ "version": 2,
+ "name": "TiZYX K25",
+ "inherits": "fdmprinter",
+ "metadata":
+ {
+ "visible": true,
+ "author": "TiZYX",
+ "manufacturer": "TiZYX",
+ "file_formats": "text/x-gcode",
+ "platform": "tizyx_k25_platform.stl",
+ "platform_offset": [0, -4, 0],
+ "exclude_materials": ["chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu", "fiberlogy_hd_pla", "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red", "generic_abs", "generic_abs_175", "generic_bam", "generic_cpe", "generic_cpe_175", "generic_cpe_plus", "generic_hips", "generic_hips_175", "generic_nylon", "generic_nylon_175", "generic_pc", "generic_pc_175", "generic_petg", "generic_petg_175", "generic_pla", "generic_pla_175", "generic_pp", "generic_pva", "generic_pva_175", "generic_tough_pla", "generic_tpu", "generic_tpu_175", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "innofill_innoflex60_175", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "ultimaker_abs_black", "ultimaker_abs_blue", "ultimaker_abs_green", "ultimaker_abs_grey", "ultimaker_abs_orange", "ultimaker_abs_pearl-gold", "ultimaker_abs_red", "ultimaker_abs_silver-metallic", "ultimaker_abs_white", "ultimaker_abs_yellow", "ultimaker_bam", "ultimaker_cpe_black", "ultimaker_cpe_blue", "ultimaker_cpe_dark-grey", "ultimaker_cpe_green", "ultimaker_cpe_light-grey", "ultimaker_cpe_plus_black", "ultimaker_cpe_plus_transparent", "ultimaker_cpe_plus_white", "ultimaker_cpe_red", "ultimaker_cpe_transparent", "ultimaker_cpe_white", "ultimaker_cpe_yellow", "ultimaker_nylon_black", "ultimaker_nylon_transparent", "ultimaker_pc_black", "ultimaker_pc_transparent", "ultimaker_pc_white", "ultimaker_pla_black", "ultimaker_pla_blue", "ultimaker_pla_green", "ultimaker_pla_magenta", "ultimaker_pla_orange", "ultimaker_pla_pearl-white", "ultimaker_pla_red", "ultimaker_pla_silver-metallic", "ultimaker_pla_transparent", "ultimaker_pla_white", "ultimaker_pla_yellow", "ultimaker_pp_transparent", "ultimaker_pva", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "ultimaker_tpu_black", "ultimaker_tpu_blue", "ultimaker_tpu_red", "ultimaker_tpu_white", "verbatim_bvoh_175", "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_TPU", "zyyx_pro_flex", "zyyx_pro_pla" ],
+ "preferred_material": "tizyx_pla",
+ "has_machine_quality": true,
+ "has_materials": true,
+ "has_variants": true,
+ "preferred_variant_name": "0.4 mm",
+ "machine_extruder_trains":
+ {
+ "0": "tizyx_k25_extruder_0"
+ }
+ },
+
+ "overrides":
+ {
+ "machine_name": { "default_value": "TiZYX K25" },
+ "machine_heated_bed": { "default_value": true },
+ "machine_width": { "default_value": 255 },
+ "machine_height": { "default_value": 255 },
+ "machine_depth": { "default_value": 255 },
+ "machine_center_is_zero": { "default_value": false },
+ "gantry_height": { "value": "500" },
+ "machine_head_with_fans_polygon": {
+ "default_value": [
+ [25, 49],
+ [25, -49],
+ [-25, -49],
+ [25, 49]
+ ]
+ },
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_start_gcode":
+ {
+ "default_value": "M82\nG90\nG28 X\nG28 Y\nG28 Z\nG29\nG91\nG1 Z0\nG90\nM82\nG92 E0\nG1 X125 Y245 F3000\nG1 Z0"
+ },
+ "machine_end_gcode":
+ {
+ "default_value": "M104 S0\nM140 S0\nG91\nG1 E-5 F300\nG1 Z+3 F3000\nG1 Y245 F3000\nM84"
+ },
+
+
+ "acceleration_enabled": {"value": "False"},
+ "acceleration_print": {"value": "1500"},
+ "z_seam_type": {"default_value": "back"},
+ "z_seam_x": {"value": "127.5"},
+ "z_seam_y": {"value": "250"},
+ "retraction_combing": {"default_value": "off"}
+ }
+}
diff --git a/resources/definitions/ubuild-3d_mr_bot_280.def.json b/resources/definitions/ubuild-3d_mr_bot_280.def.json
index 7eb65c3e78..255d8f032b 100644
--- a/resources/definitions/ubuild-3d_mr_bot_280.def.json
+++ b/resources/definitions/ubuild-3d_mr_bot_280.def.json
@@ -1,5 +1,4 @@
{
- "id": "ubuild-3d_mr_bot_280",
"version": 2,
"name": "uBuild-3D Mr Bot 280",
"inherits": "fdmprinter",
@@ -24,17 +23,14 @@
"machine_height": { "default_value": 275 },
"machine_depth": { "default_value": 275 },
"machine_center_is_zero": { "default_value": false },
- "material_bed_temperature": { "default_value": 70 },
"layer_height_0": { "default_value": 0.1 },
"retraction_amount": { "default_value": 2 },
"retraction_speed": { "default_value": 50 },
- "retraction_retract_speed": { "default_value": 50 },
- "retraction_prime_speed": { "default_value": 30 },
"adhesion_type": { "default_value": "skirt" },
"machine_nozzle_heat_up_speed": { "default_value": 2 },
"machine_nozzle_cool_down_speed": { "default_value": 2 },
"machine_head_with_fans_polygon": { "default_value": [[-20,20],[10,10],[10,10],[10,10]] },
- "gantry_height": { "default_value": 275 },
+ "gantry_height": { "value": "275" },
"machine_max_feedrate_z": { "default_value": 15 },
"machine_max_feedrate_e": { "default_value": 60 },
"machine_max_acceleration_z": { "default_value": 1000 },
diff --git a/resources/definitions/ultimaker.def.json b/resources/definitions/ultimaker.def.json
index a980a1afdf..aec7907dbe 100644
--- a/resources/definitions/ultimaker.def.json
+++ b/resources/definitions/ultimaker.def.json
@@ -7,7 +7,7 @@
"manufacturer": "Ultimaker B.V.",
"category": "Ultimaker",
"visible": false,
- "exclude_materials": [ "generic_hips", "generic_petg" ]
+ "exclude_materials": [ "generic_hips", "generic_petg", "structur3d_dap100silicone" ]
},
"overrides": {
"machine_max_feedrate_e": {
diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json
index 4cc291ff45..40fbdaf709 100644
--- a/resources/definitions/ultimaker2.def.json
+++ b/resources/definitions/ultimaker2.def.json
@@ -14,9 +14,6 @@
"has_materials": false,
"has_machine_quality": true,
"preferred_variant_name": "0.4 mm",
- "exclude_materials": ["generic_hips", "generic_petg", "generic_bam", "ultimaker_bam", "generic_pva", "ultimaker_pva", "generic_tough_pla", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white"],
- "first_start_actions": ["UM2UpgradeSelection"],
- "supported_actions":["UM2UpgradeSelection"],
"machine_extruder_trains":
{
"0": "ultimaker2_extruder_0"
@@ -56,7 +53,7 @@
"default_value": false
},
"gantry_height": {
- "default_value": 48
+ "value": "48"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
@@ -91,9 +88,6 @@
},
"machine_acceleration": {
"default_value": 3000
- },
- "machine_nozzle_temp_enabled": {
- "default_value": false
}
}
}
diff --git a/resources/definitions/ultimaker2_extended_olsson.def.json b/resources/definitions/ultimaker2_extended_olsson.def.json
new file mode 100644
index 0000000000..d2eb7f9a5d
--- /dev/null
+++ b/resources/definitions/ultimaker2_extended_olsson.def.json
@@ -0,0 +1,12 @@
+{
+ "version": 2,
+ "name": "Ultimaker 2 Extended with Olsson",
+ "inherits": "ultimaker2_extended",
+ "metadata": {
+ "has_variants": true
+ },
+
+ "overrides": {
+ "machine_name": { "default_value": "Ultimaker 2 Extended with Olsson" }
+ }
+}
diff --git a/resources/definitions/ultimaker2_go.def.json b/resources/definitions/ultimaker2_go.def.json
index 9e374b2c88..774d215bef 100644
--- a/resources/definitions/ultimaker2_go.def.json
+++ b/resources/definitions/ultimaker2_go.def.json
@@ -11,7 +11,6 @@
"platform": "ultimaker2go_platform.obj",
"platform_texture": "Ultimaker2Gobackplate.png",
"platform_offset": [0, 0, 0],
- "first_start_actions": [],
"machine_extruder_trains":
{
"0": "ultimaker2_go_extruder_0"
diff --git a/resources/definitions/ultimaker2_olsson.def.json b/resources/definitions/ultimaker2_olsson.def.json
new file mode 100644
index 0000000000..2f8b877942
--- /dev/null
+++ b/resources/definitions/ultimaker2_olsson.def.json
@@ -0,0 +1,13 @@
+{
+ "version": 2,
+ "name": "Ultimaker 2 with Olsson Block",
+ "inherits": "ultimaker2",
+ "metadata": {
+ "has_variants": true,
+ "quality_definition": "ultimaker2"
+ },
+
+ "overrides": {
+ "machine_name": { "default_value": "Ultimaker 2 with Olsson Block" }
+ }
+}
diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json
index 28fd2b71f9..633e50bdba 100644
--- a/resources/definitions/ultimaker2_plus.def.json
+++ b/resources/definitions/ultimaker2_plus.def.json
@@ -12,8 +12,8 @@
"preferred_variant_name": "0.4 mm",
"has_variants": true,
"has_materials": true,
- "has_machine_materials": true,
"has_machine_quality": true,
+ "exclude_materials": ["generic_hips", "generic_petg", "generic_bam", "ultimaker_bam", "generic_pva", "ultimaker_pva", "generic_tough_pla", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "generic_cffcpe", "generic_cffpa", "generic_gffcpe", "generic_gffpa", "structur3d_dap100silicone" ],
"first_start_actions": [],
"supported_actions": [],
"machine_extruder_trains":
@@ -37,9 +37,6 @@
"line_width": {
"value": "round(machine_nozzle_size * 0.875, 2)"
},
- "speed_layer_0": {
- "default_value": 20
- },
"speed_support": {
"value": "speed_wall_0"
},
@@ -50,7 +47,7 @@
"default_value": true
},
"gantry_height": {
- "default_value": 52
+ "value": "52"
},
"machine_nozzle_head_distance": {
"default_value": 5
diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json
index 72756de2a5..b34ff3bdba 100644
--- a/resources/definitions/ultimaker3.def.json
+++ b/resources/definitions/ultimaker3.def.json
@@ -12,8 +12,8 @@
"platform_offset": [0, 0, 0],
"has_machine_quality": true,
"has_materials": true,
- "has_machine_materials": true,
"has_variants": true,
+ "exclude_materials": [ "generic_hips", "generic_petg", "generic_cffcpe", "generic_cffpa", "generic_gffcpe", "generic_gffpa", "structur3d_dap100silicone" ],
"preferred_variant_name": "AA 0.4",
"preferred_quality_type": "normal",
"variants_name": "Print core",
@@ -25,15 +25,18 @@
"first_start_actions": [ "DiscoverUM3Action" ],
"supported_actions": [ "DiscoverUM3Action" ],
"supports_usb_connection": false,
+ "supports_network_connection": true,
"firmware_update_info": {
"id": 9066,
"check_urls":
[
- "http://software.ultimaker.com/jedi/releases/latest.version?utm_source=cura&utm_medium=software&utm_campaign=resources",
- "http://software.ultimaker.com/releases/firmware/9066/stable/version.txt"
+ "https://software.ultimaker.com/releases/firmware/9066/stable/um-update.swu.version"
],
"update_url": "https://ultimaker.com/firmware"
- }
+ },
+ "bom_numbers": [
+ 9066
+ ]
},
@@ -62,7 +65,7 @@
"machine_max_feedrate_y": { "default_value": 300 },
"machine_max_feedrate_z": { "default_value": 40 },
"machine_acceleration": { "default_value": 3000 },
- "gantry_height": { "default_value": 60 },
+ "gantry_height": { "value": "60" },
"machine_disallowed_areas": { "default_value": [
[[92.8, -53.4], [92.8, -97.5], [116.5, -97.5], [116.5, -53.4]],
[[73.8, 107.5], [73.8, 100.5], [116.5, 100.5], [116.5, 107.5]],
@@ -78,7 +81,7 @@
"prime_tower_position_x": { "value": "machine_depth - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) - 30" },
"prime_tower_wipe_enabled": { "default_value": false },
- "prime_blob_enable": { "enabled": true },
+ "prime_blob_enable": { "enabled": true, "default_value": true, "value": "resolveOrValue('print_sequence') != 'one_at_a_time'" },
"acceleration_enabled": { "value": "True" },
"acceleration_layer_0": { "value": "acceleration_topbottom" },
@@ -118,7 +121,6 @@
"material_bed_temperature": { "maximum_value": "115" },
"material_bed_temperature_layer_0": { "maximum_value": "115" },
"material_standby_temperature": { "value": "100" },
- "meshfix_maximum_resolution": { "value": "0.04" },
"multiple_mesh_overlap": { "value": "0" },
"optimize_wall_printing_order": { "value": "True" },
"prime_tower_enable": { "default_value": true },
diff --git a/resources/definitions/ultimaker3_extended.def.json b/resources/definitions/ultimaker3_extended.def.json
index 68f26969b7..ba9824896f 100644
--- a/resources/definitions/ultimaker3_extended.def.json
+++ b/resources/definitions/ultimaker3_extended.def.json
@@ -12,7 +12,6 @@
"platform_texture": "Ultimaker3Extendedbackplate.png",
"platform_offset": [0, 0, 0],
"has_machine_quality": true,
- "has_machine_materials": true,
"has_materials": true,
"has_variants": true,
"preferred_variant_name": "AA 0.4",
@@ -28,11 +27,13 @@
"id": 9511,
"check_urls":
[
- "http://software.ultimaker.com/jedi/releases/latest.version?utm_source=cura&utm_medium=software&utm_campaign=resources",
- "http://software.ultimaker.com/releases/firmware/9511/stable/version.txt"
+ "https://software.ultimaker.com/releases/firmware/9066/stable/um-update.swu.version"
],
"update_url": "https://ultimaker.com/firmware"
- }
+ },
+ "bom_numbers": [
+ 9511
+ ]
},
"overrides": {
diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json
index 6a978c47cb..71130312e7 100644
--- a/resources/definitions/ultimaker_original.def.json
+++ b/resources/definitions/ultimaker_original.def.json
@@ -11,9 +11,9 @@
"platform": "ultimaker_platform.stl",
"has_materials": true,
"has_machine_quality": true,
- "exclude_materials": ["generic_hips", "generic_petg", "generic_bam", "ultimaker_bam", "generic_pva", "ultimaker_pva", "generic_tough_pla", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white"],
- "first_start_actions": ["UMOUpgradeSelection", "UMOCheckup", "BedLevel"],
- "supported_actions": ["UMOUpgradeSelection", "UMOCheckup", "BedLevel"],
+ "exclude_materials": ["generic_hips", "generic_petg", "generic_bam", "ultimaker_bam", "generic_pva", "ultimaker_pva", "generic_tough_pla", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "generic_cffcpe", "generic_cffpa", "generic_gffcpe", "generic_gffpa", "structur3d_dap100silicone" ],
+ "first_start_actions": ["UMOUpgradeSelection", "BedLevel"],
+ "supported_actions": ["UMOUpgradeSelection", "BedLevel"],
"machine_extruder_trains":
{
"0": "ultimaker_original_extruder_0"
@@ -46,7 +46,7 @@
]
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
diff --git a/resources/definitions/ultimaker_original_dual.def.json b/resources/definitions/ultimaker_original_dual.def.json
index 999650aa28..fd9b91e238 100644
--- a/resources/definitions/ultimaker_original_dual.def.json
+++ b/resources/definitions/ultimaker_original_dual.def.json
@@ -12,7 +12,7 @@
"has_materials": true,
"has_machine_quality": true,
"quality_definition": "ultimaker_original",
- "exclude_materials": ["generic_hips", "generic_petg", "generic_bam", "ultimaker_bam", "generic_pva", "ultimaker_pva", "generic_tough_pla", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white"],
+ "exclude_materials": ["generic_hips", "generic_petg", "generic_bam", "ultimaker_bam", "generic_pva", "ultimaker_pva", "generic_tough_pla", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "generic_cffcpe", "generic_cffpa", "generic_gffcpe", "generic_gffpa", "structur3d_dap100silicone" ],
"machine_extruder_trains":
{
"0": "ultimaker_original_dual_1st",
@@ -20,8 +20,8 @@
},
"firmware_file": "MarlinUltimaker-{baudrate}-dual.hex",
"firmware_hbk_file": "MarlinUltimaker-HBK-{baudrate}-dual.hex",
- "first_start_actions": ["UMOUpgradeSelection", "UMOCheckup", "BedLevel"],
- "supported_actions": ["UMOUpgradeSelection", "UMOCheckup", "BedLevel"]
+ "first_start_actions": ["UMOUpgradeSelection", "BedLevel"],
+ "supported_actions": ["UMOUpgradeSelection", "BedLevel"]
},
"overrides": {
@@ -48,7 +48,7 @@
]
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
diff --git a/resources/definitions/ultimaker_original_plus.def.json b/resources/definitions/ultimaker_original_plus.def.json
index bdb8a3d788..949e2e8d0d 100644
--- a/resources/definitions/ultimaker_original_plus.def.json
+++ b/resources/definitions/ultimaker_original_plus.def.json
@@ -10,8 +10,8 @@
"platform": "ultimaker2_platform.obj",
"platform_texture": "UltimakerPlusbackplate.png",
"quality_definition": "ultimaker_original",
- "first_start_actions": ["UMOCheckup", "BedLevel"],
- "supported_actions": ["UMOCheckup", "BedLevel"],
+ "first_start_actions": ["BedLevel"],
+ "supported_actions": ["BedLevel"],
"machine_extruder_trains":
{
"0": "ultimaker_original_plus_extruder_0"
diff --git a/resources/definitions/ultimaker_s3.def.json b/resources/definitions/ultimaker_s3.def.json
new file mode 100644
index 0000000000..efdc7cca0a
--- /dev/null
+++ b/resources/definitions/ultimaker_s3.def.json
@@ -0,0 +1,165 @@
+{
+ "version": 2,
+ "name": "Ultimaker S3",
+ "inherits": "ultimaker",
+ "metadata": {
+ "author": "Ultimaker",
+ "manufacturer": "Ultimaker B.V.",
+ "category": "Ultimaker",
+ "visible": true,
+ "file_formats": "application/x-ufp;text/x-gcode",
+ "platform": "ultimaker_s3_platform.obj",
+ "platform_texture": "UltimakerS3backplate.png",
+ "platform_offset": [0, 0, 0],
+ "has_machine_quality": true,
+ "has_materials": true,
+ "has_variant_buildplates": false,
+ "has_variants": true,
+ "exclude_materials": [ "generic_hips", "generic_petg", "structur3d_dap100silicone" ],
+ "preferred_variant_name": "AA 0.4",
+ "preferred_quality_type": "normal",
+ "variants_name": "Print core",
+ "nozzle_offsetting_for_disallowed_areas": false,
+ "machine_extruder_trains":
+ {
+ "0": "ultimaker_s3_extruder_left",
+ "1": "ultimaker_s3_extruder_right"
+ },
+ "first_start_actions": [ "DiscoverUM3Action" ],
+ "supported_actions": [ "DiscoverUM3Action" ],
+ "supports_usb_connection": false,
+ "weight": -1,
+ "firmware_update_info": {
+ "id": 213482,
+ "check_urls": ["https://software.ultimaker.com/releases/firmware/213482/stable/um-update.swu.version"],
+ "update_url": "https://ultimaker.com/firmware"
+ },
+ "bom_numbers": [
+ 213482
+ ]
+ },
+
+ "overrides": {
+ "machine_name": { "default_value": "Ultimaker S3" },
+ "machine_width": { "default_value": 230 },
+ "machine_depth": { "default_value": 190 },
+ "machine_height": { "default_value": 200 },
+ "machine_heated_bed": { "default_value": true },
+ "machine_nozzle_heat_up_speed": { "default_value": 1.4 },
+ "machine_nozzle_cool_down_speed": { "default_value": 0.8 },
+ "machine_head_with_fans_polygon":
+ {
+ "default_value":
+ [
+ [ -41.4, -45.8 ],
+ [ -41.4, 36.0 ],
+ [ 63.3, 36.0 ],
+ [ 63.3, -45.8 ]
+ ]
+ },
+ "machine_gcode_flavor": { "default_value": "Griffin" },
+ "machine_max_feedrate_x": { "default_value": 300 },
+ "machine_max_feedrate_y": { "default_value": 300 },
+ "machine_max_feedrate_z": { "default_value": 40 },
+ "machine_acceleration": { "default_value": 3000 },
+ "gantry_height": { "value": "60" },
+ "machine_extruder_count": { "default_value": 2 },
+ "extruder_prime_pos_abs": { "default_value": true },
+ "machine_start_gcode": { "default_value": "" },
+ "machine_end_gcode": { "default_value": "" },
+ "prime_blob_enable": { "enabled": true, "default_value": false },
+
+ "speed_travel":
+ {
+ "maximum_value": "150",
+ "value": "150"
+ },
+
+ "acceleration_enabled": { "value": "True" },
+ "acceleration_layer_0": { "value": "acceleration_topbottom" },
+ "acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" },
+ "acceleration_print": { "value": "4000" },
+ "acceleration_support": { "value": "math.ceil(acceleration_print * 2000 / 4000)" },
+ "acceleration_support_interface": { "value": "acceleration_topbottom" },
+ "acceleration_topbottom": { "value": "math.ceil(acceleration_print * 500 / 4000)" },
+ "acceleration_wall": { "value": "math.ceil(acceleration_print * 1000 / 4000)" },
+ "acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 500 / 1000)" },
+ "brim_width": { "value": "3" },
+ "cool_fan_full_at_height": { "value": "layer_height_0 + 4 * layer_height" },
+ "cool_fan_speed": { "value": "50" },
+ "cool_fan_speed_max": { "value": "100" },
+ "cool_min_speed": { "value": "5" },
+ "infill_line_width": { "value": "round(line_width * 0.5 / 0.35, 2)" },
+ "infill_overlap": { "value": "0" },
+ "infill_pattern": { "value": "'triangles'" },
+ "infill_wipe_dist": { "value": "0" },
+ "jerk_enabled": { "value": "True" },
+ "jerk_layer_0": { "value": "jerk_topbottom" },
+ "jerk_prime_tower": { "value": "math.ceil(jerk_print * 15 / 25)" },
+ "jerk_print": { "value": "25" },
+ "jerk_support": { "value": "math.ceil(jerk_print * 15 / 25)" },
+ "jerk_support_interface": { "value": "jerk_topbottom" },
+ "jerk_topbottom": { "value": "math.ceil(jerk_print * 5 / 25)" },
+ "jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" },
+ "jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" },
+ "layer_height_0": { "value": "round(machine_nozzle_size / 1.5, 2)" },
+ "layer_start_x": { "value": "sum(extruderValues('machine_extruder_start_pos_x')) / len(extruderValues('machine_extruder_start_pos_x'))" },
+ "layer_start_y": { "value": "sum(extruderValues('machine_extruder_start_pos_y')) / len(extruderValues('machine_extruder_start_pos_y'))" },
+ "line_width": { "value": "machine_nozzle_size * 0.875" },
+ "machine_min_cool_heat_time_window": { "value": "15" },
+ "default_material_print_temperature": { "value": "200" },
+ "material_standby_temperature": { "value": "100" },
+ "multiple_mesh_overlap": { "value": "0" },
+ "prime_tower_enable": { "value": "True" },
+ "raft_airgap": { "value": "0" },
+ "raft_base_speed": { "value": "20" },
+ "raft_base_thickness": { "value": "0.3" },
+ "raft_interface_line_spacing": { "value": "0.5" },
+ "raft_interface_line_width": { "value": "0.5" },
+ "raft_interface_speed": { "value": "20" },
+ "raft_interface_thickness": { "value": "0.2" },
+ "raft_jerk": { "value": "jerk_layer_0" },
+ "raft_margin": { "value": "10" },
+ "raft_speed": { "value": "25" },
+ "raft_surface_layers": { "value": "1" },
+ "retraction_amount": { "value": "6.5" },
+ "retraction_count_max": { "value": "10" },
+ "retraction_extrusion_window": { "value": "1" },
+ "retraction_hop": { "value": "2" },
+ "retraction_hop_enabled": { "value": "extruders_enabled_count > 1" },
+ "retraction_hop_only_when_collides": { "value": "True" },
+ "retraction_min_travel": { "value": "5" },
+ "retraction_prime_speed": { "value": "15" },
+ "skin_overlap": { "value": "10" },
+ "speed_equalize_flow_enabled": { "value": "True" },
+ "speed_layer_0": { "value": "20" },
+ "speed_prime_tower": { "value": "speed_topbottom" },
+ "speed_print": { "value": "35" },
+ "speed_support": { "value": "speed_wall_0" },
+ "speed_support_interface": { "value": "speed_topbottom" },
+ "speed_topbottom": { "value": "math.ceil(speed_print * 20 / 35)" },
+ "speed_wall": { "value": "math.ceil(speed_print * 30 / 35)" },
+ "speed_wall_0": { "value": "math.ceil(speed_wall * 20 / 30)" },
+ "speed_wall_x": { "value": "speed_wall" },
+ "support_angle": { "value": "45" },
+ "support_pattern": { "value": "'triangles'" },
+ "support_use_towers": { "value": "False" },
+ "support_xy_distance": { "value": "wall_line_width_0 * 2.5" },
+ "support_xy_distance_overhang": { "value": "wall_line_width_0" },
+ "support_z_distance": { "value": "0" },
+ "switch_extruder_prime_speed": { "value": "15" },
+ "switch_extruder_retraction_amount": { "value": "8" },
+ "top_bottom_thickness": { "value": "1" },
+ "travel_avoid_supports": { "value": "True" },
+ "travel_avoid_distance": { "value": "3 if extruders_enabled_count > 1 else machine_nozzle_tip_outer_diameter / 2 * 1.5" },
+ "wall_0_inset": { "value": "0" },
+ "wall_line_width_x": { "value": "round(line_width * 0.3 / 0.35, 2)" },
+ "wall_thickness": { "value": "1" },
+ "meshfix_maximum_resolution": { "value": "(speed_wall_0 + speed_wall_x) / 60" },
+ "meshfix_maximum_deviation": { "value": "layer_height / 2" },
+ "optimize_wall_printing_order": { "value": "True" },
+ "retraction_combing": { "default_value": "all" },
+ "initial_layer_line_width_factor": { "value": "120" },
+ "zig_zaggify_infill": { "value": "gradual_infill_steps == 0" }
+ }
+}
diff --git a/resources/definitions/ultimaker_s5.def.json b/resources/definitions/ultimaker_s5.def.json
index 310765dbc3..dcd44a371a 100644
--- a/resources/definitions/ultimaker_s5.def.json
+++ b/resources/definitions/ultimaker_s5.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker_s5",
"version": 2,
"name": "Ultimaker S5",
"inherits": "ultimaker",
@@ -14,7 +13,6 @@
"platform_offset": [0, -30, -10],
"has_machine_quality": true,
"has_materials": true,
- "has_machine_materials": true,
"has_variant_buildplates": true,
"has_variants": true,
"preferred_variant_name": "AA 0.4",
@@ -30,12 +28,16 @@
"first_start_actions": [ "DiscoverUM3Action" ],
"supported_actions": [ "DiscoverUM3Action" ],
"supports_usb_connection": false,
- "weight": -1,
+ "supports_network_connection": true,
+ "weight": -2,
"firmware_update_info": {
"id": 9051,
- "check_urls": ["http://software.ultimaker.com/releases/firmware/9051/stable/version.txt"],
+ "check_urls": ["https://software.ultimaker.com/releases/firmware/9051/stable/um-update.swu.version"],
"update_url": "https://ultimaker.com/firmware"
- }
+ },
+ "bom_numbers": [
+ 9051, 214475
+ ]
},
"overrides": {
@@ -44,6 +46,7 @@
"machine_depth": { "default_value": 240 },
"machine_height": { "default_value": 300 },
"machine_heated_bed": { "default_value": true },
+ "machine_heated_build_volume": { "default_value": true },
"machine_nozzle_heat_up_speed": { "default_value": 1.4 },
"machine_nozzle_cool_down_speed": { "default_value": 0.8 },
"machine_head_with_fans_polygon":
@@ -61,13 +64,11 @@
"machine_max_feedrate_y": { "default_value": 300 },
"machine_max_feedrate_z": { "default_value": 40 },
"machine_acceleration": { "default_value": 3000 },
- "gantry_height": { "default_value": 60 },
+ "gantry_height": { "value": "60" },
"machine_extruder_count": { "default_value": 2 },
"extruder_prime_pos_abs": { "default_value": true },
"machine_start_gcode": { "default_value": "" },
"machine_end_gcode": { "default_value": "" },
- "prime_tower_position_x": { "default_value": 345 },
- "prime_tower_position_y": { "default_value": 222.5 },
"prime_blob_enable": { "enabled": true, "default_value": false },
"speed_travel":
@@ -156,10 +157,12 @@
"wall_0_inset": { "value": "0" },
"wall_line_width_x": { "value": "round(line_width * 0.3 / 0.35, 2)" },
"wall_thickness": { "value": "1" },
- "meshfix_maximum_resolution": { "value": "0.04" },
+ "meshfix_maximum_resolution": { "value": "(speed_wall_0 + speed_wall_x) / 60" },
+ "meshfix_maximum_deviation": { "value": "layer_height / 2" },
"optimize_wall_printing_order": { "value": "True" },
"retraction_combing": { "default_value": "all" },
"initial_layer_line_width_factor": { "value": "120" },
- "zig_zaggify_infill": { "value": "gradual_infill_steps == 0" }
+ "zig_zaggify_infill": { "value": "gradual_infill_steps == 0" },
+ "build_volume_temperature": { "maximum_value": 50 }
}
}
diff --git a/resources/definitions/uni_print_3d.def.json b/resources/definitions/uni_print_3d.def.json
index 427177176a..99d9eab1e0 100644
--- a/resources/definitions/uni_print_3d.def.json
+++ b/resources/definitions/uni_print_3d.def.json
@@ -1,5 +1,4 @@
{
- "id": "uni_print_3d",
"name": "UNI-PRINT-3D",
"version": 2,
"inherits": "fdmprinter",
diff --git a/resources/definitions/uniqbot_one.def.json b/resources/definitions/uniqbot_one.def.json
index 5a33500b75..ec8336ae50 100644
--- a/resources/definitions/uniqbot_one.def.json
+++ b/resources/definitions/uniqbot_one.def.json
@@ -30,7 +30,7 @@
"default_value": false
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/vertex_delta_k8800.def.json b/resources/definitions/vertex_delta_k8800.def.json
index df24bd84fb..c92476da49 100644
--- a/resources/definitions/vertex_delta_k8800.def.json
+++ b/resources/definitions/vertex_delta_k8800.def.json
@@ -3,10 +3,10 @@
"version": 2,
"inherits": "fdmprinter",
"metadata": {
- "manufacturer": "Velleman nv",
+ "manufacturer": "Velleman N.V.",
"file_formats": "text/x-gcode",
"visible": true,
- "author": "Velleman",
+ "author": "Velleman N.V.",
"has_machine_quality": true,
"has_materials": true,
"machine_extruder_trains":
@@ -31,7 +31,7 @@
"default_value": "elliptic"
},
"gantry_height": {
- "default_value": 0
+ "value": "0"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/vertex_k8400.def.json b/resources/definitions/vertex_k8400.def.json
index a3a3777547..bbeb8510ba 100644
--- a/resources/definitions/vertex_k8400.def.json
+++ b/resources/definitions/vertex_k8400.def.json
@@ -4,7 +4,7 @@
"inherits": "fdmprinter",
"metadata": {
"visible": true,
- "manufacturer": "Velleman",
+ "manufacturer": "Velleman N.V.",
"file_formats": "text/x-gcode",
"platform": "Vertex_build_panel.stl",
"platform_offset": [0, -3, 0],
@@ -20,12 +20,6 @@
"machine_heated_bed": {
"default_value": true
},
- "material_bed_temperature": {
- "default_value": 0
- },
- "material_bed_temperature_layer_0": {
- "default_value": 0
- },
"machine_width": {
"default_value": 200
},
@@ -41,14 +35,6 @@
"machine_center_is_zero": {
"default_value": false
},
- "machine_head_polygon": {
- "default_value": [
- [-60, -18],
- [-60, 40],
- [18, 40],
- [18, -18]
- ]
- },
"machine_head_with_fans_polygon": {
"default_value": [
[-60, -40],
@@ -58,16 +44,16 @@
]
},
"gantry_height": {
- "default_value": 18
+ "value": "18"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
- "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."
+ "default_value": "M104 T0 S{material_print_temperature_layer_0}\nG28 ;Home extruder\nG90 ;Absolute positioning\nM82 ;Extruder in absolute mode\nG1 Z1 F100\nG92 E0 ;Reset extruder position\nM109 T0 S{material_print_temperature_layer_0}\nG1 E20 F100\nG92 E0 ;Reset extruder position"
},
"machine_end_gcode": {
- "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning"
+ "default_value": "G1 X0 Y0 Z130 ;Get extruder out of way\nM107 ;Turn off fan\n;Disable all extruders\nG91 ;Relative positioning\nT0\nG1 E-1 ;Reduce filament pressure\nM104 T0 S0\nG90 ;Absolute positioning\nG92 E0 ;Reset extruder position\nM140 S0 ;Disable heated bed\nM84 ;Turn steppers off"
}
}
}
\ No newline at end of file
diff --git a/resources/definitions/vertex_k8400_dual.def.json b/resources/definitions/vertex_k8400_dual.def.json
index c7706135bd..498d550429 100644
--- a/resources/definitions/vertex_k8400_dual.def.json
+++ b/resources/definitions/vertex_k8400_dual.def.json
@@ -4,7 +4,7 @@
"inherits": "fdmprinter",
"metadata": {
"visible": true,
- "manufacturer": "Velleman",
+ "manufacturer": "Velleman N.V.",
"file_formats": "text/x-gcode",
"platform": "Vertex_build_panel.stl",
"platform_offset": [0, -3, 0],
@@ -18,12 +18,6 @@
"machine_heated_bed": {
"default_value": true
},
- "material_bed_temperature": {
- "default_value": 0
- },
- "material_bed_temperature_layer_0": {
- "default_value": 0
- },
"machine_width": {
"default_value": 223.7
},
@@ -42,14 +36,6 @@
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
},
- "machine_head_polygon": {
- "default_value": [
- [-60, -18],
- [-60, 40],
- [18, 40],
- [18, -18]
- ]
- },
"machine_head_with_fans_polygon": {
"default_value": [
[-60, -40],
@@ -59,7 +45,7 @@
]
},
"gantry_height": {
- "default_value": 18
+ "value": "18"
},
"machine_extruder_count": {
"default_value": 2
diff --git a/resources/definitions/vertex_nano_k8600.def.json b/resources/definitions/vertex_nano_k8600.def.json
new file mode 100644
index 0000000000..ef9552caf3
--- /dev/null
+++ b/resources/definitions/vertex_nano_k8600.def.json
@@ -0,0 +1,77 @@
+{
+ "version": 2,
+ "name": "Vertex K8600",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "manufacturer": "Velleman N.V.",
+ "file_formats": "text/x-gcode",
+ "supports_usb_connection": true,
+ "supported_actions": ["MachineSettingsAction"],
+ "machine_extruder_trains": {
+ "0": "vertex_nano_k8600_extruder_0"
+ }
+ },
+ "overrides": {
+ "machine_name": {
+ "default_value": "Vertex K8600"
+ },
+ "machine_heated_bed": {
+ "default_value": false
+ },
+ "machine_width": {
+ "default_value": 80
+ },
+ "machine_height": {
+ "default_value": 75
+ },
+ "machine_depth": {
+ "default_value": 80
+ },
+ "machine_center_is_zero": {
+ "default_value": false
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (Marlin/Sprinter)"
+ },
+ "machine_start_gcode": {
+ "default_value": "; Vertex Nano Start G-code M0 is my nozzle clean M400 G28 ; Home extruder G90 ; Absolute positioning M82 ; Extruder in absolute mode M104 T0 S{material_print_temperature} G92 E0 ; Reset extruder position G1 Z1 F800 M109 T0 S{material_print_temperature} M117 Priming nozzle... M83 G1 E20 F100 ; purge/prime nozzle M82 G92 E0 ; Reset extruder position G4 S3 ; Wait 3 seconds G1 Z5 F2000 M117 Vertex Nano is printing"
+ },
+ "machine_end_gcode": {
+ "default_value": "; Vertex Nano end G-Code G91 ; Relative positioning T0 G1 E-1 F1500; Reduce filament pressure M104 T0 S0 G90 ; Absolute positioning G92 E0 ; Reset extruder position G28 M84 ; Turn steppers off"
+ },
+ "line_width": {
+ "value": 0.35
+ },
+ "infill_line_width": {
+ "value": 0.35
+ },
+ "wall_thickness": {
+ "value": 0.7
+ },
+ "top_bottom_thickness": {
+ "value": 0.6
+ },
+ "infill_sparse_density": {
+ "value": 40
+ },
+ "infill_overlap": {
+ "value": 5
+ },
+ "min_infill_area": {
+ "value": 0.1
+ },
+ "retract_at_layer_change": {
+ "value": true
+ },
+ "retraction_min_travel": {
+ "value": 1
+ },
+ "retraction_count_max": {
+ "value": 15
+ },
+ "retraction_extrusion_window": {
+ "value": 1
+ }
+ }
+}
diff --git a/resources/definitions/wanhao_d6.def.json b/resources/definitions/wanhao_d6.def.json
index c8a690d02c..eaaae54826 100644
--- a/resources/definitions/wanhao_d6.def.json
+++ b/resources/definitions/wanhao_d6.def.json
@@ -36,7 +36,7 @@
"default_value": true
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
diff --git a/resources/definitions/wanhao_d9.def.json b/resources/definitions/wanhao_d9.def.json
index 4e368f970f..ac4d41fa40 100644
--- a/resources/definitions/wanhao_d9.def.json
+++ b/resources/definitions/wanhao_d9.def.json
@@ -23,16 +23,14 @@
"machine_heated_bed": { "default_value": true },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": {
- "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{travel_speed} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{travel_speed} \n ;Put printing message on LCD screen\n M117 Printing..."
+ "default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E6 ;extrude 6 mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..."
},
"machine_end_gcode": {
- "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning"
+ "default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning"
},
"support_angle": { "default_value": 60 },
"support_enable": { "default_value": true },
"layer_height_0": { "default_value": 0.15 },
- "top_thickness": { "default_value": 0.6 },
- "material_print_temperature": { "default_value": 190 },
"layer_height": { "default_value": 0.2 },
"speed_print": { "default_value": 30 },
"adhesion_type": { "default_value": "raft" },
diff --git a/resources/definitions/winbo_dragonl4.def.json b/resources/definitions/winbo_dragonl4.def.json
index 0ca68cdcee..bf52a785e9 100644
--- a/resources/definitions/winbo_dragonl4.def.json
+++ b/resources/definitions/winbo_dragonl4.def.json
@@ -37,7 +37,7 @@
"machine_max_feedrate_y": { "default_value": 300 },
"machine_max_feedrate_z": { "default_value": 40 },
"machine_acceleration": { "default_value": 2000 },
- "gantry_height": { "default_value": 80 },
+ "gantry_height": { "value": "80" },
"machine_extruder_count": { "default_value": 1 },
"machine_start_gcode": { "default_value": "G21\nG90\nM82\nM107\nM9998\nG28 X0 Y0\nG28 Z0\nG1 F6000 Z0.3\nG92 E0\nG1 F800 X585 E12\nG92 E0" },
"machine_end_gcode": { "default_value": "M104 S0\nM140 S0\nG92 E2\nG1 E0 F200\nG28 X0 Y0\nM84 X Y E" },
@@ -126,7 +126,7 @@
"support_bottom_height": { "value": "max((0.15 if(0.15%layer_height==0) else layer_height*int((0.15+layer_height)/layer_height)),layer_height)" },
"support_bottom_pattern": { "value": "'zigzag'" },
"support_connect_zigzags": { "value": "False" },
- "support_infill_rate": { "value": "8" },
+ "support_infill_rate": { "value": "8 if support_enable else 0 if support_tree_enable else 8" },
"support_interface_density": { "value": "80" },
"support_interface_enable": { "value": "True" },
"support_interface_height": { "value": "0.5" },
diff --git a/resources/definitions/winbo_mini2.def.json b/resources/definitions/winbo_mini2.def.json
index 7393fdf910..f1c94ca07e 100644
--- a/resources/definitions/winbo_mini2.def.json
+++ b/resources/definitions/winbo_mini2.def.json
@@ -37,7 +37,7 @@
"machine_max_feedrate_y": { "default_value": 200 },
"machine_max_feedrate_z": { "default_value": 40 },
"machine_acceleration": { "default_value": 3000 },
- "gantry_height": { "default_value": 75 },
+ "gantry_height": { "value": "75" },
"machine_extruder_count": { "default_value": 1 },
"machine_start_gcode": { "default_value": "G21\nG90\nM82\nM107\nG28 X0 Y0\nG28 Z0\nG1 F1000 Z3\nG1 F4000 X0\nG1 F4000 Y0\nG1 F1000 Z0.2\nG92 E0\nG1 F1000 X30 E8\nG92 E0\nM117 Printing." },
"machine_end_gcode": { "default_value": "M104 S0\nM140 S0\nG92 E2\nG1 E0 F200\nG28 X0 Y0\nM84 X Y E" },
@@ -126,7 +126,7 @@
"support_bottom_height": { "value": "max((0.15 if(0.15%layer_height==0) else layer_height*int((0.15+layer_height)/layer_height)),layer_height)" },
"support_bottom_pattern": { "value": "'zigzag'" },
"support_connect_zigzags": { "value": "False" },
- "support_infill_rate": { "value": "8" },
+ "support_infill_rate": { "value": "8 if support_enable else 0 if support_tree_enable else 8" },
"support_interface_density": { "value": "80" },
"support_interface_enable": { "value": "True" },
"support_interface_height": { "value": "0.5" },
diff --git a/resources/definitions/winbo_superhelper105.def.json b/resources/definitions/winbo_superhelper105.def.json
index 59e71fb446..ac78467a2a 100644
--- a/resources/definitions/winbo_superhelper105.def.json
+++ b/resources/definitions/winbo_superhelper105.def.json
@@ -37,7 +37,7 @@
"machine_max_feedrate_y": { "default_value": 200 },
"machine_max_feedrate_z": { "default_value": 40 },
"machine_acceleration": { "default_value": 2000 },
- "gantry_height": { "default_value": 200 },
+ "gantry_height": { "value": "200" },
"machine_extruder_count": { "default_value": 1 },
"machine_start_gcode": { "default_value": "G21\nG90\nM82\nM107\nG28 X0 Y0\nG28 Z0\nG1 F6000 Z0.3\nG92 E0\nG1 F1000 X30 E8\nG92 E0\nM117 Printing." },
"machine_end_gcode": { "default_value": "M104 S0\nM140 S0\nG92 E2\nG1 E0 F200\nG28 X0 Y0\nM84 X Y E" },
@@ -115,7 +115,7 @@
"support_bottom_height": { "value": "max((0.15 if(0.15%layer_height==0) else layer_height*int((0.15+layer_height)/layer_height)),layer_height)" },
"support_bottom_pattern": { "value": "'zigzag'" },
"support_connect_zigzags": { "value": "False" },
- "support_infill_rate": { "value": "8" },
+ "support_infill_rate": { "value": "8 if support_enable else 0 if support_tree_enable else 8" },
"support_interface_density": { "value": "80" },
"support_interface_enable": { "value": "True" },
"support_interface_height": { "value": "0.5" },
diff --git a/resources/definitions/z-bolt_classic.def.json b/resources/definitions/z-bolt_classic.def.json
index d294de473a..f9212c9597 100644
--- a/resources/definitions/z-bolt_classic.def.json
+++ b/resources/definitions/z-bolt_classic.def.json
@@ -41,7 +41,7 @@
]
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
diff --git a/resources/definitions/z-bolt_plus.def.json b/resources/definitions/z-bolt_plus.def.json
index 57331df4c6..dace8ea300 100644
--- a/resources/definitions/z-bolt_plus.def.json
+++ b/resources/definitions/z-bolt_plus.def.json
@@ -41,7 +41,7 @@
]
},
"gantry_height": {
- "default_value": 55
+ "value": "55"
},
"machine_use_extruder_offset_to_offset_coords": {
"default_value": true
diff --git a/resources/definitions/zone3d_printer.def.json b/resources/definitions/zone3d_printer.def.json
index 328505e18a..4c72422788 100644
--- a/resources/definitions/zone3d_printer.def.json
+++ b/resources/definitions/zone3d_printer.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "Ultimaker",
- "manufacturer": "Unknown",
+ "manufacturer": "Zone3D",
"file_formats": "text/x-gcode",
"platform_offset": [ 0, 0, 0],
"machine_extruder_trains":
@@ -16,9 +16,7 @@
"overrides": {
"prime_tower_size": { "default_value": 10.350983390135314 },
- "material_print_temperature": { "default_value": 260 },
"layer_height": { "default_value": 0.14 },
- "speed_travel": { "default_value": 150 },
"machine_extruder_count": { "default_value": 1 },
"machine_heated_bed": { "default_value": true },
"machine_center_is_zero": { "default_value": false },
diff --git a/resources/definitions/zyyx_agile.def.json b/resources/definitions/zyyx_agile.def.json
index 17265bf6f6..a4b3c3ee8b 100644
--- a/resources/definitions/zyyx_agile.def.json
+++ b/resources/definitions/zyyx_agile.def.json
@@ -33,7 +33,7 @@
"machine_center_is_zero": { "default_value": true },
"machine_gcode_flavor": { "default_value": "Makerbot" },
"machine_head_with_fans_polygon": { "default_value": [ [ -37, 50 ], [ 25, 50 ], [ 25, -40 ], [ -37, -40 ] ] },
- "gantry_height": { "default_value": 10 },
+ "gantry_height": { "value": "10" },
"machine_steps_per_mm_x": { "default_value": 88.888889 },
"machine_steps_per_mm_y": { "default_value": 88.888889 },
"machine_steps_per_mm_z": { "default_value": 400 },
diff --git a/resources/extruders/101Hero_extruder_0.def.json b/resources/extruders/101Hero_extruder_0.def.json
index 82c06e40d6..21c892133c 100644
--- a/resources/extruders/101Hero_extruder_0.def.json
+++ b/resources/extruders/101Hero_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "101Hero_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/3dator_extruder_0.def.json b/resources/extruders/3dator_extruder_0.def.json
index 6749eb7bb4..97b03518f7 100644
--- a/resources/extruders/3dator_extruder_0.def.json
+++ b/resources/extruders/3dator_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "3dator_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/Mark2_extruder1.def.json b/resources/extruders/Mark2_extruder1.def.json
new file mode 100644
index 0000000000..27becf88ff
--- /dev/null
+++ b/resources/extruders/Mark2_extruder1.def.json
@@ -0,0 +1,18 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "Mark2_for_Ultimaker2",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_offset_x": { "default_value": 0.0 },
+ "machine_nozzle_offset_y": { "default_value": 0.0 }
+ }
+}
diff --git a/resources/extruders/Mark2_extruder2.def.json b/resources/extruders/Mark2_extruder2.def.json
new file mode 100644
index 0000000000..ac654d9c00
--- /dev/null
+++ b/resources/extruders/Mark2_extruder2.def.json
@@ -0,0 +1,18 @@
+{
+ "version": 2,
+ "name": "Extruder 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "Mark2_for_Ultimaker2",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_offset_x": { "default_value": 0.0 },
+ "machine_nozzle_offset_y": { "default_value": 0.0 }
+ }
+}
diff --git a/resources/extruders/abax_pri3_extruder_0.def.json b/resources/extruders/abax_pri3_extruder_0.def.json
index 27e86d6042..618ca7f596 100644
--- a/resources/extruders/abax_pri3_extruder_0.def.json
+++ b/resources/extruders/abax_pri3_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "abax_pri3_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/abax_pri5_extruder_0.def.json b/resources/extruders/abax_pri5_extruder_0.def.json
index 842e76e5f3..4a96b5e12e 100644
--- a/resources/extruders/abax_pri5_extruder_0.def.json
+++ b/resources/extruders/abax_pri5_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "abax_pri5_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/abax_titan_extruder_0.def.json b/resources/extruders/abax_titan_extruder_0.def.json
index 79e1974def..078b9f0470 100644
--- a/resources/extruders/abax_titan_extruder_0.def.json
+++ b/resources/extruders/abax_titan_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "abax_titan_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/alfawise_u20_extruder_0.def.json b/resources/extruders/alfawise_u20_extruder_0.def.json
index 2fbe3f1772..6bb2bde534 100644
--- a/resources/extruders/alfawise_u20_extruder_0.def.json
+++ b/resources/extruders/alfawise_u20_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "alfawise_u20_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/alfawise_u30_extruder_0.def.json b/resources/extruders/alfawise_u30_extruder_0.def.json
index 37f59eb567..4014b5ab62 100644
--- a/resources/extruders/alfawise_u30_extruder_0.def.json
+++ b/resources/extruders/alfawise_u30_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "alfawise_u30_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/alya3dp_extruder_0.def.json b/resources/extruders/alya3dp_extruder_0.def.json
index 3676f01ad2..5e05210e2c 100644
--- a/resources/extruders/alya3dp_extruder_0.def.json
+++ b/resources/extruders/alya3dp_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "alya3dp_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/creality_cr10_extruder_0.def.json b/resources/extruders/anet_a6_extruder_0.def.json
similarity index 80%
rename from resources/extruders/creality_cr10_extruder_0.def.json
rename to resources/extruders/anet_a6_extruder_0.def.json
index 3a259b672b..c87160a542 100644
--- a/resources/extruders/creality_cr10_extruder_0.def.json
+++ b/resources/extruders/anet_a6_extruder_0.def.json
@@ -1,10 +1,9 @@
{
- "id": "creality_cr10_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
- "machine": "creality_cr10",
+ "machine": "anet_a6",
"position": "0"
},
diff --git a/resources/extruders/anycubic_4max_extruder_0.def.json b/resources/extruders/anycubic_4max_extruder_0.def.json
index 5c2ab8d479..9ea55928b8 100644
--- a/resources/extruders/anycubic_4max_extruder_0.def.json
+++ b/resources/extruders/anycubic_4max_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "anycubic_4max_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/creality_cr10s4_extruder_0.def.json b/resources/extruders/anycubic_chiron_extruder_0.def.json
similarity index 80%
rename from resources/extruders/creality_cr10s4_extruder_0.def.json
rename to resources/extruders/anycubic_chiron_extruder_0.def.json
index 8a40c6431f..b4117c755a 100644
--- a/resources/extruders/creality_cr10s4_extruder_0.def.json
+++ b/resources/extruders/anycubic_chiron_extruder_0.def.json
@@ -1,10 +1,9 @@
{
- "id": "creality_cr10s4_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
- "machine": "creality_cr10s4",
+ "machine": "anycubic_chiron",
"position": "0"
},
diff --git a/resources/extruders/anycubic_i3_mega_extruder_0.def.json b/resources/extruders/anycubic_i3_mega_extruder_0.def.json
index 6d9c330536..f15eab4829 100644
--- a/resources/extruders/anycubic_i3_mega_extruder_0.def.json
+++ b/resources/extruders/anycubic_i3_mega_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "anycubic_i3_mega_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/bfb_extruder_0.def.json b/resources/extruders/bfb_extruder_0.def.json
index 88c81ee03e..6dd995d098 100644
--- a/resources/extruders/bfb_extruder_0.def.json
+++ b/resources/extruders/bfb_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "bfb_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/bibo2_dual_extruder_0.def.json b/resources/extruders/bibo2_dual_extruder_0.def.json
index f83801fa0c..91508ecc6d 100644
--- a/resources/extruders/bibo2_dual_extruder_0.def.json
+++ b/resources/extruders/bibo2_dual_extruder_0.def.json
@@ -1,46 +1,45 @@
{
- "id": "BIBO1",
- "version": 2,
- "name": "Extruder 1",
- "inherits": "fdmextruder",
- "metadata": {
- "machine": "BIBO2 dual",
- "position": "0"
- },
- "overrides": {
- "extruder_nr": {
- "default_value": 0,
- "maximum_value": "1"
- },
- "material_diameter": {
- "default_value": 1.75
- },
- "machine_nozzle_size": {
- "default_value": 0.4
- },
- "machine_nozzle_offset_x": {
- "default_value": 0.0
- },
- "machine_nozzle_offset_y": {
- "default_value": 0.0
- },
- "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"
- }
- }
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "bibo2_dual",
+ "position": "0"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0,
+ "maximum_value": "1"
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "machine_nozzle_offset_x": {
+ "default_value": 0.0
+ },
+ "machine_nozzle_offset_y": {
+ "default_value": 0.0
+ },
+ "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"
+ }
+ }
}
diff --git a/resources/extruders/bibo2_dual_extruder_1.def.json b/resources/extruders/bibo2_dual_extruder_1.def.json
index 5f479ba54b..129ad27273 100644
--- a/resources/extruders/bibo2_dual_extruder_1.def.json
+++ b/resources/extruders/bibo2_dual_extruder_1.def.json
@@ -1,46 +1,45 @@
{
- "id": "BIBO2",
- "version": 2,
- "name": "Extruder 2",
- "inherits": "fdmextruder",
- "metadata": {
- "machine": "BIBO2 dual",
- "position": "1"
- },
- "overrides": {
- "extruder_nr": {
- "default_value": 1,
- "maximum_value": "1"
- },
- "material_diameter": {
- "default_value": 1.75
- },
- "machine_nozzle_size": {
- "default_value": 0.4
- },
- "machine_nozzle_offset_x": {
- "default_value": 0.0
- },
- "machine_nozzle_offset_y": {
- "default_value": 0.0
- },
- "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"
- }
- }
+ "version": 2,
+ "name": "Extruder 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "bibo2_dual",
+ "position": "1"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1,
+ "maximum_value": "1"
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "machine_nozzle_offset_x": {
+ "default_value": 0.0
+ },
+ "machine_nozzle_offset_y": {
+ "default_value": 0.0
+ },
+ "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"
+ }
+ }
}
diff --git a/resources/extruders/bq_hephestos_2_extruder_0.def.json b/resources/extruders/bq_hephestos_2_extruder_0.def.json
index 833907937d..d58d8d755a 100644
--- a/resources/extruders/bq_hephestos_2_extruder_0.def.json
+++ b/resources/extruders/bq_hephestos_2_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "bq_hephestos_2_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/bq_hephestos_extruder_0.def.json b/resources/extruders/bq_hephestos_extruder_0.def.json
index 753778f399..dc9b42d66d 100644
--- a/resources/extruders/bq_hephestos_extruder_0.def.json
+++ b/resources/extruders/bq_hephestos_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "bq_hephestos_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/bq_hephestos_xl_extruder_0.def.json b/resources/extruders/bq_hephestos_xl_extruder_0.def.json
index 91cac04dc9..a52032f129 100644
--- a/resources/extruders/bq_hephestos_xl_extruder_0.def.json
+++ b/resources/extruders/bq_hephestos_xl_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "bq_hephestos_xl_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/bq_witbox_2_extruder_0.def.json b/resources/extruders/bq_witbox_2_extruder_0.def.json
index 04107f4471..62fe62ad0b 100644
--- a/resources/extruders/bq_witbox_2_extruder_0.def.json
+++ b/resources/extruders/bq_witbox_2_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "bq_witbox_2_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/bq_witbox_extruder_0.def.json b/resources/extruders/bq_witbox_extruder_0.def.json
index d3a5c677af..37b1492676 100644
--- a/resources/extruders/bq_witbox_extruder_0.def.json
+++ b/resources/extruders/bq_witbox_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "bq_witbox_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/builder_premium_large_front.def.json b/resources/extruders/builder_premium_large_front.def.json
index 4834bc8fd9..dc1c557304 100644
--- a/resources/extruders/builder_premium_large_front.def.json
+++ b/resources/extruders/builder_premium_large_front.def.json
@@ -1,5 +1,4 @@
{
- "id": "builder_premium_large_front",
"version": 2,
"name": "Front Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/builder_premium_large_rear.def.json b/resources/extruders/builder_premium_large_rear.def.json
index f257749ea4..5dbe6d30c9 100644
--- a/resources/extruders/builder_premium_large_rear.def.json
+++ b/resources/extruders/builder_premium_large_rear.def.json
@@ -1,5 +1,4 @@
{
- "id": "builder_premium_large_rear",
"version": 2,
"name": "Rear Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/builder_premium_medium_front.def.json b/resources/extruders/builder_premium_medium_front.def.json
index 05dcb3d49f..2d38e48aab 100644
--- a/resources/extruders/builder_premium_medium_front.def.json
+++ b/resources/extruders/builder_premium_medium_front.def.json
@@ -1,5 +1,4 @@
{
- "id": "builder_premium_medium_front",
"version": 2,
"name": "Front Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/builder_premium_medium_rear.def.json b/resources/extruders/builder_premium_medium_rear.def.json
index 3461e07f09..0a789c38f1 100644
--- a/resources/extruders/builder_premium_medium_rear.def.json
+++ b/resources/extruders/builder_premium_medium_rear.def.json
@@ -1,5 +1,4 @@
{
- "id": "builder_premium_medium_rear",
"version": 2,
"name": "Rear Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/builder_premium_small_front.def.json b/resources/extruders/builder_premium_small_front.def.json
index 7a1c352c73..b36c535aeb 100644
--- a/resources/extruders/builder_premium_small_front.def.json
+++ b/resources/extruders/builder_premium_small_front.def.json
@@ -1,5 +1,4 @@
{
- "id": "builder_premium_small_front",
"version": 2,
"name": "Front Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/builder_premium_small_rear.def.json b/resources/extruders/builder_premium_small_rear.def.json
index 7085236a5c..8e00d0cc39 100644
--- a/resources/extruders/builder_premium_small_rear.def.json
+++ b/resources/extruders/builder_premium_small_rear.def.json
@@ -1,5 +1,4 @@
{
- "id": "builder_premium_small_rear",
"version": 2,
"name": "Rear Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/cartesio_extruder_0.def.json b/resources/extruders/cartesio_extruder_0.def.json
index 6d2b5f634e..ad27d4854c 100644
--- a/resources/extruders/cartesio_extruder_0.def.json
+++ b/resources/extruders/cartesio_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "cartesio_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/cartesio_extruder_1.def.json b/resources/extruders/cartesio_extruder_1.def.json
index 3d49a220c0..1699a9c6a8 100644
--- a/resources/extruders/cartesio_extruder_1.def.json
+++ b/resources/extruders/cartesio_extruder_1.def.json
@@ -1,5 +1,4 @@
{
- "id": "cartesio_extruder_1",
"version": 2,
"name": "Extruder 2",
"inherits": "fdmextruder",
diff --git a/resources/extruders/cartesio_extruder_2.def.json b/resources/extruders/cartesio_extruder_2.def.json
index 1f8f8b9ca9..2521ada681 100644
--- a/resources/extruders/cartesio_extruder_2.def.json
+++ b/resources/extruders/cartesio_extruder_2.def.json
@@ -1,5 +1,4 @@
{
- "id": "cartesio_extruder_2",
"version": 2,
"name": "Extruder 3",
"inherits": "fdmextruder",
diff --git a/resources/extruders/cartesio_extruder_3.def.json b/resources/extruders/cartesio_extruder_3.def.json
index 0b1cfe493e..c844e7ce54 100644
--- a/resources/extruders/cartesio_extruder_3.def.json
+++ b/resources/extruders/cartesio_extruder_3.def.json
@@ -1,5 +1,4 @@
{
- "id": "cartesio_extruder_3",
"version": 2,
"name": "Extruder 4",
"inherits": "fdmextruder",
diff --git a/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json b/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json
index 26d847483d..dfa06c776a 100644
--- a/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json
+++ b/resources/extruders/cocoon_create_modelmaker_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "cocoon_create_modelmaker_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/cr-x_extruder_0.def.json b/resources/extruders/cr-x_extruder_0.def.json
index 8135815afb..d9b7b03021 100644
--- a/resources/extruders/cr-x_extruder_0.def.json
+++ b/resources/extruders/cr-x_extruder_0.def.json
@@ -1,10 +1,9 @@
{
- "id": "cr-x_extruder_0",
"version": 2,
"name": "Left Extruder",
"inherits": "fdmextruder",
"metadata": {
- "machine": "Creality CR-X",
+ "machine": "creality_cr-x",
"position": "0"
},
diff --git a/resources/extruders/cr-x_extruder_1.def.json b/resources/extruders/cr-x_extruder_1.def.json
index 9313f2ea78..8e763df64f 100644
--- a/resources/extruders/cr-x_extruder_1.def.json
+++ b/resources/extruders/cr-x_extruder_1.def.json
@@ -1,10 +1,9 @@
{
- "id": "cr-x_extruder_1",
"version": 2,
"name": "Right Extruder",
"inherits": "fdmextruder",
"metadata": {
- "machine": "Creality CR-X",
+ "machine": "creality_cr-x",
"position": "1"
},
diff --git a/resources/extruders/creality_cr10s5_extruder_0.def.json b/resources/extruders/creality_base_extruder_0.def.json
similarity index 80%
rename from resources/extruders/creality_cr10s5_extruder_0.def.json
rename to resources/extruders/creality_base_extruder_0.def.json
index 98b701ae2e..a173d1c2fa 100644
--- a/resources/extruders/creality_cr10s5_extruder_0.def.json
+++ b/resources/extruders/creality_base_extruder_0.def.json
@@ -1,10 +1,9 @@
{
- "id": "creality_cr10s5_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
- "machine": "creality_cr10s5",
+ "machine": "creality_base",
"position": "0"
},
@@ -12,5 +11,6 @@
"extruder_nr": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 },
"material_diameter": { "default_value": 1.75 }
+
}
}
diff --git a/resources/extruders/creatable_d3_extruder_0.def.json b/resources/extruders/creatable_d3_extruder_0.def.json
index 7d45bb8e8a..95883d0f69 100644
--- a/resources/extruders/creatable_d3_extruder_0.def.json
+++ b/resources/extruders/creatable_d3_extruder_0.def.json
@@ -1,10 +1,9 @@
{
- "id": "creatable_d3_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
- "machine": "Creatable_D3",
+ "machine": "creatable_d3",
"position": "0"
},
diff --git a/resources/extruders/cubicon_3dp_110f_extruder_0.def.json b/resources/extruders/cubicon_3dp_110f_extruder_0.def.json
index 9c854fd2a1..048c12b992 100644
--- a/resources/extruders/cubicon_3dp_110f_extruder_0.def.json
+++ b/resources/extruders/cubicon_3dp_110f_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "cubicon_3dp_110f_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/cubicon_3dp_210f_extruder_0.def.json b/resources/extruders/cubicon_3dp_210f_extruder_0.def.json
index 8a8573760a..07fe7f3769 100644
--- a/resources/extruders/cubicon_3dp_210f_extruder_0.def.json
+++ b/resources/extruders/cubicon_3dp_210f_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "cubicon_3dp_210f_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/cubicon_3dp_310f_extruder_0.def.json b/resources/extruders/cubicon_3dp_310f_extruder_0.def.json
index 4edbbd5a6c..8dc336877f 100644
--- a/resources/extruders/cubicon_3dp_310f_extruder_0.def.json
+++ b/resources/extruders/cubicon_3dp_310f_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "cubicon_3dp_310f_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/cubicon_dual_pro_a30_extruder_0.def.json b/resources/extruders/cubicon_dual_pro_a30_extruder_0.def.json
new file mode 100644
index 0000000000..6c8993e799
--- /dev/null
+++ b/resources/extruders/cubicon_dual_pro_a30_extruder_0.def.json
@@ -0,0 +1,26 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "cubicon_dual_pro_a30",
+ "position": "0"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "machine_nozzle_offset_x": {
+ "default_value": -27.3
+ },
+ "machine_nozzle_offset_y": {
+ "default_value": -19.9
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ }
+ }
+}
diff --git a/resources/extruders/cubicon_dual_pro_a30_extruder_1.def.json b/resources/extruders/cubicon_dual_pro_a30_extruder_1.def.json
new file mode 100644
index 0000000000..ccdfdee1f7
--- /dev/null
+++ b/resources/extruders/cubicon_dual_pro_a30_extruder_1.def.json
@@ -0,0 +1,26 @@
+{
+ "version": 2,
+ "name": "Extruder 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "cubicon_dual_pro_a30",
+ "position": "1"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "machine_nozzle_offset_x": {
+ "default_value": -27.3
+ },
+ "machine_nozzle_offset_y": {
+ "default_value": -19.9
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ }
+ }
+}
diff --git a/resources/extruders/cubicon_style_plus_a15_extruder_0.def.json b/resources/extruders/cubicon_style_plus_a15_extruder_0.def.json
new file mode 100644
index 0000000000..12d022cd1e
--- /dev/null
+++ b/resources/extruders/cubicon_style_plus_a15_extruder_0.def.json
@@ -0,0 +1,26 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "cubicon_style_plus_a15",
+ "position": "0"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "machine_nozzle_offset_x": {
+ "default_value": -4.00
+ },
+ "machine_nozzle_offset_y": {
+ "default_value": -7.00
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ }
+ }
+}
diff --git a/resources/extruders/custom_extruder_1.def.json b/resources/extruders/custom_extruder_1.def.json
index 859c6a2f22..942f3e96b9 100644
--- a/resources/extruders/custom_extruder_1.def.json
+++ b/resources/extruders/custom_extruder_1.def.json
@@ -1,5 +1,4 @@
{
- "id": "custom_extruder_1",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/custom_extruder_2.def.json b/resources/extruders/custom_extruder_2.def.json
index eecda5dfcd..cd43efa994 100644
--- a/resources/extruders/custom_extruder_2.def.json
+++ b/resources/extruders/custom_extruder_2.def.json
@@ -1,5 +1,4 @@
{
- "id": "custom_extruder_2",
"version": 2,
"name": "Extruder 2",
"inherits": "fdmextruder",
diff --git a/resources/extruders/custom_extruder_3.def.json b/resources/extruders/custom_extruder_3.def.json
index 77909ec05d..be5bdd0e6a 100644
--- a/resources/extruders/custom_extruder_3.def.json
+++ b/resources/extruders/custom_extruder_3.def.json
@@ -1,5 +1,4 @@
{
- "id": "custom_extruder_3",
"version": 2,
"name": "Extruder 3",
"inherits": "fdmextruder",
diff --git a/resources/extruders/custom_extruder_4.def.json b/resources/extruders/custom_extruder_4.def.json
index be792c3a8e..ce1df0a5f5 100644
--- a/resources/extruders/custom_extruder_4.def.json
+++ b/resources/extruders/custom_extruder_4.def.json
@@ -1,5 +1,4 @@
{
- "id": "custom_extruder_4",
"version": 2,
"name": "Extruder 4",
"inherits": "fdmextruder",
diff --git a/resources/extruders/custom_extruder_5.def.json b/resources/extruders/custom_extruder_5.def.json
index ea64605041..beb4786505 100644
--- a/resources/extruders/custom_extruder_5.def.json
+++ b/resources/extruders/custom_extruder_5.def.json
@@ -1,5 +1,4 @@
{
- "id": "custom_extruder_5",
"version": 2,
"name": "Extruder 5",
"inherits": "fdmextruder",
diff --git a/resources/extruders/custom_extruder_6.def.json b/resources/extruders/custom_extruder_6.def.json
index fd27fadace..7f1e1a1343 100644
--- a/resources/extruders/custom_extruder_6.def.json
+++ b/resources/extruders/custom_extruder_6.def.json
@@ -1,5 +1,4 @@
{
- "id": "custom_extruder_6",
"version": 2,
"name": "Extruder 6",
"inherits": "fdmextruder",
diff --git a/resources/extruders/custom_extruder_7.def.json b/resources/extruders/custom_extruder_7.def.json
index cf003d1a6b..e4239f35f0 100644
--- a/resources/extruders/custom_extruder_7.def.json
+++ b/resources/extruders/custom_extruder_7.def.json
@@ -1,5 +1,4 @@
{
- "id": "custom_extruder_7",
"version": 2,
"name": "Extruder 7",
"inherits": "fdmextruder",
diff --git a/resources/extruders/custom_extruder_8.def.json b/resources/extruders/custom_extruder_8.def.json
index f418a55186..7671825792 100644
--- a/resources/extruders/custom_extruder_8.def.json
+++ b/resources/extruders/custom_extruder_8.def.json
@@ -1,5 +1,4 @@
{
- "id": "custom_extruder_8",
"version": 2,
"name": "Extruder 8",
"inherits": "fdmextruder",
diff --git a/resources/extruders/delta_go_extruder_0.def.json b/resources/extruders/delta_go_extruder_0.def.json
index 2262270dfb..330cde08bf 100644
--- a/resources/extruders/delta_go_extruder_0.def.json
+++ b/resources/extruders/delta_go_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "delta_go_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/deltabot_extruder_0.def.json b/resources/extruders/deltabot_extruder_0.def.json
index e13d6a6ee3..d4773ccf9f 100644
--- a/resources/extruders/deltabot_extruder_0.def.json
+++ b/resources/extruders/deltabot_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "deltabot_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/deltacomb_extruder_0.def.json b/resources/extruders/deltacomb_extruder_0.def.json
index 046becfd82..875655d5c7 100755
--- a/resources/extruders/deltacomb_extruder_0.def.json
+++ b/resources/extruders/deltacomb_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "deltacomb_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
@@ -9,8 +8,10 @@
},
"overrides": {
- "extruder_nr": { "default_value": 0 },
- "machine_nozzle_size": { "default_value": 0.4 },
- "material_diameter": { "default_value": 1.75 }
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_nozzle_offset_x": { "default_value": 0.0 },
+ "machine_nozzle_offset_y": { "default_value": 0.0 }
}
}
diff --git a/resources/extruders/deltacomb_extruder_1.def.json b/resources/extruders/deltacomb_extruder_1.def.json
new file mode 100755
index 0000000000..b1f30f4624
--- /dev/null
+++ b/resources/extruders/deltacomb_extruder_1.def.json
@@ -0,0 +1,17 @@
+{
+ "version": 2,
+ "name": "Extruder 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "deltacomb",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 1 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_nozzle_offset_x": { "default_value": 0.0 },
+ "machine_nozzle_offset_y": { "default_value": 0.0 }
+ }
+}
diff --git a/resources/extruders/easyarts_ares_extruder_0.def.json b/resources/extruders/easyarts_ares_extruder_0.def.json
index ec7ba81c57..4ddd476dbb 100644
--- a/resources/extruders/easyarts_ares_extruder_0.def.json
+++ b/resources/extruders/easyarts_ares_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "easyarts_ares_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/creality_ender3_extruder_0.def.json b/resources/extruders/erzay3d_extruder_0.def.json
similarity index 80%
rename from resources/extruders/creality_ender3_extruder_0.def.json
rename to resources/extruders/erzay3d_extruder_0.def.json
index 431366c777..a9cea62897 100644
--- a/resources/extruders/creality_ender3_extruder_0.def.json
+++ b/resources/extruders/erzay3d_extruder_0.def.json
@@ -1,10 +1,9 @@
{
- "id": "creality_ender3_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
- "machine": "creality_ender3",
+ "machine": "erzay3d",
"position": "0"
},
diff --git a/resources/extruders/fabtotum_extruder_0.def.json b/resources/extruders/fabtotum_extruder_0.def.json
index 5ed4da6256..a763fbcc15 100644
--- a/resources/extruders/fabtotum_extruder_0.def.json
+++ b/resources/extruders/fabtotum_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "fabtotum_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/felixpro2_dual_extruder_0.def.json b/resources/extruders/felixpro2_dual_extruder_0.def.json
new file mode 100644
index 0000000000..4278a532f9
--- /dev/null
+++ b/resources/extruders/felixpro2_dual_extruder_0.def.json
@@ -0,0 +1,27 @@
+{
+ "version": 2,
+ "name": "Left Extruder",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "felixpro2dual",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_offset_x": { "default_value": 0 },
+ "machine_nozzle_offset_y": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.35 },
+ "material_diameter": { "default_value": 1.75 },
+
+ "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" }
+ }
+}
diff --git a/resources/extruders/felixpro2_dual_extruder_1.def.json b/resources/extruders/felixpro2_dual_extruder_1.def.json
new file mode 100644
index 0000000000..195aad474d
--- /dev/null
+++ b/resources/extruders/felixpro2_dual_extruder_1.def.json
@@ -0,0 +1,27 @@
+{
+ "version": 2,
+ "name": "Right Extruder",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "felixpro2dual",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1,
+ "maximum_value": "2"
+ },
+ "machine_nozzle_offset_x": { "default_value": 0 },
+ "machine_nozzle_offset_y": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.35 },
+ "material_diameter": { "default_value": 1.75 },
+
+ "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" }
+ }
+}
diff --git a/resources/extruders/felixtec4_dual_extruder_0.def.json b/resources/extruders/felixtec4_dual_extruder_0.def.json
index 2a2d0468e1..1821b0e601 100644
--- a/resources/extruders/felixtec4_dual_extruder_0.def.json
+++ b/resources/extruders/felixtec4_dual_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "felixtec4_dual_extruder_0",
"version": 2,
"name": "Left Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/felixtec4_dual_extruder_1.def.json b/resources/extruders/felixtec4_dual_extruder_1.def.json
index 5d7e9c74a3..37a99c5fb4 100644
--- a/resources/extruders/felixtec4_dual_extruder_1.def.json
+++ b/resources/extruders/felixtec4_dual_extruder_1.def.json
@@ -1,5 +1,4 @@
{
- "id": "felixtec4_dual_extruder_1",
"version": 2,
"name": "Right Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/flsun_qq_extruder.def.json b/resources/extruders/flsun_qq_extruder.def.json
new file mode 100644
index 0000000000..c7ca0ed6eb
--- /dev/null
+++ b/resources/extruders/flsun_qq_extruder.def.json
@@ -0,0 +1,14 @@
+{
+ "version": 2,
+ "name": "Extruder",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "flsun_qq",
+ "position": "0"
+ },
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/flsun_qq_s_extruder_0.def.json b/resources/extruders/flsun_qq_s_extruder_0.def.json
new file mode 100644
index 0000000000..e61056fcd3
--- /dev/null
+++ b/resources/extruders/flsun_qq_s_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "flsun_qq_s",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/folgertech_FT-5_extruder_0.def.json b/resources/extruders/folgertech_FT-5_extruder_0.def.json
index 8ba9d130c6..861b0e7a7e 100644
--- a/resources/extruders/folgertech_FT-5_extruder_0.def.json
+++ b/resources/extruders/folgertech_FT-5_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "folgertech_FT-5_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/geeetech_a30_extruder_0.def.json b/resources/extruders/geeetech_a30_extruder_0.def.json
new file mode 100644
index 0000000000..90cb496877
--- /dev/null
+++ b/resources/extruders/geeetech_a30_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "geeetech_a30",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/gmax15plus_dual_extruder_0.def.json b/resources/extruders/gmax15plus_dual_extruder_0.def.json
index d3146a0576..45f35dee1f 100644
--- a/resources/extruders/gmax15plus_dual_extruder_0.def.json
+++ b/resources/extruders/gmax15plus_dual_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "gmax15plus_dual_extruder_0",
"version": 2,
"name": "Left Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/gmax15plus_dual_extruder_1.def.json b/resources/extruders/gmax15plus_dual_extruder_1.def.json
index 7b7354d794..6d0d5db06f 100644
--- a/resources/extruders/gmax15plus_dual_extruder_1.def.json
+++ b/resources/extruders/gmax15plus_dual_extruder_1.def.json
@@ -1,5 +1,4 @@
{
- "id": "gmax15plus_dual_extruder_1",
"version": 2,
"name": "Right Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/gmax15plus_extruder_0.def.json b/resources/extruders/gmax15plus_extruder_0.def.json
index 70389745b3..5b0889d46d 100644
--- a/resources/extruders/gmax15plus_extruder_0.def.json
+++ b/resources/extruders/gmax15plus_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "gmax15plus_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/grr_neo_extruder_0.def.json b/resources/extruders/grr_neo_extruder_0.def.json
index 6d76c90796..a9f1fa4faa 100644
--- a/resources/extruders/grr_neo_extruder_0.def.json
+++ b/resources/extruders/grr_neo_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "grr_neo_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/hBp_extruder_left.def.json b/resources/extruders/hBp_extruder_left.def.json
index 7e71ca27a8..ce23f27c29 100644
--- a/resources/extruders/hBp_extruder_left.def.json
+++ b/resources/extruders/hBp_extruder_left.def.json
@@ -1,5 +1,4 @@
{
- "id": "hBp_extruder_left",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/hBp_extruder_right.def.json b/resources/extruders/hBp_extruder_right.def.json
index acd2312268..170556a1fd 100644
--- a/resources/extruders/hBp_extruder_right.def.json
+++ b/resources/extruders/hBp_extruder_right.def.json
@@ -1,5 +1,4 @@
{
- "id": "hBp_extruder_right",
"version": 2,
"name": "Extruder 2",
"inherits": "fdmextruder",
diff --git a/resources/extruders/hellbot_adonis_extruder.def.json b/resources/extruders/hellbot_adonis_extruder.def.json
new file mode 100644
index 0000000000..4201f6b393
--- /dev/null
+++ b/resources/extruders/hellbot_adonis_extruder.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hellbot_adonis",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/hellbot_magna_dual_extruder_1.def.json b/resources/extruders/hellbot_magna_dual_extruder_1.def.json
new file mode 100644
index 0000000000..a31a3fdd70
--- /dev/null
+++ b/resources/extruders/hellbot_magna_dual_extruder_1.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hellbot_magna_dual",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/hellbot_magna_dual_extruder_2.def.json b/resources/extruders/hellbot_magna_dual_extruder_2.def.json
new file mode 100644
index 0000000000..651c39d53b
--- /dev/null
+++ b/resources/extruders/hellbot_magna_dual_extruder_2.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hellbot_magna_dual",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 1 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/hellbot_magna_i_extruder.def.json b/resources/extruders/hellbot_magna_i_extruder.def.json
new file mode 100644
index 0000000000..70117c2aed
--- /dev/null
+++ b/resources/extruders/hellbot_magna_i_extruder.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hellbot_magna_I",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/hms434_tool_1.def.json b/resources/extruders/hms434_tool_1.def.json
new file mode 100644
index 0000000000..3a1619d98b
--- /dev/null
+++ b/resources/extruders/hms434_tool_1.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Tool 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hms434",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0,
+ "maximum_value": "8"
+ },
+ "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_code": {
+ "default_value": "\n;changing to tool1\nM109 T0 S{material_print_temperature}\nG1 X-18 Y-50 F9000\nG1 X150 Y10 F9000\n\n"
+ },
+ "machine_extruder_end_code": {
+ "default_value": "\nG1 X150 Y10 F9000\nG1 X-20 Y-50 F9000\nG1 Y-100 F3000\n; ending tool1\n\n"
+ }
+ }
+}
diff --git a/resources/extruders/hms434_tool_2.def.json b/resources/extruders/hms434_tool_2.def.json
new file mode 100644
index 0000000000..3a174f82b9
--- /dev/null
+++ b/resources/extruders/hms434_tool_2.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Tool 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hms434",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1,
+ "maximum_value": "8"
+ },
+ "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_code": {
+ "default_value": "\n;changing to tool2\nM109 T1 S{material_print_temperature}\nG1 X-18 Y-50 F9000\nG1 X150 Y10 F9000\n\n"
+ },
+ "machine_extruder_end_code": {
+ "default_value": "\nG1 X150 Y10 F9000\nG1 X-20 Y-50 F9000\nG1 Y-100 F3000\n; ending tool2\n\n"
+ }
+ }
+}
diff --git a/resources/extruders/hms434_tool_3.def.json b/resources/extruders/hms434_tool_3.def.json
new file mode 100644
index 0000000000..e1e237d332
--- /dev/null
+++ b/resources/extruders/hms434_tool_3.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Tool 3",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hms434",
+ "position": "2"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 2,
+ "maximum_value": "8"
+ },
+ "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_code": {
+ "default_value": "\n;changing to tool3"
+ },
+ "machine_extruder_end_code": {
+ "default_value": "\n;ending tool3"
+ }
+ }
+}
diff --git a/resources/extruders/hms434_tool_4.def.json b/resources/extruders/hms434_tool_4.def.json
new file mode 100644
index 0000000000..1a68d5aff5
--- /dev/null
+++ b/resources/extruders/hms434_tool_4.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Tool 4",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hms434",
+ "position": "3"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 3,
+ "maximum_value": "8"
+ },
+ "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_code": {
+ "default_value": "\n;changing to tool4"
+ },
+ "machine_extruder_end_code": {
+ "default_value": "\n;ending tool4"
+ }
+ }
+}
diff --git a/resources/extruders/hms434_tool_5.def.json b/resources/extruders/hms434_tool_5.def.json
new file mode 100644
index 0000000000..b56e8be84e
--- /dev/null
+++ b/resources/extruders/hms434_tool_5.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Tool 5",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hms434",
+ "position": "4"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 4,
+ "maximum_value": "8"
+ },
+ "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_code": {
+ "default_value": "\n;changing to tool5"
+ },
+ "machine_extruder_end_code": {
+ "default_value": "\n;ending tool5"
+ }
+ }
+}
diff --git a/resources/extruders/hms434_tool_6.def.json b/resources/extruders/hms434_tool_6.def.json
new file mode 100644
index 0000000000..b8c8cdf062
--- /dev/null
+++ b/resources/extruders/hms434_tool_6.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Tool 6",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hms434",
+ "position": "5"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 5,
+ "maximum_value": "8"
+ },
+ "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_code": {
+ "default_value": "\n;changing to tool6"
+ },
+ "machine_extruder_end_code": {
+ "default_value": "\n;ending tool6"
+ }
+ }
+}
diff --git a/resources/extruders/hms434_tool_7.def.json b/resources/extruders/hms434_tool_7.def.json
new file mode 100644
index 0000000000..3fc04078fa
--- /dev/null
+++ b/resources/extruders/hms434_tool_7.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Tool 7",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hms434",
+ "position": "6"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 6,
+ "maximum_value": "8"
+ },
+ "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_code": {
+ "default_value": "\n;changing to tool7"
+ },
+ "machine_extruder_end_code": {
+ "default_value": "\n;ending tool7"
+ }
+ }
+}
diff --git a/resources/extruders/hms434_tool_8.def.json b/resources/extruders/hms434_tool_8.def.json
new file mode 100644
index 0000000000..faa6f36871
--- /dev/null
+++ b/resources/extruders/hms434_tool_8.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Tool 8",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "hms434",
+ "position": "7"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 7,
+ "maximum_value": "8"
+ },
+ "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_code": {
+ "default_value": "\n;changing to tool8"
+ },
+ "machine_extruder_end_code": {
+ "default_value": "\n;ending tool8"
+ }
+ }
+}
diff --git a/resources/extruders/imade3d_jellybox_2_extruder_0.def.json b/resources/extruders/imade3d_jellybox_2_extruder_0.def.json
new file mode 100644
index 0000000000..ca25b62286
--- /dev/null
+++ b/resources/extruders/imade3d_jellybox_2_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "imade3d_jellybox_2",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/imade3d_jellybox_extruder_0.def.json b/resources/extruders/imade3d_jellybox_extruder_0.def.json
index feaa717ee6..69c6d87d79 100644
--- a/resources/extruders/imade3d_jellybox_extruder_0.def.json
+++ b/resources/extruders/imade3d_jellybox_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "imade3d_jellybox_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/innovo_inventor_extruder_0.def.json b/resources/extruders/innovo_inventor_extruder_0.def.json
index ed599463f2..8758f3d516 100644
--- a/resources/extruders/innovo_inventor_extruder_0.def.json
+++ b/resources/extruders/innovo_inventor_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "innovo_inventor_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/jgaurora_a1_extruder_0.def.json b/resources/extruders/jgaurora_a1_extruder_0.def.json
index 71742b734a..f67d8d553e 100644
--- a/resources/extruders/jgaurora_a1_extruder_0.def.json
+++ b/resources/extruders/jgaurora_a1_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "jgaurora_a1_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/jgaurora_a3s_extruder_0.def.json b/resources/extruders/jgaurora_a3s_extruder_0.def.json
new file mode 100644
index 0000000000..9a42d0da04
--- /dev/null
+++ b/resources/extruders/jgaurora_a3s_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "jgaurora_a3s",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/jgaurora_a5_extruder_0.def.json b/resources/extruders/jgaurora_a5_extruder_0.def.json
index fbc6ba77e6..5308c57934 100644
--- a/resources/extruders/jgaurora_a5_extruder_0.def.json
+++ b/resources/extruders/jgaurora_a5_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "jgaurora_a5_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/jgaurora_jgmaker_magic_extruder_0.def.json b/resources/extruders/jgaurora_jgmaker_magic_extruder_0.def.json
new file mode 100644
index 0000000000..58beaa4cc8
--- /dev/null
+++ b/resources/extruders/jgaurora_jgmaker_magic_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "jgaurora_jgmaker_magic",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/jgaurora_z_603s_extruder_0.def.json b/resources/extruders/jgaurora_z_603s_extruder_0.def.json
index 987425b28a..647016d5ff 100644
--- a/resources/extruders/jgaurora_z_603s_extruder_0.def.json
+++ b/resources/extruders/jgaurora_z_603s_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "jgaurora_z_603s_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/julia_extruder_0.def.json b/resources/extruders/julia_extruder_0.def.json
index 53a569ccd8..ef0ca83ac4 100644
--- a/resources/extruders/julia_extruder_0.def.json
+++ b/resources/extruders/julia_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "julia_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/kemiq_q2_beta_extruder_0.def.json b/resources/extruders/kemiq_q2_beta_extruder_0.def.json
index 0c7d1b7b50..79d55223f3 100644
--- a/resources/extruders/kemiq_q2_beta_extruder_0.def.json
+++ b/resources/extruders/kemiq_q2_beta_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "kemiq_q2_beta_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/kemiq_q2_gama_extruder_0.def.json b/resources/extruders/kemiq_q2_gama_extruder_0.def.json
index bb165ca35e..ad6e6372ee 100644
--- a/resources/extruders/kemiq_q2_gama_extruder_0.def.json
+++ b/resources/extruders/kemiq_q2_gama_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "kemiq_q2_gama_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/key3d_tyro_extruder_0.def.json b/resources/extruders/key3d_tyro_extruder_0.def.json
new file mode 100644
index 0000000000..f08ae351ab
--- /dev/null
+++ b/resources/extruders/key3d_tyro_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "0.4mm Nozzle",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "key3d_tyro",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/kossel_mini_extruder_0.def.json b/resources/extruders/kossel_mini_extruder_0.def.json
index f57154e1a3..7da2cff3b1 100644
--- a/resources/extruders/kossel_mini_extruder_0.def.json
+++ b/resources/extruders/kossel_mini_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "kossel_mini_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/kossel_pro_extruder_0.def.json b/resources/extruders/kossel_pro_extruder_0.def.json
index 921e1d8bb4..48c1180f84 100644
--- a/resources/extruders/kossel_pro_extruder_0.def.json
+++ b/resources/extruders/kossel_pro_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "kossel_pro_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/kupido_extruder_0.def.json b/resources/extruders/kupido_extruder_0.def.json
index ef988d4fde..784e453bd1 100644
--- a/resources/extruders/kupido_extruder_0.def.json
+++ b/resources/extruders/kupido_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "kupido_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/leapfrog_bolt_pro_extruder_left.def.json b/resources/extruders/leapfrog_bolt_pro_extruder_left.def.json
new file mode 100644
index 0000000000..4ec859a60c
--- /dev/null
+++ b/resources/extruders/leapfrog_bolt_pro_extruder_left.def.json
@@ -0,0 +1,21 @@
+{
+ "version": 2,
+ "name": "Left extruder",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "leapfrog_bolt_pro",
+ "position": "1"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_nozzle_head_distance": { "default_value": 22 },
+ "machine_nozzle_offset_x": { "default_value": 0 },
+ "machine_nozzle_offset_y": { "default_value": 0.0 },
+ "machine_extruder_start_code": { "default_value": "G1 Y-32 F12000\nG1 X6 F1000\nG1 X-32 F4000\nG1 X6" }
+ }
+}
diff --git a/resources/extruders/leapfrog_bolt_pro_extruder_right.def.json b/resources/extruders/leapfrog_bolt_pro_extruder_right.def.json
new file mode 100644
index 0000000000..fe27106afd
--- /dev/null
+++ b/resources/extruders/leapfrog_bolt_pro_extruder_right.def.json
@@ -0,0 +1,21 @@
+{
+ "version": 2,
+ "name": "Right extruder",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "leapfrog_bolt_pro",
+ "position": "0"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_nozzle_head_distance": { "default_value": 22 },
+ "machine_nozzle_offset_x": { "default_value": 0 },
+ "machine_nozzle_offset_y": { "default_value": 0.0 },
+ "machine_extruder_start_code": { "default_value": "G1 Y-32 F12000\nG1 X296 F1000\nG1 X334 F4000\nG1 X296"}
+ }
+}
diff --git a/resources/extruders/makeR_pegasus_extruder_0.def.json b/resources/extruders/makeR_pegasus_extruder_0.def.json
index e37891abde..c17c51d599 100644
--- a/resources/extruders/makeR_pegasus_extruder_0.def.json
+++ b/resources/extruders/makeR_pegasus_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "makeR_pegasus_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/makeR_prusa_tairona_i3_extruder_0.def.json b/resources/extruders/makeR_prusa_tairona_i3_extruder_0.def.json
index a80d4079cb..278981f355 100644
--- a/resources/extruders/makeR_prusa_tairona_i3_extruder_0.def.json
+++ b/resources/extruders/makeR_prusa_tairona_i3_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "makeR_prusa_tairona_i3_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/makeblock_mcreate_extruder_0.def.json b/resources/extruders/makeblock_mcreate_extruder_0.def.json
new file mode 100644
index 0000000000..060ea634f8
--- /dev/null
+++ b/resources/extruders/makeblock_mcreate_extruder_0.def.json
@@ -0,0 +1,20 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "makeblock_mcreate",
+ "position": "0"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ }
+ }
+}
diff --git a/resources/extruders/makeit_dual_1st.def.json b/resources/extruders/makeit_dual_1st.def.json
index 0f5a716e16..16374b40d1 100644
--- a/resources/extruders/makeit_dual_1st.def.json
+++ b/resources/extruders/makeit_dual_1st.def.json
@@ -1,5 +1,4 @@
{
- "id": "makeit_dual_1st",
"version": 2,
"name": "1st Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/makeit_dual_2nd.def.json b/resources/extruders/makeit_dual_2nd.def.json
index f93d670c85..562cfcbc40 100644
--- a/resources/extruders/makeit_dual_2nd.def.json
+++ b/resources/extruders/makeit_dual_2nd.def.json
@@ -1,5 +1,4 @@
{
- "id": "makeit_dual_2nd",
"version": 2,
"name": "2nd Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/makeit_l_dual_1st.def.json b/resources/extruders/makeit_l_dual_1st.def.json
index 6a9e8e3fc1..8fbc2944b1 100644
--- a/resources/extruders/makeit_l_dual_1st.def.json
+++ b/resources/extruders/makeit_l_dual_1st.def.json
@@ -1,5 +1,4 @@
{
- "id": "makeit_l_dual_1st",
"version": 2,
"name": "1st Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/makeit_l_dual_2nd.def.json b/resources/extruders/makeit_l_dual_2nd.def.json
index 72b86b22e4..e163e9565a 100644
--- a/resources/extruders/makeit_l_dual_2nd.def.json
+++ b/resources/extruders/makeit_l_dual_2nd.def.json
@@ -1,5 +1,4 @@
{
- "id": "makeit_l_dual_2nd",
"version": 2,
"name": "2nd Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/maker_starter_extruder_0.def.json b/resources/extruders/maker_starter_extruder_0.def.json
index ee94250248..76e2f74a4c 100644
--- a/resources/extruders/maker_starter_extruder_0.def.json
+++ b/resources/extruders/maker_starter_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "maker_starter_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/makerbotreplicator_extruder_0.def.json b/resources/extruders/makerbotreplicator_extruder_0.def.json
index 36a975ace1..595134d788 100644
--- a/resources/extruders/makerbotreplicator_extruder_0.def.json
+++ b/resources/extruders/makerbotreplicator_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "makerbotreplicator_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/malyan_m180_extruder_0.def.json b/resources/extruders/malyan_m180_extruder_0.def.json
index bdf5350b26..04bc70ce55 100644
--- a/resources/extruders/malyan_m180_extruder_0.def.json
+++ b/resources/extruders/malyan_m180_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "malyan_m180_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/malyan_m200_extruder_0.def.json b/resources/extruders/malyan_m200_extruder_0.def.json
index 4a135aa72d..88d99fb426 100644
--- a/resources/extruders/malyan_m200_extruder_0.def.json
+++ b/resources/extruders/malyan_m200_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "malyan_m200_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/mankati_fullscale_xt_plus_extruder_0.def.json b/resources/extruders/mankati_fullscale_xt_plus_extruder_0.def.json
index 032a577022..4cb893336e 100644
--- a/resources/extruders/mankati_fullscale_xt_plus_extruder_0.def.json
+++ b/resources/extruders/mankati_fullscale_xt_plus_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "mankati_fullscale_xt_plus_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/mendel90_extruder_0.def.json b/resources/extruders/mendel90_extruder_0.def.json
index 3ee2fd2b10..2ea4d9a7de 100644
--- a/resources/extruders/mendel90_extruder_0.def.json
+++ b/resources/extruders/mendel90_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "mendel90_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/monoprice_select_mini_v1_extruder_0.def.json b/resources/extruders/monoprice_select_mini_v1_extruder_0.def.json
index e4a899d7af..023bd6b27c 100644
--- a/resources/extruders/monoprice_select_mini_v1_extruder_0.def.json
+++ b/resources/extruders/monoprice_select_mini_v1_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "monoprice_select_mini_v1_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/monoprice_select_mini_v2_extruder_0.def.json b/resources/extruders/monoprice_select_mini_v2_extruder_0.def.json
index b727cfce1f..79ba110701 100644
--- a/resources/extruders/monoprice_select_mini_v2_extruder_0.def.json
+++ b/resources/extruders/monoprice_select_mini_v2_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "monoprice_select_mini_v2_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/nwa3d_a31_extruder_0.def.json b/resources/extruders/nwa3d_a31_extruder_0.def.json
new file mode 100644
index 0000000000..de1938956a
--- /dev/null
+++ b/resources/extruders/nwa3d_a31_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Standard 0.4mm",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "nwa3d_a31",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/nwa3d_a5_extruder_0.def.json b/resources/extruders/nwa3d_a5_extruder_0.def.json
index 5c3cc6a127..9131480732 100644
--- a/resources/extruders/nwa3d_a5_extruder_0.def.json
+++ b/resources/extruders/nwa3d_a5_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "nwa3d_a5_extruder_0",
"version": 2,
"name": "Regular 0.4mm Nozzle",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ord_extruder_0.def.json b/resources/extruders/ord_extruder_0.def.json
index 317ad70a3c..61317c4a17 100644
--- a/resources/extruders/ord_extruder_0.def.json
+++ b/resources/extruders/ord_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "ord_extruder_0",
"version": 2,
"name": "0",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ord_extruder_1.def.json b/resources/extruders/ord_extruder_1.def.json
index 6e29ad2f2b..43bc11fa71 100644
--- a/resources/extruders/ord_extruder_1.def.json
+++ b/resources/extruders/ord_extruder_1.def.json
@@ -1,5 +1,4 @@
{
- "id": "ord_extruder_1",
"version": 2,
"name": "1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ord_extruder_2.def.json b/resources/extruders/ord_extruder_2.def.json
index 849930c988..84bcbd5332 100644
--- a/resources/extruders/ord_extruder_2.def.json
+++ b/resources/extruders/ord_extruder_2.def.json
@@ -1,5 +1,4 @@
{
- "id": "ord_extruder_2",
"version": 2,
"name": "2",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ord_extruder_3.def.json b/resources/extruders/ord_extruder_3.def.json
index eb3676c14f..db81f82b78 100644
--- a/resources/extruders/ord_extruder_3.def.json
+++ b/resources/extruders/ord_extruder_3.def.json
@@ -1,5 +1,4 @@
{
- "id": "ord_extruder_3",
"version": 2,
"name": "3",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ord_extruder_4.def.json b/resources/extruders/ord_extruder_4.def.json
index 291e9e5501..2ca7609e06 100644
--- a/resources/extruders/ord_extruder_4.def.json
+++ b/resources/extruders/ord_extruder_4.def.json
@@ -1,5 +1,4 @@
{
- "id": "ord_extruder_4",
"version": 2,
"name": "4",
"inherits": "fdmextruder",
diff --git a/resources/extruders/peopoly_moai_extruder_0.def.json b/resources/extruders/peopoly_moai_extruder_0.def.json
index bbffd4ac4d..1acf5b499f 100644
--- a/resources/extruders/peopoly_moai_extruder_0.def.json
+++ b/resources/extruders/peopoly_moai_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "peopoly_moai_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/printrbot_play_extruder_0.def.json b/resources/extruders/printrbot_play_extruder_0.def.json
index ef1284758b..682810c8d8 100644
--- a/resources/extruders/printrbot_play_extruder_0.def.json
+++ b/resources/extruders/printrbot_play_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "printrbot_play_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/printrbot_play_heated_extruder_0.def.json b/resources/extruders/printrbot_play_heated_extruder_0.def.json
index 0a3eeb3d06..72335e82d6 100644
--- a/resources/extruders/printrbot_play_heated_extruder_0.def.json
+++ b/resources/extruders/printrbot_play_heated_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "printrbot_play_heated_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/printrbot_simple_extended_extruder_0.def.json b/resources/extruders/printrbot_simple_extended_extruder_0.def.json
index 71c8863552..b50a142d2e 100644
--- a/resources/extruders/printrbot_simple_extended_extruder_0.def.json
+++ b/resources/extruders/printrbot_simple_extended_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "printrbot_simple_extended_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/printrbot_simple_extruder_0.def.json b/resources/extruders/printrbot_simple_extruder_0.def.json
index e97977e07e..4fa5d7fbf2 100644
--- a/resources/extruders/printrbot_simple_extruder_0.def.json
+++ b/resources/extruders/printrbot_simple_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "printrbot_simple_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/printrbot_simple_makers_kit_extruder_0.def.json b/resources/extruders/printrbot_simple_makers_kit_extruder_0.def.json
index f002bb9cf5..a58195fdfb 100644
--- a/resources/extruders/printrbot_simple_makers_kit_extruder_0.def.json
+++ b/resources/extruders/printrbot_simple_makers_kit_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "printrbot_simple_makers_kit_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/prusa_i3_extruder_0.def.json b/resources/extruders/prusa_i3_extruder_0.def.json
index 11c52e062b..dbb01032b8 100644
--- a/resources/extruders/prusa_i3_extruder_0.def.json
+++ b/resources/extruders/prusa_i3_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "prusa_i3_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/prusa_i3_mk2_extruder_0.def.json b/resources/extruders/prusa_i3_mk2_extruder_0.def.json
index a56aae4300..e802687062 100644
--- a/resources/extruders/prusa_i3_mk2_extruder_0.def.json
+++ b/resources/extruders/prusa_i3_mk2_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "prusa_i3_mk2_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/prusa_i3_mk3_extruder_0.def.json b/resources/extruders/prusa_i3_mk3_extruder_0.def.json
new file mode 100644
index 0000000000..29156f0d70
--- /dev/null
+++ b/resources/extruders/prusa_i3_mk3_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "prusa_i3_mk3",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
\ No newline at end of file
diff --git a/resources/extruders/prusa_i3_xl_extruder_0.def.json b/resources/extruders/prusa_i3_xl_extruder_0.def.json
index 5dc2ab3bc0..c4125b36ee 100644
--- a/resources/extruders/prusa_i3_xl_extruder_0.def.json
+++ b/resources/extruders/prusa_i3_xl_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "prusa_i3_xl_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/punchtec_connect_xl_extruder_0.def.json b/resources/extruders/punchtec_connect_xl_extruder_0.def.json
index 68c3d8c906..f286140167 100644
--- a/resources/extruders/punchtec_connect_xl_extruder_0.def.json
+++ b/resources/extruders/punchtec_connect_xl_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "punchtec_connect_xl_extruder_0",
"version": 2,
"name": "0",
"inherits": "fdmextruder",
diff --git a/resources/extruders/punchtec_connect_xl_extruder_1.def.json b/resources/extruders/punchtec_connect_xl_extruder_1.def.json
index a2e4b31714..47d28882cf 100644
--- a/resources/extruders/punchtec_connect_xl_extruder_1.def.json
+++ b/resources/extruders/punchtec_connect_xl_extruder_1.def.json
@@ -1,5 +1,4 @@
{
- "id": "punchtec_connect_xl_extruder_1",
"version": 2,
"name": "1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/raise3D_N2_dual_extruder_0.def.json b/resources/extruders/raise3D_N2_dual_extruder_0.def.json
index 48746969d3..9294a73933 100644
--- a/resources/extruders/raise3D_N2_dual_extruder_0.def.json
+++ b/resources/extruders/raise3D_N2_dual_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "raise3D_N2_dual_extruder_0",
"version": 2,
"name": "Left Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/raise3D_N2_dual_extruder_1.def.json b/resources/extruders/raise3D_N2_dual_extruder_1.def.json
index 8ea6f95b16..e09cb6b9fc 100644
--- a/resources/extruders/raise3D_N2_dual_extruder_1.def.json
+++ b/resources/extruders/raise3D_N2_dual_extruder_1.def.json
@@ -1,5 +1,4 @@
{
- "id": "raise3D_N2_dual_extruder_1",
"version": 2,
"name": "Right Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/raise3D_N2_plus_dual_extruder_0.def.json b/resources/extruders/raise3D_N2_plus_dual_extruder_0.def.json
index fc7531cf1b..d8821204f0 100644
--- a/resources/extruders/raise3D_N2_plus_dual_extruder_0.def.json
+++ b/resources/extruders/raise3D_N2_plus_dual_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "raise3D_N2_plus_dual_extruder_0",
"version": 2,
"name": "Left Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/raise3D_N2_plus_dual_extruder_1.def.json b/resources/extruders/raise3D_N2_plus_dual_extruder_1.def.json
index 83f949bb22..0a6ded63a3 100644
--- a/resources/extruders/raise3D_N2_plus_dual_extruder_1.def.json
+++ b/resources/extruders/raise3D_N2_plus_dual_extruder_1.def.json
@@ -1,5 +1,4 @@
{
- "id": "raise3D_N2_plus_dual_extruder_1",
"version": 2,
"name": "Right Extruder",
"inherits": "fdmextruder",
diff --git a/resources/extruders/raise3D_N2_single_extruder_0.def.json b/resources/extruders/raise3D_N2_single_extruder_0.def.json
index 08fedff99c..399d577110 100644
--- a/resources/extruders/raise3D_N2_single_extruder_0.def.json
+++ b/resources/extruders/raise3D_N2_single_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "raise3D_N2_single_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/renkforce_rf100_extruder_0.def.json b/resources/extruders/renkforce_rf100_extruder_0.def.json
index 6a7f883309..ff64e2f86a 100644
--- a/resources/extruders/renkforce_rf100_extruder_0.def.json
+++ b/resources/extruders/renkforce_rf100_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "renkforce_rf100_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/rigid3d_3rdgen_extruder_0.def.json b/resources/extruders/rigid3d_3rdgen_extruder_0.def.json
index e309086a72..edc87f695e 100644
--- a/resources/extruders/rigid3d_3rdgen_extruder_0.def.json
+++ b/resources/extruders/rigid3d_3rdgen_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "rigid3d_3rdgen_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/rigid3d_extruder_0.def.json b/resources/extruders/rigid3d_extruder_0.def.json
index e34987cd6e..eaac6b16a0 100644
--- a/resources/extruders/rigid3d_extruder_0.def.json
+++ b/resources/extruders/rigid3d_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "rigid3d_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/rigid3d_hobby_extruder_0.def.json b/resources/extruders/rigid3d_hobby_extruder_0.def.json
index 681aeecb43..68dd523af3 100644
--- a/resources/extruders/rigid3d_hobby_extruder_0.def.json
+++ b/resources/extruders/rigid3d_hobby_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "rigid3d_hobby_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/rigid3d_mucit_extruder_0.def.json b/resources/extruders/rigid3d_mucit_extruder_0.def.json
index af3f54e150..de72db7a33 100644
--- a/resources/extruders/rigid3d_mucit_extruder_0.def.json
+++ b/resources/extruders/rigid3d_mucit_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "rigid3d_mucit_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/rigid3d_zero2_extruder_0.def.json b/resources/extruders/rigid3d_zero2_extruder_0.def.json
index 30d1dbb3c4..051ce2384d 100644
--- a/resources/extruders/rigid3d_zero2_extruder_0.def.json
+++ b/resources/extruders/rigid3d_zero2_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "rigid3d_zero2_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/rigid3d_zero_extruder_0.def.json b/resources/extruders/rigid3d_zero_extruder_0.def.json
index 6c5ae10ddb..76a8fceaae 100644
--- a/resources/extruders/rigid3d_zero_extruder_0.def.json
+++ b/resources/extruders/rigid3d_zero_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "rigid3d_zero_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/rigidbot_big_extruder_0.def.json b/resources/extruders/rigidbot_big_extruder_0.def.json
index 2b07adaaaa..9ef72d5203 100644
--- a/resources/extruders/rigidbot_big_extruder_0.def.json
+++ b/resources/extruders/rigidbot_big_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "rigidbot_big_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/rigidbot_extruder_0.def.json b/resources/extruders/rigidbot_extruder_0.def.json
index 32ce3fc1c3..9155be0ff1 100644
--- a/resources/extruders/rigidbot_extruder_0.def.json
+++ b/resources/extruders/rigidbot_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "rigidbot_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/robo_3d_r1_extruder_0.def.json b/resources/extruders/robo_3d_r1_extruder_0.def.json
index 0872e91a11..60811842ac 100644
--- a/resources/extruders/robo_3d_r1_extruder_0.def.json
+++ b/resources/extruders/robo_3d_r1_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "robo_3d_r1_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/seemecnc_artemis_extruder_0.def.json b/resources/extruders/seemecnc_artemis_extruder_0.def.json
index a709a80cbf..a86e5eb2bd 100644
--- a/resources/extruders/seemecnc_artemis_extruder_0.def.json
+++ b/resources/extruders/seemecnc_artemis_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "seemecnc_artemis_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/seemecnc_v32_extruder_0.def.json b/resources/extruders/seemecnc_v32_extruder_0.def.json
index 5bd489e537..b223116be3 100644
--- a/resources/extruders/seemecnc_v32_extruder_0.def.json
+++ b/resources/extruders/seemecnc_v32_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "seemecnc_v32_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/skriware_2_extruder_0.def.json b/resources/extruders/skriware_2_extruder_0.def.json
new file mode 100644
index 0000000000..0569600094
--- /dev/null
+++ b/resources/extruders/skriware_2_extruder_0.def.json
@@ -0,0 +1,18 @@
+{
+ "version": 2,
+ "name": "Left Extruder",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "skriware_2",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/skriware_2_extruder_1.def.json b/resources/extruders/skriware_2_extruder_1.def.json
new file mode 100644
index 0000000000..d6fa76e1a0
--- /dev/null
+++ b/resources/extruders/skriware_2_extruder_1.def.json
@@ -0,0 +1,18 @@
+{
+ "version": 2,
+ "name": "Right Extruder",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "skriware_2",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/stereotech_start_extruder_0.def.json b/resources/extruders/stereotech_start_extruder_0.def.json
new file mode 100644
index 0000000000..b0a1e91d1c
--- /dev/null
+++ b/resources/extruders/stereotech_start_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "stereotech_start",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
\ No newline at end of file
diff --git a/resources/extruders/stereotech_ste320_1st.def.json b/resources/extruders/stereotech_ste320_1st.def.json
new file mode 100644
index 0000000000..8110775d33
--- /dev/null
+++ b/resources/extruders/stereotech_ste320_1st.def.json
@@ -0,0 +1,45 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "stereotech_ste320",
+ "position": "0"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_offset_x": {
+ "default_value": 0.0
+ },
+ "machine_nozzle_offset_y": {
+ "default_value": 0.0
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "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"
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/extruders/stereotech_ste320_2nd.def.json b/resources/extruders/stereotech_ste320_2nd.def.json
new file mode 100644
index 0000000000..12a1479164
--- /dev/null
+++ b/resources/extruders/stereotech_ste320_2nd.def.json
@@ -0,0 +1,45 @@
+{
+ "version": 2,
+ "name": "Extruder 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "stereotech_ste320",
+ "position": "1"
+ },
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_offset_x": {
+ "default_value": 18.0
+ },
+ "machine_nozzle_offset_y": {
+ "default_value": 0.0
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "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"
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/extruders/strateo3d_left_extruder.def.json b/resources/extruders/strateo3d_left_extruder.def.json
new file mode 100644
index 0000000000..096b265030
--- /dev/null
+++ b/resources/extruders/strateo3d_left_extruder.def.json
@@ -0,0 +1,16 @@
+{
+ "version": 2,
+ "name": "Left Extruder 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "strateo3d",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 1, "maximum_value": "1" },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_nozzle_offset_x": { "default_value": 0 },
+ "machine_nozzle_offset_y": { "default_value": 0 }
+ }
+}
\ No newline at end of file
diff --git a/resources/extruders/strateo3d_right_extruder.def.json b/resources/extruders/strateo3d_right_extruder.def.json
new file mode 100644
index 0000000000..24acdef8b5
--- /dev/null
+++ b/resources/extruders/strateo3d_right_extruder.def.json
@@ -0,0 +1,16 @@
+{
+ "version": 2,
+ "name": "Right Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "strateo3d",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0, "maximum_value": "1" },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_nozzle_offset_x": { "default_value": 0 },
+ "machine_nozzle_offset_y": { "default_value": 0 }
+ }
+}
\ No newline at end of file
diff --git a/resources/extruders/structur3d_discov3ry1_complete_um2plus_extruder_0.def.json b/resources/extruders/structur3d_discov3ry1_complete_um2plus_extruder_0.def.json
new file mode 100644
index 0000000000..c63f740f11
--- /dev/null
+++ b/resources/extruders/structur3d_discov3ry1_complete_um2plus_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Discov3ry Extruder",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "structur3d_discov3ry1_complete_um2plus",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.84 },
+ "material_diameter": { "default_value": 3.175 }
+ }
+}
diff --git a/resources/extruders/tam_extruder_0.def.json b/resources/extruders/tam_extruder_0.def.json
index fc53efad3f..f487a6ff90 100644
--- a/resources/extruders/tam_extruder_0.def.json
+++ b/resources/extruders/tam_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "tam_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/tevo_blackwidow_extruder_0.def.json b/resources/extruders/tevo_blackwidow_extruder_0.def.json
index 125cf19c98..3450b36ac6 100644
--- a/resources/extruders/tevo_blackwidow_extruder_0.def.json
+++ b/resources/extruders/tevo_blackwidow_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "tevo_blackwidow_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/tevo_tarantula_extruder_0.def.json b/resources/extruders/tevo_tarantula_extruder_0.def.json
index bc43986814..a2ac48c06d 100644
--- a/resources/extruders/tevo_tarantula_extruder_0.def.json
+++ b/resources/extruders/tevo_tarantula_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "tevo_tarantula_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/tevo_tornado_extruder_0.def.json b/resources/extruders/tevo_tornado_extruder_0.def.json
index b47a757113..6c0c9f39b1 100644
--- a/resources/extruders/tevo_tornado_extruder_0.def.json
+++ b/resources/extruders/tevo_tornado_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "tevo_tornado_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/tizyx_evy_dual_extruder_0.def.JSON b/resources/extruders/tizyx_evy_dual_extruder_0.def.JSON
new file mode 100644
index 0000000000..282d9d2651
--- /dev/null
+++ b/resources/extruders/tizyx_evy_dual_extruder_0.def.JSON
@@ -0,0 +1,17 @@
+{
+ "version": 2,
+ "name": "Classic Extruder",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "tizyx_evy_dual",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0,
+ "maximum_value": "1"
+ },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/tizyx_evy_dual_extruder_1.def.JSON b/resources/extruders/tizyx_evy_dual_extruder_1.def.JSON
new file mode 100644
index 0000000000..69e4a60952
--- /dev/null
+++ b/resources/extruders/tizyx_evy_dual_extruder_1.def.JSON
@@ -0,0 +1,17 @@
+{
+ "version": 2,
+ "name": "Direct Drive",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "tizyx_evy_dual",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1,
+ "maximum_value": "1"
+ },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/tizyx_evy_extruder_0.def.JSON b/resources/extruders/tizyx_evy_extruder_0.def.JSON
index bd3c4c9792..4f93648491 100644
--- a/resources/extruders/tizyx_evy_extruder_0.def.JSON
+++ b/resources/extruders/tizyx_evy_extruder_0.def.JSON
@@ -1,5 +1,4 @@
{
- "id": "tizyx_evy_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/tizyx_k25_extruder_0.def.json b/resources/extruders/tizyx_k25_extruder_0.def.json
index 409198d77c..626fedf434 100644
--- a/resources/extruders/tizyx_k25_extruder_0.def.json
+++ b/resources/extruders/tizyx_k25_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "tizyx_k25_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ubuild-3d_mr_bot_280_extruder_0.def.json b/resources/extruders/ubuild-3d_mr_bot_280_extruder_0.def.json
index b04ca0dcbf..749a5ed77d 100644
--- a/resources/extruders/ubuild-3d_mr_bot_280_extruder_0.def.json
+++ b/resources/extruders/ubuild-3d_mr_bot_280_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "ubuild-3d_mr_bot_280_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker2_extended_extruder_0.def.json b/resources/extruders/ultimaker2_extended_extruder_0.def.json
index 6387ec72ed..cc7306a393 100644
--- a/resources/extruders/ultimaker2_extended_extruder_0.def.json
+++ b/resources/extruders/ultimaker2_extended_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker2_extended_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker2_extended_plus_extruder_0.def.json b/resources/extruders/ultimaker2_extended_plus_extruder_0.def.json
index 39fc665ff2..337c120097 100644
--- a/resources/extruders/ultimaker2_extended_plus_extruder_0.def.json
+++ b/resources/extruders/ultimaker2_extended_plus_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker2_extended_plus_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker2_extruder_0.def.json b/resources/extruders/ultimaker2_extruder_0.def.json
index 2daf57c73f..64ac8698f1 100644
--- a/resources/extruders/ultimaker2_extruder_0.def.json
+++ b/resources/extruders/ultimaker2_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker2_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker2_go_extruder_0.def.json b/resources/extruders/ultimaker2_go_extruder_0.def.json
index 4c258e237e..5ddcfbd551 100644
--- a/resources/extruders/ultimaker2_go_extruder_0.def.json
+++ b/resources/extruders/ultimaker2_go_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker2_go_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker2_plus_extruder_0.def.json b/resources/extruders/ultimaker2_plus_extruder_0.def.json
index 13ab0c59ea..abf36c0b08 100644
--- a/resources/extruders/ultimaker2_plus_extruder_0.def.json
+++ b/resources/extruders/ultimaker2_plus_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker2_plus_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker3_extended_extruder_left.def.json b/resources/extruders/ultimaker3_extended_extruder_left.def.json
index 2d81424bc6..fbc49a1f32 100644
--- a/resources/extruders/ultimaker3_extended_extruder_left.def.json
+++ b/resources/extruders/ultimaker3_extended_extruder_left.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker3_extended_extruder_left",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker3_extended_extruder_right.def.json b/resources/extruders/ultimaker3_extended_extruder_right.def.json
index 7cdd5876c1..fbe6bcc878 100644
--- a/resources/extruders/ultimaker3_extended_extruder_right.def.json
+++ b/resources/extruders/ultimaker3_extended_extruder_right.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker3_extended_extruder_right",
"version": 2,
"name": "Extruder 2",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker3_extruder_left.def.json b/resources/extruders/ultimaker3_extruder_left.def.json
index 9f5ed34692..b18e2decfa 100644
--- a/resources/extruders/ultimaker3_extruder_left.def.json
+++ b/resources/extruders/ultimaker3_extruder_left.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker3_extruder_left",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker3_extruder_right.def.json b/resources/extruders/ultimaker3_extruder_right.def.json
index 7298a552b7..4753fde489 100644
--- a/resources/extruders/ultimaker3_extruder_right.def.json
+++ b/resources/extruders/ultimaker3_extruder_right.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker3_extruder_right",
"version": 2,
"name": "Extruder 2",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker_original_dual_1st.def.json b/resources/extruders/ultimaker_original_dual_1st.def.json
index 3d837fc989..acc8168d94 100644
--- a/resources/extruders/ultimaker_original_dual_1st.def.json
+++ b/resources/extruders/ultimaker_original_dual_1st.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker_original_dual_1st",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker_original_dual_2nd.def.json b/resources/extruders/ultimaker_original_dual_2nd.def.json
index 80cc17c58d..7907571e66 100644
--- a/resources/extruders/ultimaker_original_dual_2nd.def.json
+++ b/resources/extruders/ultimaker_original_dual_2nd.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker_original_dual_2nd",
"version": 2,
"name": "Extruder 2",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker_original_extruder_0.def.json b/resources/extruders/ultimaker_original_extruder_0.def.json
index 4aab693212..30df96df58 100644
--- a/resources/extruders/ultimaker_original_extruder_0.def.json
+++ b/resources/extruders/ultimaker_original_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker_original_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker_original_plus_extruder_0.def.json b/resources/extruders/ultimaker_original_plus_extruder_0.def.json
index 91d0751861..fec40e93a9 100644
--- a/resources/extruders/ultimaker_original_plus_extruder_0.def.json
+++ b/resources/extruders/ultimaker_original_plus_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker_original_plus_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker_s3_extruder_left.def.json b/resources/extruders/ultimaker_s3_extruder_left.def.json
new file mode 100644
index 0000000000..7af6f7d0dc
--- /dev/null
+++ b/resources/extruders/ultimaker_s3_extruder_left.def.json
@@ -0,0 +1,29 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "ultimaker_s3",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 0,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_offset_x": { "default_value": 0 },
+ "machine_nozzle_offset_y": { "default_value": 0 },
+
+ "machine_extruder_start_pos_abs": { "default_value": true },
+ "machine_extruder_start_pos_x": { "default_value": 180 },
+ "machine_extruder_start_pos_y": { "default_value": 180 },
+ "machine_extruder_end_pos_abs": { "default_value": true },
+ "machine_extruder_end_pos_x": { "default_value": 180 },
+ "machine_extruder_end_pos_y": { "default_value": 180 },
+ "machine_nozzle_head_distance": { "default_value": 2.7 },
+ "extruder_prime_pos_x": { "default_value": -3 },
+ "extruder_prime_pos_y": { "default_value": 6 },
+ "extruder_prime_pos_z": { "default_value": 2 }
+ }
+}
diff --git a/resources/extruders/ultimaker_s3_extruder_right.def.json b/resources/extruders/ultimaker_s3_extruder_right.def.json
new file mode 100644
index 0000000000..7199710327
--- /dev/null
+++ b/resources/extruders/ultimaker_s3_extruder_right.def.json
@@ -0,0 +1,29 @@
+{
+ "version": 2,
+ "name": "Extruder 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "ultimaker_s3",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": {
+ "default_value": 1,
+ "maximum_value": "1"
+ },
+ "machine_nozzle_offset_x": { "default_value": 22 },
+ "machine_nozzle_offset_y": { "default_value": 0 },
+
+ "machine_extruder_start_pos_abs": { "default_value": true },
+ "machine_extruder_start_pos_x": { "default_value": 180 },
+ "machine_extruder_start_pos_y": { "default_value": 180 },
+ "machine_extruder_end_pos_abs": { "default_value": true },
+ "machine_extruder_end_pos_x": { "default_value": 180 },
+ "machine_extruder_end_pos_y": { "default_value": 180 },
+ "machine_nozzle_head_distance": { "default_value": 4.2 },
+ "extruder_prime_pos_x": { "value": "machine_width + 3" },
+ "extruder_prime_pos_y": { "default_value": 6 },
+ "extruder_prime_pos_z": { "default_value": 2 }
+ }
+}
diff --git a/resources/extruders/ultimaker_s5_extruder_left.def.json b/resources/extruders/ultimaker_s5_extruder_left.def.json
index 275f60bb31..24de85e9cc 100644
--- a/resources/extruders/ultimaker_s5_extruder_left.def.json
+++ b/resources/extruders/ultimaker_s5_extruder_left.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker_s5_extruder_left",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/ultimaker_s5_extruder_right.def.json b/resources/extruders/ultimaker_s5_extruder_right.def.json
index 92e08f5cc5..1e0ac3eace 100644
--- a/resources/extruders/ultimaker_s5_extruder_right.def.json
+++ b/resources/extruders/ultimaker_s5_extruder_right.def.json
@@ -1,5 +1,4 @@
{
- "id": "ultimaker_s5_extruder_right",
"version": 2,
"name": "Extruder 2",
"inherits": "fdmextruder",
diff --git a/resources/extruders/uni_print_3d_extruder_0.def.json b/resources/extruders/uni_print_3d_extruder_0.def.json
index d0711fd458..747fb9e020 100644
--- a/resources/extruders/uni_print_3d_extruder_0.def.json
+++ b/resources/extruders/uni_print_3d_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "uni_print_3d_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/uniqbot_one_extruder_0.def.json b/resources/extruders/uniqbot_one_extruder_0.def.json
index 65436ee789..0a8982559d 100644
--- a/resources/extruders/uniqbot_one_extruder_0.def.json
+++ b/resources/extruders/uniqbot_one_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "uniqbot_one_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/vertex_delta_k8800_extruder_0.def.json b/resources/extruders/vertex_delta_k8800_extruder_0.def.json
index 5e09046faf..05a010222f 100644
--- a/resources/extruders/vertex_delta_k8800_extruder_0.def.json
+++ b/resources/extruders/vertex_delta_k8800_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "vertex_delta_k8800_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/vertex_k8400_dual_1st.def.json b/resources/extruders/vertex_k8400_dual_1st.def.json
index 86fb2266ba..947cfbc7d8 100644
--- a/resources/extruders/vertex_k8400_dual_1st.def.json
+++ b/resources/extruders/vertex_k8400_dual_1st.def.json
@@ -1,5 +1,4 @@
{
- "id": "vertex_k8400_dual_1st",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/vertex_k8400_dual_2nd.def.json b/resources/extruders/vertex_k8400_dual_2nd.def.json
index 306b2dcb7a..e606e46337 100644
--- a/resources/extruders/vertex_k8400_dual_2nd.def.json
+++ b/resources/extruders/vertex_k8400_dual_2nd.def.json
@@ -1,5 +1,4 @@
{
- "id": "vertex_k8400_dual_2nd",
"version": 2,
"name": "Extruder 2",
"inherits": "fdmextruder",
diff --git a/resources/extruders/vertex_k8400_extruder_0.def.json b/resources/extruders/vertex_k8400_extruder_0.def.json
index c03453b519..e0304f57bd 100644
--- a/resources/extruders/vertex_k8400_extruder_0.def.json
+++ b/resources/extruders/vertex_k8400_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "vertex_k8400_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/vertex_nano_k8600_extruder_0.def.json b/resources/extruders/vertex_nano_k8600_extruder_0.def.json
new file mode 100644
index 0000000000..cfb2d11217
--- /dev/null
+++ b/resources/extruders/vertex_nano_k8600_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "vertex_nano_k8600",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.35 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/wanhao_d4s_extruder_0.def.json b/resources/extruders/wanhao_d4s_extruder_0.def.json
index 9a750e072c..bd6023faf4 100644
--- a/resources/extruders/wanhao_d4s_extruder_0.def.json
+++ b/resources/extruders/wanhao_d4s_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "wanhao_d4s_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/wanhao_d6_extruder_0.def.json b/resources/extruders/wanhao_d6_extruder_0.def.json
index a8a3bf15d3..093546eabf 100644
--- a/resources/extruders/wanhao_d6_extruder_0.def.json
+++ b/resources/extruders/wanhao_d6_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "wanhao_d6_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/wanhao_d6_plus_extruder_0.def.json b/resources/extruders/wanhao_d6_plus_extruder_0.def.json
index b2b1e6ab05..acc5b66072 100644
--- a/resources/extruders/wanhao_d6_plus_extruder_0.def.json
+++ b/resources/extruders/wanhao_d6_plus_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "wanhao_d6_plus_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/wanhao_d9_extruder_0.def.json b/resources/extruders/wanhao_d9_extruder_0.def.json
index 76d501e5a2..40fcf422f5 100644
--- a/resources/extruders/wanhao_d9_extruder_0.def.json
+++ b/resources/extruders/wanhao_d9_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "wanhao_d9_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/wanhao_duplicator5S_extruder_0.def.json b/resources/extruders/wanhao_duplicator5S_extruder_0.def.json
index 74f47158a3..7274d5117e 100644
--- a/resources/extruders/wanhao_duplicator5S_extruder_0.def.json
+++ b/resources/extruders/wanhao_duplicator5S_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "wanhao_duplicator5S_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/wanhao_duplicator5Smini_extruder_0.def.json b/resources/extruders/wanhao_duplicator5Smini_extruder_0.def.json
index 8c91de4685..3479c94e35 100644
--- a/resources/extruders/wanhao_duplicator5Smini_extruder_0.def.json
+++ b/resources/extruders/wanhao_duplicator5Smini_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "wanhao_duplicator5Smini_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/wanhao_i3_extruder_0.def.json b/resources/extruders/wanhao_i3_extruder_0.def.json
index 7d881079c4..387a456ff2 100644
--- a/resources/extruders/wanhao_i3_extruder_0.def.json
+++ b/resources/extruders/wanhao_i3_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "wanhao_i3_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/wanhao_i3mini_extruder_0.def.json b/resources/extruders/wanhao_i3mini_extruder_0.def.json
index c5abbd175e..2d52f0d126 100644
--- a/resources/extruders/wanhao_i3mini_extruder_0.def.json
+++ b/resources/extruders/wanhao_i3mini_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "wanhao_i3mini_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/wanhao_i3plus_extruder_0.def.json b/resources/extruders/wanhao_i3plus_extruder_0.def.json
index 0dae64ce63..103e3b9335 100644
--- a/resources/extruders/wanhao_i3plus_extruder_0.def.json
+++ b/resources/extruders/wanhao_i3plus_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "wanhao_i3plus_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/z-bolt_extruder_0.def.json b/resources/extruders/z-bolt_extruder_0.def.json
index 70e9f6177c..04c8d10cbb 100644
--- a/resources/extruders/z-bolt_extruder_0.def.json
+++ b/resources/extruders/z-bolt_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "z-bolt_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/zone3d_printer_extruder_0.def.json b/resources/extruders/zone3d_printer_extruder_0.def.json
index ca024dd5c4..fb8f40d3e2 100644
--- a/resources/extruders/zone3d_printer_extruder_0.def.json
+++ b/resources/extruders/zone3d_printer_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "zone3d_printer_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/extruders/zyyx_agile_extruder_0.def.json b/resources/extruders/zyyx_agile_extruder_0.def.json
index edda9b3097..c01ffb59f3 100644
--- a/resources/extruders/zyyx_agile_extruder_0.def.json
+++ b/resources/extruders/zyyx_agile_extruder_0.def.json
@@ -1,5 +1,4 @@
{
- "id": "zyyx_agile_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
diff --git a/resources/i18n/cura.pot b/resources/i18n/cura.pot
index 1874604139..40a0c03721 100644
--- a/resources/i18n/cura.pot
+++ b/resources/i18n/cura.pot
@@ -8,17 +8,17 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-10-29 15:01+0100\n"
+"POT-Creation-Date: 2019-11-05 13:13+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"Language: \n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:22
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:30
msgctxt "@action"
msgid "Machine Settings"
msgstr ""
@@ -40,23 +40,23 @@ msgctxt "@item:inlistbox"
msgid "G-code File"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:67
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:66
msgctxt "@error:not supported"
msgid "GCodeWriter does not support non-text mode."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:73
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:89
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:72
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:88
msgctxt "@warning:status"
msgid "Please prepare G-code before exporting."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:30
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:31
msgctxt "@info:title"
msgid "3D Model Assistant"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:80
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:92
#, python-brace-format
msgctxt "@info:status"
msgid ""
@@ -69,66 +69,52 @@ msgid ""
"guide
"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.py:32
-msgctxt "@item:inmenu"
-msgid "Show Changelog"
-msgstr ""
-
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py:25
msgctxt "@action"
msgid "Update Firmware"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:23
-msgctxt "@item:inmenu"
-msgid "Flatten active settings"
+#: /home/ruben/Projects/Cura/plugins/AMFReader/__init__.py:15
+msgctxt "@item:inlistbox"
+msgid "AMF File"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:35
-msgctxt "@info:status"
-msgid "Profile has been flattened & activated."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:32
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:42
msgctxt "@item:inmenu"
msgid "USB printing"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:33
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:43
msgctxt "@action:button Preceded by 'Ready to'."
msgid "Print via USB"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:34
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:44
msgctxt "@info:tooltip"
msgid "Print via USB"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:69
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:80
msgctxt "@info:status"
msgid "Connected via USB"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:92
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:105
msgctxt "@label"
msgid ""
"A USB print is in progress, closing Cura will stop this print. Are you sure?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/install/X3GWriter/__init__.py:15
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/__init__.py:15
-msgctxt "X3G Writer File Description"
-msgid "X3G File"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid ""
+"A print is still in progress. Cura cannot start another print via USB until "
+"the previous print has completed."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:16
-msgctxt "X3g Writer Plugin Description"
-msgid "Writes X3g to files"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:21
-msgctxt "X3g Writer File Description"
-msgid "X3g File"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid "Print in Progress"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/GCodeGzWriter/__init__.py:17
@@ -143,6 +129,7 @@ msgid "GCodeGzWriter does not support text mode."
msgstr ""
#: /home/ruben/Projects/Cura/plugins/UFPWriter/__init__.py:28
+#: /home/ruben/Projects/Cura/plugins/UFPReader/__init__.py:22
msgctxt "@item:inlistbox"
msgid "Ultimaker Format Package"
msgstr ""
@@ -164,7 +151,7 @@ msgid "Save to Removable Drive {0}"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:64
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:133
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py:107
msgctxt "@info:status"
msgid "There are no file formats available to write with!"
msgstr ""
@@ -201,9 +188,9 @@ msgid "Could not save to removable drive {0}: {1}"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:137
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:133
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:140
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1607
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:139
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:146
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1668
msgctxt "@info:title"
msgid "Error"
msgstr ""
@@ -232,8 +219,9 @@ msgstr ""
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:151
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:163
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1597
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1695
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1658
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1758
msgctxt "@info:title"
msgid "Warning"
msgstr ""
@@ -260,245 +248,172 @@ msgctxt "@item:intext"
msgid "Removable Drive"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:73
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:88
-msgctxt "@action:button Preceded by 'Ready to'."
-msgid "Print over network"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:74
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:89
-msgctxt "@properties:tooltip"
-msgid "Print over network"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:87
-msgctxt "@info:status"
-msgid "Connected over the network."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:90
-msgctxt "@info:status"
-msgid ""
-"Connected over the network. Please approve the access request on the printer."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:92
-msgctxt "@info:status"
-msgid "Connected over the network. No access to control the printer."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:97
-msgctxt "@info:status"
-msgid ""
-"Access to the printer requested. Please approve the request on the printer"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:100
-msgctxt "@info:title"
-msgid "Authentication status"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:102
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:108
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:112
-msgctxt "@info:title"
-msgid "Authentication Status"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:103
-msgctxt "@action:button"
-msgid "Retry"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:104
-msgctxt "@info:tooltip"
-msgid "Re-send the access request"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:107
-msgctxt "@info:status"
-msgid "Access to the printer accepted"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:111
-msgctxt "@info:status"
-msgid "No access to print with this printer. Unable to send print job."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:113
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:33
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:70
-msgctxt "@action:button"
-msgid "Request Access"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:115
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:34
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:71
-msgctxt "@info:tooltip"
-msgid "Send access request to the printer"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:200
-msgctxt "@label"
-msgid "Unable to start a new print job."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:202
-msgctxt "@label"
-msgid ""
-"There is an issue with the configuration of your Ultimaker, which makes it "
-"impossible to start the print. Please resolve this issues before continuing."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:208
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:230
-msgctxt "@window:title"
-msgid "Mismatched configuration"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:222
-msgctxt "@label"
-msgid "Are you sure you wish to print with the selected configuration?"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:224
-msgctxt "@label"
-msgid ""
-"There is a mismatch between the configuration or calibration of the printer "
-"and Cura. For the best result, always slice for the PrintCores and materials "
-"that are inserted in your printer."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:251
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:199
-msgctxt "@info:status"
-msgid ""
-"Sending new jobs (temporarily) blocked, still sending the previous print job."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:258
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:218
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:234
-msgctxt "@info:status"
-msgid "Sending data to printer"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:259
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:219
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:235
-msgctxt "@info:title"
-msgid "Sending Data"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:260
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:236
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:80
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:381
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:20
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:143
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:391
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:87
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:279
-msgctxt "@action:button"
-msgid "Cancel"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:323
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No Printcore loaded in slot {slot_number}"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:329
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No material loaded in slot {slot_number}"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:352
-#, python-brace-format
-msgctxt "@label"
-msgid ""
-"Different PrintCore (Cura: {cura_printcore_name}, Printer: "
-"{remote_printcore_name}) selected for extruder {extruder_id}"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:361
-#, python-brace-format
-msgctxt "@label"
-msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:547
-msgctxt "@window:title"
-msgid "Sync with your printer"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:549
-msgctxt "@label"
-msgid "Would you like to use your current printer configuration in Cura?"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:551
-msgctxt "@label"
-msgid ""
-"The PrintCores and/or materials on your printer differ from those within "
-"your current project. For the best result, always slice for the PrintCores "
-"and materials that are inserted in your printer."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:91
-msgctxt "@info:status"
-msgid "Connected over the network"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:303
-msgctxt "@info:status"
-msgid "Print job was successfully sent to the printer."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:305
-msgctxt "@info:title"
-msgid "Data Sent"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:306
-msgctxt "@action:button"
-msgid "View in Monitor"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:422
-#, python-brace-format
-msgctxt "@info:status"
-msgid "Printer '{printer_name}' has finished printing '{job_name}'."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:424
-#, python-brace-format
-msgctxt "@info:status"
-msgid "The print job '{job_name}' was finished."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:425
-msgctxt "@info:status"
-msgid "Print finished"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py:26
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py:26
msgctxt "@action"
msgid "Connect via Network"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:13
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:57
+msgctxt "@action:button Preceded by 'Ready to'."
+msgid "Print over network"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:58
+msgctxt "@properties:tooltip"
+msgid "Print over network"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:59
+msgctxt "@info:status"
+msgid "Connected over the network"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:15
+msgctxt "@info:status"
+msgid "Please wait until the current job has been sent."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:16
+msgctxt "@info:title"
+msgid "Print error"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:21
+msgctxt "@info:title"
+msgid "New cloud printers found"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:22
+msgctxt "@info:message"
+msgid ""
+"New printers have been found connected to your account, you can find them in "
+"your list of discovered printers."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:27
+msgctxt "@info:option_text"
+msgid "Do not show this message again"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:27
+#, python-brace-format
+msgctxt "@info:status"
+msgid ""
+"You are attempting to connect to {0} but it is not the host of a group. You "
+"can visit the web page to configure it as a group host."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:30
+msgctxt "@info:title"
+msgid "Not a group host"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:35
+msgctxt "@action"
+msgid "Configure group"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:27
+msgctxt "@info:status"
+msgid "Send and monitor print jobs from anywhere using your Ultimaker account."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:33
+msgctxt "@info:status Ultimaker Cloud should not be translated."
+msgid "Connect to Ultimaker Cloud"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:36
+msgctxt "@action"
+msgid "Get started"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:14
+msgctxt "@info:status"
+msgid "Sending Print Job"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:15
+msgctxt "@info:status"
+msgid "Uploading print job to printer."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:15
+msgctxt "@info:status"
+msgid "Print job was successfully sent to the printer."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:16
+msgctxt "@info:title"
+msgid "Data Sent"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:18
+msgctxt "@info:status"
+msgid ""
+"You are attempting to connect to a printer that is not running Ultimaker "
+"Connect. Please update the printer to the latest firmware."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:21
+msgctxt "@info:title"
+msgid "Update your printer"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:24
+#, python-brace-format
+msgctxt "@info:status"
+msgid ""
+"Cura has detected material profiles that were not yet installed on the host "
+"printer of group {0}."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:26
+msgctxt "@info:title"
+msgid "Sending materials to printer"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:15
+msgctxt "@info:text"
+msgid "Could not upload the data to the printer."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:16
+msgctxt "@info:title"
+msgid "Network error"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:27
+msgctxt "@info:status"
+msgid "tomorrow"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:30
+msgctxt "@info:status"
+msgid "today"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:138
+msgctxt "@action:button"
+msgid "Print via Cloud"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:139
+msgctxt "@properties:tooltip"
+msgid "Print via Cloud"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:140
+msgctxt "@info:status"
+msgid "Connected via Cloud"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:14
msgctxt "@item:inmenu"
msgid "Monitor"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:119
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:125
msgctxt "@info"
msgid "Could not access update information."
msgstr ""
@@ -524,22 +439,28 @@ msgctxt "@action:button"
msgid "How to update"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:14
+#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:15
msgctxt "@item:inlistbox"
msgid "Layer view"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:113
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:117
msgctxt "@info:status"
msgid "Cura does not accurately display layers when Wire Printing is enabled"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:114
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:118
msgctxt "@info:title"
msgid "Simulation View"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:35
+msgctxt "@item:inmenu"
+msgid "Post Processing"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:36
+msgctxt "@item:inmenu"
msgid "Modify G-Code"
msgstr ""
@@ -553,39 +474,6 @@ msgctxt "@info:tooltip"
msgid "Create a volume in which supports are not printed."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:52
-msgctxt "@info"
-msgid "Cura collects anonymized usage statistics."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:55
-msgctxt "@info:title"
-msgid "Collecting Data"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:57
-msgctxt "@action:button"
-msgid "More info"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:58
-msgctxt "@action:tooltip"
-msgid "See more information on what data Cura sends."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:60
-msgctxt "@action:button"
-msgid "Allow"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:61
-msgctxt "@action:tooltip"
-msgid ""
-"Allow Cura to send anonymized usage statistics to help prioritize future "
-"improvements to Cura. Some of your preferences and settings are sent, the "
-"Cura version and a hash of the models you're slicing."
-msgstr ""
-
#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
msgid "Cura 15.04 profiles"
@@ -616,24 +504,54 @@ msgctxt "@item:inlistbox"
msgid "GIF Image"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:15
+msgctxt "@item:inlistbox 'Open' is part of the name of this file format."
+msgid "Open Compressed Triangle Mesh"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:19
+msgctxt "@item:inlistbox"
+msgid "COLLADA Digital Asset Exchange"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:23
+msgctxt "@item:inlistbox"
+msgid "glTF Binary"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:27
+msgctxt "@item:inlistbox"
+msgid "glTF Embedded JSON"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:36
+msgctxt "@item:inlistbox"
+msgid "Stanford Triangle Format"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:40
+msgctxt "@item:inlistbox"
+msgid "Compressed COLLADA Digital Asset Exchange"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
msgctxt "@info:status"
msgid ""
"Unable to slice with the current material as it is incompatible with the "
"selected machine or configuration."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:363
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:387
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:396
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:405
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:414
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
msgctxt "@info:title"
msgid "Unable to slice"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:361
#, python-brace-format
msgctxt "@info:status"
msgid ""
@@ -641,7 +559,7 @@ msgid ""
"errors: {0}"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:385
#, python-brace-format
msgctxt "@info:status"
msgid ""
@@ -649,13 +567,13 @@ msgid ""
"errors on one or more models: {error_labels}"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:394
msgctxt "@info:status"
msgid ""
"Unable to slice because the prime tower or prime position(s) are invalid."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:403
#, python-format
msgctxt "@info:status"
msgid ""
@@ -663,20 +581,21 @@ msgid ""
"%s."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:412
msgctxt "@info:status"
msgid ""
-"Nothing to slice because none of the models fit the build volume. Please "
-"scale or rotate models to fit."
+"Nothing to slice because none of the models fit the build volume or are "
+"assigned to a disabled extruder. Please scale or rotate models to fit, or "
+"enable an extruder."
msgstr ""
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:50
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:status"
msgid "Processing Layers"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:title"
msgid "Information"
msgstr ""
@@ -691,14 +610,12 @@ msgctxt "@info:tooltip"
msgid "Configure Per Model Settings"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:175
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:575
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:186
msgctxt "@title:tab"
msgid "Recommended"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:177
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:580
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:188
msgctxt "@title:tab"
msgid "Custom"
msgstr ""
@@ -709,13 +626,13 @@ msgctxt "@item:inlistbox"
msgid "3MF File"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:190
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:714
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:198
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:651
msgctxt "@label"
msgid "Nozzle"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:468
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:496
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid ""
@@ -724,7 +641,7 @@ msgid ""
"instead."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:471
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:499
msgctxt "@info:title"
msgid "Open Project File"
msgstr ""
@@ -739,24 +656,67 @@ msgctxt "@item:inlistbox"
msgid "G File"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:324
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:335
msgctxt "@info:status"
msgid "Parsing G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:326
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:474
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:337
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:491
msgctxt "@info:title"
msgid "G-code Details"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:472
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:489
msgctxt "@info:generic"
msgid ""
"Make sure the g-code is suitable for your printer and printer configuration "
"before sending the file to it. The g-code representation may not be accurate."
msgstr ""
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:64
+msgctxt "@item:inmenu"
+msgid "Manage backups"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:107
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:113
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:104
+msgctxt "@info:title"
+msgid "Backup"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+msgctxt "@info:backup_status"
+msgid "There was an error listing your backups."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:132
+msgctxt "@info:backup_status"
+msgid "There was an error trying to restore your backup."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:15
+msgctxt "@info:title"
+msgid "Backups"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:27
+msgctxt "@info:backup_status"
+msgid "Uploading your backup..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:36
+msgctxt "@info:backup_status"
+msgid "There was an error while uploading your backup."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:39
+msgctxt "@info:backup_status"
+msgid "Your backup has finished uploading."
+msgstr ""
+
#: /home/ruben/Projects/Cura/plugins/CuraProfileWriter/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
@@ -778,96 +738,44 @@ msgctxt "@error:zip"
msgid "Error writing 3mf file."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelection.py:17
+#: /home/ruben/Projects/Cura/plugins/PreviewStage/__init__.py:13
+msgctxt "@item:inmenu"
+msgid "Preview"
+msgstr ""
+
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelection.py:18
msgctxt "@action"
msgid "Select upgrades"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py:14
-msgctxt "@action"
-msgid "Checkup"
-msgstr ""
-
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.py:21
msgctxt "@action"
msgid "Level build plate"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:82
-msgctxt "@tooltip"
-msgid "Outer Wall"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:83
-msgctxt "@tooltip"
-msgid "Inner Walls"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:84
-msgctxt "@tooltip"
-msgid "Skin"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:85
-msgctxt "@tooltip"
-msgid "Infill"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:86
-msgctxt "@tooltip"
-msgid "Support Infill"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:87
-msgctxt "@tooltip"
-msgid "Support Interface"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:88
-msgctxt "@tooltip"
-msgid "Support"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:89
-msgctxt "@tooltip"
-msgid "Skirt"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:90
-msgctxt "@tooltip"
-msgid "Travel"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:91
-msgctxt "@tooltip"
-msgid "Retractions"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:92
-msgctxt "@tooltip"
-msgid "Other"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:310
-#, python-brace-format
-msgctxt "@label"
-msgid "Pre-sliced file {0}"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/API/Account.py:71
+#: /home/ruben/Projects/Cura/cura/API/Account.py:82
msgctxt "@info:title"
msgid "Login failed"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:201
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:121
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:36
+msgctxt "@info:not supported profile"
+msgid "Not supported"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:55
+msgctxt "@info:No intent profile selected"
+msgid "Default"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:196
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:125
msgctxt "@title:window"
msgid "File Already Exists"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:202
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:122
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:197
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:126
#, python-brace-format
msgctxt "@label Don't translate the XML tag !"
msgid ""
@@ -875,44 +783,45 @@ msgid ""
"overwrite it?"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/ExtrudersModel.py:212
-msgctxt "@menuitem"
-msgid "Not overridden"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:117
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:430
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:433
msgctxt "@info:status"
+msgid "Invalid file URL:"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:780
+msgctxt "@info:message Followed by a list of settings."
msgid ""
-"The selected material is incompatible with the selected machine or "
-"configuration."
+"Settings have been changed to match the current availability of extruders:"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:118
-msgctxt "@info:title"
-msgid "Incompatible Material"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:866
-#, python-format
-msgctxt "@info:generic"
-msgid ""
-"Settings have been changed to match the current availability of extruders: "
-"[%s]"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:868
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:782
msgctxt "@info:title"
msgid "Settings updated"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:131
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1334
+msgctxt "@info:title"
+msgid "Extruder(s) Disabled"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1457
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:99
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:86
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:182
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:223
+msgctxt "@label"
+msgid "Unknown"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:137
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid ""
"Failed to export profile to {0}: {1}"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:138
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid ""
@@ -920,39 +829,44 @@ msgid ""
"failure."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:143
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:149
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid "Exported profile to {0}"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:150
msgctxt "@info:title"
msgid "Export succeeded"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:170
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:177
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
-msgid ""
-"Failed to import profile from {0}: {1}"
-"message>"
+msgctxt "@info:status Don't translate the XML tags !"
+msgid "Failed to import profile from {0}: {1}"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:190
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:181
+#, python-brace-format
+msgctxt "@info:status Don't translate the XML tags !"
+msgid ""
+"Can't import profile from {0} before a printer is added."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:198
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "No custom profile to import in file {0}"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:194
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:202
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "Failed to import profile from {0}:"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:218
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:228
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:226
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:236
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid ""
@@ -960,166 +874,333 @@ msgid ""
"import it."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:241
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:325
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags !"
-msgid ""
-"The machine defined in profile {0} ({1}) doesn't match "
-"with your current machine ({2}), could not import it."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:312
-#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
+msgctxt "@info:status Don't translate the XML tag !"
msgid "Failed to import profile from {0}:"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:315
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:328
#, python-brace-format
msgctxt "@info:status"
msgid "Successfully imported profile {0}"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:318
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:331
#, python-brace-format
msgctxt "@info:status"
msgid "File {0} does not contain any valid profile."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:321
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:334
#, python-brace-format
msgctxt "@info:status"
msgid "Profile {0} has an unknown file type or is corrupted."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:339
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
msgctxt "@label"
msgid "Custom profile"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:355
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:385
msgctxt "@info:status"
msgid "Profile is missing a quality type."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:399
#, python-brace-format
msgctxt "@info:status"
msgid "Could not find a quality type {0} for the current configuration."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/ObjectsModel.py:63
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:76
+msgctxt "@tooltip"
+msgid "Outer Wall"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:77
+msgctxt "@tooltip"
+msgid "Inner Walls"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:78
+msgctxt "@tooltip"
+msgid "Skin"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:79
+msgctxt "@tooltip"
+msgid "Infill"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:80
+msgctxt "@tooltip"
+msgid "Support Infill"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:81
+msgctxt "@tooltip"
+msgid "Support Interface"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:82
+msgctxt "@tooltip"
+msgid "Support"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:83
+msgctxt "@tooltip"
+msgid "Skirt"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:84
+msgctxt "@tooltip"
+msgid "Prime Tower"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:85
+msgctxt "@tooltip"
+msgid "Travel"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:86
+msgctxt "@tooltip"
+msgid "Retractions"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:87
+msgctxt "@tooltip"
+msgid "Other"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:302
+#, python-brace-format
+msgctxt "@label"
+msgid "Pre-sliced file {0}"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/WelcomePagesModel.py:56
+msgctxt "@action:button"
+msgid "Next"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/UI/ObjectsModel.py:62
#, python-brace-format
msgctxt "@label"
msgid "Group #{group_nr}"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:65
-msgctxt "@info:title"
-msgid "Network enabled printers"
+#: /home/ruben/Projects/Cura/cura/UI/WhatsNewPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:482
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:124
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:169
+msgctxt "@action:button"
+msgid "Close"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:80
-msgctxt "@info:title"
-msgid "Local printers"
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
+msgctxt "@action:button"
+msgid "Add"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:109
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:18
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:81
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:352
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:58
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:149
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:406
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:294
+msgctxt "@action:button"
+msgid "Cancel"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:36
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:320
+msgctxt "@label"
+msgid "Default"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:39
+msgctxt "@label"
+msgid "Visual"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:40
+msgctxt "@text"
+msgid ""
+"The visual profile is designed to print visual prototypes and models with "
+"the intent of high visual and surface quality."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:43
+msgctxt "@label"
+msgid "Engineering"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:44
+msgctxt "@text"
+msgid ""
+"The engineering profile is designed to print functional prototypes and end-"
+"use parts with the intent of better accuracy and for closer tolerances."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:47
+msgctxt "@label"
+msgid "Draft"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:48
+msgctxt "@text"
+msgid ""
+"The draft profile is designed to print initial prototypes and concept "
+"validation with the intent of significant print time reduction."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/ExtrudersModel.py:208
+msgctxt "@menuitem"
+msgid "Not overridden"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:357
+msgctxt "@label"
+msgid "Custom profiles"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:391
#, python-brace-format
msgctxt "@item:inlistbox"
msgid "All Supported Types ({0})"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:110
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:392
msgctxt "@item:inlistbox"
msgid "All Files (*)"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:636
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:213
msgctxt "@label"
msgid "Custom Material"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:637
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:214
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:205
msgctxt "@label"
msgid "Custom"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:81
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:116
+msgctxt "@label"
+msgid ""
+"The printer(s) below cannot be connected because they are part of a group"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:118
+msgctxt "@label"
+msgid "Available networked printers"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:90
msgctxt "@info:status"
msgid ""
"The build volume height has been reduced due to the value of the \"Print "
"Sequence\" setting to prevent the gantry from colliding with printed models."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:83
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:92
msgctxt "@info:title"
msgid "Build Volume"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:98
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:99
msgctxt "@info:backup_failed"
msgid "Could not create archive from user data directory: {}"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:103
-msgctxt "@info:title"
-msgid "Backup"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:113
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:114
msgctxt "@info:backup_failed"
msgid "Tried to restore a Cura backup without having proper data or meta data."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:123
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:125
msgctxt "@info:backup_failed"
-msgid ""
-"Tried to restore a Cura backup that does not match your current version."
+msgid "Tried to restore a Cura backup that is higher than the current version."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:27
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationHelpers.py:79
+msgctxt "@message"
+msgid "Could not read response."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+msgctxt "@info"
+msgid "Unable to reach the Ultimaker account server."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:70
+msgctxt "@message"
+msgid "Please give the required permissions when authorizing this application."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:77
+msgctxt "@message"
+msgid "Something unexpected happened when trying to log in, please try again."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:29
msgctxt "@info:status"
msgid "Multiplying and placing objects"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:28
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:30
msgctxt "@info:title"
-msgid "Placing Object"
+msgid "Placing Objects"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:96
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:103
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:149
msgctxt "@info:status"
msgid "Unable to find a location within the build volume for all objects"
msgstr ""
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+msgctxt "@info:title"
+msgid "Placing Object"
+msgstr ""
+
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:30
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:67
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:66
msgctxt "@info:status"
msgid "Finding new location for objects"
msgstr ""
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:34
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:71
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:70
msgctxt "@info:title"
msgid "Finding Location"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:97
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:151
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:104
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
msgctxt "@info:title"
msgid "Can't Find Location"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:87
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:83
msgctxt "@title:window"
msgid "Cura can't start"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:93
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:89
msgctxt "@label crash message"
msgid ""
"
"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:222
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:218
msgctxt "@title:groupbox"
msgid "Error traceback"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:303
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:299
msgctxt "@title:groupbox"
msgid "Logs"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:326
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:322
msgctxt "@title:groupbox"
-msgid "User description"
+msgid ""
+"User description (Note: Developers may not speak your language, please use "
+"English if possible)"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:345
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:342
msgctxt "@action:button"
msgid "Send report"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:473
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:513
msgctxt "@info:progress"
msgid "Loading machines..."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:775
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:520
+msgctxt "@info:progress"
+msgid "Setting up preferences..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:824
msgctxt "@info:progress"
msgid "Setting up scene..."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:811
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:859
msgctxt "@info:progress"
msgid "Loading interface..."
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1037
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1150
#, python-format
msgctxt ""
"@info 'width', 'depth' and 'height' are variable names that must NOT be "
@@ -1270,239 +1358,181 @@ msgctxt ""
msgid "%(width).1f x %(depth).1f x %(height).1f mm"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1596
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1657
#, python-brace-format
msgctxt "@info:status"
msgid "Only one G-code file can be loaded at a time. Skipped importing {0}"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1606
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1667
#, python-brace-format
msgctxt "@info:status"
msgid "Can't open any other file if G-code is loading. Skipped importing {0}"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1694
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1757
msgctxt "@info:status"
msgid "The selected model was too small to load."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:61
-msgctxt "@title"
-msgid "Machine Settings"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:80
-msgctxt "@title:tab"
-msgid "Printer"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:99
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:56
+msgctxt "@title:label"
msgid "Printer Settings"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:110
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:70
msgctxt "@label"
msgid "X (Width)"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:111
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:121
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:131
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:237
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:386
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:402
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:428
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:440
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:896
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:74
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:88
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:102
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:243
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:265
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:285
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:79
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:93
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:109
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:124
msgctxt "@label"
msgid "mm"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:120
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:84
msgctxt "@label"
msgid "Y (Depth)"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:130
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:98
msgctxt "@label"
msgid "Z (Height)"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:142
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:112
msgctxt "@label"
msgid "Build plate shape"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:151
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:125
+msgctxt "@label"
msgid "Origin at center"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:159
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:137
+msgctxt "@label"
msgid "Heated bed"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:170
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:149
+msgctxt "@label"
+msgid "Heated build volume"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:161
msgctxt "@label"
msgid "G-code flavor"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:183
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:185
+msgctxt "@title:label"
msgid "Printhead Settings"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:193
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:199
msgctxt "@label"
msgid "X min"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:194
-msgctxt "@tooltip"
-msgid ""
-"Distance from the left of the printhead to the center of the nozzle. Used to "
-"prevent colissions between previous prints and the printhead when printing "
-"\"One at a Time\"."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:219
msgctxt "@label"
msgid "Y min"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:204
-msgctxt "@tooltip"
-msgid ""
-"Distance from the front of the printhead to the center of the nozzle. Used "
-"to prevent colissions between previous prints and the printhead when "
-"printing \"One at a Time\"."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:213
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:239
msgctxt "@label"
msgid "X max"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:214
-msgctxt "@tooltip"
-msgid ""
-"Distance from the right of the printhead to the center of the nozzle. Used "
-"to prevent colissions between previous prints and the printhead when "
-"printing \"One at a Time\"."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:261
msgctxt "@label"
msgid "Y max"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:224
-msgctxt "@tooltip"
-msgid ""
-"Distance from the rear of the printhead to the center of the nozzle. Used to "
-"prevent colissions between previous prints and the printhead when printing "
-"\"One at a Time\"."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:236
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:281
msgctxt "@label"
-msgid "Gantry height"
+msgid "Gantry Height"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:238
-msgctxt "@tooltip"
-msgid ""
-"The height difference between the tip of the nozzle and the gantry system (X "
-"and Y axes). Used to prevent collisions between previous prints and the "
-"gantry when printing \"One at a Time\"."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:257
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:295
msgctxt "@label"
msgid "Number of Extruders"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:313
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:355
+msgctxt "@title:label"
msgid "Start G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:323
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very start."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:332
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:366
+msgctxt "@title:label"
msgid "End G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:342
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very end."
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:42
+msgctxt "@title:tab"
+msgid "Printer"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:373
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:63
+msgctxt "@title:label"
msgid "Nozzle Settings"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:385
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:75
msgctxt "@label"
msgid "Nozzle size"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:401
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:89
msgctxt "@label"
msgid "Compatible material diameter"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:403
-msgctxt "@tooltip"
-msgid ""
-"The nominal diameter of filament supported by the printer. The exact "
-"diameter will be overridden by the material and/or the profile."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:427
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:105
msgctxt "@label"
msgid "Nozzle offset X"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:439
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:120
msgctxt "@label"
msgid "Nozzle offset Y"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:451
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:135
msgctxt "@label"
msgid "Cooling Fan Number"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:452
-msgctxt "@label"
-msgid ""
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:472
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:162
+msgctxt "@title:label"
msgid "Extruder Start G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:490
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:176
+msgctxt "@title:label"
msgid "Extruder End G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
msgctxt "@action:button"
msgid "Install"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:20
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
msgctxt "@action:button"
msgid "Installed"
msgstr ""
@@ -1513,68 +1543,81 @@ msgid ""
"Could not connect to the Cura Package database. Please check your connection."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:38
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:28
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/SmallRatingWidget.qml:27
+msgctxt "@label"
+msgid "ratings"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:30
msgctxt "@title:tab"
msgid "Plugins"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:75
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:42
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:66
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:77
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:44
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:89
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:417
msgctxt "@title:tab"
msgid "Materials"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:79
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+msgctxt "@label"
+msgid "Your rating"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:99
msgctxt "@label"
msgid "Version"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:85
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:106
msgctxt "@label"
msgid "Last updated"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:113
msgctxt "@label"
msgid "Author"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:120
msgctxt "@label"
msgid "Downloads"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:116
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:158
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:258
-msgctxt "@label"
-msgid "Unknown"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:56
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to install or update"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:44
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:30
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:80
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Buy material spools"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:96
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:34
msgctxt "@action:button"
msgid "Update"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:45
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:35
msgctxt "@action:button"
msgid "Updating"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:98
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:36
msgctxt "@action:button"
msgid "Updated"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/Toolbox.qml:13
msgctxt "@title"
-msgid "Toolbox"
+msgid "Marketplace"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml:25
@@ -1604,52 +1647,67 @@ msgctxt "@text:window"
msgid "Profiles"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:89
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:90
msgctxt "@action:button"
msgid "Confirm"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to login first before you can rate"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to install the package before you can rate"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:19
msgctxt "@info"
msgid "You will need to restart Cura before changes in packages have effect."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:45
msgctxt "@info:button"
msgid "Quit Cura"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Contributions"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Plugins"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:43
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:40
msgctxt "@label"
msgid "Generic Materials"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:56
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:59
msgctxt "@title:tab"
msgid "Installed"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:22
msgctxt "@label"
msgid "Will install upon restarting"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:53
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to update"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Downgrade"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Uninstall"
msgstr ""
@@ -1667,12 +1725,12 @@ msgid ""
"Do you agree with the terms below?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:54
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:55
msgctxt "@action:button"
msgid "Accept"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:65
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:66
msgctxt "@action:button"
msgid "Decline"
msgstr ""
@@ -1682,22 +1740,62 @@ msgctxt "@label"
msgid "Featured"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:34
msgctxt "@label"
msgid "Compatibility"
msgstr ""
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:124
+msgctxt "@label:table_header"
+msgid "Machine"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:137
+msgctxt "@label:table_header"
+msgid "Build Plate"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:143
+msgctxt "@label:table_header"
+msgid "Support"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:149
+msgctxt "@label:table_header"
+msgid "Quality"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:170
+msgctxt "@action:label"
+msgid "Technical Data Sheet"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:179
+msgctxt "@action:label"
+msgid "Safety Data Sheet"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:188
+msgctxt "@action:label"
+msgid "Printing Guidelines"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:197
+msgctxt "@action:label"
+msgid "Website"
+msgstr ""
+
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml:16
msgctxt "@info"
msgid "Fetching packages..."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:88
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:91
msgctxt "@label"
msgid "Website"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:94
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:98
msgctxt "@label"
msgid "Email"
msgstr ""
@@ -1709,23 +1807,6 @@ msgid ""
"adjustment."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18
-msgctxt "@label"
-msgid "Changelog"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:37
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:53
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:467
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:514
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:121
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:166
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:38
-msgctxt "@action:button"
-msgid "Close"
-msgstr ""
-
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:31
msgctxt "@title"
msgid "Update Firmware"
@@ -1809,436 +1890,513 @@ msgctxt "@label"
msgid "Firmware update failed due to missing firmware."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UserAgreement/UserAgreement.qml:16
-msgctxt "@title:window"
-msgid "User Agreement"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:155
+msgctxt "@label link to Connect and Cloud interfaces"
+msgid "Manage printer"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:46
-msgctxt "@window:title"
-msgid "Existing Connection"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:192
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:183
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:153
+msgctxt "@label"
+msgid "Glass"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:48
-msgctxt "@message:text"
-msgid ""
-"This printer/group is already added to Cura. Please select another printer/"
-"group."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:256
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:514
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:248
+msgctxt "@info"
+msgid "Please update your printer's firmware to manage the queue remotely."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:65
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:289
+msgctxt "@info"
+msgid "The webcam is not available because you are monitoring a cloud printer."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:348
+msgctxt "@label:status"
+msgid "Loading..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:352
+msgctxt "@label:status"
+msgid "Unavailable"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:356
+msgctxt "@label:status"
+msgid "Unreachable"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:360
+msgctxt "@label:status"
+msgid "Idle"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:401
+msgctxt "@label"
+msgid "Untitled"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:422
+msgctxt "@label"
+msgid "Anonymous"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:449
+msgctxt "@label:status"
+msgid "Requires configuration changes"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:487
+msgctxt "@action:button"
+msgid "Details"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:132
+msgctxt "@label"
+msgid "Unavailable printer"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:134
+msgctxt "@label"
+msgid "First available"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:31
+msgctxt "@label"
+msgid "Queued"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:67
+msgctxt "@label link to connect manager"
+msgid "Manage in browser"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:100
+msgctxt "@label"
+msgid "There are no print jobs in the queue. Slice and send a job to add one."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:115
+msgctxt "@label"
+msgid "Print jobs"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:131
+msgctxt "@label"
+msgid "Total print time"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:147
+msgctxt "@label"
+msgid "Waiting for"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:45
msgctxt "@title:window"
msgid "Connect to Networked Printer"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:75
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
msgctxt "@label"
msgid ""
"To print directly to your printer over the network, please make sure your "
"printer is connected to the network using a network cable or by connecting "
"your printer to your WIFI network. If you don't connect Cura with your "
"printer, you can still use a USB drive to transfer g-code files to your "
-"printer.\n"
-"\n"
-"Select your printer from the list below:"
+"printer."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:85
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:42
-msgctxt "@action:button"
-msgid "Add"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
+msgctxt "@label"
+msgid "Select your printer from the list below:"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:95
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:77
msgctxt "@action:button"
msgid "Edit"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:106
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:128
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:117
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:88
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:138
msgctxt "@action:button"
msgid "Remove"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:114
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:96
msgctxt "@action:button"
msgid "Refresh"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:207
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:176
msgctxt "@label"
msgid ""
"If your printer is not listed, read the network printing "
"troubleshooting guide"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:234
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:205
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:258
msgctxt "@label"
msgid "Type"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:271
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:274
msgctxt "@label"
msgid "Firmware version"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:290
msgctxt "@label"
msgid "Address"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:305
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:263
msgctxt "@label"
msgid "This printer is not set up to host a group of printers."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:309
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:267
msgctxt "@label"
msgid "This printer is the host for a group of %1 printers."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:319
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:278
msgctxt "@label"
msgid "The printer at this address has not yet responded."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:324
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
msgctxt "@action:button"
msgid "Connect"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:338
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:296
+msgctxt "@title:window"
+msgid "Invalid IP address"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:146
+msgctxt "@text"
+msgid "Please enter a valid IP address."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:308
msgctxt "@title:window"
msgid "Printer Address"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
-msgctxt "@alabel"
-msgid "Enter the IP address or hostname of your printer on the network."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:102
+msgctxt "@label"
+msgid "Enter the IP address of your printer on the network."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:390
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:132
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:138
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:181
msgctxt "@action:button"
msgid "OK"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:44
-msgctxt "@action:button"
-msgid "Print"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:47
-msgctxt "@title:window"
-msgid "Print over network"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:79
-msgctxt "@label"
-msgid "Printer selection"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:173
-msgctxt "@label"
-msgid "Not available"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:175
-msgctxt "@label"
-msgid "Unreachable"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:180
-msgctxt "@label"
-msgid "Available"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:37
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:44
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:46
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:78
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:90
msgctxt "@label:status"
msgid "Aborted"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:39
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:80
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:82
msgctxt "@label:status"
msgid "Finished"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:84
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:86
msgctxt "@label:status"
-msgid "Preparing"
+msgid "Preparing..."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:48
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:88
msgctxt "@label:status"
-msgid "Pausing"
+msgid "Aborting..."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:52
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:92
msgctxt "@label:status"
-msgid "Resuming"
+msgid "Pausing..."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:54
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:94
+msgctxt "@label:status"
+msgid "Paused"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:96
+msgctxt "@label:status"
+msgid "Resuming..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:98
msgctxt "@label:status"
msgid "Action required"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:213
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:100
+msgctxt "@label:status"
+msgid "Finishes %1 at %2"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:11
+msgctxt "@title:window"
+msgid "Print over network"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:52
+msgctxt "@action:button"
+msgid "Print"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:80
msgctxt "@label"
-msgid "Waiting for: Unavailable printer"
+msgid "Printer selection"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:215
-msgctxt "@label"
-msgid "Waiting for: First available"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:217
-msgctxt "@label"
-msgid "Waiting for: "
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:299
-msgctxt "@label"
-msgid "Configuration change"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:365
-msgctxt "@label"
-msgid ""
-"The assigned printer, %1, requires the following configuration change(s):"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:367
-msgctxt "@label"
-msgid ""
-"The printer %1 is assigned, but the job contains an unknown material "
-"configuration."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:375
-msgctxt "@label"
-msgid "Change material %1 from %2 to %3."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:378
-msgctxt "@label"
-msgid "Load %3 as material %1 (This cannot be overridden)."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:381
-msgctxt "@label"
-msgid "Change print core %1 from %2 to %3."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:384
-msgctxt "@label"
-msgid "Change build plate to %1 (This cannot be overridden)."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:404
-msgctxt "@label"
-msgid "Override"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:432
-msgctxt "@label"
-msgid ""
-"Starting a print job with an incompatible configuration could damage your 3D "
-"printer. Are you sure you want to override the configuration and print %1?"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:435
-msgctxt "@window:title"
-msgid "Override configuration configuration and start print"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:466
-msgctxt "@label"
-msgid "Glass"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:469
-msgctxt "@label"
-msgid "Aluminum"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:39
-msgctxt "@label link to connect manager"
-msgid "Manage queue"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:60
-msgctxt "@label"
-msgid "Queued"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:36
-msgctxt "@label"
-msgid "Printing"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:49
-msgctxt "@label link to connect manager"
-msgid "Manage printers"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:115
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:54
msgctxt "@label"
msgid "Move to top"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:124
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:70
msgctxt "@label"
msgid "Delete"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:100
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:289
msgctxt "@label"
msgid "Resume"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:102
+msgctxt "@label"
+msgid "Pausing..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:104
+msgctxt "@label"
+msgid "Resuming..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:106
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:284
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:293
msgctxt "@label"
msgid "Pause"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:146
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
+msgctxt "@label"
+msgid "Aborting..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
msgctxt "@label"
msgid "Abort"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:178
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:143
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to move %1 to the top of the queue?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:179
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:144
msgctxt "@window:title"
msgid "Move print job to top"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:188
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:153
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to delete %1?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:189
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:154
msgctxt "@window:title"
msgid "Delete print job"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:198
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:163
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to abort %1?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:199
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:164
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:335
msgctxt "@window:title"
msgid "Abort print"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:43
-msgctxt "@info:tooltip"
-msgid "Connect to a printer"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:20
+msgctxt "@title:window"
+msgid "Configuration Changes"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:121
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:27
msgctxt "@action:button"
-msgid "Activate Configuration"
+msgid "Override"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:122
-msgctxt "@info:tooltip"
-msgid "Load the configuration of the printer into Cura"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:85
+msgctxt "@label"
+msgid "The assigned printer, %1, requires the following configuration change:"
+msgid_plural ""
+"The assigned printer, %1, requires the following configuration changes:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:89
+msgctxt "@label"
+msgid ""
+"The printer %1 is assigned, but the job contains an unknown material "
+"configuration."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:130
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:99
+msgctxt "@label"
+msgid "Change material %1 from %2 to %3."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:102
+msgctxt "@label"
+msgid "Load %3 as material %1 (This cannot be overridden)."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:105
+msgctxt "@label"
+msgid "Change print core %1 from %2 to %3."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:108
+msgctxt "@label"
+msgid "Change build plate to %1 (This cannot be overridden)."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:115
+msgctxt "@label"
+msgid ""
+"Override will use the specified settings with the existing printer "
+"configuration. This may result in a failed print."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:156
+msgctxt "@label"
+msgid "Aluminum"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:100
+msgctxt "@info"
+msgid ""
+"Please make sure your printer has a connection:\n"
+"- Check if the printer is turned on.\n"
+"- Check if the printer is connected to the network.\n"
+"- Check if you are signed in to discover cloud-connected printers."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:117
+msgctxt "@info"
+msgid "Please connect your printer to the network."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:156
+msgctxt "@label link to technical assistance"
+msgid "View user manuals online"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:20
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:49
msgctxt "@label"
msgid "Color scheme"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:145
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:107
msgctxt "@label:listbox"
msgid "Material Color"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:149
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:111
msgctxt "@label:listbox"
msgid "Line Type"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:153
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:115
msgctxt "@label:listbox"
msgid "Feedrate"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:157
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:119
msgctxt "@label:listbox"
msgid "Layer thickness"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:198
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:156
msgctxt "@label"
msgid "Compatibility Mode"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:284
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:230
msgctxt "@label"
-msgid "Show Travels"
+msgid "Travels"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:290
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:236
msgctxt "@label"
-msgid "Show Helpers"
+msgid "Helpers"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:296
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:242
msgctxt "@label"
-msgid "Show Shell"
+msgid "Shell"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:302
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:248
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:65
msgctxt "@label"
-msgid "Show Infill"
+msgid "Infill"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:355
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:298
msgctxt "@label"
msgid "Only Show Top Layers"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:366
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:308
msgctxt "@label"
msgid "Show 5 Detailed Layers On Top"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:379
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:322
msgctxt "@label"
msgid "Top / Bottom"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:383
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:326
msgctxt "@label"
msgid "Inner Wall"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:448
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:384
msgctxt "@label"
msgid "min"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:500
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:433
msgctxt "@label"
msgid "max"
msgstr ""
@@ -2253,41 +2411,41 @@ msgctxt "@label"
msgid "Post Processing Scripts"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:227
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:233
msgctxt "@action"
msgid "Add a script"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:273
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:279
msgctxt "@label"
msgid "Settings"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:477
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:493
msgctxt "@info:tooltip"
msgid "Change active post-processing scripts"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:16
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:17
msgctxt "@title:window"
msgid "More information on anonymous data collection"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:66
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:74
msgctxt "@text:window"
msgid ""
-"Cura sends anonymous data to Ultimaker in order to improve the print quality "
-"and user experience. Below is an example of all the data that is sent."
+"Ultimaker Cura collects anonymous data in order to improve the print quality "
+"and user experience. Below is an example of all the data that is shared:"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:101
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:109
msgctxt "@text:window"
-msgid "I don't want to send these data"
+msgid "I don't want to send anonymous data"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:111
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:118
msgctxt "@text:window"
-msgid "Allow sending these data to Ultimaker and help us improve Cura"
+msgid "Allow sending anonymous data"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:19
@@ -2338,15 +2496,10 @@ msgstr ""
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:126
msgctxt "@info:tooltip"
msgid ""
-"By default, white pixels represent high points on the mesh and black pixels "
-"represent low points on the mesh. Change this option to reverse the behavior "
-"such that black pixels represent high points on the mesh and white pixels "
-"represent low points on the mesh."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
-msgctxt "@item:inlistbox"
-msgid "Lighter is higher"
+"For lithophanes dark pixels should correspond to thicker locations in order "
+"to block more light coming through. For height maps lighter pixels signify "
+"higher terrain, so lighter pixels should correspond to thicker locations in "
+"the generated 3D model."
msgstr ""
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
@@ -2354,6 +2507,11 @@ msgctxt "@item:inlistbox"
msgid "Darker is higher"
msgstr ""
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
+msgctxt "@item:inlistbox"
+msgid "Lighter is higher"
+msgstr ""
+
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:149
msgctxt "@info:tooltip"
msgid "The amount of smoothing to apply to the image."
@@ -2364,81 +2522,80 @@ msgctxt "@action:label"
msgid "Smoothing"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:37
-msgctxt "@label"
-msgid "Mesh Type"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:68
-msgctxt "@label"
-msgid "Normal model"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:75
-msgctxt "@label"
-msgid "Print as support"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:83
-msgctxt "@label"
-msgid "Don't support overlap with other models"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:91
-msgctxt "@label"
-msgid "Modify settings for overlap with other models"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:99
-msgctxt "@label"
-msgid "Modify settings for infill of other models"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:347
-msgctxt "@action:button"
-msgid "Select settings"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:389
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:13
msgctxt "@title:window"
msgid "Select Settings to Customize for this model"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:437
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:98
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:56
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:94
msgctxt "@label:textbox"
msgid "Filter..."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:451
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:70
msgctxt "@label:checkbox"
msgid "Show all"
msgstr ""
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:44
+msgctxt "@label"
+msgid "Mesh Type"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:85
+msgctxt "@label"
+msgid "Normal model"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:97
+msgctxt "@label"
+msgid "Print as support"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:109
+msgctxt "@label"
+msgid "Modify settings for overlaps"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:121
+msgctxt "@label"
+msgid "Don't support overlaps"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:145
+msgctxt "@action:checkbox"
+msgid "Infill only"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:368
+msgctxt "@action:button"
+msgid "Select settings"
+msgstr ""
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:14
msgctxt "@title:window"
msgid "Open Project"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:58
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Update/override existing profile"
msgid "Update existing"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:59
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Save settings in a new profile"
msgid "Create new"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:70
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:73
msgctxt "@action:title"
msgid "Summary - Cura Project"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:92
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:97
msgctxt "@action:label"
msgid "Printer settings"
msgstr ""
@@ -2454,20 +2611,25 @@ msgctxt "@action:ComboBox option"
msgid "Update"
msgstr ""
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
+msgctxt "@action:ComboBox option"
+msgid "Create new"
+msgstr ""
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:143
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:105
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:106
msgctxt "@action:label"
msgid "Type"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:159
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
msgctxt "@action:label"
msgid "Printer Group"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:180
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:196
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:220
msgctxt "@action:label"
msgid "Profile settings"
msgstr ""
@@ -2478,104 +2640,199 @@ msgid "How should the conflict in the profile be resolved?"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:216
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:220
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:323
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:244
msgctxt "@action:label"
msgid "Name"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:231
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:204
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:261
+msgctxt "@action:label"
+msgid "Intent"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:246
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:228
msgctxt "@action:label"
msgid "Not in profile"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:236
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:209
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:251
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:233
msgctxt "@action:label"
msgid "%1 override"
msgid_plural "%1 overrides"
msgstr[0] ""
msgstr[1] ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:247
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:262
msgctxt "@action:label"
msgid "Derivative from"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:252
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:267
msgctxt "@action:label"
msgid "%1, %2 override"
msgid_plural "%1, %2 overrides"
msgstr[0] ""
msgstr[1] ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:268
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:283
msgctxt "@action:label"
msgid "Material settings"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:284
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:299
msgctxt "@info:tooltip"
msgid "How should the conflict in the material be resolved?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:327
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:237
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:342
msgctxt "@action:label"
msgid "Setting visibility"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:336
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:351
msgctxt "@action:label"
msgid "Mode"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:352
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:246
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:367
msgctxt "@action:label"
msgid "Visible settings:"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:357
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:251
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:372
msgctxt "@action:label"
msgid "%1 out of %2"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:383
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:398
msgctxt "@action:warning"
msgid "Loading a project will clear all models on the build plate."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:401
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:416
msgctxt "@action:button"
msgid "Open"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:26
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:25
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:28
msgctxt "@title"
-msgid "Select Printer Upgrades"
+msgid "My Backups"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:38
-msgctxt "@label"
-msgid "Please select any upgrades made to this Ultimaker 2."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:38
+msgctxt "@empty_state"
+msgid ""
+"You don't have any backups currently. Use the 'Backup Now' button to create "
+"one."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:47
-msgctxt "@label"
-msgid "Olsson Block"
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:60
+msgctxt "@backup_limit_info"
+msgid ""
+"During the preview phase, you'll be limited to 5 visible backups. Remove a "
+"backup to see older ones."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:27
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:34
+msgctxt "@description"
+msgid "Backup and synchronize your Cura settings."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:51
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:68
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:138
+msgctxt "@button"
+msgid "Sign in"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/main.qml:24
+msgctxt "@title:window"
+msgid "Cura Backups"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:21
+msgctxt "@backuplist:label"
+msgid "Cura Version"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:29
+msgctxt "@backuplist:label"
+msgid "Machines"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:37
+msgctxt "@backuplist:label"
+msgid "Materials"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:45
+msgctxt "@backuplist:label"
+msgid "Profiles"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:53
+msgctxt "@backuplist:label"
+msgid "Plugins"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:71
+msgctxt "@button"
+msgid "Restore"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:99
+msgctxt "@dialog:title"
+msgid "Delete Backup"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:100
+msgctxt "@dialog:info"
+msgid "Are you sure you want to delete this backup? This cannot be undone."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:108
+msgctxt "@dialog:title"
+msgid "Restore Backup"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:109
+msgctxt "@dialog:info"
+msgid ""
+"You will need to restart Cura before your backup is restored. Do you want to "
+"close Cura now?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:22
+msgctxt "@button"
+msgid "Want more?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:31
+msgctxt "@button"
+msgid "Backup Now"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:43
+msgctxt "@checkbox:description"
+msgid "Auto Backup"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:44
+msgctxt "@checkbox:description"
+msgid "Automatically create a backup each day that Cura is started."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:30
msgctxt "@title"
msgid "Build Plate Leveling"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:38
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:44
msgctxt "@label"
msgid ""
"To make sure your prints will come out great, you can now adjust your "
@@ -2583,7 +2840,7 @@ msgid ""
"the different positions that can be adjusted."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:47
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:57
msgctxt "@label"
msgid ""
"For every position; insert a piece of paper under the nozzle and adjust the "
@@ -2591,121 +2848,26 @@ msgid ""
"paper is slightly gripped by the tip of the nozzle."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:62
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:75
msgctxt "@action:button"
msgid "Start Build Plate Leveling"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:74
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:87
msgctxt "@action:button"
msgid "Move to Next Position"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:37
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:30
msgctxt "@label"
msgid "Please select any upgrades made to this Ultimaker Original"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:45
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:41
msgctxt "@label"
msgid "Heated Build Plate (official kit or self-built)"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:27
-msgctxt "@title"
-msgid "Check Printer"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:39
-msgctxt "@label"
-msgid ""
-"It's a good idea to do a few sanity checks on your Ultimaker. You can skip "
-"this step if you know your machine is functional"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:53
-msgctxt "@action:button"
-msgid "Start Printer Check"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:80
-msgctxt "@label"
-msgid "Connection: "
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Connected"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Not connected"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:99
-msgctxt "@label"
-msgid "Min endstop X: "
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-msgctxt "@info:status"
-msgid "Works"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:173
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Not checked"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:120
-msgctxt "@label"
-msgid "Min endstop Y: "
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:141
-msgctxt "@label"
-msgid "Min endstop Z: "
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:163
-msgctxt "@label"
-msgid "Nozzle temperature check: "
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Stop Heating"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Start Heating"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:223
-msgctxt "@label"
-msgid "Build plate temperature check:"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Checked"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:284
-msgctxt "@label"
-msgid "Everything is in order! You're done with your CheckUp."
-msgstr ""
-
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:119
msgctxt "@label:MonitorStatus"
msgid "Not connected to a printer"
@@ -2717,7 +2879,6 @@ msgid "Printer does not accept commands"
msgstr ""
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:133
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:197
msgctxt "@label:MonitorStatus"
msgid "In maintenance. Please check the printer"
msgstr ""
@@ -2728,19 +2889,16 @@ msgid "Lost connection with the printer"
msgstr ""
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:146
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:187
msgctxt "@label:MonitorStatus"
msgid "Printing..."
msgstr ""
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:149
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:189
msgctxt "@label:MonitorStatus"
msgid "Paused"
msgstr ""
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:152
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:191
msgctxt "@label:MonitorStatus"
msgid "Preparing..."
msgstr ""
@@ -2760,237 +2918,180 @@ msgctxt "@label"
msgid "Are you sure you want to abort the print?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:15
-msgctxt "@title:window"
-msgid "Discard or Keep changes"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:57
-msgctxt "@text:window"
-msgid ""
-"You have customized some profile settings.\n"
-"Would you like to keep or discard those settings?"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:110
-msgctxt "@title:column"
-msgid "Profile settings"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:117
-msgctxt "@title:column"
-msgid "Default"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:124
-msgctxt "@title:column"
-msgid "Customized"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:157
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:637
-msgctxt "@option:discardOrKeep"
-msgid "Always ask me this"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:158
-msgctxt "@option:discardOrKeep"
-msgid "Discard and never ask again"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:159
-msgctxt "@option:discardOrKeep"
-msgid "Keep and never ask again"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:196
-msgctxt "@action:button"
-msgid "Discard"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:209
-msgctxt "@action:button"
-msgid "Keep"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:222
-msgctxt "@action:button"
-msgid "Create New Profile"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:71
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:72
msgctxt "@title"
msgid "Information"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:100
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
msgctxt "@title:window"
msgid "Confirm Diameter Change"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:102
msgctxt "@label (%1 is a number)"
msgid ""
"The new filament diameter is set to %1 mm, which is not compatible with the "
"current extruder. Do you wish to continue?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:128
msgctxt "@label"
msgid "Display Name"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:143
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:138
msgctxt "@label"
msgid "Brand"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:148
msgctxt "@label"
msgid "Material Type"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:158
msgctxt "@label"
msgid "Color"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:212
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:208
msgctxt "@label"
msgid "Properties"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:214
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:210
msgctxt "@label"
msgid "Density"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:229
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:225
msgctxt "@label"
msgid "Diameter"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:263
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:259
msgctxt "@label"
msgid "Filament Cost"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:280
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:276
msgctxt "@label"
msgid "Filament weight"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:298
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:294
msgctxt "@label"
msgid "Filament length"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:307
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:303
msgctxt "@label"
msgid "Cost per Meter"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:321
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:317
msgctxt "@label"
msgid "This material is linked to %1 and shares some of its properties."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:328
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:324
msgctxt "@label"
msgid "Unlink Material"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:335
msgctxt "@label"
msgid "Description"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:352
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:348
msgctxt "@label"
msgid "Adhesion Information"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:378
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:19
msgctxt "@label"
msgid "Print settings"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:84
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:35
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:108
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:40
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:84
msgctxt "@action:button"
msgid "Activate"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:126
msgctxt "@action:button"
msgid "Create"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:140
msgctxt "@action:button"
msgid "Duplicate"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:141
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:170
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:167
msgctxt "@action:button"
msgid "Import"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:154
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:184
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:179
msgctxt "@action:button"
msgid "Export"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:233
msgctxt "@action:label"
msgid "Printer"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:262
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:274
msgctxt "@title:window"
msgid "Confirm Remove"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:263
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:240
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:300
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:275
msgctxt "@label (%1 is object name)"
msgid "Are you sure you wish to remove %1? This cannot be undone!"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:277
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:285
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:314
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:322
msgctxt "@title:window"
msgid "Import Material"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:286
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:323
msgctxt "@info:status Don't translate the XML tags or !"
msgid ""
"Could not import material %1: %2"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:290
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:327
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully imported material %1"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:316
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:345
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:353
msgctxt "@title:window"
msgid "Export Material"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:320
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:357
msgctxt "@info:status Don't translate the XML tags and !"
msgid ""
"Failed to export material to %1: %2"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:326
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:363
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully exported material to %1"
msgstr ""
@@ -3000,253 +3101,287 @@ msgctxt "@title:tab"
msgid "Setting Visibility"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:46
msgctxt "@label:textbox"
msgid "Check all"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:47
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:61
msgctxt "@info:status"
msgid "Calculated"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:60
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:75
msgctxt "@title:column"
msgid "Setting"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
msgctxt "@title:column"
msgid "Profile"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:74
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:89
msgctxt "@title:column"
msgid "Current"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:97
msgctxt "@title:column"
msgid "Unit"
msgstr ""
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:15
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:410
msgctxt "@title:tab"
msgid "General"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:132
msgctxt "@label"
msgid "Interface"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:143
msgctxt "@label"
msgid "Language:"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:221
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:210
msgctxt "@label"
msgid "Currency:"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:235
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:223
msgctxt "@label"
msgid "Theme:"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:292
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:279
msgctxt "@label"
msgid ""
"You will need to restart the application for these changes to have effect."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:309
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:296
msgctxt "@info:tooltip"
msgid "Slice automatically when changing settings."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:317
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:304
msgctxt "@option:check"
msgid "Slice automatically"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:318
msgctxt "@label"
msgid "Viewport behavior"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:326
msgctxt "@info:tooltip"
msgid ""
"Highlight unsupported areas of the model in red. Without support these areas "
"will not print properly."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:335
msgctxt "@option:check"
msgid "Display overhang"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:355
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:343
msgctxt "@info:tooltip"
msgid ""
"Moves the camera so the model is in the center of the view when a model is "
"selected"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
msgctxt "@action:button"
msgid "Center camera when item is selected"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:369
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:358
msgctxt "@info:tooltip"
msgid "Should the default zoom behavior of cura be inverted?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:363
msgctxt "@action:button"
msgid "Invert the direction of camera zoom."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
msgctxt "@info:tooltip"
msgid "Should zooming move in the direction of the mouse?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:389
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
+msgctxt "@info:tooltip"
+msgid ""
+"Zooming towards the mouse is not supported in the orthographic perspective."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
msgctxt "@action:button"
msgid "Zoom toward mouse direction"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:399
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:410
msgctxt "@info:tooltip"
msgid ""
"Should models on the platform be moved so that they no longer intersect?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:404
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:415
msgctxt "@option:check"
msgid "Ensure models are kept apart"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:413
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:424
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved down to touch the build plate?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:418
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:429
msgctxt "@option:check"
msgid "Automatically drop models to the build plate"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:430
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:441
msgctxt "@info:tooltip"
msgid "Show caution message in g-code reader."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:439
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:450
msgctxt "@option:check"
msgid "Caution message in g-code reader"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:447
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:458
msgctxt "@info:tooltip"
msgid "Should layer be forced into compatibility mode?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:452
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:463
msgctxt "@option:check"
msgid "Force layer view compatibility mode (restart required)"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:468
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:473
+msgctxt "@info:tooltip"
+msgid "Should Cura open at the location it was closed?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:478
+msgctxt "@option:check"
+msgid "Restore window position on start"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:488
+msgctxt "@info:tooltip"
+msgid "What type of camera rendering should be used?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+msgctxt "@window:text"
+msgid "Camera rendering:"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:506
+msgid "Perspective"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:507
+msgid "Orthographic"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:538
msgctxt "@label"
msgid "Opening and saving files"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:475
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:545
msgctxt "@info:tooltip"
msgid "Should models be scaled to the build volume if they are too large?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:550
msgctxt "@option:check"
msgid "Scale large models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:490
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:560
msgctxt "@info:tooltip"
msgid ""
"An model may appear extremely small if its unit is for example in meters "
"rather than millimeters. Should these models be scaled up?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:565
msgctxt "@option:check"
msgid "Scale extremely small models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:505
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:575
msgctxt "@info:tooltip"
msgid "Should models be selected after they are loaded?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:510
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:580
msgctxt "@option:check"
msgid "Select models when loaded"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:520
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:590
msgctxt "@info:tooltip"
msgid ""
"Should a prefix based on the printer name be added to the print job name "
"automatically?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:525
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:595
msgctxt "@option:check"
msgid "Add machine prefix to job name"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:535
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:605
msgctxt "@info:tooltip"
msgid "Should a summary be shown when saving a project file?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
msgctxt "@option:check"
msgid "Show summary dialog when saving project"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:619
msgctxt "@info:tooltip"
msgid "Default behavior when opening a project file"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:557
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:627
msgctxt "@window:text"
msgid "Default behavior when opening a project file: "
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:571
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:641
msgctxt "@option:openProject"
msgid "Always ask me this"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:572
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:642
msgctxt "@option:openProject"
msgid "Always open as a project"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:573
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:643
msgctxt "@option:openProject"
msgid "Always import models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:679
msgctxt "@info:tooltip"
msgid ""
"When you have made changes to a profile and switched to a different one, a "
@@ -3254,44 +3389,51 @@ msgid ""
"not, or you can choose a default behaviour and never show that dialog again."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:618
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:688
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:52
msgctxt "@label"
msgid "Profiles"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:623
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:693
msgctxt "@window:text"
msgid ""
"Default behavior for changed setting values when switching to a different "
"profile: "
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:638
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:707
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:157
+msgctxt "@option:discardOrKeep"
+msgid "Always ask me this"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:708
msgctxt "@option:discardOrKeep"
msgid "Always discard changed settings"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:639
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:709
msgctxt "@option:discardOrKeep"
msgid "Always transfer changed settings to new profile"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:673
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:743
msgctxt "@label"
msgid "Privacy"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:681
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:750
msgctxt "@info:tooltip"
msgid "Should Cura check for updates when the program is started?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:686
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:755
msgctxt "@option:check"
msgid "Check for updates on start"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:697
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:765
msgctxt "@info:tooltip"
msgid ""
"Should anonymous data about your print be sent to Ultimaker? Note, no "
@@ -3299,386 +3441,204 @@ msgid ""
"stored."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:702
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:770
msgctxt "@option:check"
msgid "Send (anonymous) print information"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:711
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:779
msgctxt "@action:button"
msgid "More information"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:729
-msgctxt "@label"
-msgid "Experimental"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:736
-msgctxt "@info:tooltip"
-msgid "Use multi build plate functionality"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:741
-msgctxt "@option:check"
-msgid "Use multi build plate functionality (restart required)"
-msgstr ""
-
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:16
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:415
msgctxt "@title:tab"
msgid "Printers"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:63
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
msgctxt "@action:button"
msgid "Rename"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:147
-msgctxt "@label"
-msgid "Printer type:"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:156
-msgctxt "@label"
-msgid "Connection:"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:162
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
-msgctxt "@info:status"
-msgid "The printer is not connected."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:168
-msgctxt "@label"
-msgid "State:"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:181
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for a printjob"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:193
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for someone to clear the build plate"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:199
-msgctxt "@label:MonitorStatus"
-msgid "Aborting print..."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:553
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:34
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:419
msgctxt "@title:tab"
msgid "Profiles"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:104
msgctxt "@label"
msgid "Create"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:102
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:121
msgctxt "@label"
msgid "Duplicate"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:174
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:202
msgctxt "@title:window"
msgid "Create Profile"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:204
+msgctxt "@info"
+msgid "Please provide a name for this profile."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:260
msgctxt "@title:window"
msgid "Duplicate Profile"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:256
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:291
msgctxt "@title:window"
msgid "Rename Profile"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:304
msgctxt "@title:window"
msgid "Import Profile"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:333
msgctxt "@title:window"
msgid "Export Profile"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:350
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:396
msgctxt "@label %1 is printer name"
msgid "Printer: %1"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Protected profiles"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Custom profiles"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:554
msgctxt "@action:button"
msgid "Update profile with current settings/overrides"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:487
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:561
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:257
msgctxt "@action:button"
msgid "Discard current changes"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:504
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:580
msgctxt "@action:label"
msgid ""
"This profile uses the defaults specified by the printer, so it has no "
"settings/overrides in the list below."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:511
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:588
msgctxt "@action:label"
msgid "Your current settings match the selected profile."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:530
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:606
msgctxt "@title:tab"
msgid "Global Settings"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:18
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:953
-msgctxt "@title:window"
-msgid "Add Printer"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:195
-msgctxt "@label"
-msgid "Printer Name:"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:219
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/MainWindowHeader.qml:90
msgctxt "@action:button"
-msgid "Add Printer"
+msgid "Marketplace"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:84
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:27
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&File"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:31
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Edit"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:48
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
+msgctxt "@title:menu menubar:toplevel"
+msgid "&View"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Settings"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:55
+msgctxt "@title:menu menubar:toplevel"
+msgid "E&xtensions"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:89
+msgctxt "@title:menu menubar:toplevel"
+msgid "P&references"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:97
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Help"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:124
+msgctxt "@title:window"
+msgid "New project"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:125
+msgctxt "@info:question"
+msgid ""
+"Are you sure you want to start a new project? This will clear the build "
+"plate and any unsaved settings."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:88
msgctxt "@text Print job name"
msgid "Untitled"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:15
-msgctxt "@title:window"
-msgid "About Cura"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:55
-msgctxt "@label"
-msgid "version: %1"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:69
-msgctxt "@label"
-msgid "End-to-end solution for fused filament 3D printing."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:82
-msgctxt "@info:credit"
-msgid ""
-"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
-"Cura proudly uses the following open source projects:"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:132
-msgctxt "@label"
-msgid "Graphical user interface"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:133
-msgctxt "@label"
-msgid "Application framework"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:134
-msgctxt "@label"
-msgid "G-code generator"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:135
-msgctxt "@label"
-msgid "Interprocess communication library"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:137
-msgctxt "@label"
-msgid "Programming language"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:138
-msgctxt "@label"
-msgid "GUI framework"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139
-msgctxt "@label"
-msgid "GUI framework bindings"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:140
-msgctxt "@label"
-msgid "C/C++ Binding library"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:141
-msgctxt "@label"
-msgid "Data interchange format"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:142
-msgctxt "@label"
-msgid "Support library for scientific computing"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:143
-msgctxt "@label"
-msgid "Support library for faster math"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:144
-msgctxt "@label"
-msgid "Support library for handling STL files"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:145
-msgctxt "@label"
-msgid "Support library for handling planar objects"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:146
-msgctxt "@label"
-msgid "Support library for handling triangular meshes"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:147
-msgctxt "@label"
-msgid "Support library for analysis of complex networks"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:148
-msgctxt "@label"
-msgid "Support library for handling 3MF files"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:149
-msgctxt "@label"
-msgid "Support library for file metadata and streaming"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:150
-msgctxt "@label"
-msgid "Serial communication library"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:151
-msgctxt "@label"
-msgid "ZeroConf discovery library"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:152
-msgctxt "@label"
-msgid "Polygon clipping library"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:153
-msgctxt "@Label"
-msgid "Python HTTP library"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:155
-msgctxt "@label"
-msgid "Font"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:156
-msgctxt "@label"
-msgid "SVG icons"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:157
-msgctxt "@label"
-msgid "Linux cross-distribution application deployment"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:42
-msgctxt "@label"
-msgid "Profile:"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:104
-msgctxt "@tooltip"
-msgid ""
-"Some setting/override values are different from the values stored in the "
-"profile.\n"
-"\n"
-"Click to open the profile manager."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:200
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:68
msgctxt "@label:textbox"
-msgid "Search..."
+msgid "Search settings"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:545
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:462
msgctxt "@action:menu"
msgid "Copy value to all extruders"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:554
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:471
msgctxt "@action:menu"
msgid "Copy all changed values to all extruders"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:591
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:508
msgctxt "@action:menu"
msgid "Hide this setting"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:521
msgctxt "@action:menu"
msgid "Don't show this setting"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:613
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:525
msgctxt "@action:menu"
msgid "Keep this setting visible"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:637
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:417
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:434
msgctxt "@action:menu"
msgid "Configure setting visibility..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:644
-msgctxt "@action:inmenu"
-msgid "Collapse All"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:649
-msgctxt "@action:inmenu"
-msgid "Expand All"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:253
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:237
msgctxt "@label"
msgid ""
"Some hidden settings use values different from their normal calculated "
@@ -3687,29 +3647,36 @@ msgid ""
"Click to make these settings visible."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:81
+msgctxt "@label"
+msgid ""
+"This setting is not used because all the settings that it influences are "
+"overridden."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:86
msgctxt "@label Header for list of settings."
msgid "Affects"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:91
msgctxt "@label Header for list of settings."
msgid "Affected By"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:187
msgctxt "@label"
msgid ""
"This setting is always shared between all extruders. Changing it here will "
"change the value for all extruders."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:158
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:191
msgctxt "@label"
msgid "The value is resolved from per-extruder values "
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:189
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:230
msgctxt "@label"
msgid ""
"This setting has a value that is different from the profile.\n"
@@ -3717,7 +3684,7 @@ msgid ""
"Click to restore the value of the profile."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:281
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:329
msgctxt "@label"
msgid ""
"This setting is normally calculated, but it currently has an absolute value "
@@ -3726,79 +3693,182 @@ msgid ""
"Click to restore the calculated value."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/NoIntentIcon.qml:31
+msgctxt ""
+"@label %1 is filled in with the type of a profile. %2 is filled with a list "
+"of numbers (eg '1' or '1, 2')"
+msgid ""
+"There is no %1 profile for the configuration in extruder %2. The default "
+"intent will be used instead"
+msgid_plural ""
+"There is no %1 profile for the configurations in extruders %2. The default "
+"intent will be used instead"
+msgstr[0] ""
+msgstr[1] ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:144
+msgctxt "@button"
+msgid "Recommended"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:158
+msgctxt "@button"
+msgid "Custom"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:193
+msgctxt "@label"
+msgid "Gradual infill"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:232
+msgctxt "@label"
+msgid ""
+"Gradual infill will gradually increase the amount of infill towards the top."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:30
+msgctxt "@label"
+msgid "Support"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:71
+msgctxt "@label"
+msgid ""
+"Generate structures to support parts of the model which have overhangs. "
+"Without these structures, such parts would collapse during printing."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:29
+msgctxt "@label"
+msgid "Adhesion"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:74
+msgctxt "@label"
+msgid ""
+"Enable printing a brim or raft. This will add a flat area around or under "
+"your object which is easy to cut off afterwards."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:81
+msgctxt "@tooltip"
+msgid ""
+"You have modified some profile settings. If you want to change these go to "
+"custom mode."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:13
+msgctxt "@label:Should be short"
+msgid "On"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:14
+msgctxt "@label:Should be short"
+msgid "Off"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:33
+msgctxt "@label"
+msgid "Experimental"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:47
+msgctxt "@label"
+msgid "Profile"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:172
+msgctxt "@tooltip"
+msgid ""
+"Some setting/override values are different from the values stored in the "
+"profile.\n"
+"\n"
+"Click to open the profile manager."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:160
+msgctxt "@label:header"
+msgid "Custom profiles"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:21
+msgctxt "@label shown when we load a Gcode file"
+msgid "Print setup disabled. G-code file can not be modified."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:52
msgctxt "@label"
msgid "Printer control"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:144
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:67
msgctxt "@label"
msgid "Jog Position"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:85
msgctxt "@label"
msgid "X/Y"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:192
msgctxt "@label"
msgid "Z"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:257
msgctxt "@label"
msgid "Jog Distance"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:443
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:301
msgctxt "@label"
msgid "Send G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:506
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:365
msgctxt "@tooltip of G-code command input"
msgid ""
"Send a custom G-code command to the connected printer. Press 'enter' to send "
"the command."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:272
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:41
msgctxt "@label"
msgid "Extruder"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:71
msgctxt "@tooltip"
msgid ""
"The target temperature of the hotend. The hotend will heat up or cool down "
"towards this temperature. If this is 0, the hotend heating is turned off."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:98
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:103
msgctxt "@tooltip"
msgid "The current temperature of this hotend."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:172
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:177
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the hotend to."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:336
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:341
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:332
msgctxt "@button Cancel pre-heating"
msgid "Cancel"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:339
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:344
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:335
msgctxt "@button"
msgid "Pre-heat"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:365
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:370
msgctxt "@tooltip of pre-heat"
msgid ""
"Heat the hotend in advance before printing. You can continue adjusting your "
@@ -3806,45 +3876,49 @@ msgid ""
"up when you're ready to print."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:401
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:406
msgctxt "@tooltip"
msgid "The colour of the material in this extruder."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:433
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:438
msgctxt "@tooltip"
msgid "The material in this extruder."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:465
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:470
msgctxt "@tooltip"
msgid "The nozzle inserted in this extruder."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:25
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:493
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
+msgctxt "@info:status"
+msgid "The printer is not connected."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:26
msgctxt "@label"
msgid "Build plate"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:56
msgctxt "@tooltip"
msgid ""
"The target temperature of the heated bed. The bed will heat up or cool down "
"towards this temperature. If this is 0, the bed heating is turned off."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:88
msgctxt "@tooltip"
msgid "The current temperature of the heated bed."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:160
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:161
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the bed to."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:361
msgctxt "@tooltip of pre-heat"
msgid ""
"Heat the bed in advance before printing. You can continue adjusting your "
@@ -3857,12 +3931,12 @@ msgctxt "@label:category menu label"
msgid "Material"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:37
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:46
msgctxt "@label:category menu label"
msgid "Favorites"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:71
msgctxt "@label:category menu label"
msgid "Generic"
msgstr ""
@@ -3877,17 +3951,52 @@ msgctxt "@label:category menu label"
msgid "Local printers"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
-msgctxt "@title:menu menubar:toplevel"
-msgid "&View"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:15
+msgctxt "@title:menu menubar:settings"
+msgid "&Printer"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:42
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:27
+msgctxt "@title:menu"
+msgid "&Material"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:36
+msgctxt "@action:inmenu"
+msgid "Set as Active Extruder"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:42
+msgctxt "@action:inmenu"
+msgid "Enable Extruder"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:49
+msgctxt "@action:inmenu"
+msgid "Disable Extruder"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:19
msgctxt "@action:inmenu menubar:view"
msgid "&Camera position"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:58
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:44
+msgctxt "@action:inmenu menubar:view"
+msgid "Camera view"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:47
+msgctxt "@action:inmenu menubar:view"
+msgid "Perspective"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:59
+msgctxt "@action:inmenu menubar:view"
+msgid "Orthographic"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:80
msgctxt "@action:inmenu menubar:view"
msgid "&Build plate"
msgstr ""
@@ -3907,6 +4016,21 @@ msgctxt "@action:inmenu"
msgid "Manage Setting Visibility..."
msgstr ""
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:33
+msgctxt "@title:menu menubar:file"
+msgid "&Save..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:54
+msgctxt "@title:menu menubar:file"
+msgid "&Export..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:65
+msgctxt "@action:inmenu menubar:file"
+msgid "Export Selection..."
+msgstr ""
+
#: /home/ruben/Projects/Cura/resources/qml/Menus/ContextMenu.qml:27
msgctxt "@label"
msgid "Print Selected Model With:"
@@ -3926,550 +4050,496 @@ msgctxt "@label"
msgid "Number of Copies"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:33
-msgctxt "@label:header configurations"
-msgid "Available configurations"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml:18
+msgctxt "@header"
+msgid "Configurations"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml:28
-msgctxt "@label:extruder label"
-msgid "Extruder"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:112
+msgctxt "@label"
+msgid "Select configuration"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "Yes"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:223
+msgctxt "@label"
+msgid "Configurations"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "No"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:57
+msgctxt "@label"
+msgid "Loading available configurations from the printer..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:13
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:58
+msgctxt "@label"
+msgid ""
+"The configurations are not available because the printer is disconnected."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:25
+msgctxt "@header"
+msgid "Custom"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:61
+msgctxt "@label"
+msgid "Printer"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:213
+msgctxt "@label"
+msgid "Enabled"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:251
+msgctxt "@label"
+msgid "Material"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:378
+msgctxt "@label"
+msgid "Use glue for better adhesion with this material combination."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:128
+msgctxt "@label"
+msgid ""
+"This configuration is not available because %1 is not recognized. Please "
+"visit %2 to download the correct material profile."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:129
+msgctxt "@label"
+msgid "Marketplace"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:15
msgctxt "@title:menu menubar:file"
msgid "Open &Recent"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid "Print Setup"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid ""
-"Print Setup disabled\n"
-"G-code files cannot be modified"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:340
-msgctxt "@label Hours and minutes"
-msgid "00h 00min"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:358
-msgctxt "@tooltip"
-msgid "Time specification"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:440
-msgctxt "@label"
-msgid "Cost specification"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:445
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:454
-msgctxt "@label m for meter"
-msgid "%1m"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:446
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:455
-msgctxt "@label g for grams"
-msgid "%1g"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:453
-msgctxt "@label"
-msgid "Total:"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:576
-msgctxt "@tooltip"
-msgid ""
-"Recommended Print Setup
Print with the recommended settings "
-"for the selected printer, material and quality."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:581
-msgctxt "@tooltip"
-msgid ""
-"Custom Print Setup
Print with finegrained control over every "
-"last bit of the slicing process."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:140
msgctxt "@label"
msgid "Active print"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:148
msgctxt "@label"
msgid "Job Name"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:156
msgctxt "@label"
msgid "Printing Time"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:130
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:164
msgctxt "@label"
msgid "Estimated time left"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:79
+#: /home/ruben/Projects/Cura/resources/qml/ViewsSelector.qml:50
+msgctxt "@label"
+msgid "View type"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ObjectSelector.qml:59
+msgctxt "@label"
+msgid "Object list"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:22
+msgctxt "@label The argument is a username."
+msgid "Hi %1"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:33
+msgctxt "@button"
+msgid "Ultimaker account"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:42
+msgctxt "@button"
+msgid "Sign out"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/AccountWidget.qml:24
+msgctxt "@action:button"
+msgid "Sign in"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:40
+msgctxt "@label"
+msgid "The next generation 3D printing workflow"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:51
+msgctxt "@text"
+msgid ""
+"- Send print jobs to Ultimaker printers outside your local network\n"
+"- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+"- Get exclusive access to print profiles from leading brands"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:78
+msgctxt "@button"
+msgid "Create account"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:59
+msgctxt "@label"
+msgid "No time estimation available"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:77
+msgctxt "@label"
+msgid "No cost estimation available"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:127
+msgctxt "@button"
+msgid "Preview"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:55
+msgctxt "@label:PrintjobStatus"
+msgid "Slicing..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:67
+msgctxt "@label:PrintjobStatus"
+msgid "Unable to slice"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Processing"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Slice"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:104
+msgctxt "@label"
+msgid "Start the slicing process"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:118
+msgctxt "@button"
+msgid "Cancel"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:31
+msgctxt "@label"
+msgid "Time estimation"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:114
+msgctxt "@label"
+msgid "Material estimation"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:164
+msgctxt "@label m for meter"
+msgid "%1m"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:165
+msgctxt "@label g for grams"
+msgid "%1g"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Connected printers"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Preset printers"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:166
+msgctxt "@button"
+msgid "Add printer"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:182
+msgctxt "@button"
+msgid "Manage printers"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:81
+msgctxt "@action:inmenu"
+msgid "Show Online Troubleshooting Guide"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:88
msgctxt "@action:inmenu"
msgid "Toggle Full Screen"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:86
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+msgctxt "@action:inmenu"
+msgid "Exit Full Screen"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:103
msgctxt "@action:inmenu menubar:edit"
msgid "&Undo"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
msgctxt "@action:inmenu menubar:edit"
msgid "&Redo"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:123
msgctxt "@action:inmenu menubar:file"
msgid "&Quit"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:131
msgctxt "@action:inmenu menubar:view"
msgid "3D View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:138
msgctxt "@action:inmenu menubar:view"
msgid "Front View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:128
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:145
msgctxt "@action:inmenu menubar:view"
msgid "Top View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:135
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:152
msgctxt "@action:inmenu menubar:view"
msgid "Left Side View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:159
msgctxt "@action:inmenu menubar:view"
msgid "Right Side View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:149
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:166
msgctxt "@action:inmenu"
msgid "Configure Cura..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:156
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:173
msgctxt "@action:inmenu menubar:printer"
msgid "&Add Printer..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:179
msgctxt "@action:inmenu menubar:printer"
msgid "Manage Pr&inters..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:169
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:186
msgctxt "@action:inmenu"
msgid "Manage Materials..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:177
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:195
msgctxt "@action:inmenu menubar:profile"
msgid "&Update profile with current settings/overrides"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:185
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
msgctxt "@action:inmenu menubar:profile"
msgid "&Discard current changes"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:197
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:215
msgctxt "@action:inmenu menubar:profile"
msgid "&Create profile from current settings/overrides..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:221
msgctxt "@action:inmenu menubar:profile"
msgid "Manage Profiles..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:210
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:229
msgctxt "@action:inmenu menubar:help"
msgid "Show Online &Documentation"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:218
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:237
msgctxt "@action:inmenu menubar:help"
msgid "Report a &Bug"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:226
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:245
+msgctxt "@action:inmenu menubar:help"
+msgid "What's New"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:251
msgctxt "@action:inmenu menubar:help"
msgid "About..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:233
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:258
msgctxt "@action:inmenu menubar:edit"
msgid "Delete Selected Model"
msgid_plural "Delete Selected Models"
msgstr[0] ""
msgstr[1] ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:243
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:268
msgctxt "@action:inmenu menubar:edit"
msgid "Center Selected Model"
msgid_plural "Center Selected Models"
msgstr[0] ""
msgstr[1] ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:277
msgctxt "@action:inmenu menubar:edit"
msgid "Multiply Selected Model"
msgid_plural "Multiply Selected Models"
msgstr[0] ""
msgstr[1] ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:261
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:286
msgctxt "@action:inmenu"
msgid "Delete Model"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:294
msgctxt "@action:inmenu"
msgid "Ce&nter Model on Platform"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:275
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:300
msgctxt "@action:inmenu menubar:edit"
msgid "&Group Models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:320
msgctxt "@action:inmenu menubar:edit"
msgid "Ungroup Models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:305
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:330
msgctxt "@action:inmenu menubar:edit"
msgid "&Merge Models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:315
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:340
msgctxt "@action:inmenu"
msgid "&Multiply Model..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:322
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:347
msgctxt "@action:inmenu menubar:edit"
msgid "Select All Models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:332
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:357
msgctxt "@action:inmenu menubar:edit"
msgid "Clear Build Plate"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:342
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:367
msgctxt "@action:inmenu menubar:file"
msgid "Reload All Models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:376
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models To All Build Plates"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:358
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:383
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:366
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:391
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange Selection"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:373
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:398
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Positions"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:380
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:405
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Transformations"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:387
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:412
msgctxt "@action:inmenu menubar:file"
msgid "&Open File(s)..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:395
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:420
msgctxt "@action:inmenu menubar:file"
msgid "&New Project..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:402
-msgctxt "@action:inmenu menubar:help"
-msgid "Show Engine &Log..."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:410
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:427
msgctxt "@action:inmenu menubar:help"
msgid "Show Configuration Folder"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:424
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:441
msgctxt "@action:menu"
-msgid "Browse packages..."
+msgid "&Marketplace"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:431
-msgctxt "@action:inmenu menubar:view"
-msgid "Expand/Collapse Sidebar"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:27
-msgctxt "@label:PrintjobStatus"
-msgid "Please load a 3D model"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:37
-msgctxt "@label:PrintjobStatus"
-msgid "Ready to slice"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:39
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing..."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:41
-msgctxt "@label:PrintjobStatus %1 is target operation"
-msgid "Ready to %1"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:43
-msgctxt "@label:PrintjobStatus"
-msgid "Unable to Slice"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:45
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing unavailable"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Slice current printjob"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Cancel slicing process"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Prepare"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Cancel"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:320
-msgctxt "@info:tooltip"
-msgid "Select the active output device"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:19
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:767
-msgctxt "@title:window"
-msgid "Open file(s)"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:64
-msgctxt "@text:window"
-msgid ""
-"We have found one or more project file(s) within the files you have "
-"selected. You can open only one project file at a time. We suggest to only "
-"import models from those files. Would you like to proceed?"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:99
-msgctxt "@action:button"
-msgid "Import all as models"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:19
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:24
msgctxt "@title:window"
msgid "Ultimaker Cura"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:103
-msgctxt "@title:menu menubar:toplevel"
-msgid "&File"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:121
-msgctxt "@title:menu menubar:file"
-msgid "&Save..."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:142
-msgctxt "@title:menu menubar:file"
-msgid "&Export..."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:153
-msgctxt "@action:inmenu menubar:file"
-msgid "Export Selection..."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:174
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Edit"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:191
-msgctxt "@title:menu"
-msgid "&View"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:196
-msgctxt "@title:menu"
-msgid "&Settings"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:198
-msgctxt "@title:menu menubar:settings"
-msgid "&Printer"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:207
-msgctxt "@title:menu"
-msgid "&Material"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:216
-msgctxt "@action:inmenu"
-msgid "Set as Active Extruder"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:222
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:188
-msgctxt "@action:inmenu"
-msgid "Enable Extruder"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:229
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:194
-msgctxt "@action:inmenu"
-msgid "Disable Extruder"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:241
-msgctxt "@title:menu"
-msgid "&Build plate"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:242
-msgctxt "@title:settings"
-msgid "&Profile"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:252
-msgctxt "@title:menu menubar:toplevel"
-msgid "E&xtensions"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:286
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Toolbox"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:294
-msgctxt "@title:menu menubar:toplevel"
-msgid "P&references"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:302
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Help"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:232
msgctxt "@label"
msgid "This package will be installed after restarting."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:377
-msgctxt "@action:button"
-msgid "Open File"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:547
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:413
msgctxt "@title:tab"
msgid "Settings"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:593
-msgctxt "@title:window"
-msgid "New project"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:594
-msgctxt "@info:question"
-msgid ""
-"Are you sure you want to start a new project? This will clear the build "
-"plate and any unsaved settings."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:722
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:538
msgctxt "@title:window"
msgid "Closing Cura"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:723
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:735
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
msgctxt "@label"
msgid "Are you sure you want to exit Cura?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:868
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:589
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:19
+msgctxt "@title:window"
+msgid "Open file(s)"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:695
msgctxt "@window:title"
msgid "Install Package"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:875
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:703
msgctxt "@title:window"
msgid "Open File(s)"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:878
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:706
msgctxt "@text:window"
msgid ""
"We have found one or more G-Code files within the files you have selected. "
@@ -4477,130 +4547,14 @@ msgid ""
"file, please just select only one."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:14
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:809
msgctxt "@title:window"
-msgid "Save Project"
+msgid "Add Printer"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:137
-msgctxt "@action:label"
-msgid "Build plate"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:169
-msgctxt "@action:label"
-msgid "Extruder %1"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:179
-msgctxt "@action:label"
-msgid "%1 & material"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:268
-msgctxt "@action:label"
-msgid "Don't show project summary on save again"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:287
-msgctxt "@action:button"
-msgid "Save"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:192
-msgctxt "@label"
-msgid "Layer Height"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:277
-msgctxt "@tooltip"
-msgid ""
-"This quality profile is not available for you current material and nozzle "
-"configuration. Please change these to enable this quality profile"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:450
-msgctxt "@tooltip"
-msgid ""
-"A custom profile is currently active. To enable the quality slider, choose a "
-"default quality profile in Custom tab"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:467
-msgctxt "@label"
-msgid "Print Speed"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:479
-msgctxt "@label"
-msgid "Slower"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:490
-msgctxt "@label"
-msgid "Faster"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:518
-msgctxt "@tooltip"
-msgid ""
-"You have modified some profile settings. If you want to change these go to "
-"custom mode."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:541
-msgctxt "@label"
-msgid "Infill"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:777
-msgctxt "@label"
-msgid ""
-"Gradual infill will gradually increase the amount of infill towards the top."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:791
-msgctxt "@label"
-msgid "Enable gradual"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:858
-msgctxt "@label"
-msgid "Generate Support"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:892
-msgctxt "@label"
-msgid ""
-"Generate structures to support parts of the model which have overhangs. "
-"Without these structures, such parts would collapse during printing."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:964
-msgctxt "@label"
-msgid ""
-"Select which extruder to use for support. This will build up supporting "
-"structures below the model to prevent the model from sagging or printing in "
-"mid air."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:987
-msgctxt "@label"
-msgid "Build Plate Adhesion"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1042
-msgctxt "@label"
-msgid ""
-"Enable printing a brim or raft. This will add a flat area around or under "
-"your object which is easy to cut off afterwards."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1082
-msgctxt "@label"
-msgid ""
-"Need help improving your prints? Read the Ultimaker "
-"Troubleshooting Guides"
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:817
+msgctxt "@title:window"
+msgid "What's New"
msgstr ""
#: /home/ruben/Projects/Cura/resources/qml/ExtruderButton.qml:16
@@ -4610,80 +4564,513 @@ msgid_plural "Print Selected Models with %1"
msgstr[0] ""
msgstr[1] ""
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:20
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:15
+msgctxt "@title:window"
+msgid "Discard or Keep changes"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:57
+msgctxt "@text:window"
+msgid ""
+"You have customized some profile settings.\n"
+"Would you like to keep or discard those settings?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:110
+msgctxt "@title:column"
+msgid "Profile settings"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:117
+msgctxt "@title:column"
+msgid "Default"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:124
+msgctxt "@title:column"
+msgid "Customized"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:158
+msgctxt "@option:discardOrKeep"
+msgid "Discard and never ask again"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:159
+msgctxt "@option:discardOrKeep"
+msgid "Keep and never ask again"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:196
+msgctxt "@action:button"
+msgid "Discard"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:209
+msgctxt "@action:button"
+msgid "Keep"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:222
+msgctxt "@action:button"
+msgid "Create New Profile"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:15
+msgctxt "@title:window"
+msgid "About Cura"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:57
+msgctxt "@label"
+msgid "version: %1"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:72
+msgctxt "@label"
+msgid "End-to-end solution for fused filament 3D printing."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:85
+msgctxt "@info:credit"
+msgid ""
+"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
+"Cura proudly uses the following open source projects:"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:135
+msgctxt "@label"
+msgid "Graphical user interface"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:136
+msgctxt "@label"
+msgid "Application framework"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:137
+msgctxt "@label"
+msgid "G-code generator"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:138
+msgctxt "@label"
+msgid "Interprocess communication library"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:140
+msgctxt "@label"
+msgid "Programming language"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:141
+msgctxt "@label"
+msgid "GUI framework"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:142
+msgctxt "@label"
+msgid "GUI framework bindings"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:143
+msgctxt "@label"
+msgid "C/C++ Binding library"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:144
+msgctxt "@label"
+msgid "Data interchange format"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:145
+msgctxt "@label"
+msgid "Support library for scientific computing"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:146
+msgctxt "@label"
+msgid "Support library for faster math"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:147
+msgctxt "@label"
+msgid "Support library for handling STL files"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:148
+msgctxt "@label"
+msgid "Support library for handling planar objects"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:149
+msgctxt "@label"
+msgid "Support library for handling triangular meshes"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:150
+msgctxt "@label"
+msgid "Support library for analysis of complex networks"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:151
+msgctxt "@label"
+msgid "Support library for handling 3MF files"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:152
+msgctxt "@label"
+msgid "Support library for file metadata and streaming"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:153
+msgctxt "@label"
+msgid "Serial communication library"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:154
+msgctxt "@label"
+msgid "ZeroConf discovery library"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:155
+msgctxt "@label"
+msgid "Polygon clipping library"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:156
+msgctxt "@Label"
+msgid "Python HTTP library"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:158
+msgctxt "@label"
+msgid "Font"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:159
+msgctxt "@label"
+msgid "SVG icons"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:160
+msgctxt "@label"
+msgid "Linux cross-distribution application deployment"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:64
+msgctxt "@text:window"
+msgid ""
+"We have found one or more project file(s) within the files you have "
+"selected. You can open only one project file at a time. We suggest to only "
+"import models from those files. Would you like to proceed?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:99
+msgctxt "@action:button"
+msgid "Import all as models"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:15
+msgctxt "@title:window"
+msgid "Save Project"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:177
+msgctxt "@action:label"
+msgid "Extruder %1"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:192
+msgctxt "@action:label"
+msgid "%1 & material"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:194
+msgctxt "@action:label"
+msgid "Material"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:283
+msgctxt "@action:label"
+msgid "Don't show project summary on save again"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:302
+msgctxt "@action:button"
+msgid "Save"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:20
msgctxt "@title:window"
msgid "Open project file"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:93
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:93
msgctxt "@text:window"
msgid ""
"This is a Cura project file. Would you like to open it as a project or "
"import the models from it?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:103
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:103
msgctxt "@text:window"
msgid "Remember my choice"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:122
msgctxt "@action:button"
msgid "Open as project"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:131
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:131
msgctxt "@action:button"
msgid "Import models"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15
-msgctxt "@title:window"
-msgid "Engine Log"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:70
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DropDownWidget.qml:93
msgctxt "@label"
-msgid "Printer type"
+msgid "Empty"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:376
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:24
msgctxt "@label"
-msgid "Material"
+msgid "Add a printer"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:543
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:39
msgctxt "@label"
-msgid "Use glue with this material combination"
+msgid "Add a networked printer"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:575
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:81
msgctxt "@label"
-msgid "Check compatibility"
+msgid "Add a non-networked printer"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:593
-msgctxt "@tooltip"
-msgid "Click to check the material compatibility on Ultimaker.com."
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:70
+msgctxt "@label"
+msgid "Add printer by IP address"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:211
-msgctxt "@option:check"
-msgid "See only current build plate"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:133
+msgctxt "@text"
+msgid "Place enter your printer's IP address."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:227
-msgctxt "@action:button"
-msgid "Arrange to all build plates"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:158
+msgctxt "@button"
+msgid "Add"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:247
-msgctxt "@action:button"
-msgid "Arrange current build plate"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:204
+msgctxt "@label"
+msgid "Could not connect to device."
msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:208
+msgctxt "@label"
+msgid "The printer at this address has not responded yet."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:240
+msgctxt "@label"
+msgid ""
+"This printer cannot be added because it's an unknown printer or it's not the "
+"host of a group."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:329
+msgctxt "@button"
+msgid "Back"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:342
+msgctxt "@button"
+msgid "Connect"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/FirstStartMachineActionsContent.qml:77
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:123
+msgctxt "@button"
+msgid "Next"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:23
+msgctxt "@label"
+msgid "User Agreement"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:56
+msgctxt "@button"
+msgid "Agree"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:70
+msgctxt "@button"
+msgid "Decline and close"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:24
+msgctxt "@label"
+msgid "Help us to improve Ultimaker Cura"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:57
+msgctxt "@text"
+msgid ""
+"Ultimaker Cura collects anonymous data to improve print quality and user "
+"experience, including:"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:71
+msgctxt "@text"
+msgid "Machine types"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:77
+msgctxt "@text"
+msgid "Material usage"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:83
+msgctxt "@text"
+msgid "Number of slices"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:89
+msgctxt "@text"
+msgid "Print settings"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:102
+msgctxt "@text"
+msgid ""
+"Data collected by Ultimaker Cura will not contain any personal information."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:103
+msgctxt "@text"
+msgid "More information"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WhatsNewContent.qml:24
+msgctxt "@label"
+msgid "What's new in Ultimaker Cura"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:42
+msgctxt "@label"
+msgid "There is no printer found over your network."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:179
+msgctxt "@label"
+msgid "Refresh"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:190
+msgctxt "@label"
+msgid "Add printer by IP"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:223
+msgctxt "@label"
+msgid "Troubleshooting"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:211
+msgctxt "@label"
+msgid "Printer name"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:224
+msgctxt "@text"
+msgid "Please give your printer a name"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:36
+msgctxt "@label"
+msgid "Ultimaker Cloud"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:77
+msgctxt "@text"
+msgid "The next generation 3D printing workflow"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:94
+msgctxt "@text"
+msgid "- Send print jobs to Ultimaker printers outside your local network"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:97
+msgctxt "@text"
+msgid "- Store your Ultimaker Cura settings in the cloud for use anywhere"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:100
+msgctxt "@text"
+msgid "- Get exclusive access to print profiles from leading brands"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:119
+msgctxt "@button"
+msgid "Finish"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:128
+msgctxt "@button"
+msgid "Create an account"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:29
+msgctxt "@label"
+msgid "Welcome to Ultimaker Cura"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:47
+msgctxt "@text"
+msgid ""
+"Please follow these steps to set up\n"
+"Ultimaker Cura. This will only take a few moments."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:58
+msgctxt "@button"
+msgid "Get started"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:27
+msgctxt "@info:tooltip"
+msgid "3D View"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:40
+msgctxt "@info:tooltip"
+msgid "Front View"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:53
+msgctxt "@info:tooltip"
+msgid "Top View"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:66
+msgctxt "@info:tooltip"
+msgid "Left View"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:79
+msgctxt "@info:tooltip"
+msgid "Right View"
+msgstr ""
+
#: MachineSettingsAction/plugin.json
msgctxt "description"
-msgid "Provides a way to change machine settings (such as build volume, nozzle size, etc.)."
+msgid ""
+"Provides a way to change machine settings (such as build volume, nozzle "
+"size, etc.)."
msgstr ""
#: MachineSettingsAction/plugin.json
@@ -4733,7 +5120,9 @@ msgstr ""
#: ModelChecker/plugin.json
msgctxt "description"
-msgid "Checks models and print configuration for possible printing issues and give suggestions."
+msgid ""
+"Checks models and print configuration for possible printing issues and give "
+"suggestions."
msgstr ""
#: ModelChecker/plugin.json
@@ -4741,26 +5130,6 @@ msgctxt "name"
msgid "Model Checker"
msgstr ""
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "description"
-msgid "Dump the contents of all settings to a HTML file."
-msgstr ""
-
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "name"
-msgid "God Mode"
-msgstr ""
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "description"
-msgid "Shows changes since latest checked version."
-msgstr ""
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "name"
-msgid "Changelog"
-msgstr ""
-
#: FirmwareUpdater/plugin.json
msgctxt "description"
msgid "Provides a machine actions for updating firmware."
@@ -4771,19 +5140,20 @@ msgctxt "name"
msgid "Firmware Updater"
msgstr ""
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "description"
-msgid "Create a flattend quality changes profile."
+msgid "Provides support for reading AMF files."
msgstr ""
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "name"
-msgid "Profile flatener"
+msgid "AMF Reader"
msgstr ""
#: USBPrinting/plugin.json
msgctxt "description"
-msgid "Accepts G-Code and sends them to a printer. Plugin can also update firmware."
+msgid ""
+"Accepts G-Code and sends them to a printer. Plugin can also update firmware."
msgstr ""
#: USBPrinting/plugin.json
@@ -4791,26 +5161,6 @@ msgctxt "name"
msgid "USB printing"
msgstr ""
-#: UserAgreement/plugin.json
-msgctxt "description"
-msgid "Ask the user once if he/she agrees with our license."
-msgstr ""
-
-#: UserAgreement/plugin.json
-msgctxt "name"
-msgid "UserAgreement"
-msgstr ""
-
-#: X3GWriter/plugin.json
-msgctxt "description"
-msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
-msgstr ""
-
-#: X3GWriter/plugin.json
-msgctxt "name"
-msgid "X3GWriter"
-msgstr ""
-
#: GCodeGzWriter/plugin.json
msgctxt "description"
msgid "Writes g-code to a compressed archive."
@@ -4853,12 +5203,12 @@ msgstr ""
#: UM3NetworkPrinting/plugin.json
msgctxt "description"
-msgid "Manages network connections to Ultimaker 3 printers."
+msgid "Manages network connections to Ultimaker networked printers."
msgstr ""
#: UM3NetworkPrinting/plugin.json
msgctxt "name"
-msgid "UM3 Network Connection"
+msgid "Ultimaker Network Connection"
msgstr ""
#: MonitorStage/plugin.json
@@ -4913,7 +5263,8 @@ msgstr ""
#: SupportEraser/plugin.json
msgctxt "description"
-msgid "Creates an eraser mesh to block the printing of support in certain places"
+msgid ""
+"Creates an eraser mesh to block the printing of support in certain places"
msgstr ""
#: SupportEraser/plugin.json
@@ -4921,6 +5272,16 @@ msgctxt "name"
msgid "Support Eraser"
msgstr ""
+#: UFPReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading Ultimaker Format Packages."
+msgstr ""
+
+#: UFPReader/plugin.json
+msgctxt "name"
+msgid "UFP Reader"
+msgstr ""
+
#: SliceInfoPlugin/plugin.json
msgctxt "description"
msgid "Submits anonymous slice info. Can be disabled through preferences."
@@ -4981,6 +5342,16 @@ msgctxt "name"
msgid "Version Upgrade 3.3 to 3.4"
msgstr ""
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.3 to Cura 4.4."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.3 to 4.4"
+msgstr ""
+
#: VersionUpgrade/VersionUpgrade25to26/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.5 to Cura 2.6."
@@ -5001,6 +5372,16 @@ msgctxt "name"
msgid "Version Upgrade 2.7 to 3.0"
msgstr ""
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 3.5 to Cura 4.0."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 3.5 to 4.0"
+msgstr ""
+
#: VersionUpgrade/VersionUpgrade34to35/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.4 to Cura 3.5."
@@ -5011,6 +5392,16 @@ msgctxt "name"
msgid "Version Upgrade 3.4 to 3.5"
msgstr ""
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.0 to Cura 4.1."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.0 to 4.1"
+msgstr ""
+
#: VersionUpgrade/VersionUpgrade30to31/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.0 to Cura 3.1."
@@ -5021,6 +5412,16 @@ msgctxt "name"
msgid "Version Upgrade 3.0 to 3.1"
msgstr ""
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.1 to Cura 4.2."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.1 to 4.2"
+msgstr ""
+
#: VersionUpgrade/VersionUpgrade26to27/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.6 to Cura 2.7."
@@ -5051,6 +5452,16 @@ msgctxt "name"
msgid "Version Upgrade 2.2 to 2.4"
msgstr ""
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.2 to Cura 4.3."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.2 to 4.3"
+msgstr ""
+
#: ImageReader/plugin.json
msgctxt "description"
msgid "Enables ability to generate printable geometry from 2D image files."
@@ -5061,6 +5472,16 @@ msgctxt "name"
msgid "Image Reader"
msgstr ""
+#: TrimeshReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading model files."
+msgstr ""
+
+#: TrimeshReader/plugin.json
+msgctxt "name"
+msgid "Trimesh Reader"
+msgstr ""
+
#: CuraEngineBackend/plugin.json
msgctxt "description"
msgid "Provides the link to the CuraEngine slicing backend."
@@ -5111,6 +5532,16 @@ msgctxt "name"
msgid "G-code Reader"
msgstr ""
+#: CuraDrive/plugin.json
+msgctxt "description"
+msgid "Backup and restore your configuration."
+msgstr ""
+
+#: CuraDrive/plugin.json
+msgctxt "name"
+msgid "Cura Backups"
+msgstr ""
+
#: CuraProfileWriter/plugin.json
msgctxt "description"
msgid "Provides support for exporting Cura profiles."
@@ -5131,9 +5562,21 @@ msgctxt "name"
msgid "3MF Writer"
msgstr ""
+#: PreviewStage/plugin.json
+msgctxt "description"
+msgid "Provides a preview stage in Cura."
+msgstr ""
+
+#: PreviewStage/plugin.json
+msgctxt "name"
+msgid "Preview Stage"
+msgstr ""
+
#: UltimakerMachineActions/plugin.json
msgctxt "description"
-msgid "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.)."
+msgid ""
+"Provides machine actions for Ultimaker machines (such as bed leveling "
+"wizard, selecting upgrades, etc.)."
msgstr ""
#: UltimakerMachineActions/plugin.json
@@ -5150,4 +5593,3 @@ msgstr ""
msgctxt "name"
msgid "Cura Profile Reader"
msgstr ""
-
diff --git a/resources/i18n/de_DE/cura.po b/resources/i18n/de_DE/cura.po
index 3433edc5bd..3b0073bc31 100644
--- a/resources/i18n/de_DE/cura.po
+++ b/resources/i18n/de_DE/cura.po
@@ -1,24 +1,24 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-10-29 15:01+0100\n"
-"PO-Revision-Date: 2018-09-28 14:42+0200\n"
-"Last-Translator: Bothof \n"
-"Language-Team: German\n"
+"Project-Id-Version: Cura 4.4\n"
+"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
+"POT-Creation-Date: 2019-11-05 13:13+0100\n"
+"PO-Revision-Date: 2019-07-29 15:51+0200\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: German , German \n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.2.3\n"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:22
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:30
msgctxt "@action"
msgid "Machine Settings"
msgstr "Geräteeinstellungen"
@@ -40,23 +40,23 @@ msgctxt "@item:inlistbox"
msgid "G-code File"
msgstr "G-Code-Datei"
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:67
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:66
msgctxt "@error:not supported"
msgid "GCodeWriter does not support non-text mode."
msgstr "GCodeWriter unterstützt keinen Nicht-Textmodus."
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:73
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:89
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:72
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:88
msgctxt "@warning:status"
msgid "Please prepare G-code before exporting."
msgstr "Vor dem Exportieren bitte G-Code vorbereiten."
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:30
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:31
msgctxt "@info:title"
msgid "3D Model Assistant"
msgstr "3D-Modell-Assistent"
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:80
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:92
#, python-brace-format
msgctxt "@info:status"
msgid ""
@@ -64,68 +64,56 @@ msgid ""
"
{model_names}
\n"
"
Find out how to ensure the best possible print quality and reliability.
"
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py:25
msgctxt "@action"
msgid "Update Firmware"
msgstr "Firmware aktualisieren"
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:23
-msgctxt "@item:inmenu"
-msgid "Flatten active settings"
-msgstr "Einstellungen Glätten aktiv"
+#: /home/ruben/Projects/Cura/plugins/AMFReader/__init__.py:15
+msgctxt "@item:inlistbox"
+msgid "AMF File"
+msgstr "AMF-Datei"
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:35
-msgctxt "@info:status"
-msgid "Profile has been flattened & activated."
-msgstr "Das Profil wurde geglättet und aktiviert."
-
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:32
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:42
msgctxt "@item:inmenu"
msgid "USB printing"
msgstr "USB-Drucken"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:33
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:43
msgctxt "@action:button Preceded by 'Ready to'."
msgid "Print via USB"
msgstr "Über USB drucken"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:34
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:44
msgctxt "@info:tooltip"
msgid "Print via USB"
msgstr "Über USB drucken"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:69
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:80
msgctxt "@info:status"
msgid "Connected via USB"
msgstr "Über USB verbunden"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:92
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:105
msgctxt "@label"
msgid "A USB print is in progress, closing Cura will stop this print. Are you sure?"
msgstr "Ein USB-Druck wird ausgeführt. Das Schließen von Cura beendet diesen Druck. Sind Sie sicher?"
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/install/X3GWriter/__init__.py:15
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/__init__.py:15
-msgctxt "X3G Writer File Description"
-msgid "X3G File"
-msgstr "X3G-Datei"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid "A print is still in progress. Cura cannot start another print via USB until the previous print has completed."
+msgstr "Druck wird bearbeitet. Cura kann keinen weiteren Druck via USB starten, bis der vorherige Druck abgeschlossen wurde."
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:16
-msgctxt "X3g Writer Plugin Description"
-msgid "Writes X3g to files"
-msgstr "Schreibt X3g in Dateien"
-
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:21
-msgctxt "X3g Writer File Description"
-msgid "X3g File"
-msgstr "X3g-Datei"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid "Print in Progress"
+msgstr "Druck in Bearbeitung"
#: /home/ruben/Projects/Cura/plugins/GCodeGzWriter/__init__.py:17
#: /home/ruben/Projects/Cura/plugins/GCodeGzReader/__init__.py:17
@@ -139,6 +127,7 @@ msgid "GCodeGzWriter does not support text mode."
msgstr "GCodeWriter unterstützt keinen Textmodus."
#: /home/ruben/Projects/Cura/plugins/UFPWriter/__init__.py:28
+#: /home/ruben/Projects/Cura/plugins/UFPReader/__init__.py:22
msgctxt "@item:inlistbox"
msgid "Ultimaker Format Package"
msgstr "Ultimaker Format Package"
@@ -160,7 +149,7 @@ msgid "Save to Removable Drive {0}"
msgstr "Auf Wechseldatenträger speichern {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:64
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:133
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py:107
msgctxt "@info:status"
msgid "There are no file formats available to write with!"
msgstr "Es sind keine Dateiformate zum Schreiben vorhanden!"
@@ -197,9 +186,9 @@ msgid "Could not save to removable drive {0}: {1}"
msgstr "Konnte nicht auf dem Wechseldatenträger gespeichert werden {0}: {1}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:137
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:133
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:140
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1607
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:139
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:146
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1668
msgctxt "@info:title"
msgid "Error"
msgstr "Fehler"
@@ -228,8 +217,9 @@ msgstr "Wechseldatenträger auswerfen {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:151
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:163
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1597
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1695
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1658
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1758
msgctxt "@info:title"
msgid "Warning"
msgstr "Warnhinweis"
@@ -256,232 +246,164 @@ msgctxt "@item:intext"
msgid "Removable Drive"
msgstr "Wechseldatenträger"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:73
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:88
-msgctxt "@action:button Preceded by 'Ready to'."
-msgid "Print over network"
-msgstr "Drucken über Netzwerk"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:74
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:89
-msgctxt "@properties:tooltip"
-msgid "Print over network"
-msgstr "Drücken über Netzwerk"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:87
-msgctxt "@info:status"
-msgid "Connected over the network."
-msgstr "Über Netzwerk verbunden."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:90
-msgctxt "@info:status"
-msgid "Connected over the network. Please approve the access request on the printer."
-msgstr "Über Netzwerk verbunden. Geben Sie die Zugriffsanforderung für den Drucker frei."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:92
-msgctxt "@info:status"
-msgid "Connected over the network. No access to control the printer."
-msgstr "Über Netzwerk verbunden. Kein Zugriff auf die Druckerverwaltung."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:97
-msgctxt "@info:status"
-msgid "Access to the printer requested. Please approve the request on the printer"
-msgstr "Zugriff auf Drucker erforderlich. Bestätigen Sie den Zugriff auf den Drucker"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:100
-msgctxt "@info:title"
-msgid "Authentication status"
-msgstr "Authentifizierungsstatus"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:102
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:108
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:112
-msgctxt "@info:title"
-msgid "Authentication Status"
-msgstr "Authentifizierungsstatus"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:103
-msgctxt "@action:button"
-msgid "Retry"
-msgstr "Erneut versuchen"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:104
-msgctxt "@info:tooltip"
-msgid "Re-send the access request"
-msgstr "Zugriffanforderung erneut senden"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:107
-msgctxt "@info:status"
-msgid "Access to the printer accepted"
-msgstr "Zugriff auf den Drucker genehmigt"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:111
-msgctxt "@info:status"
-msgid "No access to print with this printer. Unable to send print job."
-msgstr "Kein Zugriff auf das Drucken mit diesem Drucker. Druckauftrag kann nicht gesendet werden."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:113
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:33
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:70
-msgctxt "@action:button"
-msgid "Request Access"
-msgstr "Zugriff anfordern"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:115
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:34
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:71
-msgctxt "@info:tooltip"
-msgid "Send access request to the printer"
-msgstr "Zugriffsanforderung für den Drucker senden"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:200
-msgctxt "@label"
-msgid "Unable to start a new print job."
-msgstr "Es kann kein neuer Druckauftrag gestartet werden."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:202
-msgctxt "@label"
-msgid "There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. Please resolve this issues before continuing."
-msgstr "Es liegt ein Problem mit der Konfiguration Ihres Ultimaker vor, das den Druckstart verhindert. Lösen Sie dieses Problem bitte, bevor Sie fortfahren."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:208
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:230
-msgctxt "@window:title"
-msgid "Mismatched configuration"
-msgstr "Konfiguration nicht übereinstimmend"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:222
-msgctxt "@label"
-msgid "Are you sure you wish to print with the selected configuration?"
-msgstr "Möchten Sie wirklich mit der gewählten Konfiguration drucken?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:224
-msgctxt "@label"
-msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "Anforderungen zwischen der Druckerkonfiguration oder -kalibrierung und Cura stimmen nicht überein. Für optimale Ergebnisse schneiden Sie stets für die PrintCores und Materialien, die in Ihren Drucker eingelegt wurden."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:251
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:199
-msgctxt "@info:status"
-msgid "Sending new jobs (temporarily) blocked, still sending the previous print job."
-msgstr "Das Senden neuer Aufträge ist (vorübergehend) blockiert; der vorherige Druckauftrag wird noch gesendet."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:258
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:218
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:234
-msgctxt "@info:status"
-msgid "Sending data to printer"
-msgstr "Daten werden zum Drucker gesendet"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:259
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:219
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:235
-msgctxt "@info:title"
-msgid "Sending Data"
-msgstr "Daten werden gesendet"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:260
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:236
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:80
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:381
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:20
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:143
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:391
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:87
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:279
-msgctxt "@action:button"
-msgid "Cancel"
-msgstr "Abbrechen"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:323
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No Printcore loaded in slot {slot_number}"
-msgstr "Kein PrintCore geladen in Steckplatz {slot_number}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:329
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No material loaded in slot {slot_number}"
-msgstr "Kein Material geladen in Steckplatz {slot_number}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:352
-#, python-brace-format
-msgctxt "@label"
-msgid "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}"
-msgstr "Abweichender PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) für Extruder gewählt {extruder_id}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:361
-#, python-brace-format
-msgctxt "@label"
-msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
-msgstr "Abweichendes Material (Cura: {0}, Drucker: {1}) für Extruder {2} gewählt"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:547
-msgctxt "@window:title"
-msgid "Sync with your printer"
-msgstr "Synchronisieren Ihres Druckers"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:549
-msgctxt "@label"
-msgid "Would you like to use your current printer configuration in Cura?"
-msgstr "Möchten Sie Ihre aktuelle Druckerkonfiguration in Cura verwenden?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:551
-msgctxt "@label"
-msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "Die PrintCores und/oder Materialien auf Ihrem Drucker unterscheiden sich von denen Ihres aktuellen Projekts. Für optimale Ergebnisse schneiden Sie stets für die PrintCores und Materialien, die in Ihren Drucker eingelegt wurden."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:91
-msgctxt "@info:status"
-msgid "Connected over the network"
-msgstr "Über Netzwerk verbunden"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:303
-msgctxt "@info:status"
-msgid "Print job was successfully sent to the printer."
-msgstr "Der Druckauftrag wurde erfolgreich an den Drucker gesendet."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:305
-msgctxt "@info:title"
-msgid "Data Sent"
-msgstr "Daten gesendet"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:306
-msgctxt "@action:button"
-msgid "View in Monitor"
-msgstr "In Monitor überwachen"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:422
-#, python-brace-format
-msgctxt "@info:status"
-msgid "Printer '{printer_name}' has finished printing '{job_name}'."
-msgstr "Drucker '{printer_name}' hat '{job_name}' vollständig gedrückt."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:424
-#, python-brace-format
-msgctxt "@info:status"
-msgid "The print job '{job_name}' was finished."
-msgstr "Der Druckauftrag '{job_name}' wurde ausgeführt."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:425
-msgctxt "@info:status"
-msgid "Print finished"
-msgstr "Druck vollendet"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py:26
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py:26
msgctxt "@action"
msgid "Connect via Network"
msgstr "Anschluss über Netzwerk"
-#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:13
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:57
+msgctxt "@action:button Preceded by 'Ready to'."
+msgid "Print over network"
+msgstr "Drucken über Netzwerk"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:58
+msgctxt "@properties:tooltip"
+msgid "Print over network"
+msgstr "Drücken über Netzwerk"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:59
+msgctxt "@info:status"
+msgid "Connected over the network"
+msgstr "Über Netzwerk verbunden"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:15
+msgctxt "@info:status"
+msgid "Please wait until the current job has been sent."
+msgstr "Bitte warten Sie, bis der aktuelle Druckauftrag gesendet wurde."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:16
+msgctxt "@info:title"
+msgid "Print error"
+msgstr "Druckfehler"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:21
+msgctxt "@info:title"
+msgid "New cloud printers found"
+msgstr "Neue Cloud-Drucker gefunden"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:22
+msgctxt "@info:message"
+msgid "New printers have been found connected to your account, you can find them in your list of discovered printers."
+msgstr "Es wurden neue Drucker gefunden, die Sie zu Ihrem Konto hinzufügen können. Sie finden diese in der Liste gefundener Drucker."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:27
+msgctxt "@info:option_text"
+msgid "Do not show this message again"
+msgstr "Diese Meldung nicht mehr anzeigen"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:27
+#, python-brace-format
+msgctxt "@info:status"
+msgid "You are attempting to connect to {0} but it is not the host of a group. You can visit the web page to configure it as a group host."
+msgstr "Sie versuchen, sich mit {0} zu verbinden, aber dieser Drucker ist nicht der Host, der die Gruppe verwaltet. Besuchen Sie die Website, um den Drucker als Host der Gruppe zu konfigurieren."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:30
+msgctxt "@info:title"
+msgid "Not a group host"
+msgstr "Nicht Host-Drucker der Gruppe"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:35
+msgctxt "@action"
+msgid "Configure group"
+msgstr "Gruppe konfigurieren"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:27
+msgctxt "@info:status"
+msgid "Send and monitor print jobs from anywhere using your Ultimaker account."
+msgstr "Druckaufträge mithilfe Ihres Ultimaker-Kontos von einem anderen Ort aus senden und überwachen."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:33
+msgctxt "@info:status Ultimaker Cloud should not be translated."
+msgid "Connect to Ultimaker Cloud"
+msgstr "Verbinden mit Ultimaker Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:36
+msgctxt "@action"
+msgid "Get started"
+msgstr "Erste Schritte"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:14
+msgctxt "@info:status"
+msgid "Sending Print Job"
+msgstr "Druckauftrag senden"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:15
+msgctxt "@info:status"
+msgid "Uploading print job to printer."
+msgstr "Druckauftrag wird vorbereitet."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:15
+msgctxt "@info:status"
+msgid "Print job was successfully sent to the printer."
+msgstr "Der Druckauftrag wurde erfolgreich an den Drucker gesendet."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:16
+msgctxt "@info:title"
+msgid "Data Sent"
+msgstr "Daten gesendet"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:18
+msgctxt "@info:status"
+msgid "You are attempting to connect to a printer that is not running Ultimaker Connect. Please update the printer to the latest firmware."
+msgstr "Sie versuchen, sich mit einem Drucker zu verbinden, auf dem Ultimaker Connect nicht läuft. Bitte aktualisieren Sie die Firmware des Druckers."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:21
+msgctxt "@info:title"
+msgid "Update your printer"
+msgstr "Drucker aktualisieren"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:24
+#, python-brace-format
+msgctxt "@info:status"
+msgid "Cura has detected material profiles that were not yet installed on the host printer of group {0}."
+msgstr "Cura hat Materialprofile entdeckt, die auf dem Host-Drucker der Gruppe {0} noch nicht installiert wurden."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:26
+msgctxt "@info:title"
+msgid "Sending materials to printer"
+msgstr "Material an Drucker senden"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:15
+msgctxt "@info:text"
+msgid "Could not upload the data to the printer."
+msgstr "Daten konnten nicht in Drucker geladen werden."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:16
+msgctxt "@info:title"
+msgid "Network error"
+msgstr "Netzwerkfehler"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:27
+msgctxt "@info:status"
+msgid "tomorrow"
+msgstr "morgen"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:30
+msgctxt "@info:status"
+msgid "today"
+msgstr "heute"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:138
+msgctxt "@action:button"
+msgid "Print via Cloud"
+msgstr "Über Cloud drucken"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:139
+msgctxt "@properties:tooltip"
+msgid "Print via Cloud"
+msgstr "Über Cloud drucken"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:140
+msgctxt "@info:status"
+msgid "Connected via Cloud"
+msgstr "Über Cloud verbunden"
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:14
msgctxt "@item:inmenu"
msgid "Monitor"
msgstr "Überwachen"
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:119
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:125
msgctxt "@info"
msgid "Could not access update information."
msgstr "Zugriff auf Update-Informationen nicht möglich."
@@ -503,22 +425,28 @@ msgctxt "@action:button"
msgid "How to update"
msgstr "Anleitung für die Aktualisierung"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:14
+#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:15
msgctxt "@item:inlistbox"
msgid "Layer view"
msgstr "Schichtenansicht"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:113
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:117
msgctxt "@info:status"
msgid "Cura does not accurately display layers when Wire Printing is enabled"
msgstr "Cura zeigt die Schichten nicht akkurat an, wenn Wire Printing aktiviert ist"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:114
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:118
msgctxt "@info:title"
msgid "Simulation View"
msgstr "Simulationsansicht"
#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:35
+msgctxt "@item:inmenu"
+msgid "Post Processing"
+msgstr "Nachbearbeitung"
+
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:36
+msgctxt "@item:inmenu"
msgid "Modify G-Code"
msgstr "G-Code ändern"
@@ -532,36 +460,6 @@ msgctxt "@info:tooltip"
msgid "Create a volume in which supports are not printed."
msgstr "Erstellt ein Volumen, in dem keine Stützstrukturen gedruckt werden."
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:52
-msgctxt "@info"
-msgid "Cura collects anonymized usage statistics."
-msgstr "Cura erfasst anonymisierte Nutzungsstatistiken."
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:55
-msgctxt "@info:title"
-msgid "Collecting Data"
-msgstr "Daten werden erfasst"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:57
-msgctxt "@action:button"
-msgid "More info"
-msgstr "Mehr Infos"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:58
-msgctxt "@action:tooltip"
-msgid "See more information on what data Cura sends."
-msgstr "Siehe mehr Informationen dazu, was Cura sendet."
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:60
-msgctxt "@action:button"
-msgid "Allow"
-msgstr "Zulassen"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:61
-msgctxt "@action:tooltip"
-msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
-msgstr "Damit lassen Sie zu, dass Cura anonymisierte Nutzungsstatistiken sendet, um zukünftige Verbesserungen für Cura zu definieren. Einige Ihrer Präferenzen und Einstellungen, die Cura-Version und ein Hash der Modelle, die Sie slicen, werden gesendet."
-
#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
msgid "Cura 15.04 profiles"
@@ -592,56 +490,86 @@ msgctxt "@item:inlistbox"
msgid "GIF Image"
msgstr "GIF-Bilddatei"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:15
+msgctxt "@item:inlistbox 'Open' is part of the name of this file format."
+msgid "Open Compressed Triangle Mesh"
+msgstr "Öffnen Sie das komprimierte Dreiecksnetz"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:19
+msgctxt "@item:inlistbox"
+msgid "COLLADA Digital Asset Exchange"
+msgstr "COLLADA Digital Asset Exchange"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:23
+msgctxt "@item:inlistbox"
+msgid "glTF Binary"
+msgstr "glTF Binary"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:27
+msgctxt "@item:inlistbox"
+msgid "glTF Embedded JSON"
+msgstr "glTF Embedded JSON"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:36
+msgctxt "@item:inlistbox"
+msgid "Stanford Triangle Format"
+msgstr "Stanford Triangle Format"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:40
+msgctxt "@item:inlistbox"
+msgid "Compressed COLLADA Digital Asset Exchange"
+msgstr "Compressed COLLADA Digital Asset Exchange"
+
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
msgctxt "@info:status"
msgid "Unable to slice with the current material as it is incompatible with the selected machine or configuration."
msgstr "Slicing mit dem aktuellen Material nicht möglich, da es mit der gewählten Maschine oder Konfiguration nicht kompatibel ist."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:363
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:387
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:396
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:405
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:414
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
msgctxt "@info:title"
msgid "Unable to slice"
msgstr "Slicing nicht möglich"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:361
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice with the current settings. The following settings have errors: {0}"
msgstr "Die aktuellen Einstellungen lassen kein Schneiden (Slicing) zu. Die folgenden Einstellungen sind fehlerhaft:{0}"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:385
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice due to some per-model settings. The following settings have errors on one or more models: {error_labels}"
msgstr "Aufgrund der Pro-Modell-Einstellungen ist kein Schneiden (Slicing) möglich. Die folgenden Einstellungen sind für ein oder mehrere Modelle fehlerhaft: {error_labels}"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:394
msgctxt "@info:status"
msgid "Unable to slice because the prime tower or prime position(s) are invalid."
msgstr "Schneiden (Slicing) ist nicht möglich, da der Einzugsturm oder die Einzugsposition(en) ungültig ist (sind)."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:403
#, python-format
msgctxt "@info:status"
msgid "Unable to slice because there are objects associated with disabled Extruder %s."
msgstr "Schneiden (Slicing) ist nicht möglich, da Objekte vorhanden sind, die mit dem deaktivierten Extruder %s verbunden sind."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:412
msgctxt "@info:status"
-msgid "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."
-msgstr "Es ist kein Objekt zum Schneiden vorhanden, da keines der Modelle der Druckabmessung entspricht. Bitte die Modelle passend skalieren oder drehen."
+msgid "Nothing to slice because none of the models fit the build volume or are assigned to a disabled extruder. Please scale or rotate models to fit, or enable an extruder."
+msgstr "Es ist kein Objekt zum Schneiden vorhanden, da keines der Modelle den Druckabmessungen entspricht oder weil sie einem deaktivierten Extruder zugewiesen wurden. Bitte die Modelle passend skalieren oder drehen."
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:50
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:status"
msgid "Processing Layers"
msgstr "Schichten werden verarbeitet"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:title"
msgid "Information"
msgstr "Informationen"
@@ -656,14 +584,12 @@ msgctxt "@info:tooltip"
msgid "Configure Per Model Settings"
msgstr "Pro Objekteinstellungen konfigurieren"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:175
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:575
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:186
msgctxt "@title:tab"
msgid "Recommended"
msgstr "Empfohlen"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:177
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:580
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:188
msgctxt "@title:tab"
msgid "Custom"
msgstr "Benutzerdefiniert"
@@ -674,19 +600,19 @@ msgctxt "@item:inlistbox"
msgid "3MF File"
msgstr "3MF-Datei"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:190
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:714
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:198
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:651
msgctxt "@label"
msgid "Nozzle"
msgstr "Düse"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:468
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:496
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Project file {0} contains an unknown machine type {1}. Cannot import the machine. Models will be imported instead."
msgstr "Projektdatei {0} enthält einen unbekannten Maschinentyp {1}. Importieren der Maschine ist nicht möglich. Stattdessen werden die Modelle importiert."
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:471
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:499
msgctxt "@info:title"
msgid "Open Project File"
msgstr "Projektdatei öffnen"
@@ -701,22 +627,65 @@ msgctxt "@item:inlistbox"
msgid "G File"
msgstr "G-Datei"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:324
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:335
msgctxt "@info:status"
msgid "Parsing G-code"
msgstr "G-Code parsen"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:326
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:474
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:337
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:491
msgctxt "@info:title"
msgid "G-code Details"
msgstr "G-Code-Details"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:472
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:489
msgctxt "@info:generic"
msgid "Make sure the g-code is suitable for your printer and printer configuration before sending the file to it. The g-code representation may not be accurate."
msgstr "Stellen Sie sicher, dass der G-Code für Ihren Drucker und Ihre Druckerkonfiguration geeignet ist, bevor Sie die Datei senden. Der Darstellung des G-Codes ist möglicherweise nicht korrekt."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:64
+msgctxt "@item:inmenu"
+msgid "Manage backups"
+msgstr "Backups verwalten"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:107
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:113
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:104
+msgctxt "@info:title"
+msgid "Backup"
+msgstr "Backup"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+msgctxt "@info:backup_status"
+msgid "There was an error listing your backups."
+msgstr "Beim Versuch, Ihre Backups aufzulisten, trat ein Fehler auf."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:132
+msgctxt "@info:backup_status"
+msgid "There was an error trying to restore your backup."
+msgstr "Beim Versuch, Ihr Backup wiederherzustellen, trat ein Fehler auf."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:15
+msgctxt "@info:title"
+msgid "Backups"
+msgstr "Backups"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:27
+msgctxt "@info:backup_status"
+msgid "Uploading your backup..."
+msgstr "Ihr Backup wird hochgeladen..."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:36
+msgctxt "@info:backup_status"
+msgid "There was an error while uploading your backup."
+msgstr "Beim Versuch, Ihr Backup hochzuladen, trat ein Fehler auf."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:39
+msgctxt "@info:backup_status"
+msgid "Your backup has finished uploading."
+msgstr "Ihr Backup wurde erfolgreich hochgeladen."
+
#: /home/ruben/Projects/Cura/plugins/CuraProfileWriter/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
@@ -738,330 +707,452 @@ msgctxt "@error:zip"
msgid "Error writing 3mf file."
msgstr "Fehler beim Schreiben von 3MF-Datei."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelection.py:17
+#: /home/ruben/Projects/Cura/plugins/PreviewStage/__init__.py:13
+msgctxt "@item:inmenu"
+msgid "Preview"
+msgstr "Vorschau"
+
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelection.py:18
msgctxt "@action"
msgid "Select upgrades"
msgstr "Upgrades wählen"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py:14
-msgctxt "@action"
-msgid "Checkup"
-msgstr "Check-up"
-
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.py:21
msgctxt "@action"
msgid "Level build plate"
msgstr "Druckbett nivellieren"
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:82
-msgctxt "@tooltip"
-msgid "Outer Wall"
-msgstr "Außenwand"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:83
-msgctxt "@tooltip"
-msgid "Inner Walls"
-msgstr "Innenwände"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:84
-msgctxt "@tooltip"
-msgid "Skin"
-msgstr "Außenhaut"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:85
-msgctxt "@tooltip"
-msgid "Infill"
-msgstr "Füllung"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:86
-msgctxt "@tooltip"
-msgid "Support Infill"
-msgstr "Stützstruktur-Füllung"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:87
-msgctxt "@tooltip"
-msgid "Support Interface"
-msgstr "Stützstruktur-Schnittstelle"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:88
-msgctxt "@tooltip"
-msgid "Support"
-msgstr "Stützstruktur"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:89
-msgctxt "@tooltip"
-msgid "Skirt"
-msgstr "Skirt"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:90
-msgctxt "@tooltip"
-msgid "Travel"
-msgstr "Bewegungen"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:91
-msgctxt "@tooltip"
-msgid "Retractions"
-msgstr "Einzüge"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:92
-msgctxt "@tooltip"
-msgid "Other"
-msgstr "Sonstige"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:310
-#, python-brace-format
-msgctxt "@label"
-msgid "Pre-sliced file {0}"
-msgstr "Vorgeschnittene Datei {0}"
-
-#: /home/ruben/Projects/Cura/cura/API/Account.py:71
+#: /home/ruben/Projects/Cura/cura/API/Account.py:82
msgctxt "@info:title"
msgid "Login failed"
msgstr "Login fehlgeschlagen"
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:201
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:121
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:36
+msgctxt "@info:not supported profile"
+msgid "Not supported"
+msgstr "Nicht unterstützt"
+
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:55
+msgctxt "@info:No intent profile selected"
+msgid "Default"
+msgstr "Default"
+
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:196
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:125
msgctxt "@title:window"
msgid "File Already Exists"
msgstr "Datei bereits vorhanden"
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:202
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:122
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:197
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:126
#, python-brace-format
msgctxt "@label Don't translate the XML tag !"
msgid "The file {0} already exists. Are you sure you want to overwrite it?"
msgstr "Die Datei {0} ist bereits vorhanden. Soll die Datei wirklich überschrieben werden?"
-#: /home/ruben/Projects/Cura/cura/Settings/ExtrudersModel.py:212
-msgctxt "@menuitem"
-msgid "Not overridden"
-msgstr "Nicht überschrieben"
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:117
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:430
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:433
msgctxt "@info:status"
-msgid "The selected material is incompatible with the selected machine or configuration."
-msgstr "Das gewählte Material ist mit der gewählten Maschine oder Konfiguration nicht kompatibel."
+msgid "Invalid file URL:"
+msgstr "Ungültige Datei-URL:"
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:118
-msgctxt "@info:title"
-msgid "Incompatible Material"
-msgstr "Material nicht kompatibel"
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:780
+msgctxt "@info:message Followed by a list of settings."
+msgid "Settings have been changed to match the current availability of extruders:"
+msgstr "Die Einstellungen wurden an die aktuell verfügbaren Extruder angepasst:"
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:866
-#, python-format
-msgctxt "@info:generic"
-msgid "Settings have been changed to match the current availability of extruders: [%s]"
-msgstr "Die Einstellungen wurden passend für die aktuelle Verfügbarkeit der Extruder geändert: [%s]"
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:868
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:782
msgctxt "@info:title"
msgid "Settings updated"
msgstr "Einstellungen aktualisiert"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:131
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1334
+msgctxt "@info:title"
+msgid "Extruder(s) Disabled"
+msgstr "Extruder deaktiviert"
+
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1457
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:99
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:86
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:182
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:223
+msgctxt "@label"
+msgid "Unknown"
+msgstr "Unbekannt"
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:137
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Failed to export profile to {0}: {1}"
msgstr "Export des Profils nach {0} fehlgeschlagen: {1}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:138
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid "Failed to export profile to {0}: Writer plugin reported failure."
msgstr "Export des Profils nach {0} fehlgeschlagen: Fehlermeldung von Writer-Plugin."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:143
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:149
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid "Exported profile to {0}"
msgstr "Profil wurde nach {0} exportiert"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:150
msgctxt "@info:title"
msgid "Export succeeded"
msgstr "Export erfolgreich ausgeführt"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:170
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:177
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
-msgid "Failed to import profile from {0}: {1}"
-msgstr "Import des Profils aus Datei {0} fehlgeschlagen: {1}"
+msgctxt "@info:status Don't translate the XML tags !"
+msgid "Failed to import profile from {0}: {1}"
+msgstr "Import des Profils aus Datei {0}: {1} fehlgeschlagen"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:190
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:181
+#, python-brace-format
+msgctxt "@info:status Don't translate the XML tags !"
+msgid "Can't import profile from {0} before a printer is added."
+msgstr "Import des Profils aus Datei {0} kann erst durchgeführt werden, wenn ein Drucker hinzugefügt wurde."
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:198
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "No custom profile to import in file {0}"
msgstr "Kein benutzerdefiniertes Profil für das Importieren in Datei {0}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:194
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:202
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "Failed to import profile from {0}:"
msgstr "Import des Profils aus Datei {0} fehlgeschlagen:"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:218
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:228
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:226
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:236
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "This profile {0} contains incorrect data, could not import it."
msgstr "Dieses Profil {0} enthält falsche Daten, Importieren nicht möglich."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:241
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:325
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags !"
-msgid "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it."
-msgstr "Die Maschine, die im Profil {0} ({1}) definiert wurde, entspricht nicht Ihrer derzeitigen Maschine ({2}). Importieren nicht möglich."
-
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:312
-#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
+msgctxt "@info:status Don't translate the XML tag !"
msgid "Failed to import profile from {0}:"
msgstr "Import des Profils aus Datei {0} fehlgeschlagen:"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:315
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:328
#, python-brace-format
msgctxt "@info:status"
msgid "Successfully imported profile {0}"
msgstr "Profil erfolgreich importiert {0}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:318
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:331
#, python-brace-format
msgctxt "@info:status"
msgid "File {0} does not contain any valid profile."
msgstr "Datei {0} enthält kein gültiges Profil."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:321
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:334
#, python-brace-format
msgctxt "@info:status"
msgid "Profile {0} has an unknown file type or is corrupted."
msgstr "Profil {0} hat einen unbekannten Dateityp oder ist beschädigt."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:339
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
msgctxt "@label"
msgid "Custom profile"
msgstr "Benutzerdefiniertes Profil"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:355
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:385
msgctxt "@info:status"
msgid "Profile is missing a quality type."
msgstr "Für das Profil fehlt eine Qualitätsangabe."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:399
#, python-brace-format
msgctxt "@info:status"
msgid "Could not find a quality type {0} for the current configuration."
msgstr "Es konnte keine Qualitätsangabe {0} für die vorliegende Konfiguration gefunden werden."
-#: /home/ruben/Projects/Cura/cura/ObjectsModel.py:63
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:76
+msgctxt "@tooltip"
+msgid "Outer Wall"
+msgstr "Außenwand"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:77
+msgctxt "@tooltip"
+msgid "Inner Walls"
+msgstr "Innenwände"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:78
+msgctxt "@tooltip"
+msgid "Skin"
+msgstr "Außenhaut"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:79
+msgctxt "@tooltip"
+msgid "Infill"
+msgstr "Füllung"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:80
+msgctxt "@tooltip"
+msgid "Support Infill"
+msgstr "Stützstruktur-Füllung"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:81
+msgctxt "@tooltip"
+msgid "Support Interface"
+msgstr "Stützstruktur-Schnittstelle"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:82
+msgctxt "@tooltip"
+msgid "Support"
+msgstr "Stützstruktur"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:83
+msgctxt "@tooltip"
+msgid "Skirt"
+msgstr "Skirt"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:84
+msgctxt "@tooltip"
+msgid "Prime Tower"
+msgstr "Einzugsturm"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:85
+msgctxt "@tooltip"
+msgid "Travel"
+msgstr "Bewegungen"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:86
+msgctxt "@tooltip"
+msgid "Retractions"
+msgstr "Einzüge"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:87
+msgctxt "@tooltip"
+msgid "Other"
+msgstr "Sonstige"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:302
+#, python-brace-format
+msgctxt "@label"
+msgid "Pre-sliced file {0}"
+msgstr "Vorgeschnittene Datei {0}"
+
+#: /home/ruben/Projects/Cura/cura/UI/WelcomePagesModel.py:56
+msgctxt "@action:button"
+msgid "Next"
+msgstr "Weiter"
+
+#: /home/ruben/Projects/Cura/cura/UI/ObjectsModel.py:62
#, python-brace-format
msgctxt "@label"
msgid "Group #{group_nr}"
msgstr "Gruppe #{group_nr}"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:65
-msgctxt "@info:title"
-msgid "Network enabled printers"
-msgstr "Netzwerkfähige Drucker"
+#: /home/ruben/Projects/Cura/cura/UI/WhatsNewPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:482
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:124
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:169
+msgctxt "@action:button"
+msgid "Close"
+msgstr "Schließen"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:80
-msgctxt "@info:title"
-msgid "Local printers"
-msgstr "Lokale Drucker"
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
+msgctxt "@action:button"
+msgid "Add"
+msgstr "Hinzufügen"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:109
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:18
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:81
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:352
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:58
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:149
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:406
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:294
+msgctxt "@action:button"
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:36
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:320
+msgctxt "@label"
+msgid "Default"
+msgstr "Default"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:39
+msgctxt "@label"
+msgid "Visual"
+msgstr "Visuell"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:40
+msgctxt "@text"
+msgid "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality."
+msgstr "Das visuelle Profil wurde für den Druck visueller Prototypen und Modellen entwickelt, bei denen das Ziel eine hohe visuelle Qualität und eine hohe Oberflächenqualität"
+" ist."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:43
+msgctxt "@label"
+msgid "Engineering"
+msgstr "Engineering"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:44
+msgctxt "@text"
+msgid "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances."
+msgstr "Das Engineering-Profil ist für den Druck von Funktionsprototypen und Endnutzungsteilen gedacht, bei denen Präzision gefragt ist und engere Toleranzen gelten."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:47
+msgctxt "@label"
+msgid "Draft"
+msgstr "Entwurf"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:48
+msgctxt "@text"
+msgid "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction."
+msgstr "Das Entwurfsprofil wurde für erste Prototypen und die Konzeptvalidierung entwickelt, um einen deutlich schnelleren Druck zu ermöglichen."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/ExtrudersModel.py:208
+msgctxt "@menuitem"
+msgid "Not overridden"
+msgstr "Nicht überschrieben"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:357
+msgctxt "@label"
+msgid "Custom profiles"
+msgstr "Benutzerdefinierte Profile"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:391
#, python-brace-format
msgctxt "@item:inlistbox"
msgid "All Supported Types ({0})"
msgstr "Alle unterstützten Typen ({0})"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:110
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:392
msgctxt "@item:inlistbox"
msgid "All Files (*)"
msgstr "Alle Dateien (*)"
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:636
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:213
msgctxt "@label"
msgid "Custom Material"
msgstr "Benutzerdefiniertes Material"
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:637
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:214
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:205
msgctxt "@label"
msgid "Custom"
msgstr "Benutzerdefiniert"
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:81
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:116
+msgctxt "@label"
+msgid "The printer(s) below cannot be connected because they are part of a group"
+msgstr "Der/die nachfolgende(n) Drucker kann/können nicht verbunden werden, weil er/sie Teil einer Gruppe ist/sind"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:118
+msgctxt "@label"
+msgid "Available networked printers"
+msgstr "Verfügbare vernetzte Drucker"
+
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:90
msgctxt "@info:status"
msgid "The build volume height has been reduced due to the value of the \"Print Sequence\" setting to prevent the gantry from colliding with printed models."
msgstr "Die Höhe der Druckabmessung wurde aufgrund des Wertes der Einstellung „Druckreihenfolge“ reduziert, um eine Kollision der Brücke mit den gedruckten Modellen zu verhindern."
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:83
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:92
msgctxt "@info:title"
msgid "Build Volume"
msgstr "Produktabmessungen"
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:98
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:99
msgctxt "@info:backup_failed"
msgid "Could not create archive from user data directory: {}"
msgstr "Konnte kein Archiv von Benutzer-Datenverzeichnis {} erstellen"
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:103
-msgctxt "@info:title"
-msgid "Backup"
-msgstr "Backup"
-
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:113
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:114
msgctxt "@info:backup_failed"
msgid "Tried to restore a Cura backup without having proper data or meta data."
msgstr "Versucht, ein Cura-Backup-Verzeichnis ohne entsprechende Daten oder Metadaten wiederherzustellen."
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:123
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:125
msgctxt "@info:backup_failed"
-msgid "Tried to restore a Cura backup that does not match your current version."
-msgstr "Versucht, ein Cura-Backup zu erstellen, das nicht Ihrer aktuellen Version entspricht."
+msgid "Tried to restore a Cura backup that is higher than the current version."
+msgstr "Versucht, ein Cura-Backup wiederherzustellen, das eine höhere Version als die aktuelle hat."
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:27
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationHelpers.py:79
+msgctxt "@message"
+msgid "Could not read response."
+msgstr "Antwort konnte nicht gelesen werden."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+msgctxt "@info"
+msgid "Unable to reach the Ultimaker account server."
+msgstr "Der Ultimaker-Konto-Server konnte nicht erreicht werden."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:70
+msgctxt "@message"
+msgid "Please give the required permissions when authorizing this application."
+msgstr "Erteilen Sie bitte die erforderlichen Freigaben bei der Autorisierung dieser Anwendung."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:77
+msgctxt "@message"
+msgid "Something unexpected happened when trying to log in, please try again."
+msgstr "Bei dem Versuch, sich anzumelden, trat ein unerwarteter Fehler auf. Bitte erneut versuchen."
+
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:29
msgctxt "@info:status"
msgid "Multiplying and placing objects"
msgstr "Objekte vervielfältigen und platzieren"
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:28
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:30
msgctxt "@info:title"
-msgid "Placing Object"
-msgstr "Objekt-Platzierung"
+msgid "Placing Objects"
+msgstr "Objekte platzieren"
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:96
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:103
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:149
msgctxt "@info:status"
msgid "Unable to find a location within the build volume for all objects"
msgstr "Innerhalb der Druckabmessung für alle Objekte konnte keine Position gefunden werden"
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+msgctxt "@info:title"
+msgid "Placing Object"
+msgstr "Objekt-Platzierung"
+
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:30
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:67
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:66
msgctxt "@info:status"
msgid "Finding new location for objects"
msgstr "Neue Position für Objekte finden"
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:34
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:71
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:70
msgctxt "@info:title"
msgid "Finding Location"
msgstr "Position finden"
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:97
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:151
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:104
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
msgctxt "@info:title"
msgid "Can't Find Location"
msgstr "Kann Position nicht finden"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:87
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:83
msgctxt "@title:window"
msgid "Cura can't start"
msgstr "Cura kann nicht starten"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:93
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:89
msgctxt "@label crash message"
msgid ""
"
Oops, Ultimaker Cura has encountered something that doesn't seem right.
\n"
@@ -1069,356 +1160,328 @@ msgid ""
"
Backups can be found in the configuration folder.
\n"
"
Please send us this Crash Report to fix the problem.
\n"
" "
-msgstr "
Hoppla, bei Ultimaker Cura ist ein Problem aufgetreten.
\n
Beim Start ist ein nicht behebbarer Fehler aufgetreten. Er wurde möglicherweise durch einige falsche Konfigurationsdateien verursacht. Wir empfehlen ein Backup und Reset Ihrer Konfiguration.
\n
Backups sind im Konfigurationsordner abgelegt.
\n
Senden Sie uns diesen Absturzbericht bitte, um das Problem zu beheben.
\n "
+msgstr ""
+"
Hoppla, bei Ultimaker Cura ist ein Problem aufgetreten.
\n"
+"
Beim Start ist ein nicht behebbarer Fehler aufgetreten. Er wurde möglicherweise durch einige falsche Konfigurationsdateien verursacht. Wir empfehlen ein Backup und Reset Ihrer Konfiguration.
\n"
+"
Backups sind im Konfigurationsordner abgelegt.
\n"
+"
Senden Sie uns diesen Absturzbericht bitte, um das Problem zu beheben.
"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:222
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:218
msgctxt "@title:groupbox"
msgid "Error traceback"
msgstr "Fehler-Rückverfolgung"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:303
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:299
msgctxt "@title:groupbox"
msgid "Logs"
msgstr "Protokolle"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:326
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:322
msgctxt "@title:groupbox"
-msgid "User description"
-msgstr "Benutzerbeschreibung"
+msgid "User description (Note: Developers may not speak your language, please use English if possible)"
+msgstr "Benutzerbeschreibung (Hinweis: Bitte schreiben Sie auf Englisch, da die Entwickler Ihre Sprache möglicherweise nicht beherrschen.)"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:345
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:342
msgctxt "@action:button"
msgid "Send report"
msgstr "Bericht senden"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:473
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:513
msgctxt "@info:progress"
msgid "Loading machines..."
msgstr "Geräte werden geladen..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:775
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:520
+msgctxt "@info:progress"
+msgid "Setting up preferences..."
+msgstr "Erstellungen werden eingerichtet ..."
+
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:824
msgctxt "@info:progress"
msgid "Setting up scene..."
msgstr "Die Szene wird eingerichtet..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:811
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:859
msgctxt "@info:progress"
msgid "Loading interface..."
msgstr "Die Benutzeroberfläche wird geladen..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1037
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1150
#, python-format
msgctxt "@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm."
msgid "%(width).1f x %(depth).1f x %(height).1f mm"
msgstr "%(width).1f x %(depth).1f x %(height).1f mm"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1596
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1657
#, python-brace-format
msgctxt "@info:status"
msgid "Only one G-code file can be loaded at a time. Skipped importing {0}"
msgstr "Es kann nur jeweils ein G-Code gleichzeitig geladen werden. Wichtige {0} werden übersprungen."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1606
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1667
#, python-brace-format
msgctxt "@info:status"
msgid "Can't open any other file if G-code is loading. Skipped importing {0}"
msgstr "Wenn G-Code geladen wird, kann keine weitere Datei geöffnet werden. Wichtige {0} werden übersprungen."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1694
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1757
msgctxt "@info:status"
msgid "The selected model was too small to load."
msgstr "Das gewählte Modell war zu klein zum Laden."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:61
-msgctxt "@title"
-msgid "Machine Settings"
-msgstr "Geräteeinstellungen"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:80
-msgctxt "@title:tab"
-msgid "Printer"
-msgstr "Drucker"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:99
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:56
+msgctxt "@title:label"
msgid "Printer Settings"
msgstr "Druckereinstellungen"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:110
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:70
msgctxt "@label"
msgid "X (Width)"
msgstr "X (Breite)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:111
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:121
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:131
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:237
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:386
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:402
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:428
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:440
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:896
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:74
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:88
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:102
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:243
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:265
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:285
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:79
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:93
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:109
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:124
msgctxt "@label"
msgid "mm"
msgstr "mm"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:120
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:84
msgctxt "@label"
msgid "Y (Depth)"
msgstr "Y (Tiefe)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:130
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:98
msgctxt "@label"
msgid "Z (Height)"
msgstr "Z (Höhe)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:142
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:112
msgctxt "@label"
msgid "Build plate shape"
msgstr "Druckbettform"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:151
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:125
+msgctxt "@label"
msgid "Origin at center"
msgstr "Ausgang in Mitte"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:159
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:137
+msgctxt "@label"
msgid "Heated bed"
msgstr "Heizbares Bett"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:170
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:149
+msgctxt "@label"
+msgid "Heated build volume"
+msgstr "Druckraum aufgeheizt"
+
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:161
msgctxt "@label"
msgid "G-code flavor"
msgstr "G-Code-Variante"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:183
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:185
+msgctxt "@title:label"
msgid "Printhead Settings"
msgstr "Druckkopfeinstellungen"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:193
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:199
msgctxt "@label"
msgid "X min"
msgstr "X min."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:194
-msgctxt "@tooltip"
-msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Abstand von der linken Seite des Druckkopfes zur Düsenmitte. Wird verwendet, um Kollisionen zwischen vorherigen Drucken und dem Druckkopf während des Druckmodus „Nacheinander“ zu vermeiden."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:219
msgctxt "@label"
msgid "Y min"
msgstr "Y min."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:204
-msgctxt "@tooltip"
-msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Abstand von der Vorderseite des Druckkopfes zur Düsenmitte. Wird verwendet, um Kollisionen zwischen vorherigen Drucken und dem Druckkopf während des Druckmodus „Nacheinander“ zu vermeiden."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:213
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:239
msgctxt "@label"
msgid "X max"
msgstr "X max."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:214
-msgctxt "@tooltip"
-msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Abstand von der rechten Seite des Druckkopfes zur Düsenmitte. Wird verwendet, um Kollisionen zwischen vorherigen Drucken und dem Druckkopf während des Druckmodus „Nacheinander“ zu vermeiden."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:261
msgctxt "@label"
msgid "Y max"
msgstr "Y max."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:224
-msgctxt "@tooltip"
-msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Abstand von der Rückseite des Druckkopfes zur Düsenmitte. Wird verwendet, um Kollisionen zwischen vorherigen Drucken und dem Druckkopf während des Druckmodus „Nacheinander“ zu vermeiden."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:236
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:281
msgctxt "@label"
-msgid "Gantry height"
+msgid "Gantry Height"
msgstr "Brückenhöhe"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:238
-msgctxt "@tooltip"
-msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
-msgstr "Der Höhenunterschied zwischen der Düsenspitze und dem Brückensystem (X- und Y-Achsen). Wird verwendet, um Kollisionen zwischen vorherigen Drucken und der Brücke zu verhindern, wenn im Modus „Nacheinander“ gedruckt wird."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:257
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:295
msgctxt "@label"
msgid "Number of Extruders"
msgstr "Anzahl Extruder"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:313
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:355
+msgctxt "@title:label"
msgid "Start G-code"
-msgstr "Start G-code"
+msgstr "Start G-Code"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:323
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very start."
-msgstr "G-Code-Befehle, die zum Start ausgeführt werden sollen."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:332
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:366
+msgctxt "@title:label"
msgid "End G-code"
-msgstr "Ende G-code"
+msgstr "Ende G-Code"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:342
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very end."
-msgstr "G-Code-Befehle, die am Ende ausgeführt werden sollen."
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:42
+msgctxt "@title:tab"
+msgid "Printer"
+msgstr "Drucker"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:373
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:63
+msgctxt "@title:label"
msgid "Nozzle Settings"
msgstr "Düseneinstellungen"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:385
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:75
msgctxt "@label"
msgid "Nozzle size"
msgstr "Düsengröße"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:401
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:89
msgctxt "@label"
msgid "Compatible material diameter"
msgstr "Kompatibler Materialdurchmesser"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:403
-msgctxt "@tooltip"
-msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
-msgstr "Der Nenndurchmesser des durch den Drucker unterstützten Filaments. Der exakte Durchmesser wird durch das Material und/oder das Profil überschrieben."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:427
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:105
msgctxt "@label"
msgid "Nozzle offset X"
msgstr "X-Versatz Düse"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:439
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:120
msgctxt "@label"
msgid "Nozzle offset Y"
msgstr "Y-Versatz Düse"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:451
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:135
msgctxt "@label"
msgid "Cooling Fan Number"
msgstr "Kühllüfter-Nr."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:452
-msgctxt "@label"
-msgid ""
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:472
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:162
+msgctxt "@title:label"
msgid "Extruder Start G-code"
msgstr "G-Code Extruder-Start"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:490
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:176
+msgctxt "@title:label"
msgid "Extruder End G-code"
msgstr "G-Code Extruder-Ende"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
msgctxt "@action:button"
msgid "Install"
msgstr "Installieren"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:20
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
msgctxt "@action:button"
msgid "Installed"
msgstr "Installiert"
@@ -1428,69 +1491,82 @@ msgctxt "@info"
msgid "Could not connect to the Cura Package database. Please check your connection."
msgstr "Verbindung zur Cura Paket-Datenbank konnte nicht hergestellt werden. Bitte überprüfen Sie Ihre Verbindung."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:38
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:28
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/SmallRatingWidget.qml:27
+msgctxt "@label"
+msgid "ratings"
+msgstr "Bewertungen"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:30
msgctxt "@title:tab"
msgid "Plugins"
msgstr "Plugins"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:75
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:42
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:66
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:77
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:44
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:89
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:417
msgctxt "@title:tab"
msgid "Materials"
msgstr "Materialien"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:79
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+msgctxt "@label"
+msgid "Your rating"
+msgstr "Ihre Bewertung"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:99
msgctxt "@label"
msgid "Version"
msgstr "Version"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:85
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:106
msgctxt "@label"
msgid "Last updated"
msgstr "Zuletzt aktualisiert"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:113
msgctxt "@label"
msgid "Author"
msgstr "Autor"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:120
msgctxt "@label"
msgid "Downloads"
msgstr "Downloads"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:116
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:158
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:258
-msgctxt "@label"
-msgid "Unknown"
-msgstr "Unbekannt"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:56
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to install or update"
+msgstr "Anmeldung für Installation oder Update erforderlich"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:44
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:30
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:80
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Buy material spools"
+msgstr "Materialspulen kaufen"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:96
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:34
msgctxt "@action:button"
msgid "Update"
msgstr "Aktualisierung"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:45
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:35
msgctxt "@action:button"
msgid "Updating"
msgstr "Aktualisierung wird durchgeführt"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:98
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:36
msgctxt "@action:button"
msgid "Updated"
msgstr "Aktualisiert"
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/Toolbox.qml:13
msgctxt "@title"
-msgid "Toolbox"
-msgstr "Toolbox"
+msgid "Marketplace"
+msgstr "Marktplatz"
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml:25
msgctxt "@action:button"
@@ -1517,52 +1593,67 @@ msgctxt "@text:window"
msgid "Profiles"
msgstr "Profile"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:89
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:90
msgctxt "@action:button"
msgid "Confirm"
msgstr "Bestätigen"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to login first before you can rate"
+msgstr "Vor der Bewertung müssen Sie sich anmelden"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to install the package before you can rate"
+msgstr "Vor der Bewertung müssen Sie das Paket installierten"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:19
msgctxt "@info"
msgid "You will need to restart Cura before changes in packages have effect."
msgstr "Cura muss neu gestartet werden, um die Änderungen der Pakete zu übernehmen."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:45
msgctxt "@info:button"
msgid "Quit Cura"
msgstr "Quit Cura"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Contributions"
msgstr "Community-Beiträge"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Plugins"
msgstr "Community-Plugins"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:43
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:40
msgctxt "@label"
msgid "Generic Materials"
msgstr "Generische Materialien"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:56
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:59
msgctxt "@title:tab"
msgid "Installed"
msgstr "Installiert"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:22
msgctxt "@label"
msgid "Will install upon restarting"
msgstr "Installiert nach Neustart"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:53
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to update"
+msgstr "Anmeldung für Update erforderlich"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Downgrade"
msgstr "Downgraden"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Uninstall"
msgstr "Deinstallieren"
@@ -1578,14 +1669,17 @@ msgid ""
"This plugin contains a license.\n"
"You need to accept this license to install this plugin.\n"
"Do you agree with the terms below?"
-msgstr "Dieses Plugin enthält eine Lizenz.\nSie müssen diese Lizenz akzeptieren, um das Plugin zu installieren.\nStimmen Sie den nachfolgenden Bedingungen zu?"
+msgstr ""
+"Dieses Plugin enthält eine Lizenz.\n"
+"Sie müssen diese Lizenz akzeptieren, um das Plugin zu installieren.\n"
+"Stimmen Sie den nachfolgenden Bedingungen zu?"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:54
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:55
msgctxt "@action:button"
msgid "Accept"
msgstr "Akzeptieren"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:65
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:66
msgctxt "@action:button"
msgid "Decline"
msgstr "Ablehnen"
@@ -1595,22 +1689,62 @@ msgctxt "@label"
msgid "Featured"
msgstr "Unterstützter"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:34
msgctxt "@label"
msgid "Compatibility"
msgstr "Kompatibilität"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:124
+msgctxt "@label:table_header"
+msgid "Machine"
+msgstr "Gerät"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:137
+msgctxt "@label:table_header"
+msgid "Build Plate"
+msgstr "Druckbett"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:143
+msgctxt "@label:table_header"
+msgid "Support"
+msgstr "Support"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:149
+msgctxt "@label:table_header"
+msgid "Quality"
+msgstr "Qualität"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:170
+msgctxt "@action:label"
+msgid "Technical Data Sheet"
+msgstr "Technisches Datenblatt"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:179
+msgctxt "@action:label"
+msgid "Safety Data Sheet"
+msgstr "Sicherheitsdatenblatt"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:188
+msgctxt "@action:label"
+msgid "Printing Guidelines"
+msgstr "Druckrichtlinien"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:197
+msgctxt "@action:label"
+msgid "Website"
+msgstr "Website"
+
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml:16
msgctxt "@info"
msgid "Fetching packages..."
msgstr "Pakete werden abgeholt..."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:88
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:91
msgctxt "@label"
msgid "Website"
msgstr "Website"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:94
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:98
msgctxt "@label"
msgid "Email"
msgstr "E-Mail"
@@ -1620,23 +1754,6 @@ msgctxt "@info:tooltip"
msgid "Some things could be problematic in this print. Click to see tips for adjustment."
msgstr "Einige Punkte bei diesem Druck könnten problematisch sein. Klicken Sie, um Tipps für die Anpassung zu erhalten."
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18
-msgctxt "@label"
-msgid "Changelog"
-msgstr "Änderungsprotokoll"
-
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:37
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:53
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:467
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:514
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:121
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:166
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:38
-msgctxt "@action:button"
-msgid "Close"
-msgstr "Schließen"
-
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:31
msgctxt "@title"
msgid "Update Firmware"
@@ -1712,423 +1829,504 @@ msgctxt "@label"
msgid "Firmware update failed due to missing firmware."
msgstr "Die Firmware-Aktualisierung ist aufgrund von fehlender Firmware fehlgeschlagen."
-#: /home/ruben/Projects/Cura/plugins/UserAgreement/UserAgreement.qml:16
-msgctxt "@title:window"
-msgid "User Agreement"
-msgstr "Benutzervereinbarung"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:155
+msgctxt "@label link to Connect and Cloud interfaces"
+msgid "Manage printer"
+msgstr "Drucker verwalten"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:46
-msgctxt "@window:title"
-msgid "Existing Connection"
-msgstr "Vorhandene Verbindung"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:192
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:183
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:153
+msgctxt "@label"
+msgid "Glass"
+msgstr "Glas"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:48
-msgctxt "@message:text"
-msgid "This printer/group is already added to Cura. Please select another printer/group."
-msgstr "Diese/r Drucker/Gruppe wurde bereits zu Cura hinzugefügt. Wählen Sie bitte eine/n andere/n Drucker/Gruppe."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:256
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:514
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:248
+msgctxt "@info"
+msgid "Please update your printer's firmware to manage the queue remotely."
+msgstr "Damit Sie die Warteschlange aus der Ferne verwalten können, müssen Sie die Druckfirmware aktualisieren."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:65
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:289
+msgctxt "@info"
+msgid "The webcam is not available because you are monitoring a cloud printer."
+msgstr "Die Webcam ist nicht verfügbar, weil Sie einen Cloud-Drucker überwachen."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:348
+msgctxt "@label:status"
+msgid "Loading..."
+msgstr "Lädt..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:352
+msgctxt "@label:status"
+msgid "Unavailable"
+msgstr "Nicht verfügbar"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:356
+msgctxt "@label:status"
+msgid "Unreachable"
+msgstr "Nicht erreichbar"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:360
+msgctxt "@label:status"
+msgid "Idle"
+msgstr "Leerlauf"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:401
+msgctxt "@label"
+msgid "Untitled"
+msgstr "Unbenannt"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:422
+msgctxt "@label"
+msgid "Anonymous"
+msgstr "Anonym"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:449
+msgctxt "@label:status"
+msgid "Requires configuration changes"
+msgstr "Erfordert Konfigurationsänderungen"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:487
+msgctxt "@action:button"
+msgid "Details"
+msgstr "Details"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:132
+msgctxt "@label"
+msgid "Unavailable printer"
+msgstr "Drucker nicht verfügbar"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:134
+msgctxt "@label"
+msgid "First available"
+msgstr "Zuerst verfügbar"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:31
+msgctxt "@label"
+msgid "Queued"
+msgstr "In Warteschlange"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:67
+msgctxt "@label link to connect manager"
+msgid "Manage in browser"
+msgstr "Im Browser verwalten"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:100
+msgctxt "@label"
+msgid "There are no print jobs in the queue. Slice and send a job to add one."
+msgstr "Die Warteschlange enthält keine Druckaufträge. Slicen Sie einen Auftrag und schicken Sie ihn ab, um ihn zur Warteschlange hinzuzufügen."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:115
+msgctxt "@label"
+msgid "Print jobs"
+msgstr "Druckaufträge"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:131
+msgctxt "@label"
+msgid "Total print time"
+msgstr "Druckdauer insgesamt"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:147
+msgctxt "@label"
+msgid "Waiting for"
+msgstr "Warten auf"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:45
msgctxt "@title:window"
msgid "Connect to Networked Printer"
msgstr "Anschluss an vernetzten Drucker"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:75
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
msgctxt "@label"
-msgid ""
-"To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
-"\n"
-"Select your printer from the list below:"
-msgstr "Um über das Netzwerk direkt auf Ihrem Drucker zu drucken, stellen Sie bitte sicher, dass der Drucker mit dem Netzwerkkabel verbunden ist oder verbinden Sie Ihren Drucker mit Ihrem WLAN-Netzwerk. Wenn Sie Cura nicht mit Ihrem Drucker verbinden, können Sie dennoch ein USB-Laufwerk für die Übertragung von G-Code-Dateien auf Ihren Drucker verwenden.\n\nWählen Sie Ihren Drucker aus der folgenden Liste:"
+msgid "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer."
+msgstr "Um direkt auf Ihrem Drucker über das Netzwerk zu drucken, muss der Drucker über ein Netzwerkkabel oder per WLAN mit dem Netzwerk verbunden sein. Wenn Sie Cura nicht mit Ihrem Drucker verbinden, können Sie G-Code-Dateien auf einen USB-Stick kopieren und diesen am Drucker anschließen."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:85
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:42
-msgctxt "@action:button"
-msgid "Add"
-msgstr "Hinzufügen"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
+msgctxt "@label"
+msgid "Select your printer from the list below:"
+msgstr "Wählen Sie Ihren Drucker aus der folgenden Liste aus:"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:95
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:77
msgctxt "@action:button"
msgid "Edit"
msgstr "Bearbeiten"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:106
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:128
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:117
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:88
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:138
msgctxt "@action:button"
msgid "Remove"
msgstr "Entfernen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:114
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:96
msgctxt "@action:button"
msgid "Refresh"
msgstr "Aktualisieren"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:207
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:176
msgctxt "@label"
msgid "If your printer is not listed, read the network printing troubleshooting guide"
msgstr "Wenn Ihr Drucker nicht aufgeführt ist, lesen Sie die Anleitung für Fehlerbehebung für Netzwerkdruck"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:234
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:205
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:258
msgctxt "@label"
msgid "Type"
msgstr "Typ"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:271
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:274
msgctxt "@label"
msgid "Firmware version"
msgstr "Firmware-Version"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:290
msgctxt "@label"
msgid "Address"
msgstr "Adresse"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:305
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:263
msgctxt "@label"
msgid "This printer is not set up to host a group of printers."
msgstr "Dieser Drucker ist nicht eingerichtet um eine Gruppe von Druckern anzusteuern."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:309
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:267
msgctxt "@label"
msgid "This printer is the host for a group of %1 printers."
msgstr "Dieser Drucker steuert eine Gruppe von %1 Druckern an."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:319
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:278
msgctxt "@label"
msgid "The printer at this address has not yet responded."
msgstr "Der Drucker unter dieser Adresse hat nicht reagiert."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:324
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
msgctxt "@action:button"
msgid "Connect"
msgstr "Verbinden"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:338
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:296
+msgctxt "@title:window"
+msgid "Invalid IP address"
+msgstr "Ungültige IP-Adresse"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:146
+msgctxt "@text"
+msgid "Please enter a valid IP address."
+msgstr "Bitte eine gültige IP-Adresse eingeben."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:308
msgctxt "@title:window"
msgid "Printer Address"
msgstr "Druckeradresse"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
-msgctxt "@alabel"
-msgid "Enter the IP address or hostname of your printer on the network."
-msgstr "Geben Sie die IP-Adresse oder den Hostnamen Ihres Druckers auf dem Netzwerk ein."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:102
+msgctxt "@label"
+msgid "Enter the IP address of your printer on the network."
+msgstr "Geben Sie die IP-Adresse Ihres Druckers in das Netzwerk ein."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:390
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:132
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:138
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:181
msgctxt "@action:button"
msgid "OK"
msgstr "OK"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:44
-msgctxt "@action:button"
-msgid "Print"
-msgstr "Drucken"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:47
-msgctxt "@title:window"
-msgid "Print over network"
-msgstr "Drucken über Netzwerk"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:79
-msgctxt "@label"
-msgid "Printer selection"
-msgstr "Druckerauswahl"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:173
-msgctxt "@label"
-msgid "Not available"
-msgstr "Nicht verfügbar"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:175
-msgctxt "@label"
-msgid "Unreachable"
-msgstr "Nicht erreichbar"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:180
-msgctxt "@label"
-msgid "Available"
-msgstr "Verfügbar"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:37
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:44
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:46
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:78
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:90
msgctxt "@label:status"
msgid "Aborted"
msgstr "Abgebrochen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:39
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:80
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:82
msgctxt "@label:status"
msgid "Finished"
msgstr "Beendet"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:84
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:86
msgctxt "@label:status"
-msgid "Preparing"
-msgstr "Vorbereitung"
+msgid "Preparing..."
+msgstr "Vorbereitung..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:48
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:88
msgctxt "@label:status"
-msgid "Pausing"
-msgstr "Wird pausiert"
+msgid "Aborting..."
+msgstr "Wird abgebrochen..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:52
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:92
msgctxt "@label:status"
-msgid "Resuming"
-msgstr "Wird fortgesetzt"
+msgid "Pausing..."
+msgstr "Wird pausiert..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:54
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:94
+msgctxt "@label:status"
+msgid "Paused"
+msgstr "Pausiert"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:96
+msgctxt "@label:status"
+msgid "Resuming..."
+msgstr "Wird fortgesetzt..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:98
msgctxt "@label:status"
msgid "Action required"
msgstr "Handlung erforderlich"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:213
-msgctxt "@label"
-msgid "Waiting for: Unavailable printer"
-msgstr "Warten auf: Drucker nicht verfügbar"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:100
+msgctxt "@label:status"
+msgid "Finishes %1 at %2"
+msgstr "Fertigstellung %1 auf %2"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:215
-msgctxt "@label"
-msgid "Waiting for: First available"
-msgstr "Warten auf: Ersten verfügbaren"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:11
+msgctxt "@title:window"
+msgid "Print over network"
+msgstr "Drucken über Netzwerk"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:217
-msgctxt "@label"
-msgid "Waiting for: "
-msgstr "Warten auf: "
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:299
-msgctxt "@label"
-msgid "Configuration change"
-msgstr "Konfigurationsänderung"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:365
-msgctxt "@label"
-msgid "The assigned printer, %1, requires the following configuration change(s):"
-msgstr "Der zugewiesene Drucker %1 erfordert die folgende(n) Konfigurationsänderung(en):"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:367
-msgctxt "@label"
-msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
-msgstr "Der Drucker %1 wurde zugewiesen, allerdings enthält der Auftrag eine unbekannte Materialkonfiguration."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:375
-msgctxt "@label"
-msgid "Change material %1 from %2 to %3."
-msgstr "Material %1 von %2 auf %3 wechseln."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:378
-msgctxt "@label"
-msgid "Load %3 as material %1 (This cannot be overridden)."
-msgstr "%3 als Material %1 laden (Dies kann nicht übergangen werden)."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:381
-msgctxt "@label"
-msgid "Change print core %1 from %2 to %3."
-msgstr "Print Core %1 von %2 auf %3 wechseln."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:384
-msgctxt "@label"
-msgid "Change build plate to %1 (This cannot be overridden)."
-msgstr "Druckplatte auf %1 wechseln (Dies kann nicht übergangen werden)."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:404
-msgctxt "@label"
-msgid "Override"
-msgstr "Überschreiben"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:432
-msgctxt "@label"
-msgid "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?"
-msgstr "Das Starten eines Druckauftrags mit einer inkompatiblen Konfiguration kann Ihren 3D-Drucker beschädigen. Möchten Sie die Konfiguration wirklich überschreiben und %1 drucken?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:435
-msgctxt "@window:title"
-msgid "Override configuration configuration and start print"
-msgstr "Konfiguration überschreiben und Druck starten"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:466
-msgctxt "@label"
-msgid "Glass"
-msgstr "Glas"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:469
-msgctxt "@label"
-msgid "Aluminum"
-msgstr "Aluminium"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:39
-msgctxt "@label link to connect manager"
-msgid "Manage queue"
-msgstr "Warteschlange verwalten"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:60
-msgctxt "@label"
-msgid "Queued"
-msgstr "In Warteschlange"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:36
-msgctxt "@label"
-msgid "Printing"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:52
+msgctxt "@action:button"
+msgid "Print"
msgstr "Drucken"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:49
-msgctxt "@label link to connect manager"
-msgid "Manage printers"
-msgstr "Drucker verwalten"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:80
+msgctxt "@label"
+msgid "Printer selection"
+msgstr "Druckerauswahl"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:115
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:54
msgctxt "@label"
msgid "Move to top"
msgstr "Vorziehen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:124
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:70
msgctxt "@label"
msgid "Delete"
msgstr "Löschen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:100
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:289
msgctxt "@label"
msgid "Resume"
msgstr "Zurückkehren"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:102
+msgctxt "@label"
+msgid "Pausing..."
+msgstr "Wird pausiert..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:104
+msgctxt "@label"
+msgid "Resuming..."
+msgstr "Wird fortgesetzt..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:106
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:284
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:293
msgctxt "@label"
msgid "Pause"
msgstr "Pausieren"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:146
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
+msgctxt "@label"
+msgid "Aborting..."
+msgstr "Wird abgebrochen..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
msgctxt "@label"
msgid "Abort"
msgstr "Abbrechen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:178
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:143
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to move %1 to the top of the queue?"
msgstr "Soll dieser %1 wirklich an den Anfang der Warteschlange vorgezogen werden?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:179
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:144
msgctxt "@window:title"
msgid "Move print job to top"
msgstr "Druckauftrag vorziehen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:188
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:153
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to delete %1?"
msgstr "Soll %1 wirklich gelöscht werden?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:189
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:154
msgctxt "@window:title"
msgid "Delete print job"
msgstr "Druckauftrag löschen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:198
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:163
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to abort %1?"
msgstr "Möchten Sie %1 wirklich abbrechen?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:199
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:164
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:335
msgctxt "@window:title"
msgid "Abort print"
msgstr "Drucken abbrechen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:43
-msgctxt "@info:tooltip"
-msgid "Connect to a printer"
-msgstr "Mit einem Drucker verbinden"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:20
+msgctxt "@title:window"
+msgid "Configuration Changes"
+msgstr "Konfigurationsänderungen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:121
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:27
msgctxt "@action:button"
-msgid "Activate Configuration"
-msgstr "Konfiguration aktivieren"
+msgid "Override"
+msgstr "Überschreiben"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:122
-msgctxt "@info:tooltip"
-msgid "Load the configuration of the printer into Cura"
-msgstr "Die Druckerkonfiguration in Cura laden"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:85
+msgctxt "@label"
+msgid "The assigned printer, %1, requires the following configuration change:"
+msgid_plural "The assigned printer, %1, requires the following configuration changes:"
+msgstr[0] "Der zugewiesene Drucker %1 erfordert die folgende Konfigurationsänderung:"
+msgstr[1] "Der zugewiesene Drucker %1 erfordert die folgenden Konfigurationsänderungen:"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:130
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:89
+msgctxt "@label"
+msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
+msgstr "Der Drucker %1 wurde zugewiesen, allerdings enthält der Auftrag eine unbekannte Materialkonfiguration."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:99
+msgctxt "@label"
+msgid "Change material %1 from %2 to %3."
+msgstr "Material %1 von %2 auf %3 wechseln."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:102
+msgctxt "@label"
+msgid "Load %3 as material %1 (This cannot be overridden)."
+msgstr "%3 als Material %1 laden (Dies kann nicht übergangen werden)."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:105
+msgctxt "@label"
+msgid "Change print core %1 from %2 to %3."
+msgstr "Print Core %1 von %2 auf %3 wechseln."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:108
+msgctxt "@label"
+msgid "Change build plate to %1 (This cannot be overridden)."
+msgstr "Druckplatte auf %1 wechseln (Dies kann nicht übergangen werden)."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:115
+msgctxt "@label"
+msgid "Override will use the specified settings with the existing printer configuration. This may result in a failed print."
+msgstr "Überschreiben verwendet die definierten Einstellungen mit der vorhandenen Druckerkonfiguration. Dies kann zu einem fehlgeschlagenen Druck führen."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:156
+msgctxt "@label"
+msgid "Aluminum"
+msgstr "Aluminium"
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:100
+msgctxt "@info"
+msgid ""
+"Please make sure your printer has a connection:\n"
+"- Check if the printer is turned on.\n"
+"- Check if the printer is connected to the network.\n"
+"- Check if you are signed in to discover cloud-connected printers."
+msgstr ""
+"Stellen Sie sicher, dass der Drucker verbunden ist:\n"
+"– Prüfen Sie, ob der Drucker eingeschaltet ist.– Prüfen Sie, ob der Drucker mit dem Netzwerk verbunden ist.\n"
+"– Prüfen Sie, ob Sie angemeldet sind, falls Sie über die Cloud verbundene Drucker suchen möchten."
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:117
+msgctxt "@info"
+msgid "Please connect your printer to the network."
+msgstr "Verbinden Sie Ihren Drucker bitte mit dem Netzwerk."
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:156
+msgctxt "@label link to technical assistance"
+msgid "View user manuals online"
+msgstr "Benutzerhandbücher online anzeigen"
+
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:20
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:49
msgctxt "@label"
msgid "Color scheme"
msgstr "Farbschema"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:145
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:107
msgctxt "@label:listbox"
msgid "Material Color"
msgstr "Materialfarbe"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:149
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:111
msgctxt "@label:listbox"
msgid "Line Type"
msgstr "Linientyp"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:153
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:115
msgctxt "@label:listbox"
msgid "Feedrate"
msgstr "Vorschub"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:157
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:119
msgctxt "@label:listbox"
msgid "Layer thickness"
msgstr "Schichtdicke"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:198
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:156
msgctxt "@label"
msgid "Compatibility Mode"
msgstr "Kompatibilitätsmodus"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:284
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:230
msgctxt "@label"
-msgid "Show Travels"
-msgstr "Bewegungen anzeigen"
+msgid "Travels"
+msgstr "Bewegungen"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:290
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:236
msgctxt "@label"
-msgid "Show Helpers"
-msgstr "Helfer anzeigen"
+msgid "Helpers"
+msgstr "Helfer"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:296
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:242
msgctxt "@label"
-msgid "Show Shell"
-msgstr "Gehäuse anzeigen"
+msgid "Shell"
+msgstr "Gehäuse"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:302
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:248
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:65
msgctxt "@label"
-msgid "Show Infill"
-msgstr "Füllung anzeigen"
+msgid "Infill"
+msgstr "Füllung"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:355
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:298
msgctxt "@label"
msgid "Only Show Top Layers"
msgstr "Nur obere Schichten anzeigen"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:366
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:308
msgctxt "@label"
msgid "Show 5 Detailed Layers On Top"
msgstr "5 detaillierte Schichten oben anzeigen"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:379
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:322
msgctxt "@label"
msgid "Top / Bottom"
msgstr "Oben/Unten"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:383
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:326
msgctxt "@label"
msgid "Inner Wall"
msgstr "Innenwand"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:448
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:384
msgctxt "@label"
msgid "min"
msgstr "min."
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:500
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:433
msgctxt "@label"
msgid "max"
msgstr "max."
@@ -2143,40 +2341,40 @@ msgctxt "@label"
msgid "Post Processing Scripts"
msgstr "Skripts Nachbearbeitung"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:227
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:233
msgctxt "@action"
msgid "Add a script"
msgstr "Ein Skript hinzufügen"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:273
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:279
msgctxt "@label"
msgid "Settings"
msgstr "Einstellungen"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:477
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:493
msgctxt "@info:tooltip"
msgid "Change active post-processing scripts"
msgstr "Aktive Skripts Nachbearbeitung ändern"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:16
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:17
msgctxt "@title:window"
msgid "More information on anonymous data collection"
msgstr "Weitere Informationen zur anonymen Datenerfassung"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:66
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:74
msgctxt "@text:window"
-msgid "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent."
-msgstr "Cura sendet anonyme Daten an Ultimaker, um die Druckqualität und Benutzererfahrung zu steigern. Nachfolgend ist ein Beispiel aller Daten, die gesendet werden."
+msgid "Ultimaker Cura collects anonymous data in order to improve the print quality and user experience. Below is an example of all the data that is shared:"
+msgstr "Ultimaker Cura erfasst anonyme Daten, um die Druckqualität und Benutzererfahrung zu steigern. Nachfolgend ist ein Beispiel aller Daten, die geteilt werden:"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:101
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:109
msgctxt "@text:window"
-msgid "I don't want to send these data"
-msgstr "Ich möchte diese Daten nicht senden"
+msgid "I don't want to send anonymous data"
+msgstr "Ich möchte keine anonymen Daten senden"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:111
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:118
msgctxt "@text:window"
-msgid "Allow sending these data to Ultimaker and help us improve Cura"
-msgstr "Ich erlaube das Senden dieser Daten an Ultimaker, um Cura zu verbessern"
+msgid "Allow sending anonymous data"
+msgstr "Senden von anonymen Daten erlauben"
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:19
msgctxt "@title:window"
@@ -2225,19 +2423,19 @@ msgstr "Tiefe (mm)"
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:126
msgctxt "@info:tooltip"
-msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
-msgstr "Standardmäßig repräsentieren weiße Pixel hohe Punkte im Netz und schwarze Pixel repräsentieren niedrige Punkte im Netz. Ändern Sie diese Option um das Verhalten so umzukehren, dass schwarze Pixel hohe Punkte im Netz darstellen und weiße Pixel niedrige Punkte im Netz."
-
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
-msgctxt "@item:inlistbox"
-msgid "Lighter is higher"
-msgstr "Heller ist höher"
+msgid "For lithophanes dark pixels should correspond to thicker locations in order to block more light coming through. For height maps lighter pixels signify higher terrain, so lighter pixels should correspond to thicker locations in the generated 3D model."
+msgstr "Für Lithophanien sollten dunkle Pixel dickeren Positionen entsprechen, um mehr einfallendes Licht zu blockieren. Für Höhenkarten stellen hellere Pixel höheres Terrain dar, sodass hellere Pixel dickeren Positionen im generierten 3D-Modell entsprechen sollten."
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
msgctxt "@item:inlistbox"
msgid "Darker is higher"
msgstr "Dunkler ist höher"
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
+msgctxt "@item:inlistbox"
+msgid "Lighter is higher"
+msgstr "Heller ist höher"
+
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:149
msgctxt "@info:tooltip"
msgid "The amount of smoothing to apply to the image."
@@ -2248,81 +2446,80 @@ msgctxt "@action:label"
msgid "Smoothing"
msgstr "Glättung"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:37
-msgctxt "@label"
-msgid "Mesh Type"
-msgstr "Mesh-Typ"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:68
-msgctxt "@label"
-msgid "Normal model"
-msgstr "Normales Modell"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:75
-msgctxt "@label"
-msgid "Print as support"
-msgstr "Als Stützstruktur drucken"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:83
-msgctxt "@label"
-msgid "Don't support overlap with other models"
-msgstr "Keine Überlappung mit anderen Modellen unterstützen"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:91
-msgctxt "@label"
-msgid "Modify settings for overlap with other models"
-msgstr "Einstellungen für Überlappung mit anderen Modellen bearbeiten"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:99
-msgctxt "@label"
-msgid "Modify settings for infill of other models"
-msgstr "Einstellungen für Füllung von anderen Modellen bearbeiten"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:347
-msgctxt "@action:button"
-msgid "Select settings"
-msgstr "Einstellungen wählen"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:389
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:13
msgctxt "@title:window"
msgid "Select Settings to Customize for this model"
msgstr "Einstellungen für die benutzerdefinierte Anpassung dieses Modells wählen"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:437
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:98
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:56
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:94
msgctxt "@label:textbox"
msgid "Filter..."
msgstr "Filtern..."
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:451
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:70
msgctxt "@label:checkbox"
msgid "Show all"
msgstr "Alle anzeigen"
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:44
+msgctxt "@label"
+msgid "Mesh Type"
+msgstr "Mesh-Typ"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:85
+msgctxt "@label"
+msgid "Normal model"
+msgstr "Normales Modell"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:97
+msgctxt "@label"
+msgid "Print as support"
+msgstr "Als Stützstruktur drucken"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:109
+msgctxt "@label"
+msgid "Modify settings for overlaps"
+msgstr "Einstellungen für Überlappungen ändern"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:121
+msgctxt "@label"
+msgid "Don't support overlaps"
+msgstr "Überlappungen nicht unterstützen"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:145
+msgctxt "@action:checkbox"
+msgid "Infill only"
+msgstr "Nur Füllungen"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:368
+msgctxt "@action:button"
+msgid "Select settings"
+msgstr "Einstellungen wählen"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:14
msgctxt "@title:window"
msgid "Open Project"
msgstr "Projekt öffnen"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:58
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Update/override existing profile"
msgid "Update existing"
msgstr "Vorhandenes aktualisieren"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:59
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Save settings in a new profile"
msgid "Create new"
msgstr "Neu erstellen"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:70
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:73
msgctxt "@action:title"
msgid "Summary - Cura Project"
msgstr "Zusammenfassung – Cura-Projekt"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:92
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:97
msgctxt "@action:label"
msgid "Printer settings"
msgstr "Druckereinstellungen"
@@ -2338,20 +2535,25 @@ msgctxt "@action:ComboBox option"
msgid "Update"
msgstr "Aktualisierung"
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
+msgctxt "@action:ComboBox option"
+msgid "Create new"
+msgstr "Neu erstellen"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:143
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:105
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:106
msgctxt "@action:label"
msgid "Type"
msgstr "Typ"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:159
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
msgctxt "@action:label"
msgid "Printer Group"
msgstr "Druckergruppe"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:180
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:196
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:220
msgctxt "@action:label"
msgid "Profile settings"
msgstr "Profileinstellungen"
@@ -2362,226 +2564,222 @@ msgid "How should the conflict in the profile be resolved?"
msgstr "Wie soll der Konflikt im Profil gelöst werden?"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:216
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:220
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:323
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:244
msgctxt "@action:label"
msgid "Name"
msgstr "Name"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:231
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:204
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:261
+msgctxt "@action:label"
+msgid "Intent"
+msgstr "Intent"
+
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:246
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:228
msgctxt "@action:label"
msgid "Not in profile"
msgstr "Nicht im Profil"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:236
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:209
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:251
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:233
msgctxt "@action:label"
msgid "%1 override"
msgid_plural "%1 overrides"
msgstr[0] "%1 überschreiben"
msgstr[1] "%1 überschreibt"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:247
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:262
msgctxt "@action:label"
msgid "Derivative from"
msgstr "Ableitung von"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:252
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:267
msgctxt "@action:label"
msgid "%1, %2 override"
msgid_plural "%1, %2 overrides"
msgstr[0] "%1, %2 überschreiben"
msgstr[1] "%1, %2 überschreibt"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:268
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:283
msgctxt "@action:label"
msgid "Material settings"
msgstr "Materialeinstellungen"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:284
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:299
msgctxt "@info:tooltip"
msgid "How should the conflict in the material be resolved?"
msgstr "Wie soll der Konflikt im Material gelöst werden?"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:327
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:237
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:342
msgctxt "@action:label"
msgid "Setting visibility"
msgstr "Sichtbarkeit einstellen"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:336
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:351
msgctxt "@action:label"
msgid "Mode"
msgstr "Modus"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:352
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:246
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:367
msgctxt "@action:label"
msgid "Visible settings:"
msgstr "Sichtbare Einstellungen:"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:357
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:251
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:372
msgctxt "@action:label"
msgid "%1 out of %2"
msgstr "%1 von %2"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:383
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:398
msgctxt "@action:warning"
msgid "Loading a project will clear all models on the build plate."
msgstr "Das Laden eines Projekts entfernt alle Modelle von der Druckplatte."
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:401
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:416
msgctxt "@action:button"
msgid "Open"
msgstr "Öffnen"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:26
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:25
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:28
msgctxt "@title"
-msgid "Select Printer Upgrades"
-msgstr "Drucker-Upgrades wählen"
+msgid "My Backups"
+msgstr "Meine Backups"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:38
-msgctxt "@label"
-msgid "Please select any upgrades made to this Ultimaker 2."
-msgstr "Wählen Sie bitte alle durchgeführten Upgrades für diesen Ultimaker 2."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:38
+msgctxt "@empty_state"
+msgid "You don't have any backups currently. Use the 'Backup Now' button to create one."
+msgstr "Sie verfügen derzeit über keine Backups. Verwenden Sie die Schaltfläche ‚Jetzt Backup erstellen‘, um ein Backup zu erstellen."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:47
-msgctxt "@label"
-msgid "Olsson Block"
-msgstr "Olsson-Block"
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:60
+msgctxt "@backup_limit_info"
+msgid "During the preview phase, you'll be limited to 5 visible backups. Remove a backup to see older ones."
+msgstr "In der Vorschau-Phase sind Sie auf 5 sichtbare Backups beschränkt. Ein Backup entfernen, um ältere anzusehen."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:27
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:34
+msgctxt "@description"
+msgid "Backup and synchronize your Cura settings."
+msgstr "Ihre Cura-Einstellungen sichern und synchronisieren."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:51
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:68
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:138
+msgctxt "@button"
+msgid "Sign in"
+msgstr "Anmelden"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/main.qml:24
+msgctxt "@title:window"
+msgid "Cura Backups"
+msgstr "Cura-Backups"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:21
+msgctxt "@backuplist:label"
+msgid "Cura Version"
+msgstr "Cura-Version"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:29
+msgctxt "@backuplist:label"
+msgid "Machines"
+msgstr "Maschinen"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:37
+msgctxt "@backuplist:label"
+msgid "Materials"
+msgstr "Materialien"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:45
+msgctxt "@backuplist:label"
+msgid "Profiles"
+msgstr "Profile"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:53
+msgctxt "@backuplist:label"
+msgid "Plugins"
+msgstr "Plugins"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:71
+msgctxt "@button"
+msgid "Restore"
+msgstr "Wiederherstellen"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:99
+msgctxt "@dialog:title"
+msgid "Delete Backup"
+msgstr "Backup löschen"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:100
+msgctxt "@dialog:info"
+msgid "Are you sure you want to delete this backup? This cannot be undone."
+msgstr "Soll dieses Backup wirklich gelöscht werden? Der Vorgang kann nicht rückgängig gemacht werden."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:108
+msgctxt "@dialog:title"
+msgid "Restore Backup"
+msgstr "Backup wiederherstellen"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:109
+msgctxt "@dialog:info"
+msgid "You will need to restart Cura before your backup is restored. Do you want to close Cura now?"
+msgstr "Cura muss neu gestartet werden, um Ihre Datensicherung wiederherzustellen. Möchten Sie Cura jetzt schließen?"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:22
+msgctxt "@button"
+msgid "Want more?"
+msgstr "Möchten Sie mehr?"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:31
+msgctxt "@button"
+msgid "Backup Now"
+msgstr "Jetzt Backup durchführen"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:43
+msgctxt "@checkbox:description"
+msgid "Auto Backup"
+msgstr "Automatisches Backup"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:44
+msgctxt "@checkbox:description"
+msgid "Automatically create a backup each day that Cura is started."
+msgstr "An jedem Tag, an dem Cura gestartet wird, ein automatisches Backup erstellen."
+
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:30
msgctxt "@title"
msgid "Build Plate Leveling"
msgstr "Nivellierung der Druckplatte"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:38
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:44
msgctxt "@label"
msgid "To make sure your prints will come out great, you can now adjust your buildplate. When you click 'Move to Next Position' the nozzle will move to the different positions that can be adjusted."
msgstr "Um sicherzustellen, dass Ihre Drucke hervorragend werden, können Sie nun Ihre Druckplatte justieren. Wenn Sie auf „Gehe zur nächsten Position“ klicken, bewegt sich die Düse zu den verschiedenen Positionen, die justiert werden können."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:47
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:57
msgctxt "@label"
msgid "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle."
msgstr "Legen Sie für jede Position ein Blatt Papier unter die Düse und stellen Sie die Höhe der Druckplatte ein. Die Höhe der Druckplatte ist korrekt, wenn das Papier von der Spitze der Düse leicht berührt wird."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:62
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:75
msgctxt "@action:button"
msgid "Start Build Plate Leveling"
msgstr "Nivellierung der Druckplatte starten"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:74
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:87
msgctxt "@action:button"
msgid "Move to Next Position"
msgstr "Gehe zur nächsten Position"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:37
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:30
msgctxt "@label"
msgid "Please select any upgrades made to this Ultimaker Original"
msgstr "Wählen Sie bitte alle Upgrades für dieses Ultimaker-Original"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:45
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:41
msgctxt "@label"
msgid "Heated Build Plate (official kit or self-built)"
msgstr "Beheizte Druckplatte (offizielles Kit oder Eigenbau)"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:27
-msgctxt "@title"
-msgid "Check Printer"
-msgstr "Drucker prüfen"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:39
-msgctxt "@label"
-msgid "It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional"
-msgstr "Sie sollten einige Sanity Checks bei Ihrem Ultimaker durchführen. Sie können diesen Schritt überspringen, wenn Sie wissen, dass Ihr Gerät funktionsfähig ist"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:53
-msgctxt "@action:button"
-msgid "Start Printer Check"
-msgstr "Überprüfung des Druckers starten"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:80
-msgctxt "@label"
-msgid "Connection: "
-msgstr "Verbindung: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Connected"
-msgstr "Verbunden"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Not connected"
-msgstr "Nicht verbunden"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:99
-msgctxt "@label"
-msgid "Min endstop X: "
-msgstr "Min. Endstopp X: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-msgctxt "@info:status"
-msgid "Works"
-msgstr "Funktionsfähig"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:173
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Not checked"
-msgstr "Nicht überprüft"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:120
-msgctxt "@label"
-msgid "Min endstop Y: "
-msgstr "Min. Endstopp Y: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:141
-msgctxt "@label"
-msgid "Min endstop Z: "
-msgstr "Min. Endstopp Z: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:163
-msgctxt "@label"
-msgid "Nozzle temperature check: "
-msgstr "Temperaturprüfung der Düse: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Stop Heating"
-msgstr "Aufheizen stoppen"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Start Heating"
-msgstr "Aufheizen starten"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:223
-msgctxt "@label"
-msgid "Build plate temperature check:"
-msgstr "Temperaturprüfung der Druckplatte:"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Checked"
-msgstr "Geprüft"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:284
-msgctxt "@label"
-msgid "Everything is in order! You're done with your CheckUp."
-msgstr "Alles ist in Ordnung! Der Check-up ist abgeschlossen."
-
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:119
msgctxt "@label:MonitorStatus"
msgid "Not connected to a printer"
@@ -2593,7 +2791,6 @@ msgid "Printer does not accept commands"
msgstr "Drucker nimmt keine Befehle an"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:133
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:197
msgctxt "@label:MonitorStatus"
msgid "In maintenance. Please check the printer"
msgstr "In Wartung. Den Drucker überprüfen"
@@ -2604,19 +2801,16 @@ msgid "Lost connection with the printer"
msgstr "Verbindung zum Drucker wurde unterbrochen"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:146
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:187
msgctxt "@label:MonitorStatus"
msgid "Printing..."
msgstr "Es wird gedruckt..."
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:149
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:189
msgctxt "@label:MonitorStatus"
msgid "Paused"
msgstr "Pausiert"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:152
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:191
msgctxt "@label:MonitorStatus"
msgid "Preparing..."
msgstr "Vorbereitung läuft..."
@@ -2636,233 +2830,176 @@ msgctxt "@label"
msgid "Are you sure you want to abort the print?"
msgstr "Soll das Drucken wirklich abgebrochen werden?"
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:15
-msgctxt "@title:window"
-msgid "Discard or Keep changes"
-msgstr "Änderungen verwerfen oder übernehmen"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:57
-msgctxt "@text:window"
-msgid ""
-"You have customized some profile settings.\n"
-"Would you like to keep or discard those settings?"
-msgstr "Sie haben einige Profileinstellungen angepasst.\nMöchten Sie diese Einstellungen übernehmen oder verwerfen?"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:110
-msgctxt "@title:column"
-msgid "Profile settings"
-msgstr "Profileinstellungen"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:117
-msgctxt "@title:column"
-msgid "Default"
-msgstr "Standard"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:124
-msgctxt "@title:column"
-msgid "Customized"
-msgstr "Angepasst"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:157
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:637
-msgctxt "@option:discardOrKeep"
-msgid "Always ask me this"
-msgstr "Stets nachfragen"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:158
-msgctxt "@option:discardOrKeep"
-msgid "Discard and never ask again"
-msgstr "Verwerfen und zukünftig nicht mehr nachfragen"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:159
-msgctxt "@option:discardOrKeep"
-msgid "Keep and never ask again"
-msgstr "Übernehmen und zukünftig nicht mehr nachfragen"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:196
-msgctxt "@action:button"
-msgid "Discard"
-msgstr "Verwerfen"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:209
-msgctxt "@action:button"
-msgid "Keep"
-msgstr "Übernehmen"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:222
-msgctxt "@action:button"
-msgid "Create New Profile"
-msgstr "Neues Profil erstellen"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:71
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:72
msgctxt "@title"
msgid "Information"
msgstr "Informationen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:100
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
msgctxt "@title:window"
msgid "Confirm Diameter Change"
msgstr "Änderung Durchmesser bestätigen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:102
msgctxt "@label (%1 is a number)"
msgid "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?"
msgstr "Der neue Filament-Durchmesser wurde auf %1 mm eingestellt, was nicht kompatibel mit dem aktuellen Extruder ist. Möchten Sie fortfahren?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:128
msgctxt "@label"
msgid "Display Name"
msgstr "Namen anzeigen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:143
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:138
msgctxt "@label"
msgid "Brand"
msgstr "Marke"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:148
msgctxt "@label"
msgid "Material Type"
msgstr "Materialtyp"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:158
msgctxt "@label"
msgid "Color"
msgstr "Farbe"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:212
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:208
msgctxt "@label"
msgid "Properties"
msgstr "Eigenschaften"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:214
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:210
msgctxt "@label"
msgid "Density"
msgstr "Dichte"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:229
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:225
msgctxt "@label"
msgid "Diameter"
msgstr "Durchmesser"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:263
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:259
msgctxt "@label"
msgid "Filament Cost"
msgstr "Filamentkosten"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:280
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:276
msgctxt "@label"
msgid "Filament weight"
msgstr "Filamentgewicht"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:298
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:294
msgctxt "@label"
msgid "Filament length"
msgstr "Filamentlänge"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:307
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:303
msgctxt "@label"
msgid "Cost per Meter"
msgstr "Kosten pro Meter"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:321
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:317
msgctxt "@label"
msgid "This material is linked to %1 and shares some of its properties."
msgstr "Dieses Material ist mit %1 verknüpft und teilt sich damit einige seiner Eigenschaften."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:328
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:324
msgctxt "@label"
msgid "Unlink Material"
msgstr "Material trennen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:335
msgctxt "@label"
msgid "Description"
msgstr "Beschreibung"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:352
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:348
msgctxt "@label"
msgid "Adhesion Information"
msgstr "Haftungsinformationen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:378
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:19
msgctxt "@label"
msgid "Print settings"
msgstr "Druckeinstellungen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:84
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:35
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:108
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:40
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:84
msgctxt "@action:button"
msgid "Activate"
msgstr "Aktivieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:126
msgctxt "@action:button"
msgid "Create"
msgstr "Erstellen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:140
msgctxt "@action:button"
msgid "Duplicate"
msgstr "Duplizieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:141
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:170
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:167
msgctxt "@action:button"
msgid "Import"
msgstr "Import"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:154
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:184
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:179
msgctxt "@action:button"
msgid "Export"
msgstr "Export"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:233
msgctxt "@action:label"
msgid "Printer"
msgstr "Drucker"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:262
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:274
msgctxt "@title:window"
msgid "Confirm Remove"
msgstr "Entfernen bestätigen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:263
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:240
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:300
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:275
msgctxt "@label (%1 is object name)"
msgid "Are you sure you wish to remove %1? This cannot be undone!"
msgstr "Möchten Sie %1 wirklich entfernen? Dies kann nicht rückgängig gemacht werden!"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:277
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:285
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:314
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:322
msgctxt "@title:window"
msgid "Import Material"
msgstr "Material importieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:286
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:323
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Could not import material %1: %2"
msgstr "Material konnte nicht importiert werden %1: %2"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:290
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:327
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully imported material %1"
msgstr "Material wurde erfolgreich importiert %1"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:316
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:345
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:353
msgctxt "@title:window"
msgid "Export Material"
msgstr "Material exportieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:320
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:357
msgctxt "@info:status Don't translate the XML tags and !"
msgid "Failed to export material to %1: %2"
msgstr "Exportieren des Materials nach %1: %2 schlug fehl"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:326
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:363
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully exported material to %1"
msgstr "Material erfolgreich nach %1 exportiert"
@@ -2872,817 +3009,784 @@ msgctxt "@title:tab"
msgid "Setting Visibility"
msgstr "Sichtbarkeit einstellen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:46
msgctxt "@label:textbox"
msgid "Check all"
msgstr "Alle prüfen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:47
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:61
msgctxt "@info:status"
msgid "Calculated"
msgstr "Berechnet"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:60
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:75
msgctxt "@title:column"
msgid "Setting"
msgstr "Einstellung"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
msgctxt "@title:column"
msgid "Profile"
msgstr "Profil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:74
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:89
msgctxt "@title:column"
msgid "Current"
msgstr "Aktuell"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:97
msgctxt "@title:column"
msgid "Unit"
msgstr "Einheit"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:15
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:410
msgctxt "@title:tab"
msgid "General"
msgstr "Allgemein"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:132
msgctxt "@label"
msgid "Interface"
msgstr "Schnittstelle"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:143
msgctxt "@label"
msgid "Language:"
msgstr "Sprache:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:221
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:210
msgctxt "@label"
msgid "Currency:"
msgstr "Währung:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:235
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:223
msgctxt "@label"
msgid "Theme:"
msgstr "Thema:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:292
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:279
msgctxt "@label"
msgid "You will need to restart the application for these changes to have effect."
msgstr "Die Anwendung muss neu gestartet werden, um die Änderungen zu übernehmen."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:309
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:296
msgctxt "@info:tooltip"
msgid "Slice automatically when changing settings."
msgstr "Bei Änderung der Einstellungen automatisch schneiden."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:317
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:304
msgctxt "@option:check"
msgid "Slice automatically"
msgstr "Automatisch schneiden"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:318
msgctxt "@label"
msgid "Viewport behavior"
msgstr "Viewport-Verhalten"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:326
msgctxt "@info:tooltip"
msgid "Highlight unsupported areas of the model in red. Without support these areas will not print properly."
msgstr "Nicht gestützte Bereiche des Modells in rot hervorheben. Ohne Support werden diese Bereiche nicht korrekt gedruckt."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:335
msgctxt "@option:check"
msgid "Display overhang"
msgstr "Überhang anzeigen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:355
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:343
msgctxt "@info:tooltip"
msgid "Moves the camera so the model is in the center of the view when a model is selected"
msgstr "Bewegt die Kamera, bis sich das Modell im Mittelpunkt der Ansicht befindet, wenn ein Modell ausgewählt wurde"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
msgctxt "@action:button"
msgid "Center camera when item is selected"
msgstr "Zentrieren Sie die Kamera, wenn das Element ausgewählt wurde"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:369
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:358
msgctxt "@info:tooltip"
msgid "Should the default zoom behavior of cura be inverted?"
msgstr "Soll das standardmäßige Zoom-Verhalten von Cura umgekehrt werden?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:363
msgctxt "@action:button"
msgid "Invert the direction of camera zoom."
msgstr "Kehren Sie die Richtung des Kamera-Zooms um."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
msgctxt "@info:tooltip"
msgid "Should zooming move in the direction of the mouse?"
msgstr "Soll das Zoomen in Richtung der Maus erfolgen?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:389
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
+msgctxt "@info:tooltip"
+msgid "Zooming towards the mouse is not supported in the orthographic perspective."
+msgstr "Das Zoomen in Richtung der Maus wird in der orthografischen Perspektive nicht unterstützt."
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
msgctxt "@action:button"
msgid "Zoom toward mouse direction"
msgstr "In Mausrichtung zoomen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:399
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:410
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved so that they no longer intersect?"
msgstr "Sollen Modelle auf der Plattform so verschoben werden, dass sie sich nicht länger überschneiden?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:404
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:415
msgctxt "@option:check"
msgid "Ensure models are kept apart"
msgstr "Stellen Sie sicher, dass die Modelle getrennt gehalten werden"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:413
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:424
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved down to touch the build plate?"
msgstr "Sollen Modelle auf der Plattform so nach unten verschoben werden, dass sie die Druckplatte berühren?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:418
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:429
msgctxt "@option:check"
msgid "Automatically drop models to the build plate"
msgstr "Setzt Modelle automatisch auf der Druckplatte ab"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:430
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:441
msgctxt "@info:tooltip"
msgid "Show caution message in g-code reader."
msgstr "Warnmeldung im G-Code-Reader anzeigen."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:439
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:450
msgctxt "@option:check"
msgid "Caution message in g-code reader"
msgstr "Warnmeldung in G-Code-Reader"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:447
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:458
msgctxt "@info:tooltip"
msgid "Should layer be forced into compatibility mode?"
msgstr "Soll die Schicht in den Kompatibilitätsmodus gezwungen werden?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:452
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:463
msgctxt "@option:check"
msgid "Force layer view compatibility mode (restart required)"
msgstr "Schichtenansicht Kompatibilitätsmodus erzwingen (Neustart erforderlich)"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:468
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:473
+msgctxt "@info:tooltip"
+msgid "Should Cura open at the location it was closed?"
+msgstr "Sollte Cura sich an der Stelle öffnen, an der das Programm geschlossen wurde?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:478
+msgctxt "@option:check"
+msgid "Restore window position on start"
+msgstr "Fensterposition beim Start wiederherstellen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:488
+msgctxt "@info:tooltip"
+msgid "What type of camera rendering should be used?"
+msgstr "Welches Kamera-Rendering sollte verwendet werden?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+msgctxt "@window:text"
+msgid "Camera rendering:"
+msgstr "Kamera-Rendering:"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:506
+msgid "Perspective"
+msgstr "Ansicht"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:507
+msgid "Orthographic"
+msgstr "Orthogonal"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:538
msgctxt "@label"
msgid "Opening and saving files"
msgstr "Dateien öffnen und speichern"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:475
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:545
msgctxt "@info:tooltip"
msgid "Should models be scaled to the build volume if they are too large?"
msgstr "Sollen Modelle an das Erstellungsvolumen angepasst werden, wenn sie zu groß sind?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:550
msgctxt "@option:check"
msgid "Scale large models"
msgstr "Große Modelle anpassen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:490
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:560
msgctxt "@info:tooltip"
msgid "An model may appear extremely small if its unit is for example in meters rather than millimeters. Should these models be scaled up?"
msgstr "Ein Modell kann extrem klein erscheinen, wenn seine Maßeinheit z. B. in Metern anstelle von Millimetern angegeben ist. Sollen diese Modelle hoch skaliert werden?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:565
msgctxt "@option:check"
msgid "Scale extremely small models"
msgstr "Extrem kleine Modelle skalieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:505
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:575
msgctxt "@info:tooltip"
msgid "Should models be selected after they are loaded?"
msgstr "Sollten Modelle gewählt werden, nachdem sie geladen wurden?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:510
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:580
msgctxt "@option:check"
msgid "Select models when loaded"
msgstr "Modelle wählen, nachdem sie geladen wurden"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:520
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:590
msgctxt "@info:tooltip"
msgid "Should a prefix based on the printer name be added to the print job name automatically?"
msgstr "Soll ein Präfix anhand des Druckernamens automatisch zum Namen des Druckauftrags hinzugefügt werden?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:525
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:595
msgctxt "@option:check"
msgid "Add machine prefix to job name"
msgstr "Geräte-Präfix zu Auftragsnamen hinzufügen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:535
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:605
msgctxt "@info:tooltip"
msgid "Should a summary be shown when saving a project file?"
msgstr "Soll beim Speichern einer Projektdatei eine Zusammenfassung angezeigt werden?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
msgctxt "@option:check"
msgid "Show summary dialog when saving project"
msgstr "Dialog Zusammenfassung beim Speichern eines Projekts anzeigen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:619
msgctxt "@info:tooltip"
msgid "Default behavior when opening a project file"
msgstr "Standardverhalten beim Öffnen einer Projektdatei"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:557
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:627
msgctxt "@window:text"
msgid "Default behavior when opening a project file: "
msgstr "Standardverhalten beim Öffnen einer Projektdatei: "
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:571
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:641
msgctxt "@option:openProject"
msgid "Always ask me this"
msgstr "Stets nachfragen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:572
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:642
msgctxt "@option:openProject"
msgid "Always open as a project"
msgstr "Immer als Projekt öffnen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:573
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:643
msgctxt "@option:openProject"
msgid "Always import models"
msgstr "Modelle immer importieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:679
msgctxt "@info:tooltip"
msgid "When you have made changes to a profile and switched to a different one, a dialog will be shown asking whether you want to keep your modifications or not, or you can choose a default behaviour and never show that dialog again."
msgstr "Wenn Sie Änderungen für ein Profil vorgenommen haben und zu einem anderen Profil gewechselt sind, wird ein Dialog angezeigt, der hinterfragt, ob Sie Ihre Änderungen beibehalten möchten oder nicht; optional können Sie ein Standardverhalten wählen, sodass dieser Dialog nicht erneut angezeigt wird."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:618
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:688
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:52
msgctxt "@label"
msgid "Profiles"
msgstr "Profile"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:623
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:693
msgctxt "@window:text"
msgid "Default behavior for changed setting values when switching to a different profile: "
msgstr "Standardverhalten für geänderte Einstellungswerte beim Wechsel zu einem anderen Profil: "
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:638
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:707
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:157
+msgctxt "@option:discardOrKeep"
+msgid "Always ask me this"
+msgstr "Stets nachfragen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:708
msgctxt "@option:discardOrKeep"
msgid "Always discard changed settings"
msgstr "Geänderte Einstellungen immer verwerfen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:639
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:709
msgctxt "@option:discardOrKeep"
msgid "Always transfer changed settings to new profile"
msgstr "Geänderte Einstellungen immer auf neues Profil übertragen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:673
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:743
msgctxt "@label"
msgid "Privacy"
msgstr "Privatsphäre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:681
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:750
msgctxt "@info:tooltip"
msgid "Should Cura check for updates when the program is started?"
msgstr "Soll Cura bei Programmstart nach Updates suchen?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:686
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:755
msgctxt "@option:check"
msgid "Check for updates on start"
msgstr "Bei Start nach Updates suchen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:697
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:765
msgctxt "@info:tooltip"
msgid "Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored."
msgstr "Sollen anonyme Daten über Ihren Druck an Ultimaker gesendet werden? Beachten Sie, dass keine Modelle, IP-Adressen oder andere personenbezogene Daten gesendet oder gespeichert werden."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:702
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:770
msgctxt "@option:check"
msgid "Send (anonymous) print information"
msgstr "(Anonyme) Druckinformationen senden"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:711
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:779
msgctxt "@action:button"
msgid "More information"
msgstr "Mehr Informationen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:729
-msgctxt "@label"
-msgid "Experimental"
-msgstr "Experimentell"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:736
-msgctxt "@info:tooltip"
-msgid "Use multi build plate functionality"
-msgstr "Mehrfach-Druckplattenfunktion verwenden"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:741
-msgctxt "@option:check"
-msgid "Use multi build plate functionality (restart required)"
-msgstr "Mehrfach-Druckplattenfunktion verwenden (Neustart erforderlich)"
-
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:16
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:415
msgctxt "@title:tab"
msgid "Printers"
msgstr "Drucker"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:63
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
msgctxt "@action:button"
msgid "Rename"
msgstr "Umbenennen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:147
-msgctxt "@label"
-msgid "Printer type:"
-msgstr "Druckertyp:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:156
-msgctxt "@label"
-msgid "Connection:"
-msgstr "Verbindung:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:162
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
-msgctxt "@info:status"
-msgid "The printer is not connected."
-msgstr "Der Drucker ist nicht verbunden."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:168
-msgctxt "@label"
-msgid "State:"
-msgstr "Status:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:181
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for a printjob"
-msgstr "Warten auf einen Druckauftrag"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:193
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for someone to clear the build plate"
-msgstr "Warten auf Räumen des Druckbeets"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:199
-msgctxt "@label:MonitorStatus"
-msgid "Aborting print..."
-msgstr "Drucken wird abgebrochen..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:553
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:34
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:419
msgctxt "@title:tab"
msgid "Profiles"
msgstr "Profile"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:104
msgctxt "@label"
msgid "Create"
msgstr "Erstellen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:102
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:121
msgctxt "@label"
msgid "Duplicate"
msgstr "Duplizieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:174
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:202
msgctxt "@title:window"
msgid "Create Profile"
msgstr "Profil erstellen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:204
+msgctxt "@info"
+msgid "Please provide a name for this profile."
+msgstr "Geben Sie bitte einen Namen für dieses Profil an."
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:260
msgctxt "@title:window"
msgid "Duplicate Profile"
msgstr "Profil duplizieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:256
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:291
msgctxt "@title:window"
msgid "Rename Profile"
msgstr "Profil umbenennen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:304
msgctxt "@title:window"
msgid "Import Profile"
msgstr "Profil importieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:333
msgctxt "@title:window"
msgid "Export Profile"
msgstr "Profil exportieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:350
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:396
msgctxt "@label %1 is printer name"
msgid "Printer: %1"
msgstr "Drucker: %1"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Protected profiles"
-msgstr "Geschützte Profile"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Custom profiles"
-msgstr "Benutzerdefinierte Profile"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:554
msgctxt "@action:button"
msgid "Update profile with current settings/overrides"
msgstr "Profil mit aktuellen Einstellungen/Überschreibungen aktualisieren"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:487
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:561
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:257
msgctxt "@action:button"
msgid "Discard current changes"
msgstr "Aktuelle Änderungen verwerfen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:504
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:580
msgctxt "@action:label"
msgid "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below."
msgstr "Dieses Profil verwendet die vom Drucker festgelegten Standardeinstellungen, deshalb sind in der folgenden Liste keine Einstellungen/Überschreibungen enthalten."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:511
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:588
msgctxt "@action:label"
msgid "Your current settings match the selected profile."
msgstr "Ihre aktuellen Einstellungen stimmen mit dem gewählten Profil überein."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:530
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:606
msgctxt "@title:tab"
msgid "Global Settings"
msgstr "Globale Einstellungen"
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:18
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:953
-msgctxt "@title:window"
-msgid "Add Printer"
-msgstr "Drucker hinzufügen"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:195
-msgctxt "@label"
-msgid "Printer Name:"
-msgstr "Druckername:"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:219
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/MainWindowHeader.qml:90
msgctxt "@action:button"
-msgid "Add Printer"
-msgstr "Drucker hinzufügen"
+msgid "Marketplace"
+msgstr "Marktplatz"
-#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:84
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:27
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&File"
+msgstr "&Datei"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:31
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Edit"
+msgstr "&Bearbeiten"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:48
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
+msgctxt "@title:menu menubar:toplevel"
+msgid "&View"
+msgstr "&Ansicht"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Settings"
+msgstr "&Einstellungen"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:55
+msgctxt "@title:menu menubar:toplevel"
+msgid "E&xtensions"
+msgstr "Er&weiterungen"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:89
+msgctxt "@title:menu menubar:toplevel"
+msgid "P&references"
+msgstr "E&instellungen"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:97
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Help"
+msgstr "&Hilfe"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:124
+msgctxt "@title:window"
+msgid "New project"
+msgstr "Neues Projekt"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:125
+msgctxt "@info:question"
+msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
+msgstr "Möchten Sie wirklich ein neues Projekt beginnen? Damit werden das Druckbett und alle nicht gespeicherten Einstellungen gelöscht."
+
+#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:88
msgctxt "@text Print job name"
msgid "Untitled"
msgstr "Unbenannt"
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:15
-msgctxt "@title:window"
-msgid "About Cura"
-msgstr "Über Cura"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:55
-msgctxt "@label"
-msgid "version: %1"
-msgstr "Version: %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:69
-msgctxt "@label"
-msgid "End-to-end solution for fused filament 3D printing."
-msgstr "Komplettlösung für den 3D-Druck mit geschmolzenem Filament."
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:82
-msgctxt "@info:credit"
-msgid ""
-"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
-"Cura proudly uses the following open source projects:"
-msgstr "Cura wurde von Ultimaker B.V. in Zusammenarbeit mit der Community entwickelt.\nCura verwendet mit Stolz die folgenden Open Source-Projekte:"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:132
-msgctxt "@label"
-msgid "Graphical user interface"
-msgstr "Grafische Benutzerschnittstelle"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:133
-msgctxt "@label"
-msgid "Application framework"
-msgstr "Anwendungsrahmenwerk"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:134
-msgctxt "@label"
-msgid "G-code generator"
-msgstr "G-Code-Generator"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:135
-msgctxt "@label"
-msgid "Interprocess communication library"
-msgstr "Bibliothek Interprozess-Kommunikation"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:137
-msgctxt "@label"
-msgid "Programming language"
-msgstr "Programmiersprache"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:138
-msgctxt "@label"
-msgid "GUI framework"
-msgstr "GUI-Rahmenwerk"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139
-msgctxt "@label"
-msgid "GUI framework bindings"
-msgstr "GUI-Rahmenwerk Einbindungen"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:140
-msgctxt "@label"
-msgid "C/C++ Binding library"
-msgstr "C/C++ Einbindungsbibliothek"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:141
-msgctxt "@label"
-msgid "Data interchange format"
-msgstr "Format Datenaustausch"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:142
-msgctxt "@label"
-msgid "Support library for scientific computing"
-msgstr "Support-Bibliothek für wissenschaftliche Berechnung"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:143
-msgctxt "@label"
-msgid "Support library for faster math"
-msgstr "Support-Bibliothek für schnelleres Rechnen"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:144
-msgctxt "@label"
-msgid "Support library for handling STL files"
-msgstr "Support-Bibliothek für die Handhabung von STL-Dateien"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:145
-msgctxt "@label"
-msgid "Support library for handling planar objects"
-msgstr "Support-Bibliothek für die Handhabung von ebenen Objekten"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:146
-msgctxt "@label"
-msgid "Support library for handling triangular meshes"
-msgstr "Support-Bibliothek für die Handhabung von dreieckigen Netzen"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:147
-msgctxt "@label"
-msgid "Support library for analysis of complex networks"
-msgstr "Support-Bibliothek für die Analyse von komplexen Netzwerken"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:148
-msgctxt "@label"
-msgid "Support library for handling 3MF files"
-msgstr "Support-Bibliothek für die Handhabung von 3MF-Dateien"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:149
-msgctxt "@label"
-msgid "Support library for file metadata and streaming"
-msgstr "Support-Bibliothek für Datei-Metadaten und Streaming"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:150
-msgctxt "@label"
-msgid "Serial communication library"
-msgstr "Bibliothek für serielle Kommunikation"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:151
-msgctxt "@label"
-msgid "ZeroConf discovery library"
-msgstr "Bibliothek für ZeroConf-Erkennung"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:152
-msgctxt "@label"
-msgid "Polygon clipping library"
-msgstr "Bibliothek für Polygon-Beschneidung"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:153
-msgctxt "@Label"
-msgid "Python HTTP library"
-msgstr "Bibliothek für Python HTTP"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:155
-msgctxt "@label"
-msgid "Font"
-msgstr "Schriftart"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:156
-msgctxt "@label"
-msgid "SVG icons"
-msgstr "SVG-Symbole"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:157
-msgctxt "@label"
-msgid "Linux cross-distribution application deployment"
-msgstr "Distributionsunabhängiges Format für Linux-Anwendungen"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:42
-msgctxt "@label"
-msgid "Profile:"
-msgstr "Profil:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:104
-msgctxt "@tooltip"
-msgid ""
-"Some setting/override values are different from the values stored in the profile.\n"
-"\n"
-"Click to open the profile manager."
-msgstr "Einige Einstellungs-/Überschreibungswerte unterscheiden sich von den im Profil gespeicherten Werten.\n\nKlicken Sie, um den Profilmanager zu öffnen."
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:200
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:68
msgctxt "@label:textbox"
-msgid "Search..."
-msgstr "Suchen..."
+msgid "Search settings"
+msgstr "Einstellungen durchsuchen"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:545
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:462
msgctxt "@action:menu"
msgid "Copy value to all extruders"
msgstr "Werte für alle Extruder kopieren"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:554
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:471
msgctxt "@action:menu"
msgid "Copy all changed values to all extruders"
msgstr "Alle geänderten Werte für alle Extruder kopieren"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:591
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:508
msgctxt "@action:menu"
msgid "Hide this setting"
msgstr "Diese Einstellung ausblenden"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:521
msgctxt "@action:menu"
msgid "Don't show this setting"
msgstr "Diese Einstellung ausblenden"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:613
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:525
msgctxt "@action:menu"
msgid "Keep this setting visible"
msgstr "Diese Einstellung weiterhin anzeigen"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:637
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:417
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:434
msgctxt "@action:menu"
msgid "Configure setting visibility..."
msgstr "Sichtbarkeit einstellen wird konfiguriert..."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:644
-msgctxt "@action:inmenu"
-msgid "Collapse All"
-msgstr "Alle verkleinern"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:649
-msgctxt "@action:inmenu"
-msgid "Expand All"
-msgstr "Alle vergrößern"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:253
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:237
msgctxt "@label"
msgid ""
"Some hidden settings use values different from their normal calculated value.\n"
"\n"
"Click to make these settings visible."
-msgstr "Einige ausgeblendete Einstellungen verwenden Werte, die von ihren normalen, berechneten Werten abweichen.\n\nKlicken Sie, um diese Einstellungen sichtbar zu machen."
+msgstr ""
+"Einige ausgeblendete Einstellungen verwenden Werte, die von ihren normalen, berechneten Werten abweichen.\n"
+"\n"
+"Klicken Sie, um diese Einstellungen sichtbar zu machen."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:81
+msgctxt "@label"
+msgid "This setting is not used because all the settings that it influences are overridden."
+msgstr "Diese Einstellung wird nicht verwendet, weil alle hierdurch beeinflussten Einstellungen aufgehoben werden."
+
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:86
msgctxt "@label Header for list of settings."
msgid "Affects"
msgstr "Hat Einfluss auf"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:91
msgctxt "@label Header for list of settings."
msgid "Affected By"
msgstr "Wird beeinflusst von"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:187
msgctxt "@label"
msgid "This setting is always shared between all extruders. Changing it here will change the value for all extruders."
msgstr "Diese Einstellung wird stets zwischen allen Extrudern geteilt. Eine Änderung ändert den Wert für alle Extruder."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:158
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:191
msgctxt "@label"
msgid "The value is resolved from per-extruder values "
msgstr "Der Wert wird von Pro-Extruder-Werten gelöst "
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:189
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:230
msgctxt "@label"
msgid ""
"This setting has a value that is different from the profile.\n"
"\n"
"Click to restore the value of the profile."
-msgstr "Diese Einstellung hat einen vom Profil abweichenden Wert.\n\nKlicken Sie, um den Wert des Profils wiederherzustellen."
+msgstr ""
+"Diese Einstellung hat einen vom Profil abweichenden Wert.\n"
+"\n"
+"Klicken Sie, um den Wert des Profils wiederherzustellen."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:281
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:329
msgctxt "@label"
msgid ""
"This setting is normally calculated, but it currently has an absolute value set.\n"
"\n"
"Click to restore the calculated value."
-msgstr "Diese Einstellung wird normalerweise berechnet; aktuell ist jedoch ein Absolutwert eingestellt.\n\nKlicken Sie, um den berechneten Wert wiederherzustellen."
+msgstr ""
+"Diese Einstellung wird normalerweise berechnet; aktuell ist jedoch ein Absolutwert eingestellt.\n"
+"\n"
+"Klicken Sie, um den berechneten Wert wiederherzustellen."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/NoIntentIcon.qml:31
+msgctxt "@label %1 is filled in with the type of a profile. %2 is filled with a list of numbers (eg '1' or '1, 2')"
+msgid "There is no %1 profile for the configuration in extruder %2. The default intent will be used instead"
+msgid_plural "There is no %1 profile for the configurations in extruders %2. The default intent will be used instead"
+msgstr[0] ""
+msgstr[1] ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:144
+msgctxt "@button"
+msgid "Recommended"
+msgstr "Empfohlen"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:158
+msgctxt "@button"
+msgid "Custom"
+msgstr "Benutzerdefiniert"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:193
+msgctxt "@label"
+msgid "Gradual infill"
+msgstr "Stufenweise Füllung"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:232
+msgctxt "@label"
+msgid "Gradual infill will gradually increase the amount of infill towards the top."
+msgstr "Die graduelle Füllung steigert die Menge der Füllung nach oben hin schrittweise."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:30
+msgctxt "@label"
+msgid "Support"
+msgstr "Stützstruktur"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:71
+msgctxt "@label"
+msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
+msgstr "Damit werden Strukturen zur Unterstützung von Modellteilen mit Überhängen generiert. Ohne diese Strukturen würden solche Teile während des Druckvorgangs zusammenfallen."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:29
+msgctxt "@label"
+msgid "Adhesion"
+msgstr "Haftung"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:74
+msgctxt "@label"
+msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
+msgstr "Drucken eines Brim- oder Raft-Elements aktivieren. Es wird ein flacher Bereich rund um oder unter Ihrem Objekt hinzugefügt, das im Anschluss leicht abgeschnitten werden kann."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:81
+msgctxt "@tooltip"
+msgid "You have modified some profile settings. If you want to change these go to custom mode."
+msgstr "Sie haben einige Profileinstellungen geändert. Wenn Sie diese ändern möchten, wechseln Sie in den Modus „Benutzerdefiniert“."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:13
+msgctxt "@label:Should be short"
+msgid "On"
+msgstr "Ein"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:14
+msgctxt "@label:Should be short"
+msgid "Off"
+msgstr "Aus"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:33
+msgctxt "@label"
+msgid "Experimental"
+msgstr "Experimentell"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:47
+msgctxt "@label"
+msgid "Profile"
+msgstr "Profil"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:172
+msgctxt "@tooltip"
+msgid ""
+"Some setting/override values are different from the values stored in the profile.\n"
+"\n"
+"Click to open the profile manager."
+msgstr ""
+"Einige Einstellungs-/Überschreibungswerte unterscheiden sich von den im Profil gespeicherten Werten.\n"
+"\n"
+"Klicken Sie, um den Profilmanager zu öffnen."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:160
+msgctxt "@label:header"
+msgid "Custom profiles"
+msgstr "Benutzerdefinierte Profile"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:21
+msgctxt "@label shown when we load a Gcode file"
+msgid "Print setup disabled. G-code file can not be modified."
+msgstr "Druckeinrichtung ist deaktiviert. G-Code-Datei kann nicht geändert werden."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:52
msgctxt "@label"
msgid "Printer control"
msgstr "Druckersteuerung"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:144
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:67
msgctxt "@label"
msgid "Jog Position"
msgstr "Tippposition"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:85
msgctxt "@label"
msgid "X/Y"
msgstr "X/Y"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:192
msgctxt "@label"
msgid "Z"
msgstr "Z"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:257
msgctxt "@label"
msgid "Jog Distance"
msgstr "Tippdistanz"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:443
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:301
msgctxt "@label"
msgid "Send G-code"
msgstr "G-Code senden"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:506
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:365
msgctxt "@tooltip of G-code command input"
msgid "Send a custom G-code command to the connected printer. Press 'enter' to send the command."
msgstr "Einen benutzerdefinierten G-Code-Befehl an den verbundenen Drucker senden. „Eingabe“ drücken, um den Befehl zu senden."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:272
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:41
msgctxt "@label"
msgid "Extruder"
msgstr "Extruder"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:71
msgctxt "@tooltip"
msgid "The target temperature of the hotend. The hotend will heat up or cool down towards this temperature. If this is 0, the hotend heating is turned off."
msgstr "Die Zieltemperatur des Hotend. Das Hotend wird auf diese Temperatur aufgeheizt oder abgekühlt. Wenn der Wert 0 beträgt, wird die Hotend-Heizung ausgeschaltet."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:98
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:103
msgctxt "@tooltip"
msgid "The current temperature of this hotend."
msgstr "Die aktuelle Temperatur dieses Hotends."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:172
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:177
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the hotend to."
msgstr "Die Temperatur, auf die das Hotend vorgeheizt wird."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:336
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:341
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:332
msgctxt "@button Cancel pre-heating"
msgid "Cancel"
msgstr "Abbrechen"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:339
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:344
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:335
msgctxt "@button"
msgid "Pre-heat"
msgstr "Vorheizen"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:365
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:370
msgctxt "@tooltip of pre-heat"
msgid "Heat the hotend in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the hotend to heat up when you're ready to print."
msgstr "Heizen Sie das Hotend vor Druckbeginn auf. Sie können Ihren Druck während des Aufheizens weiter anpassen und müssen nicht warten, bis das Hotend aufgeheizt ist, wenn Sie druckbereit sind."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:401
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:406
msgctxt "@tooltip"
msgid "The colour of the material in this extruder."
msgstr "Die Farbe des Materials in diesem Extruder."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:433
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:438
msgctxt "@tooltip"
msgid "The material in this extruder."
msgstr "Das Material in diesem Extruder."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:465
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:470
msgctxt "@tooltip"
msgid "The nozzle inserted in this extruder."
msgstr "Die in diesem Extruder eingesetzte Düse."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:25
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:493
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
+msgctxt "@info:status"
+msgid "The printer is not connected."
+msgstr "Der Drucker ist nicht verbunden."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:26
msgctxt "@label"
msgid "Build plate"
msgstr "Druckbett"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:56
msgctxt "@tooltip"
msgid "The target temperature of the heated bed. The bed will heat up or cool down towards this temperature. If this is 0, the bed heating is turned off."
msgstr "Die Zieltemperatur des heizbaren Betts. Das Bett wird auf diese Temperatur aufgeheizt oder abgekühlt. Wenn der Wert 0 beträgt, wird die Bettheizung ausgeschaltet."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:88
msgctxt "@tooltip"
msgid "The current temperature of the heated bed."
msgstr "Die aktuelle Temperatur des beheizten Betts."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:160
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:161
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the bed to."
msgstr "Die Temperatur, auf die das Bett vorgeheizt wird."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:361
msgctxt "@tooltip of pre-heat"
msgid "Heat the bed in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the bed to heat up when you're ready to print."
msgstr "Heizen Sie das Bett vor Druckbeginn auf. Sie können Ihren Druck während des Aufheizens weiter anpassen und müssen nicht warten, bis das Bett aufgeheizt ist, wenn Sie druckbereit sind."
@@ -3692,12 +3796,12 @@ msgctxt "@label:category menu label"
msgid "Material"
msgstr "Material"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:37
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:46
msgctxt "@label:category menu label"
msgid "Favorites"
msgstr "Favoriten"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:71
msgctxt "@label:category menu label"
msgid "Generic"
msgstr "Generisch"
@@ -3712,17 +3816,52 @@ msgctxt "@label:category menu label"
msgid "Local printers"
msgstr "Lokale Drucker"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
-msgctxt "@title:menu menubar:toplevel"
-msgid "&View"
-msgstr "&Ansicht"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:15
+msgctxt "@title:menu menubar:settings"
+msgid "&Printer"
+msgstr "Dr&ucker"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:42
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:27
+msgctxt "@title:menu"
+msgid "&Material"
+msgstr "&Material"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:36
+msgctxt "@action:inmenu"
+msgid "Set as Active Extruder"
+msgstr "Als aktiven Extruder festlegen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:42
+msgctxt "@action:inmenu"
+msgid "Enable Extruder"
+msgstr "Extruder aktivieren"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:49
+msgctxt "@action:inmenu"
+msgid "Disable Extruder"
+msgstr "Extruder deaktivieren"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:19
msgctxt "@action:inmenu menubar:view"
msgid "&Camera position"
msgstr "&Kameraposition"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:58
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:44
+msgctxt "@action:inmenu menubar:view"
+msgid "Camera view"
+msgstr "Kameraansicht"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:47
+msgctxt "@action:inmenu menubar:view"
+msgid "Perspective"
+msgstr "Ansicht"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:59
+msgctxt "@action:inmenu menubar:view"
+msgid "Orthographic"
+msgstr "Orthogonal"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:80
msgctxt "@action:inmenu menubar:view"
msgid "&Build plate"
msgstr "&Druckplatte"
@@ -3742,6 +3881,21 @@ msgctxt "@action:inmenu"
msgid "Manage Setting Visibility..."
msgstr "Sichtbarkeit einstellen verwalten..."
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:33
+msgctxt "@title:menu menubar:file"
+msgid "&Save..."
+msgstr "&Speichern..."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:54
+msgctxt "@title:menu menubar:file"
+msgid "&Export..."
+msgstr "&Exportieren..."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:65
+msgctxt "@action:inmenu menubar:file"
+msgid "Export Selection..."
+msgstr "Auswahl exportieren..."
+
#: /home/ruben/Projects/Cura/resources/qml/Menus/ContextMenu.qml:27
msgctxt "@label"
msgid "Print Selected Model With:"
@@ -3761,654 +3915,509 @@ msgctxt "@label"
msgid "Number of Copies"
msgstr "Anzahl Kopien"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:33
-msgctxt "@label:header configurations"
-msgid "Available configurations"
-msgstr "Verfügbare Konfigurationen"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml:18
+msgctxt "@header"
+msgid "Configurations"
+msgstr "Konfigurationen"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml:28
-msgctxt "@label:extruder label"
-msgid "Extruder"
-msgstr "Extruder"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:112
+msgctxt "@label"
+msgid "Select configuration"
+msgstr "Konfiguration wählen"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "Yes"
-msgstr "Ja"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:223
+msgctxt "@label"
+msgid "Configurations"
+msgstr "Konfigurationen"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "No"
-msgstr "Nein"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:57
+msgctxt "@label"
+msgid "Loading available configurations from the printer..."
+msgstr "Verfügbare Konfigurationen werden von diesem Drucker geladen..."
-#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:13
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:58
+msgctxt "@label"
+msgid "The configurations are not available because the printer is disconnected."
+msgstr "Die Konfigurationen sind nicht verfügbar, da der Drucker getrennt ist."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:25
+msgctxt "@header"
+msgid "Custom"
+msgstr "Benutzerdefiniert"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:61
+msgctxt "@label"
+msgid "Printer"
+msgstr "Drucker"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:213
+msgctxt "@label"
+msgid "Enabled"
+msgstr "Aktiviert"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:251
+msgctxt "@label"
+msgid "Material"
+msgstr "Material"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:378
+msgctxt "@label"
+msgid "Use glue for better adhesion with this material combination."
+msgstr "Für diese Materialkombination Kleber für eine bessere Haftung verwenden."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:128
+msgctxt "@label"
+msgid "This configuration is not available because %1 is not recognized. Please visit %2 to download the correct material profile."
+msgstr "Diese Konfigurationen sind nicht verfügbar, weil %1 nicht erkannt wird. Besuchen Sie bitte %2 für das Herunterladen des korrekten Materialprofils."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:129
+msgctxt "@label"
+msgid "Marketplace"
+msgstr "Marktplatz"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:15
msgctxt "@title:menu menubar:file"
msgid "Open &Recent"
msgstr "&Zuletzt geöffnet"
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid "Print Setup"
-msgstr "Druckeinrichtung"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid ""
-"Print Setup disabled\n"
-"G-code files cannot be modified"
-msgstr "Druckeinrichtung deaktiviert\nG-Code-Dateien können nicht geändert werden"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:340
-msgctxt "@label Hours and minutes"
-msgid "00h 00min"
-msgstr "00 Stunden 00 Minuten"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:358
-msgctxt "@tooltip"
-msgid "Time specification"
-msgstr "Zeitangabe"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:440
-msgctxt "@label"
-msgid "Cost specification"
-msgstr "Kostenangabe"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:445
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:454
-msgctxt "@label m for meter"
-msgid "%1m"
-msgstr "%1 m"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:446
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:455
-msgctxt "@label g for grams"
-msgid "%1g"
-msgstr "%1 g"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:453
-msgctxt "@label"
-msgid "Total:"
-msgstr "Insgesamt:"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:576
-msgctxt "@tooltip"
-msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
-msgstr "Empfohlene Druckeinrichtung
Drucken mit den empfohlenen Einstellungen für den gewählten Drucker, das gewählte Material und die gewählte Qualität."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:581
-msgctxt "@tooltip"
-msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
-msgstr "Benutzerdefinierte Druckeinrichtung
Druck mit Feineinstellung über jedem einzelnen Bereich des Schneidvorgangs."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:140
msgctxt "@label"
msgid "Active print"
msgstr "Aktiver Druck"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:148
msgctxt "@label"
msgid "Job Name"
msgstr "Name des Auftrags"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:156
msgctxt "@label"
msgid "Printing Time"
msgstr "Druckzeit"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:130
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:164
msgctxt "@label"
msgid "Estimated time left"
msgstr "Geschätzte verbleibende Zeit"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:79
+#: /home/ruben/Projects/Cura/resources/qml/ViewsSelector.qml:50
+msgctxt "@label"
+msgid "View type"
+msgstr "Typ anzeigen"
+
+#: /home/ruben/Projects/Cura/resources/qml/ObjectSelector.qml:59
+msgctxt "@label"
+msgid "Object list"
+msgstr "Objektliste"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:22
+msgctxt "@label The argument is a username."
+msgid "Hi %1"
+msgstr "Hallo %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:33
+msgctxt "@button"
+msgid "Ultimaker account"
+msgstr "Ultimaker‑Konto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:42
+msgctxt "@button"
+msgid "Sign out"
+msgstr "Abmelden"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/AccountWidget.qml:24
+msgctxt "@action:button"
+msgid "Sign in"
+msgstr "Anmelden"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:40
+msgctxt "@label"
+msgid "The next generation 3D printing workflow"
+msgstr "Der 3D-Druckablauf der nächsten Generation"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:51
+msgctxt "@text"
+msgid ""
+"- Send print jobs to Ultimaker printers outside your local network\n"
+"- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+"- Get exclusive access to print profiles from leading brands"
+msgstr ""
+"- Aufträge an Ultimaker-Drucker außerhalb Ihres lokalen Netzwerks senden\n"
+"- Ihre Ultimaker Cura-Einstellungen für die Verwendung andernorts an die Cloud senden\n"
+"- Exklusiven Zugang zu Druckprofilen von führenden Marken erhalten"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:78
+msgctxt "@button"
+msgid "Create account"
+msgstr "Konto erstellen"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:59
+msgctxt "@label"
+msgid "No time estimation available"
+msgstr "Keine Zeitschätzung verfügbar"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:77
+msgctxt "@label"
+msgid "No cost estimation available"
+msgstr "Keine Kostenschätzung verfügbar"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:127
+msgctxt "@button"
+msgid "Preview"
+msgstr "Vorschau"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:55
+msgctxt "@label:PrintjobStatus"
+msgid "Slicing..."
+msgstr "Das Slicing läuft..."
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:67
+msgctxt "@label:PrintjobStatus"
+msgid "Unable to slice"
+msgstr "Slicing nicht möglich"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Processing"
+msgstr "Verarbeitung läuft"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Slice"
+msgstr "Slice"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:104
+msgctxt "@label"
+msgid "Start the slicing process"
+msgstr "Slicing-Vorgang starten"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:118
+msgctxt "@button"
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:31
+msgctxt "@label"
+msgid "Time estimation"
+msgstr "Zeitschätzung"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:114
+msgctxt "@label"
+msgid "Material estimation"
+msgstr "Materialschätzung"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:164
+msgctxt "@label m for meter"
+msgid "%1m"
+msgstr "%1 m"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:165
+msgctxt "@label g for grams"
+msgid "%1g"
+msgstr "%1 g"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Connected printers"
+msgstr "Verbundene Drucker"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Preset printers"
+msgstr "Voreingestellte Drucker"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:166
+msgctxt "@button"
+msgid "Add printer"
+msgstr "Drucker hinzufügen"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:182
+msgctxt "@button"
+msgid "Manage printers"
+msgstr "Drucker verwalten"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:81
+msgctxt "@action:inmenu"
+msgid "Show Online Troubleshooting Guide"
+msgstr "Online-Fehlerbehebung anzeigen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:88
msgctxt "@action:inmenu"
msgid "Toggle Full Screen"
msgstr "Umschalten auf Vollbild-Modus"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:86
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+msgctxt "@action:inmenu"
+msgid "Exit Full Screen"
+msgstr "Vollbildmodus beenden"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:103
msgctxt "@action:inmenu menubar:edit"
msgid "&Undo"
msgstr "&Rückgängig machen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
msgctxt "@action:inmenu menubar:edit"
msgid "&Redo"
msgstr "&Wiederholen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:123
msgctxt "@action:inmenu menubar:file"
msgid "&Quit"
msgstr "&Beenden"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:131
msgctxt "@action:inmenu menubar:view"
msgid "3D View"
msgstr "3D-Ansicht"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:138
msgctxt "@action:inmenu menubar:view"
msgid "Front View"
msgstr "Vorderansicht"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:128
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:145
msgctxt "@action:inmenu menubar:view"
msgid "Top View"
msgstr "Draufsicht"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:135
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:152
msgctxt "@action:inmenu menubar:view"
msgid "Left Side View"
msgstr "Ansicht von links"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:159
msgctxt "@action:inmenu menubar:view"
msgid "Right Side View"
msgstr "Ansicht von rechts"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:149
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:166
msgctxt "@action:inmenu"
msgid "Configure Cura..."
msgstr "Cura konfigurieren..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:156
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:173
msgctxt "@action:inmenu menubar:printer"
msgid "&Add Printer..."
msgstr "&Drucker hinzufügen..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:179
msgctxt "@action:inmenu menubar:printer"
msgid "Manage Pr&inters..."
msgstr "Dr&ucker verwalten..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:169
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:186
msgctxt "@action:inmenu"
msgid "Manage Materials..."
msgstr "Materialien werden verwaltet..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:177
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:195
msgctxt "@action:inmenu menubar:profile"
msgid "&Update profile with current settings/overrides"
msgstr "&Profil mit aktuellen Einstellungen/Überschreibungen aktualisieren"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:185
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
msgctxt "@action:inmenu menubar:profile"
msgid "&Discard current changes"
msgstr "&Aktuelle Änderungen verwerfen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:197
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:215
msgctxt "@action:inmenu menubar:profile"
msgid "&Create profile from current settings/overrides..."
msgstr "P&rofil von aktuellen Einstellungen/Überschreibungen erstellen..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:221
msgctxt "@action:inmenu menubar:profile"
msgid "Manage Profiles..."
msgstr "Profile verwalten..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:210
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:229
msgctxt "@action:inmenu menubar:help"
msgid "Show Online &Documentation"
msgstr "Online-&Dokumentation anzeigen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:218
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:237
msgctxt "@action:inmenu menubar:help"
msgid "Report a &Bug"
msgstr "&Fehler melden"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:226
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:245
+msgctxt "@action:inmenu menubar:help"
+msgid "What's New"
+msgstr "Neuheiten"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:251
msgctxt "@action:inmenu menubar:help"
msgid "About..."
msgstr "Über..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:233
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:258
msgctxt "@action:inmenu menubar:edit"
msgid "Delete Selected Model"
msgid_plural "Delete Selected Models"
msgstr[0] "Ausgewähltes Modell löschen"
msgstr[1] "Ausgewählte Modelle löschen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:243
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:268
msgctxt "@action:inmenu menubar:edit"
msgid "Center Selected Model"
msgid_plural "Center Selected Models"
msgstr[0] "Ausgewähltes Modell zentrieren"
msgstr[1] "Ausgewählte Modelle zentrieren"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:277
msgctxt "@action:inmenu menubar:edit"
msgid "Multiply Selected Model"
msgid_plural "Multiply Selected Models"
msgstr[0] "Ausgewähltes Modell multiplizieren"
msgstr[1] "Ausgewählte Modelle multiplizieren"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:261
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:286
msgctxt "@action:inmenu"
msgid "Delete Model"
msgstr "Modell löschen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:294
msgctxt "@action:inmenu"
msgid "Ce&nter Model on Platform"
msgstr "Modell auf Druckplatte ze&ntrieren"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:275
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:300
msgctxt "@action:inmenu menubar:edit"
msgid "&Group Models"
msgstr "Modelle &gruppieren"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:320
msgctxt "@action:inmenu menubar:edit"
msgid "Ungroup Models"
msgstr "Gruppierung für Modelle aufheben"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:305
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:330
msgctxt "@action:inmenu menubar:edit"
msgid "&Merge Models"
msgstr "Modelle &zusammenführen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:315
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:340
msgctxt "@action:inmenu"
msgid "&Multiply Model..."
msgstr "Modell &multiplizieren..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:322
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:347
msgctxt "@action:inmenu menubar:edit"
msgid "Select All Models"
msgstr "Alle Modelle wählen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:332
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:357
msgctxt "@action:inmenu menubar:edit"
msgid "Clear Build Plate"
msgstr "Druckplatte reinigen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:342
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:367
msgctxt "@action:inmenu menubar:file"
msgid "Reload All Models"
msgstr "Alle Modelle neu laden"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:376
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models To All Build Plates"
msgstr "Alle Modelle an allen Druckplatten anordnen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:358
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:383
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models"
msgstr "Alle Modelle anordnen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:366
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:391
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange Selection"
msgstr "Anordnung auswählen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:373
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:398
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Positions"
msgstr "Alle Modellpositionen zurücksetzen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:380
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:405
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Transformations"
msgstr "Alle Modelltransformationen zurücksetzen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:387
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:412
msgctxt "@action:inmenu menubar:file"
msgid "&Open File(s)..."
msgstr "&Datei(en) öffnen..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:395
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:420
msgctxt "@action:inmenu menubar:file"
msgid "&New Project..."
msgstr "&Neues Projekt..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:402
-msgctxt "@action:inmenu menubar:help"
-msgid "Show Engine &Log..."
-msgstr "Engine-&Protokoll anzeigen..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:410
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:427
msgctxt "@action:inmenu menubar:help"
msgid "Show Configuration Folder"
msgstr "Konfigurationsordner anzeigen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:424
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:441
msgctxt "@action:menu"
-msgid "Browse packages..."
-msgstr "Pakete durchsuchen..."
+msgid "&Marketplace"
+msgstr "&Marktplatz"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:431
-msgctxt "@action:inmenu menubar:view"
-msgid "Expand/Collapse Sidebar"
-msgstr "Seitenleiste vergrößern/verkleinern"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:27
-msgctxt "@label:PrintjobStatus"
-msgid "Please load a 3D model"
-msgstr "Bitte laden Sie ein 3D-Modell"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:37
-msgctxt "@label:PrintjobStatus"
-msgid "Ready to slice"
-msgstr "Bereit zum Slicen (Schneiden)"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:39
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing..."
-msgstr "Das Slicing läuft..."
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:41
-msgctxt "@label:PrintjobStatus %1 is target operation"
-msgid "Ready to %1"
-msgstr "Bereit zum %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:43
-msgctxt "@label:PrintjobStatus"
-msgid "Unable to Slice"
-msgstr "Slicing nicht möglich"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:45
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing unavailable"
-msgstr "Slicing ist nicht verfügbar"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Slice current printjob"
-msgstr "Aktuellen Druckauftrag slicen"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Cancel slicing process"
-msgstr "Slicing-Vorgang abbrechen"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Prepare"
-msgstr "Vorbereiten"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Cancel"
-msgstr "Abbrechen"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:320
-msgctxt "@info:tooltip"
-msgid "Select the active output device"
-msgstr "Wählen Sie das aktive Ausgabegerät"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:19
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:767
-msgctxt "@title:window"
-msgid "Open file(s)"
-msgstr "Datei(en) öffnen"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:64
-msgctxt "@text:window"
-msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
-msgstr "Es wurden eine oder mehrere Projektdatei(en) innerhalb der von Ihnen gewählten Dateien gefunden. Sie können nur eine Projektdatei auf einmal öffnen. Es wird empfohlen, nur Modelle aus diesen Dateien zu importieren. Möchten Sie fortfahren?"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:99
-msgctxt "@action:button"
-msgid "Import all as models"
-msgstr "Alle als Modelle importieren"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:19
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:24
msgctxt "@title:window"
msgid "Ultimaker Cura"
msgstr "Ultimaker Cura"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:103
-msgctxt "@title:menu menubar:toplevel"
-msgid "&File"
-msgstr "&Datei"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:121
-msgctxt "@title:menu menubar:file"
-msgid "&Save..."
-msgstr "&Speichern..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:142
-msgctxt "@title:menu menubar:file"
-msgid "&Export..."
-msgstr "&Exportieren..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:153
-msgctxt "@action:inmenu menubar:file"
-msgid "Export Selection..."
-msgstr "Auswahl exportieren..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:174
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Edit"
-msgstr "&Bearbeiten"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:191
-msgctxt "@title:menu"
-msgid "&View"
-msgstr "&Ansicht"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:196
-msgctxt "@title:menu"
-msgid "&Settings"
-msgstr "&Konfiguration"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:198
-msgctxt "@title:menu menubar:settings"
-msgid "&Printer"
-msgstr "Dr&ucker"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:207
-msgctxt "@title:menu"
-msgid "&Material"
-msgstr "&Material"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:216
-msgctxt "@action:inmenu"
-msgid "Set as Active Extruder"
-msgstr "Als aktiven Extruder festlegen"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:222
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:188
-msgctxt "@action:inmenu"
-msgid "Enable Extruder"
-msgstr "Extruder aktivieren"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:229
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:194
-msgctxt "@action:inmenu"
-msgid "Disable Extruder"
-msgstr "Extruder deaktivieren"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:241
-msgctxt "@title:menu"
-msgid "&Build plate"
-msgstr "&Druckplatte"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:242
-msgctxt "@title:settings"
-msgid "&Profile"
-msgstr "&Profil"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:252
-msgctxt "@title:menu menubar:toplevel"
-msgid "E&xtensions"
-msgstr "Er&weiterungen"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:286
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Toolbox"
-msgstr "&Toolbox"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:294
-msgctxt "@title:menu menubar:toplevel"
-msgid "P&references"
-msgstr "E&instellungen"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:302
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Help"
-msgstr "&Hilfe"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:232
msgctxt "@label"
msgid "This package will be installed after restarting."
msgstr "Dieses Paket wird nach einem Neustart installiert."
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:377
-msgctxt "@action:button"
-msgid "Open File"
-msgstr "Datei öffnen"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:547
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:413
msgctxt "@title:tab"
msgid "Settings"
msgstr "Einstellungen"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:593
-msgctxt "@title:window"
-msgid "New project"
-msgstr "Neues Projekt"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:594
-msgctxt "@info:question"
-msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
-msgstr "Möchten Sie wirklich ein neues Projekt beginnen? Damit werden das Druckbett und alle nicht gespeicherten Einstellungen gelöscht."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:722
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:538
msgctxt "@title:window"
msgid "Closing Cura"
msgstr "Cura wird geschlossen"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:723
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:735
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
msgctxt "@label"
msgid "Are you sure you want to exit Cura?"
msgstr "Möchten Sie Cura wirklich beenden?"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:868
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:589
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:19
+msgctxt "@title:window"
+msgid "Open file(s)"
+msgstr "Datei(en) öffnen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:695
msgctxt "@window:title"
msgid "Install Package"
msgstr "Paket installieren"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:875
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:703
msgctxt "@title:window"
msgid "Open File(s)"
msgstr "Datei(en) öffnen"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:878
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:706
msgctxt "@text:window"
msgid "We have found one or more G-Code files within the files you have selected. You can only open one G-Code file at a time. If you want to open a G-Code file, please just select only one."
msgstr "Es wurden eine oder mehrere G-Code-Datei(en) innerhalb der von Ihnen gewählten Dateien gefunden. Sie können nur eine G-Code-Datei auf einmal öffnen. Wenn Sie eine G-Code-Datei öffnen möchten wählen Sie bitte nur eine Datei."
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:14
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:809
msgctxt "@title:window"
-msgid "Save Project"
-msgstr "Projekt speichern"
+msgid "Add Printer"
+msgstr "Drucker hinzufügen"
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:137
-msgctxt "@action:label"
-msgid "Build plate"
-msgstr "Druckplatte"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:169
-msgctxt "@action:label"
-msgid "Extruder %1"
-msgstr "Extruder %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:179
-msgctxt "@action:label"
-msgid "%1 & material"
-msgstr "%1 & Material"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:268
-msgctxt "@action:label"
-msgid "Don't show project summary on save again"
-msgstr "Projektzusammenfassung beim Speichern nicht erneut anzeigen"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:287
-msgctxt "@action:button"
-msgid "Save"
-msgstr "Speichern"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:192
-msgctxt "@label"
-msgid "Layer Height"
-msgstr "Schichtdicke"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:277
-msgctxt "@tooltip"
-msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
-msgstr "Dieses Qualitätsprofil ist für Ihr aktuelles Material und Ihre derzeitige Düsenkonfiguration nicht verfügbar. Bitte ändern Sie diese, um dieses Qualitätsprofil zu aktivieren"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:450
-msgctxt "@tooltip"
-msgid "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab"
-msgstr "Ein benutzerdefiniertes Profil ist derzeit aktiv. Wählen Sie ein voreingestelltes Qualitätsprofil aus der Registerkarte „Benutzerdefiniert“, um den Schieberegler für Qualität zu aktivieren"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:467
-msgctxt "@label"
-msgid "Print Speed"
-msgstr "Druckgeschwindigkeit"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:479
-msgctxt "@label"
-msgid "Slower"
-msgstr "Langsamer"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:490
-msgctxt "@label"
-msgid "Faster"
-msgstr "Schneller"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:518
-msgctxt "@tooltip"
-msgid "You have modified some profile settings. If you want to change these go to custom mode."
-msgstr "Sie haben einige Profileinstellungen geändert. Wenn Sie diese ändern möchten, wechseln Sie in den Modus „Benutzerdefiniert“."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:541
-msgctxt "@label"
-msgid "Infill"
-msgstr "Füllung"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:777
-msgctxt "@label"
-msgid "Gradual infill will gradually increase the amount of infill towards the top."
-msgstr "Die graduelle Füllung steigert die Menge der Füllung nach oben hin schrittweise."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:791
-msgctxt "@label"
-msgid "Enable gradual"
-msgstr "Graduell aktivieren"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:858
-msgctxt "@label"
-msgid "Generate Support"
-msgstr "Stützstruktur generieren"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:892
-msgctxt "@label"
-msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
-msgstr "Damit werden Strukturen zur Unterstützung von Modellteilen mit Überhängen generiert. Ohne diese Strukturen würden solche Teile während des Druckvorgangs zusammenfallen."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:964
-msgctxt "@label"
-msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
-msgstr "Wählen Sie, welcher Extruder für die Unterstützung verwendet wird. Dient zum Konstruieren von Stützstrukturen unter dem Modell, damit dieses nicht absinkt oder frei schwebend gedruckt wird."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:987
-msgctxt "@label"
-msgid "Build Plate Adhesion"
-msgstr "Druckplattenhaftung"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1042
-msgctxt "@label"
-msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
-msgstr "Drucken eines Brim- oder Raft-Elements aktivieren. Es wird ein flacher Bereich rund um oder unter Ihrem Objekt hinzugefügt, das im Anschluss leicht abgeschnitten werden kann."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1082
-msgctxt "@label"
-msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
-msgstr "Sie benötigen Hilfe für Ihre Drucke? Lesen Sie die Ultimaker Anleitungen für Fehlerbehebung>"
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:817
+msgctxt "@title:window"
+msgid "What's New"
+msgstr "Neuheiten"
#: /home/ruben/Projects/Cura/resources/qml/ExtruderButton.qml:16
msgctxt "@label %1 is filled in with the name of an extruder"
@@ -4417,75 +4426,503 @@ msgid_plural "Print Selected Models with %1"
msgstr[0] "Ausgewähltes Modell drucken mit %1"
msgstr[1] "Ausgewählte Modelle drucken mit %1"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:20
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:15
+msgctxt "@title:window"
+msgid "Discard or Keep changes"
+msgstr "Änderungen verwerfen oder übernehmen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:57
+msgctxt "@text:window"
+msgid ""
+"You have customized some profile settings.\n"
+"Would you like to keep or discard those settings?"
+msgstr ""
+"Sie haben einige Profileinstellungen angepasst.\n"
+"Möchten Sie diese Einstellungen übernehmen oder verwerfen?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:110
+msgctxt "@title:column"
+msgid "Profile settings"
+msgstr "Profileinstellungen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:117
+msgctxt "@title:column"
+msgid "Default"
+msgstr "Standard"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:124
+msgctxt "@title:column"
+msgid "Customized"
+msgstr "Angepasst"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:158
+msgctxt "@option:discardOrKeep"
+msgid "Discard and never ask again"
+msgstr "Verwerfen und zukünftig nicht mehr nachfragen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:159
+msgctxt "@option:discardOrKeep"
+msgid "Keep and never ask again"
+msgstr "Übernehmen und zukünftig nicht mehr nachfragen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:196
+msgctxt "@action:button"
+msgid "Discard"
+msgstr "Verwerfen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:209
+msgctxt "@action:button"
+msgid "Keep"
+msgstr "Übernehmen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:222
+msgctxt "@action:button"
+msgid "Create New Profile"
+msgstr "Neues Profil erstellen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:15
+msgctxt "@title:window"
+msgid "About Cura"
+msgstr "Über Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:57
+msgctxt "@label"
+msgid "version: %1"
+msgstr "Version: %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:72
+msgctxt "@label"
+msgid "End-to-end solution for fused filament 3D printing."
+msgstr "Komplettlösung für den 3D-Druck mit geschmolzenem Filament."
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:85
+msgctxt "@info:credit"
+msgid ""
+"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
+"Cura proudly uses the following open source projects:"
+msgstr ""
+"Cura wurde von Ultimaker B.V. in Zusammenarbeit mit der Community entwickelt.\n"
+"Cura verwendet mit Stolz die folgenden Open Source-Projekte:"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:135
+msgctxt "@label"
+msgid "Graphical user interface"
+msgstr "Grafische Benutzerschnittstelle"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:136
+msgctxt "@label"
+msgid "Application framework"
+msgstr "Anwendungsrahmenwerk"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:137
+msgctxt "@label"
+msgid "G-code generator"
+msgstr "G-Code-Generator"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:138
+msgctxt "@label"
+msgid "Interprocess communication library"
+msgstr "Bibliothek Interprozess-Kommunikation"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:140
+msgctxt "@label"
+msgid "Programming language"
+msgstr "Programmiersprache"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:141
+msgctxt "@label"
+msgid "GUI framework"
+msgstr "GUI-Rahmenwerk"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:142
+msgctxt "@label"
+msgid "GUI framework bindings"
+msgstr "GUI-Rahmenwerk Einbindungen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:143
+msgctxt "@label"
+msgid "C/C++ Binding library"
+msgstr "C/C++ Einbindungsbibliothek"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:144
+msgctxt "@label"
+msgid "Data interchange format"
+msgstr "Format Datenaustausch"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:145
+msgctxt "@label"
+msgid "Support library for scientific computing"
+msgstr "Support-Bibliothek für wissenschaftliche Berechnung"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:146
+msgctxt "@label"
+msgid "Support library for faster math"
+msgstr "Support-Bibliothek für schnelleres Rechnen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:147
+msgctxt "@label"
+msgid "Support library for handling STL files"
+msgstr "Support-Bibliothek für die Handhabung von STL-Dateien"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:148
+msgctxt "@label"
+msgid "Support library for handling planar objects"
+msgstr "Support-Bibliothek für die Handhabung von ebenen Objekten"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:149
+msgctxt "@label"
+msgid "Support library for handling triangular meshes"
+msgstr "Support-Bibliothek für die Handhabung von dreieckigen Netzen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:150
+msgctxt "@label"
+msgid "Support library for analysis of complex networks"
+msgstr "Support-Bibliothek für die Analyse von komplexen Netzwerken"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:151
+msgctxt "@label"
+msgid "Support library for handling 3MF files"
+msgstr "Support-Bibliothek für die Handhabung von 3MF-Dateien"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:152
+msgctxt "@label"
+msgid "Support library for file metadata and streaming"
+msgstr "Support-Bibliothek für Datei-Metadaten und Streaming"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:153
+msgctxt "@label"
+msgid "Serial communication library"
+msgstr "Bibliothek für serielle Kommunikation"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:154
+msgctxt "@label"
+msgid "ZeroConf discovery library"
+msgstr "Bibliothek für ZeroConf-Erkennung"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:155
+msgctxt "@label"
+msgid "Polygon clipping library"
+msgstr "Bibliothek für Polygon-Beschneidung"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:156
+msgctxt "@Label"
+msgid "Python HTTP library"
+msgstr "Bibliothek für Python HTTP"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:158
+msgctxt "@label"
+msgid "Font"
+msgstr "Schriftart"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:159
+msgctxt "@label"
+msgid "SVG icons"
+msgstr "SVG-Symbole"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:160
+msgctxt "@label"
+msgid "Linux cross-distribution application deployment"
+msgstr "Distributionsunabhängiges Format für Linux-Anwendungen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:64
+msgctxt "@text:window"
+msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
+msgstr "Es wurden eine oder mehrere Projektdatei(en) innerhalb der von Ihnen gewählten Dateien gefunden. Sie können nur eine Projektdatei auf einmal öffnen. Es wird empfohlen, nur Modelle aus diesen Dateien zu importieren. Möchten Sie fortfahren?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:99
+msgctxt "@action:button"
+msgid "Import all as models"
+msgstr "Alle als Modelle importieren"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:15
+msgctxt "@title:window"
+msgid "Save Project"
+msgstr "Projekt speichern"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:177
+msgctxt "@action:label"
+msgid "Extruder %1"
+msgstr "Extruder %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:192
+msgctxt "@action:label"
+msgid "%1 & material"
+msgstr "%1 & Material"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:194
+msgctxt "@action:label"
+msgid "Material"
+msgstr "Material"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:283
+msgctxt "@action:label"
+msgid "Don't show project summary on save again"
+msgstr "Projektzusammenfassung beim Speichern nicht erneut anzeigen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:302
+msgctxt "@action:button"
+msgid "Save"
+msgstr "Speichern"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:20
msgctxt "@title:window"
msgid "Open project file"
msgstr "Projektdatei öffnen"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:93
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:93
msgctxt "@text:window"
msgid "This is a Cura project file. Would you like to open it as a project or import the models from it?"
msgstr "Dies ist eine Cura-Projektdatei. Möchten Sie diese als Projekt öffnen oder die Modelle hieraus importieren?"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:103
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:103
msgctxt "@text:window"
msgid "Remember my choice"
msgstr "Meine Auswahl merken"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:122
msgctxt "@action:button"
msgid "Open as project"
msgstr "Als Projekt öffnen"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:131
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:131
msgctxt "@action:button"
msgid "Import models"
msgstr "Modelle importieren"
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15
-msgctxt "@title:window"
-msgid "Engine Log"
-msgstr "Engine-Protokoll"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:70
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DropDownWidget.qml:93
msgctxt "@label"
-msgid "Printer type"
-msgstr "Druckertyp"
+msgid "Empty"
+msgstr "Leer"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:376
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:24
msgctxt "@label"
-msgid "Material"
-msgstr "Material"
+msgid "Add a printer"
+msgstr "Einen Drucker hinzufügen"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:543
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:39
msgctxt "@label"
-msgid "Use glue with this material combination"
-msgstr "Für diese Materialkombination Kleber verwenden"
+msgid "Add a networked printer"
+msgstr "Einen vernetzten Drucker hinzufügen"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:575
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:81
msgctxt "@label"
-msgid "Check compatibility"
-msgstr "Kompatibilität prüfen"
+msgid "Add a non-networked printer"
+msgstr "Einen unvernetzten Drucker hinzufügen"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:593
-msgctxt "@tooltip"
-msgid "Click to check the material compatibility on Ultimaker.com."
-msgstr "Klicken Sie, um die Materialkompatibilität auf Ultimaker.com zu prüfen."
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:70
+msgctxt "@label"
+msgid "Add printer by IP address"
+msgstr "Drucker nach IP-Adresse hinzufügen"
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:211
-msgctxt "@option:check"
-msgid "See only current build plate"
-msgstr "Nur aktuelle Druckplatte anzeigen"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:133
+msgctxt "@text"
+msgid "Place enter your printer's IP address."
+msgstr "Bitte geben Sie die IP-Adresse Ihres Druckers ein."
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:227
-msgctxt "@action:button"
-msgid "Arrange to all build plates"
-msgstr "An allen Druckplatten ausrichten"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:158
+msgctxt "@button"
+msgid "Add"
+msgstr "Hinzufügen"
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:247
-msgctxt "@action:button"
-msgid "Arrange current build plate"
-msgstr "An aktueller Druckplatte ausrichten"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:204
+msgctxt "@label"
+msgid "Could not connect to device."
+msgstr "Verbindung mit Drucker nicht möglich."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:208
+msgctxt "@label"
+msgid "The printer at this address has not responded yet."
+msgstr "Der Drucker unter dieser Adresse hat noch nicht reagiert."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:240
+msgctxt "@label"
+msgid "This printer cannot be added because it's an unknown printer or it's not the host of a group."
+msgstr "Dieser Drucker kann nicht hinzugefügt werden, weil es sich um einen unbekannten Drucker handelt oder er nicht im Host einer Gruppe enthalten ist."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:329
+msgctxt "@button"
+msgid "Back"
+msgstr "Zurück"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:342
+msgctxt "@button"
+msgid "Connect"
+msgstr "Verbinden"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/FirstStartMachineActionsContent.qml:77
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:123
+msgctxt "@button"
+msgid "Next"
+msgstr "Weiter"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:23
+msgctxt "@label"
+msgid "User Agreement"
+msgstr "Benutzervereinbarung"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:56
+msgctxt "@button"
+msgid "Agree"
+msgstr "Stimme zu"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:70
+msgctxt "@button"
+msgid "Decline and close"
+msgstr "Ablehnen und schließen"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:24
+msgctxt "@label"
+msgid "Help us to improve Ultimaker Cura"
+msgstr "Helfen Sie uns, Ultimaker Cura zu verbessern"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:57
+msgctxt "@text"
+msgid "Ultimaker Cura collects anonymous data to improve print quality and user experience, including:"
+msgstr "Ultimaker Cura erfasst anonyme Daten, um die Druckqualität und Benutzererfahrung zu steigern. Dazu gehören:"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:71
+msgctxt "@text"
+msgid "Machine types"
+msgstr "Gerätetypen"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:77
+msgctxt "@text"
+msgid "Material usage"
+msgstr "Materialverbrauch"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:83
+msgctxt "@text"
+msgid "Number of slices"
+msgstr "Anzahl der Slices"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:89
+msgctxt "@text"
+msgid "Print settings"
+msgstr "Druckeinstellungen"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:102
+msgctxt "@text"
+msgid "Data collected by Ultimaker Cura will not contain any personal information."
+msgstr "Die von Ultimaker Cura erfassten Daten enthalten keine personenbezogenen Daten."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:103
+msgctxt "@text"
+msgid "More information"
+msgstr "Mehr Informationen"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WhatsNewContent.qml:24
+msgctxt "@label"
+msgid "What's new in Ultimaker Cura"
+msgstr "Neuheiten bei Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:42
+msgctxt "@label"
+msgid "There is no printer found over your network."
+msgstr "Kein Drucker in Ihrem Netzwerk gefunden."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:179
+msgctxt "@label"
+msgid "Refresh"
+msgstr "Aktualisieren"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:190
+msgctxt "@label"
+msgid "Add printer by IP"
+msgstr "Drucker nach IP hinzufügen"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:223
+msgctxt "@label"
+msgid "Troubleshooting"
+msgstr "Störungen beheben"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:211
+msgctxt "@label"
+msgid "Printer name"
+msgstr "Druckername"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:224
+msgctxt "@text"
+msgid "Please give your printer a name"
+msgstr "Weisen Sie Ihrem Drucker bitte einen Namen zu"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:36
+msgctxt "@label"
+msgid "Ultimaker Cloud"
+msgstr "Ultimaker Cloud"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:77
+msgctxt "@text"
+msgid "The next generation 3D printing workflow"
+msgstr "Der 3D-Druckablauf der nächsten Generation"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:94
+msgctxt "@text"
+msgid "- Send print jobs to Ultimaker printers outside your local network"
+msgstr "- Aufträge an Ultimaker-Drucker außerhalb Ihres lokalen Netzwerks senden"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:97
+msgctxt "@text"
+msgid "- Store your Ultimaker Cura settings in the cloud for use anywhere"
+msgstr "- Ihre Ultimaker Cura-Einstellungen für die Verwendung andernorts an die Cloud senden"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:100
+msgctxt "@text"
+msgid "- Get exclusive access to print profiles from leading brands"
+msgstr "- Exklusiven Zugang zu Druckprofilen von führenden Marken erhalten"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:119
+msgctxt "@button"
+msgid "Finish"
+msgstr "Beenden"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:128
+msgctxt "@button"
+msgid "Create an account"
+msgstr "Ein Konto erstellen"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:29
+msgctxt "@label"
+msgid "Welcome to Ultimaker Cura"
+msgstr "Willkommen bei Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:47
+msgctxt "@text"
+msgid ""
+"Please follow these steps to set up\n"
+"Ultimaker Cura. This will only take a few moments."
+msgstr ""
+"Befolgen Sie bitte diese Schritte für das Einrichten von\n"
+"Ultimaker Cura. Dies dauert nur wenige Sekunden."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:58
+msgctxt "@button"
+msgid "Get started"
+msgstr "Erste Schritte"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:27
+msgctxt "@info:tooltip"
+msgid "3D View"
+msgstr "3D-Ansicht"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:40
+msgctxt "@info:tooltip"
+msgid "Front View"
+msgstr "Vorderansicht"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:53
+msgctxt "@info:tooltip"
+msgid "Top View"
+msgstr "Draufsicht"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:66
+msgctxt "@info:tooltip"
+msgid "Left View"
+msgstr "Ansicht von links"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:79
+msgctxt "@info:tooltip"
+msgid "Right View"
+msgstr "Ansicht von rechts"
#: MachineSettingsAction/plugin.json
msgctxt "description"
@@ -4547,26 +4984,6 @@ msgctxt "name"
msgid "Model Checker"
msgstr "Modell-Prüfer"
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "description"
-msgid "Dump the contents of all settings to a HTML file."
-msgstr "Die Inhalte aller Einstellungen in eine HTML-Datei ausgeben."
-
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "name"
-msgid "God Mode"
-msgstr "Gott-Modus"
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "description"
-msgid "Shows changes since latest checked version."
-msgstr "Zeigt die Änderungen seit der letzten geprüften Version an."
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "name"
-msgid "Changelog"
-msgstr "Änderungsprotokoll"
-
#: FirmwareUpdater/plugin.json
msgctxt "description"
msgid "Provides a machine actions for updating firmware."
@@ -4577,15 +4994,15 @@ msgctxt "name"
msgid "Firmware Updater"
msgstr "Firmware-Aktualisierungsfunktion"
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "description"
-msgid "Create a flattend quality changes profile."
-msgstr "Erstellt eine geglättete Qualität, verändert das Profil."
+msgid "Provides support for reading AMF files."
+msgstr "Ermöglicht das Lesen von AMF-Dateien."
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "name"
-msgid "Profile flatener"
-msgstr "Profilglättfunktion"
+msgid "AMF Reader"
+msgstr "AMF-Reader"
#: USBPrinting/plugin.json
msgctxt "description"
@@ -4597,26 +5014,6 @@ msgctxt "name"
msgid "USB printing"
msgstr "USB-Drucken"
-#: UserAgreement/plugin.json
-msgctxt "description"
-msgid "Ask the user once if he/she agrees with our license."
-msgstr "Den Benutzer einmalig fragen, ob er unsere Lizenz akzeptiert."
-
-#: UserAgreement/plugin.json
-msgctxt "name"
-msgid "UserAgreement"
-msgstr "UserAgreement"
-
-#: X3GWriter/plugin.json
-msgctxt "description"
-msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
-msgstr "Ermöglicht das Speichern des resultierenden Slices als X3G-Datei, um Drucker zu unterstützen, die dieses Format lesen (Malyan, Makerbot und andere Sailfish-basierte Drucker)."
-
-#: X3GWriter/plugin.json
-msgctxt "name"
-msgid "X3GWriter"
-msgstr "X3G-Writer"
-
#: GCodeGzWriter/plugin.json
msgctxt "description"
msgid "Writes g-code to a compressed archive."
@@ -4659,13 +5056,13 @@ msgstr "Ausgabegerät-Plugin für Wechseldatenträger"
#: UM3NetworkPrinting/plugin.json
msgctxt "description"
-msgid "Manages network connections to Ultimaker 3 printers."
-msgstr "Verwaltet Netzwerkverbindungen zu Ultimaker 3-Druckern."
+msgid "Manages network connections to Ultimaker networked printers."
+msgstr "Verwaltet Netzwerkverbindungen zu Ultimaker-Netzwerkdruckern."
#: UM3NetworkPrinting/plugin.json
msgctxt "name"
-msgid "UM3 Network Connection"
-msgstr "UM3-Netzwerkverbindung"
+msgid "Ultimaker Network Connection"
+msgstr "Ultimaker-Netzwerkverbindung"
#: MonitorStage/plugin.json
msgctxt "description"
@@ -4727,6 +5124,16 @@ msgctxt "name"
msgid "Support Eraser"
msgstr "Stützstruktur-Radierer"
+#: UFPReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading Ultimaker Format Packages."
+msgstr "Bietet Unterstützung für das Lesen von Ultimaker Format Packages."
+
+#: UFPReader/plugin.json
+msgctxt "name"
+msgid "UFP Reader"
+msgstr "UFP-Reader"
+
#: SliceInfoPlugin/plugin.json
msgctxt "description"
msgid "Submits anonymous slice info. Can be disabled through preferences."
@@ -4787,6 +5194,16 @@ msgctxt "name"
msgid "Version Upgrade 3.3 to 3.4"
msgstr "Upgrade von Version 3.3 auf 3.4"
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.3 to Cura 4.4."
+msgstr "Aktualisiert Konfigurationen von Cura 4.3 auf Cura 4.4."
+
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.3 to 4.4"
+msgstr "Upgrade von Version 4.3 auf 4.4"
+
#: VersionUpgrade/VersionUpgrade25to26/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.5 to Cura 2.6."
@@ -4807,6 +5224,16 @@ msgctxt "name"
msgid "Version Upgrade 2.7 to 3.0"
msgstr "Upgrade von Version 2.7 auf 3.0"
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 3.5 to Cura 4.0."
+msgstr "Aktualisiert Konfigurationen von Cura 3.5 auf Cura 4.0."
+
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 3.5 to 4.0"
+msgstr "Upgrade von Version 3.5 auf 4.0"
+
#: VersionUpgrade/VersionUpgrade34to35/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.4 to Cura 3.5."
@@ -4817,6 +5244,16 @@ msgctxt "name"
msgid "Version Upgrade 3.4 to 3.5"
msgstr "Upgrade von Version 3.4 auf 3.5"
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.0 to Cura 4.1."
+msgstr "Aktualisiert Konfigurationen von Cura 4.0 auf Cura 4.1."
+
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.0 to 4.1"
+msgstr "Upgrade von Version 4.0 auf 4.1"
+
#: VersionUpgrade/VersionUpgrade30to31/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.0 to Cura 3.1."
@@ -4827,6 +5264,16 @@ msgctxt "name"
msgid "Version Upgrade 3.0 to 3.1"
msgstr "Upgrade von Version 3.0 auf 3.1"
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.1 to Cura 4.2."
+msgstr "Aktualisiert Konfigurationen von Cura 4.1 auf Cura 4.2."
+
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.1 to 4.2"
+msgstr "Upgrade von Version 4.1 auf 4.2"
+
#: VersionUpgrade/VersionUpgrade26to27/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.6 to Cura 2.7."
@@ -4857,6 +5304,16 @@ msgctxt "name"
msgid "Version Upgrade 2.2 to 2.4"
msgstr "Upgrade von Version 2.2 auf 2.4"
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.2 to Cura 4.3."
+msgstr "Aktualisiert Konfigurationen von Cura 4.2 auf Cura 4.3."
+
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.2 to 4.3"
+msgstr "Upgrade von Version 4.2 auf 4.3"
+
#: ImageReader/plugin.json
msgctxt "description"
msgid "Enables ability to generate printable geometry from 2D image files."
@@ -4867,6 +5324,16 @@ msgctxt "name"
msgid "Image Reader"
msgstr "Bild-Reader"
+#: TrimeshReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading model files."
+msgstr "Unterstützt das Lesen von Modelldateien."
+
+#: TrimeshReader/plugin.json
+msgctxt "name"
+msgid "Trimesh Reader"
+msgstr "Trimesh Reader"
+
#: CuraEngineBackend/plugin.json
msgctxt "description"
msgid "Provides the link to the CuraEngine slicing backend."
@@ -4917,6 +5384,16 @@ msgctxt "name"
msgid "G-code Reader"
msgstr "G-Code-Reader"
+#: CuraDrive/plugin.json
+msgctxt "description"
+msgid "Backup and restore your configuration."
+msgstr "Sicherung und Wiederherstellen Ihrer Konfiguration."
+
+#: CuraDrive/plugin.json
+msgctxt "name"
+msgid "Cura Backups"
+msgstr "Cura-Backups"
+
#: CuraProfileWriter/plugin.json
msgctxt "description"
msgid "Provides support for exporting Cura profiles."
@@ -4937,6 +5414,16 @@ msgctxt "name"
msgid "3MF Writer"
msgstr "3MF-Writer"
+#: PreviewStage/plugin.json
+msgctxt "description"
+msgid "Provides a preview stage in Cura."
+msgstr "Bietet eine Vorschaustufe in Cura."
+
+#: PreviewStage/plugin.json
+msgctxt "name"
+msgid "Preview Stage"
+msgstr "Vorschaustufe"
+
#: UltimakerMachineActions/plugin.json
msgctxt "description"
msgid "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.)."
@@ -4957,9 +5444,29 @@ msgctxt "name"
msgid "Cura Profile Reader"
msgstr "Cura-Profil-Reader"
-#~ msgctxt "@warning:status"
-#~ msgid "Please generate G-code before saving."
-#~ msgstr "Generieren Sie vor dem Speichern bitte einen G-Code."
+#~ msgctxt "@item:inmenu"
+#~ msgid "Flatten active settings"
+#~ msgstr "Einstellungen Glätten aktiv"
+
+#~ msgctxt "@info:status"
+#~ msgid "Profile has been flattened & activated."
+#~ msgstr "Das Profil wurde geglättet und aktiviert."
+
+#~ msgctxt "X3g Writer Plugin Description"
+#~ msgid "Writes X3g to files"
+#~ msgstr "Schreibt X3g in Dateien"
+
+#~ msgctxt "X3g Writer File Description"
+#~ msgid "X3g File"
+#~ msgstr "X3g-Datei"
+
+#~ msgctxt "X3G Writer File Description"
+#~ msgid "X3G File"
+#~ msgstr "X3G-Datei"
+
+#~ msgctxt "@item:inlistbox"
+#~ msgid "Open Compressed Triangle Mesh"
+#~ msgstr "Öffnen Sie das komprimierte Dreiecksnetz"
#~ msgctxt "@item:inmenu"
#~ msgid "Profile Assistant"
@@ -4969,6 +5476,1032 @@ msgstr "Cura-Profil-Reader"
#~ msgid "Profile Assistant"
#~ msgstr "Profilassistent"
+#~ msgctxt "@action:button"
+#~ msgid "Retry"
+#~ msgstr "Erneut versuchen"
+
+#~ msgctxt "@label:table_header"
+#~ msgid "Print Core"
+#~ msgstr "Print Core"
+
+#~ msgctxt "@label"
+#~ msgid "Don't support overlap with other models"
+#~ msgstr "Keine Überlappung mit anderen Modellen unterstützen"
+
+#~ msgctxt "@label"
+#~ msgid "Modify settings for overlap with other models"
+#~ msgstr "Einstellungen für Überlappung mit anderen Modellen bearbeiten"
+
+#~ msgctxt "@label"
+#~ msgid "Modify settings for infill of other models"
+#~ msgstr "Einstellungen für Füllung von anderen Modellen bearbeiten"
+
+#~ msgctxt "@action:ComboBox option"
+#~ msgid "Update existing"
+#~ msgstr "Vorhandenes aktualisieren"
+
+#~ msgctxt "@label"
+#~ msgid "Not supported"
+#~ msgstr "Nicht unterstützt"
+
+#~ msgctxt "@action:button"
+#~ msgid "Previous"
+#~ msgstr "Zurück"
+
+#~ msgctxt "@label"
+#~ msgid "Tip"
+#~ msgstr "Tipp"
+
+#~ msgctxt "@label"
+#~ msgid "Print experiment"
+#~ msgstr "Druckexperiment"
+
+#~ msgctxt "@label"
+#~ msgid "Checklist"
+#~ msgstr "Checkliste"
+
+#~ msgctxt "@label"
+#~ msgid "Please select any upgrades made to this Ultimaker 2."
+#~ msgstr "Wählen Sie bitte alle durchgeführten Upgrades für diesen Ultimaker 2."
+
+#~ msgctxt "@label"
+#~ msgid "Olsson Block"
+#~ msgstr "Olsson-Block"
+
+#~ msgctxt "@window:text"
+#~ msgid "Camera rendering: "
+#~ msgstr "Kamera-Rendering: "
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Use multi build plate functionality"
+#~ msgstr "Mehrfach-Druckplattenfunktion verwenden"
+
+#~ msgctxt "@option:check"
+#~ msgid "Use multi build plate functionality (restart required)"
+#~ msgstr "Mehrfach-Druckplattenfunktion verwenden (Neustart erforderlich)"
+
+#~ msgctxt "@label"
+#~ msgid "Default profiles"
+#~ msgstr "Standardprofile"
+
+#~ msgctxt "@label:textbox"
+#~ msgid "search settings"
+#~ msgstr "Einstellungen durchsuchen"
+
+#~ msgctxt "@label"
+#~ msgid "Layer Height"
+#~ msgstr "Schichtdicke"
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile."
+#~ msgstr "Dieses Qualitätsprofil ist für Ihr aktuelles Material und Ihre derzeitige Düsenkonfiguration nicht verfügbar. Bitte ändern Sie diese, um das Qualitätsprofil zu aktivieren."
+
+#~ msgctxt "@tooltip"
+#~ msgid "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab"
+#~ msgstr "Ein benutzerdefiniertes Profil ist derzeit aktiv. Wählen Sie ein voreingestelltes Qualitätsprofil aus der Registerkarte „Benutzerdefiniert“, um den Schieberegler für Qualität zu aktivieren"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Build plate"
+#~ msgstr "&Druckplatte"
+
+#~ msgctxt "@title:settings"
+#~ msgid "&Profile"
+#~ msgstr "&Profil"
+
+#~ msgctxt "@action:label"
+#~ msgid "Build plate"
+#~ msgstr "Druckplatte"
+
+#~ msgctxt "description"
+#~ msgid "Dump the contents of all settings to a HTML file."
+#~ msgstr "Die Inhalte aller Einstellungen in eine HTML-Datei ausgeben."
+
+#~ msgctxt "name"
+#~ msgid "God Mode"
+#~ msgstr "Gott-Modus"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattened quality changes profile."
+#~ msgstr "Erstellt eine geglättete Qualität, verändert das Profil."
+
+#~ msgctxt "name"
+#~ msgid "Profile Flattener"
+#~ msgstr "Profilglättfunktion"
+
+#~ msgctxt "description"
+#~ msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
+#~ msgstr "Ermöglichen Sie Materialherstellern die Erstellung neuer Material- und Qualitätsprofile, indem Sie eine Drop-In-Benutzerschnittstelle verwenden."
+
+#~ msgctxt "name"
+#~ msgid "Print Profile Assistant"
+#~ msgstr "Druckprofil-Assistent"
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network."
+#~ msgstr "Über Netzwerk verbunden."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. Please approve the access request on the printer."
+#~ msgstr "Über Netzwerk verbunden. Geben Sie die Zugriffsanforderung für den Drucker frei."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. No access to control the printer."
+#~ msgstr "Über Netzwerk verbunden. Kein Zugriff auf die Druckerverwaltung."
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer requested. Please approve the request on the printer"
+#~ msgstr "Zugriff auf Drucker erforderlich. Bestätigen Sie den Zugriff auf den Drucker"
+
+#~ msgctxt "@info:title"
+#~ msgid "Authentication status"
+#~ msgstr "Authentifizierungsstatus"
+
+#~ msgctxt "@info:title"
+#~ msgid "Authentication Status"
+#~ msgstr "Authentifizierungsstatus"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Re-send the access request"
+#~ msgstr "Zugriffanforderung erneut senden"
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer accepted"
+#~ msgstr "Zugriff auf den Drucker genehmigt"
+
+#~ msgctxt "@info:status"
+#~ msgid "No access to print with this printer. Unable to send print job."
+#~ msgstr "Kein Zugriff auf das Drucken mit diesem Drucker. Druckauftrag kann nicht gesendet werden."
+
+#~ msgctxt "@action:button"
+#~ msgid "Request Access"
+#~ msgstr "Zugriff anfordern"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Send access request to the printer"
+#~ msgstr "Zugriffsanforderung für den Drucker senden"
+
+#~ msgctxt "@label"
+#~ msgid "Unable to start a new print job."
+#~ msgstr "Es kann kein neuer Druckauftrag gestartet werden."
+
+#~ msgctxt "@label"
+#~ msgid "There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. Please resolve this issues before continuing."
+#~ msgstr "Es liegt ein Problem mit der Konfiguration Ihres Ultimaker vor, das den Druckstart verhindert. Lösen Sie dieses Problem bitte, bevor Sie fortfahren."
+
+#~ msgctxt "@window:title"
+#~ msgid "Mismatched configuration"
+#~ msgstr "Konfiguration nicht übereinstimmend"
+
+#~ msgctxt "@label"
+#~ msgid "Are you sure you wish to print with the selected configuration?"
+#~ msgstr "Möchten Sie wirklich mit der gewählten Konfiguration drucken?"
+
+#~ msgctxt "@label"
+#~ msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "Anforderungen zwischen der Druckerkonfiguration oder -kalibrierung und Cura stimmen nicht überein. Für optimale Ergebnisse schneiden Sie stets für die PrintCores und Materialien, die in Ihren Drucker eingelegt wurden."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending new jobs (temporarily) blocked, still sending the previous print job."
+#~ msgstr "Das Senden neuer Aufträge ist (vorübergehend) blockiert; der vorherige Druckauftrag wird noch gesendet."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending data to printer"
+#~ msgstr "Daten werden zum Drucker gesendet"
+
+#~ msgctxt "@info:title"
+#~ msgid "Sending Data"
+#~ msgstr "Daten werden gesendet"
+
+#~ msgctxt "@info:status"
+#~ msgid "No Printcore loaded in slot {slot_number}"
+#~ msgstr "Kein PrintCore geladen in Steckplatz {slot_number}"
+
+#~ msgctxt "@info:status"
+#~ msgid "No material loaded in slot {slot_number}"
+#~ msgstr "Kein Material geladen in Steckplatz {slot_number}"
+
+#~ msgctxt "@label"
+#~ msgid "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}"
+#~ msgstr "Abweichender PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) für Extruder gewählt {extruder_id}"
+
+#~ msgctxt "@label"
+#~ msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
+#~ msgstr "Abweichendes Material (Cura: {0}, Drucker: {1}) für Extruder {2} gewählt"
+
+#~ msgctxt "@window:title"
+#~ msgid "Sync with your printer"
+#~ msgstr "Synchronisieren Ihres Druckers"
+
+#~ msgctxt "@label"
+#~ msgid "Would you like to use your current printer configuration in Cura?"
+#~ msgstr "Möchten Sie Ihre aktuelle Druckerkonfiguration in Cura verwenden?"
+
+#~ msgctxt "@label"
+#~ msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "Die PrintCores und/oder Materialien auf Ihrem Drucker unterscheiden sich von denen Ihres aktuellen Projekts. Für optimale Ergebnisse schneiden Sie stets für die PrintCores und Materialien, die in Ihren Drucker eingelegt wurden."
+
+#~ msgctxt "@action:button"
+#~ msgid "View in Monitor"
+#~ msgstr "In Monitor überwachen"
+
+#~ msgctxt "@info:status"
+#~ msgid "Printer '{printer_name}' has finished printing '{job_name}'."
+#~ msgstr "Drucker '{printer_name}' hat '{job_name}' vollständig gedrückt."
+
+#~ msgctxt "@info:status"
+#~ msgid "The print job '{job_name}' was finished."
+#~ msgstr "Der Druckauftrag '{job_name}' wurde ausgeführt."
+
+#~ msgctxt "@info:status"
+#~ msgid "Print finished"
+#~ msgstr "Druck vollendet"
+
+#~ msgctxt "@label:material"
+#~ msgid "Empty"
+#~ msgstr "Leer"
+
+#~ msgctxt "@label:material"
+#~ msgid "Unknown"
+#~ msgstr "Unbekannt"
+
+#~ msgctxt "@info:title"
+#~ msgid "Cloud error"
+#~ msgstr "Cloudfehler"
+
+#~ msgctxt "@info:status"
+#~ msgid "Could not export print job."
+#~ msgstr "Druckauftrag konnte nicht exportiert werden."
+
+#~ msgctxt "@info:description"
+#~ msgid "There was an error connecting to the cloud."
+#~ msgstr "Es liegt ein Fehler beim Verbinden mit der Cloud vor."
+
+#~ msgctxt "@info:status"
+#~ msgid "Uploading via Ultimaker Cloud"
+#~ msgstr "Über Ultimaker Cloud hochladen"
+
+#~ msgctxt "@info:status Ultimaker Cloud is a brand name and shouldn't be translated."
+#~ msgid "Connect to Ultimaker Cloud"
+#~ msgstr "Verbinden mit Ultimaker Cloud"
+
+#~ msgctxt "@action"
+#~ msgid "Don't ask me again for this printer."
+#~ msgstr "Nicht mehr für diesen Drucker nachfragen."
+
+#~ msgctxt "@info:status"
+#~ msgid "You can now send and monitor print jobs from anywhere using your Ultimaker account."
+#~ msgstr "Sie können jetzt Druckaufträge mithilfe Ihres Ultimaker-Kontos von einem anderen Ort aus senden und überwachen."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected!"
+#~ msgstr "Verbunden!"
+
+#~ msgctxt "@action"
+#~ msgid "Review your connection"
+#~ msgstr "Ihre Verbindung überprüfen"
+
+#~ msgctxt "@info:status Don't translate the XML tags !"
+#~ msgid "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it."
+#~ msgstr "Die Maschine, die im Profil {0} ({1}) definiert wurde, entspricht nicht Ihrer derzeitigen Maschine ({2}). Importieren nicht möglich."
+
+#~ msgctxt "@info:status Don't translate the XML tags or !"
+#~ msgid "Failed to import profile from {0}:"
+#~ msgstr "Import des Profils aus Datei {0} fehlgeschlagen:"
+
+#~ msgctxt "@window:title"
+#~ msgid "Existing Connection"
+#~ msgstr "Vorhandene Verbindung"
+
+#~ msgctxt "@message:text"
+#~ msgid "This printer/group is already added to Cura. Please select another printer/group."
+#~ msgstr "Diese/r Drucker/Gruppe wurde bereits zu Cura hinzugefügt. Wählen Sie bitte eine/n andere/n Drucker/Gruppe."
+
+#~ msgctxt "@label"
+#~ msgid "Enter the IP address or hostname of your printer on the network."
+#~ msgstr "Geben Sie die IP-Adresse oder den Hostnamen Ihres Druckers auf dem Netzwerk ein."
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Connect to a printer"
+#~ msgstr "Mit einem Drucker verbinden"
+
+#~ msgctxt "@title"
+#~ msgid "Cura Settings Guide"
+#~ msgstr "Anleitung für Cura-Einstellungen"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Zooming towards the mouse is not supported in the orthogonal perspective."
+#~ msgstr "Das Zoomen in Mausrichtung wird in der Orthogonalansicht nicht unterstützt."
+
+#~ msgid "Orthogonal"
+#~ msgstr "Orthogonal"
+
+#~ msgctxt "description"
+#~ msgid "Manages network connections to Ultimaker 3 printers."
+#~ msgstr "Verwaltet Netzwerkverbindungen zu Ultimaker 3-Druckern."
+
+#~ msgctxt "name"
+#~ msgid "UM3 Network Connection"
+#~ msgstr "UM3-Netzwerkverbindung"
+
+#~ msgctxt "description"
+#~ msgid "Provides extra information and explanations about settings in Cura, with images and animations."
+#~ msgstr "Bietet zusätzliche Informationen und Erklärungen zu den Einstellungen in Cura mit Abbildungen und Animationen."
+
+#~ msgctxt "name"
+#~ msgid "Settings Guide"
+#~ msgstr "Anleitung für Einstellungen"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Cura Settings Guide"
+#~ msgstr "Anleitung für Cura-Einstellungen"
+
+#~ msgctxt "@info:generic"
+#~ msgid "Settings have been changed to match the current availability of extruders: [%s]"
+#~ msgstr "Die Einstellungen wurden passend für die aktuelle Verfügbarkeit der Extruder geändert: [%s]"
+
+#~ msgctxt "@title:groupbox"
+#~ msgid "User description"
+#~ msgstr "Benutzerbeschreibung"
+
+#~ msgctxt "@info"
+#~ msgid "These options are not available because you are monitoring a cloud printer."
+#~ msgstr "Diese Optionen sind nicht verfügbar, weil Sie einen Cloud-Drucker überwachen."
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Go to Cura Connect"
+#~ msgstr "Gehe zu Cura Connect"
+
+#~ msgctxt "@info"
+#~ msgid "All jobs are printed."
+#~ msgstr "Alle Aufträge wurden gedruckt."
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "View print history"
+#~ msgstr "Druckauftragshistorie anzeigen"
+
+#~ msgctxt "@label"
+#~ msgid ""
+#~ "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
+#~ "\n"
+#~ "Select your printer from the list below:"
+#~ msgstr ""
+#~ "Um über das Netzwerk direkt auf Ihrem Drucker zu drucken, stellen Sie bitte sicher, dass der Drucker mit dem Netzwerkkabel verbunden ist oder verbinden Sie Ihren Drucker mit Ihrem WLAN-Netzwerk. Wenn Sie Cura nicht mit Ihrem Drucker verbinden, können Sie dennoch ein USB-Laufwerk für die Übertragung von G-Code-Dateien auf Ihren Drucker verwenden.\n"
+#~ "\n"
+#~ "Wählen Sie Ihren Drucker aus der folgenden Liste:"
+
+#~ msgctxt "@info"
+#~ msgid ""
+#~ "Please make sure your printer has a connection:\n"
+#~ "- Check if the printer is turned on.\n"
+#~ "- Check if the printer is connected to the network."
+#~ msgstr ""
+#~ "Stellen Sie bitte sicher, dass Ihr Drucker verbunden ist:\n"
+#~ "- Prüfen Sie, ob Ihr Drucker eingeschaltet ist.\n"
+#~ "- Prüfen Sie, ob der Drucker mit dem Netzwerk verbunden ist."
+
+#~ msgctxt "@option:check"
+#~ msgid "See only current build plate"
+#~ msgstr "Nur aktuelle Druckplatte anzeigen"
+
+#~ msgctxt "@action:button"
+#~ msgid "Arrange to all build plates"
+#~ msgstr "An allen Druckplatten ausrichten"
+
+#~ msgctxt "@action:button"
+#~ msgid "Arrange current build plate"
+#~ msgstr "An aktueller Druckplatte ausrichten"
+
+#~ msgctxt "description"
+#~ msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
+#~ msgstr "Ermöglicht das Speichern des resultierenden Slices als X3G-Datei, um Drucker zu unterstützen, die dieses Format lesen (Malyan, Makerbot und andere Sailfish-basierte Drucker)."
+
+#~ msgctxt "name"
+#~ msgid "X3GWriter"
+#~ msgstr "X3G-Writer"
+
+#~ msgctxt "description"
+#~ msgid "Reads SVG files as toolpaths, for debugging printer movements."
+#~ msgstr "Liest SVG-Dateien als Werkzeugwege für die Fehlersuche bei Druckerbewegungen."
+
+#~ msgctxt "name"
+#~ msgid "SVG Toolpath Reader"
+#~ msgstr "SVG-Werkzeugweg-Reader"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Changelog"
+#~ msgstr "Änderungsprotokoll"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Show Changelog"
+#~ msgstr "Änderungsprotokoll anzeigen"
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending data to remote cluster"
+#~ msgstr "Daten werden zu Remote-Cluster gesendet"
+
+#~ msgctxt "@info:status"
+#~ msgid "Connect to Ultimaker Cloud"
+#~ msgstr "Verbinden mit Ultimaker Cloud"
+
+#~ msgctxt "@info"
+#~ msgid "Cura collects anonymized usage statistics."
+#~ msgstr "Cura erfasst anonymisierte Nutzungsstatistiken."
+
+#~ msgctxt "@info:title"
+#~ msgid "Collecting Data"
+#~ msgstr "Daten werden erfasst"
+
+#~ msgctxt "@action:button"
+#~ msgid "More info"
+#~ msgstr "Mehr Infos"
+
+#~ msgctxt "@action:tooltip"
+#~ msgid "See more information on what data Cura sends."
+#~ msgstr "Siehe mehr Informationen dazu, was Cura sendet."
+
+#~ msgctxt "@action:button"
+#~ msgid "Allow"
+#~ msgstr "Zulassen"
+
+#~ msgctxt "@action:tooltip"
+#~ msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
+#~ msgstr "Damit lassen Sie zu, dass Cura anonymisierte Nutzungsstatistiken sendet, um zukünftige Verbesserungen für Cura zu definieren. Einige Ihrer Präferenzen und Einstellungen, die Cura-Version und ein Hash der Modelle, die Sie slicen, werden gesendet."
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Evaluation"
+#~ msgstr "Bewertung"
+
+#~ msgctxt "@info:title"
+#~ msgid "Network enabled printers"
+#~ msgstr "Netzwerkfähige Drucker"
+
+#~ msgctxt "@info:title"
+#~ msgid "Local printers"
+#~ msgstr "Lokale Drucker"
+
+#~ msgctxt "@info:backup_failed"
+#~ msgid "Tried to restore a Cura backup that does not match your current version."
+#~ msgstr "Versucht, ein Cura-Backup zu erstellen, das nicht Ihrer aktuellen Version entspricht."
+
+#~ msgctxt "@title"
+#~ msgid "Machine Settings"
+#~ msgstr "Geräteeinstellungen"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Settings"
+#~ msgstr "Druckereinstellungen"
+
+#~ msgctxt "@option:check"
+#~ msgid "Origin at center"
+#~ msgstr "Ausgang in Mitte"
+
+#~ msgctxt "@option:check"
+#~ msgid "Heated bed"
+#~ msgstr "Heizbares Bett"
+
+#~ msgctxt "@label"
+#~ msgid "Printhead Settings"
+#~ msgstr "Druckkopfeinstellungen"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Abstand von der linken Seite des Druckkopfes zur Düsenmitte. Wird verwendet, um Kollisionen zwischen vorherigen Drucken und dem Druckkopf während des Druckmodus „Nacheinander“ zu vermeiden."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Abstand von der Vorderseite des Druckkopfes zur Düsenmitte. Wird verwendet, um Kollisionen zwischen vorherigen Drucken und dem Druckkopf während des Druckmodus „Nacheinander“ zu vermeiden."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Abstand von der rechten Seite des Druckkopfes zur Düsenmitte. Wird verwendet, um Kollisionen zwischen vorherigen Drucken und dem Druckkopf während des Druckmodus „Nacheinander“ zu vermeiden."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Abstand von der Rückseite des Druckkopfes zur Düsenmitte. Wird verwendet, um Kollisionen zwischen vorherigen Drucken und dem Druckkopf während des Druckmodus „Nacheinander“ zu vermeiden."
+
+#~ msgctxt "@label"
+#~ msgid "Gantry height"
+#~ msgstr "Brückenhöhe"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
+#~ msgstr "Der Höhenunterschied zwischen der Düsenspitze und dem Brückensystem (X- und Y-Achsen). Wird verwendet, um Kollisionen zwischen vorherigen Drucken und der Brücke zu verhindern, wenn im Modus „Nacheinander“ gedruckt wird."
+
+#~ msgctxt "@label"
+#~ msgid "Start G-code"
+#~ msgstr "Start G-code"
+
+#~ msgctxt "@tooltip"
+#~ msgid "G-code commands to be executed at the very start."
+#~ msgstr "G-Code-Befehle, die zum Start ausgeführt werden sollen."
+
+#~ msgctxt "@label"
+#~ msgid "End G-code"
+#~ msgstr "Ende G-code"
+
+#~ msgctxt "@tooltip"
+#~ msgid "G-code commands to be executed at the very end."
+#~ msgstr "G-Code-Befehle, die am Ende ausgeführt werden sollen."
+
+#~ msgctxt "@label"
+#~ msgid "Nozzle Settings"
+#~ msgstr "Düseneinstellungen"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
+#~ msgstr "Der Nenndurchmesser des durch den Drucker unterstützten Filaments. Der exakte Durchmesser wird durch das Material und/oder das Profil überschrieben."
+
+#~ msgctxt "@label"
+#~ msgid "Extruder Start G-code"
+#~ msgstr "G-Code Extruder-Start"
+
+#~ msgctxt "@label"
+#~ msgid "Extruder End G-code"
+#~ msgstr "G-Code Extruder-Ende"
+
+#~ msgctxt "@label"
+#~ msgid "Changelog"
+#~ msgstr "Änderungsprotokoll"
+
+#~ msgctxt "@title:window"
+#~ msgid "User Agreement"
+#~ msgstr "Benutzervereinbarung"
+
+#~ msgctxt "@alabel"
+#~ msgid "Enter the IP address or hostname of your printer on the network."
+#~ msgstr "Geben Sie die IP-Adresse oder den Hostnamen Ihres Druckers auf dem Netzwerk ein."
+
+#~ msgctxt "@info"
+#~ msgid "Please select a network connected printer to monitor."
+#~ msgstr "Bitte einen mit dem Netzwerk verbunden Drucker für die Überwachung wählen."
+
+#~ msgctxt "@info"
+#~ msgid "Please connect your Ultimaker printer to your local network."
+#~ msgstr "Verbinden Sie Ihren Ultimaker-Drucker bitte mit Ihrem lokalen Netzwerk."
+
+#~ msgctxt "@text:window"
+#~ msgid "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent."
+#~ msgstr "Cura sendet anonyme Daten an Ultimaker, um die Druckqualität und Benutzererfahrung zu steigern. Nachfolgend ist ein Beispiel aller Daten, die gesendet werden."
+
+#~ msgctxt "@text:window"
+#~ msgid "I don't want to send this data"
+#~ msgstr "Ich möchte diese Daten nicht senden"
+
+#~ msgctxt "@text:window"
+#~ msgid "Allow sending this data to Ultimaker and help us improve Cura"
+#~ msgstr "Ich erlaube das Senden der Daten an Ultimaker, um Cura zu verbessern"
+
+#~ msgctxt "@label"
+#~ msgid "No print selected"
+#~ msgstr "Kein Druck ausgewählt"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
+#~ msgstr "Standardmäßig repräsentieren weiße Pixel hohe Punkte im Netz und schwarze Pixel repräsentieren niedrige Punkte im Netz. Ändern Sie diese Option um das Verhalten so umzukehren, dass schwarze Pixel hohe Punkte im Netz darstellen und weiße Pixel niedrige Punkte im Netz."
+
+#~ msgctxt "@title"
+#~ msgid "Select Printer Upgrades"
+#~ msgstr "Drucker-Upgrades wählen"
+
+#~ msgctxt "@label"
+#~ msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
+#~ msgstr "Wählen Sie, welcher Extruder für die Unterstützung verwendet wird. Dient zum Konstruieren von Stützstrukturen unter dem Modell, damit dieses nicht absinkt oder frei schwebend gedruckt wird."
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile"
+#~ msgstr "Dieses Qualitätsprofil ist für Ihr aktuelles Material und Ihre derzeitige Düsenkonfiguration nicht verfügbar. Bitte ändern Sie diese, um das Qualitätsprofil zu aktivieren."
+
+#~ msgctxt "@label shown when we load a Gcode file"
+#~ msgid "Print setup disabled. G code file can not be modified."
+#~ msgstr "Druckeinrichtung ist deaktiviert. G-Code kann nicht geändert werden."
+
+#~ msgctxt "@label"
+#~ msgid "See the material compatibility chart"
+#~ msgstr "Siehe Materialkompatibilitätstabelle"
+
+#~ msgctxt "@label"
+#~ msgid "View types"
+#~ msgstr "Typen anzeigen"
+
+#~ msgctxt "@label"
+#~ msgid "Hi "
+#~ msgstr "Hallo "
+
+#~ msgctxt "@text"
+#~ msgid ""
+#~ "- Send print jobs to Ultimaker printers outside your local network\n"
+#~ "- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+#~ "- Get exclusive access to material profiles from leading brands"
+#~ msgstr ""
+#~ "- Aufträge an Ultimaker-Drucker außerhalb Ihres lokalen Netzwerks senden\n"
+#~ "- Ihre Ultimaker Cura-Einstellungen für die Verwendung andernorts an die Cloud senden\n"
+#~ "- Exklusiven Zugang zu Materialprofilen von führenden Marken erhalten"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Unable to Slice"
+#~ msgstr "Slicing nicht möglich"
+
+#~ msgctxt "@label"
+#~ msgid "Time specification"
+#~ msgstr "Zeitangabe"
+
+#~ msgctxt "@label"
+#~ msgid "Material specification"
+#~ msgstr "Materialangabe"
+
+#~ msgctxt "@title:tab"
+#~ msgid "Add a printer to Cura"
+#~ msgstr "Fügen Sie einen Drucker zu Cura hinzu"
+
+#~ msgctxt "@title:tab"
+#~ msgid ""
+#~ "Select the printer you want to use from the list below.\n"
+#~ "\n"
+#~ "If your printer is not in the list, use the \"Custom FFF Printer\" from the \"Custom\" category and adjust the settings to match your printer in the next dialog."
+#~ msgstr ""
+#~ "Wählen Sie den zu verwendenden Drucker aus der nachfolgenden Liste.\n"
+#~ "\n"
+#~ "Wenn Ihr Drucker nicht in der Liste aufgeführt ist, verwenden Sie „Benutzerdefinierter FFF-Drucker“ aus der Kategorie „Benutzerdefiniert“ und passen Sie die Einstellungen im folgenden Dialog passend für Ihren Drucker an."
+
+#~ msgctxt "@label"
+#~ msgid "Manufacturer"
+#~ msgstr "Hersteller"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Name"
+#~ msgstr "Druckername"
+
+#~ msgctxt "@action:button"
+#~ msgid "Add Printer"
+#~ msgstr "Drucker hinzufügen"
+
+#~ msgid "Modify G-Code"
+#~ msgstr "G-Code ändern"
+
+#~ msgctxt "@info:status"
+#~ msgid "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."
+#~ msgstr "Es ist kein Objekt zum Schneiden vorhanden, da keines der Modelle der Druckabmessung entspricht. Bitte die Modelle passend skalieren oder drehen."
+
+#~ msgctxt "@info:status"
+#~ msgid "The selected material is incompatible with the selected machine or configuration."
+#~ msgstr "Das gewählte Material ist mit der gewählten Maschine oder Konfiguration nicht kompatibel."
+
+#~ msgctxt "@info:title"
+#~ msgid "Incompatible Material"
+#~ msgstr "Material nicht kompatibel"
+
+#~ msgctxt "@info:status Don't translate the XML tags or !"
+#~ msgid "Failed to import profile from {0}: {1}"
+#~ msgstr "Import des Profils aus Datei {0} fehlgeschlagen: {1}"
+
+#~ msgctxt "@title"
+#~ msgid "Toolbox"
+#~ msgstr "Toolbox"
+
+#~ msgctxt "@label"
+#~ msgid "Not available"
+#~ msgstr "Nicht verfügbar"
+
+#~ msgctxt "@label"
+#~ msgid "Unreachable"
+#~ msgstr "Nicht erreichbar"
+
+#~ msgctxt "@label"
+#~ msgid "Available"
+#~ msgstr "Verfügbar"
+
+#~ msgctxt "@label:status"
+#~ msgid "Preparing"
+#~ msgstr "Vorbereitung"
+
+#~ msgctxt "@label:status"
+#~ msgid "Pausing"
+#~ msgstr "Wird pausiert"
+
+#~ msgctxt "@label:status"
+#~ msgid "Resuming"
+#~ msgstr "Wird fortgesetzt"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: Unavailable printer"
+#~ msgstr "Warten auf: Drucker nicht verfügbar"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: First available"
+#~ msgstr "Warten auf: Ersten verfügbaren"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: "
+#~ msgstr "Warten auf: "
+
+#~ msgctxt "@label"
+#~ msgid "Configuration change"
+#~ msgstr "Konfigurationsänderung"
+
+#~ msgctxt "@label"
+#~ msgid "The assigned printer, %1, requires the following configuration change(s):"
+#~ msgstr "Der zugewiesene Drucker %1 erfordert die folgende(n) Konfigurationsänderung(en):"
+
+#~ msgctxt "@label"
+#~ msgid "Override"
+#~ msgstr "Überschreiben"
+
+#~ msgctxt "@label"
+#~ msgid "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?"
+#~ msgstr "Das Starten eines Druckauftrags mit einer inkompatiblen Konfiguration kann Ihren 3D-Drucker beschädigen. Möchten Sie die Konfiguration wirklich überschreiben und %1 drucken?"
+
+#~ msgctxt "@window:title"
+#~ msgid "Override configuration configuration and start print"
+#~ msgstr "Konfiguration überschreiben und Druck starten"
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Manage queue"
+#~ msgstr "Warteschlange verwalten"
+
+#~ msgctxt "@label"
+#~ msgid "Printing"
+#~ msgstr "Drucken"
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Manage printers"
+#~ msgstr "Drucker verwalten"
+
+#~ msgctxt "@action:button"
+#~ msgid "Activate Configuration"
+#~ msgstr "Konfiguration aktivieren"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Load the configuration of the printer into Cura"
+#~ msgstr "Die Druckerkonfiguration in Cura laden"
+
+#~ msgctxt "@label"
+#~ msgid "Show Travels"
+#~ msgstr "Bewegungen anzeigen"
+
+#~ msgctxt "@label"
+#~ msgid "Show Helpers"
+#~ msgstr "Helfer anzeigen"
+
+#~ msgctxt "@label"
+#~ msgid "Show Shell"
+#~ msgstr "Gehäuse anzeigen"
+
+#~ msgctxt "@label"
+#~ msgid "Show Infill"
+#~ msgstr "Füllung anzeigen"
+
+#~ msgctxt "@text:window"
+#~ msgid "I don't want to send these data"
+#~ msgstr "Ich möchte diese Daten nicht senden"
+
+#~ msgctxt "@text:window"
+#~ msgid "Allow sending these data to Ultimaker and help us improve Cura"
+#~ msgstr "Ich erlaube das Senden dieser Daten an Ultimaker, um Cura zu verbessern"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type:"
+#~ msgstr "Druckertyp:"
+
+#~ msgctxt "@label"
+#~ msgid "Connection:"
+#~ msgstr "Verbindung:"
+
+#~ msgctxt "@label"
+#~ msgid "State:"
+#~ msgstr "Status:"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for a printjob"
+#~ msgstr "Warten auf einen Druckauftrag"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for someone to clear the build plate"
+#~ msgstr "Warten auf Räumen des Druckbeets"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Aborting print..."
+#~ msgstr "Drucken wird abgebrochen..."
+
+#~ msgctxt "@label"
+#~ msgid "Protected profiles"
+#~ msgstr "Geschützte Profile"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Name:"
+#~ msgstr "Druckername:"
+
+#~ msgctxt "@label"
+#~ msgid "Profile:"
+#~ msgstr "Profil:"
+
+#~ msgctxt "@label:textbox"
+#~ msgid "Search..."
+#~ msgstr "Suchen..."
+
+#~ msgctxt "@action:inmenu"
+#~ msgid "Collapse All"
+#~ msgstr "Alle verkleinern"
+
+#~ msgctxt "@action:inmenu"
+#~ msgid "Expand All"
+#~ msgstr "Alle vergrößern"
+
+#~ msgctxt "@label:header configurations"
+#~ msgid "Available configurations"
+#~ msgstr "Verfügbare Konfigurationen"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "Extruder"
+#~ msgstr "Extruder"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "Yes"
+#~ msgstr "Ja"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "No"
+#~ msgstr "Nein"
+
+#~ msgctxt "@label:listbox"
+#~ msgid "Print Setup"
+#~ msgstr "Druckeinrichtung"
+
+#~ msgctxt "@label:listbox"
+#~ msgid ""
+#~ "Print Setup disabled\n"
+#~ "G-code files cannot be modified"
+#~ msgstr ""
+#~ "Druckeinrichtung deaktiviert\n"
+#~ "G-Code-Dateien können nicht geändert werden"
+
+#~ msgctxt "@label Hours and minutes"
+#~ msgid "00h 00min"
+#~ msgstr "00 Stunden 00 Minuten"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Time specification"
+#~ msgstr "Zeitangabe"
+
+#~ msgctxt "@label"
+#~ msgid "Cost specification"
+#~ msgstr "Kostenangabe"
+
+#~ msgctxt "@label"
+#~ msgid "Total:"
+#~ msgstr "Insgesamt:"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
+#~ msgstr "Empfohlene Druckeinrichtung
Drucken mit den empfohlenen Einstellungen für den gewählten Drucker, das gewählte Material und die gewählte Qualität."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
+#~ msgstr "Benutzerdefinierte Druckeinrichtung
Druck mit Feineinstellung über jedem einzelnen Bereich des Schneidvorgangs."
+
+#~ msgctxt "@action:inmenu menubar:help"
+#~ msgid "Show Engine &Log..."
+#~ msgstr "Engine-&Protokoll anzeigen..."
+
+#~ msgctxt "@action:menu"
+#~ msgid "Browse packages..."
+#~ msgstr "Pakete durchsuchen..."
+
+#~ msgctxt "@action:inmenu menubar:view"
+#~ msgid "Expand/Collapse Sidebar"
+#~ msgstr "Seitenleiste vergrößern/verkleinern"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Please load a 3D model"
+#~ msgstr "Bitte laden Sie ein 3D-Modell"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Ready to slice"
+#~ msgstr "Bereit zum Slicen (Schneiden)"
+
+#~ msgctxt "@label:PrintjobStatus %1 is target operation"
+#~ msgid "Ready to %1"
+#~ msgstr "Bereit zum %1"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Slicing unavailable"
+#~ msgstr "Slicing ist nicht verfügbar"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Slice current printjob"
+#~ msgstr "Aktuellen Druckauftrag slicen"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Cancel slicing process"
+#~ msgstr "Slicing-Vorgang abbrechen"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Prepare"
+#~ msgstr "Vorbereiten"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Cancel"
+#~ msgstr "Abbrechen"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Select the active output device"
+#~ msgstr "Wählen Sie das aktive Ausgabegerät"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&View"
+#~ msgstr "&Ansicht"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Settings"
+#~ msgstr "&Konfiguration"
+
+#~ msgctxt "@title:menu menubar:toplevel"
+#~ msgid "&Toolbox"
+#~ msgstr "&Toolbox"
+
+#~ msgctxt "@action:button"
+#~ msgid "Open File"
+#~ msgstr "Datei öffnen"
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
+#~ msgstr "Dieses Qualitätsprofil ist für Ihr aktuelles Material und Ihre derzeitige Düsenkonfiguration nicht verfügbar. Bitte ändern Sie diese, um dieses Qualitätsprofil zu aktivieren"
+
+#~ msgctxt "@label"
+#~ msgid "Print Speed"
+#~ msgstr "Druckgeschwindigkeit"
+
+#~ msgctxt "@label"
+#~ msgid "Slower"
+#~ msgstr "Langsamer"
+
+#~ msgctxt "@label"
+#~ msgid "Faster"
+#~ msgstr "Schneller"
+
+#~ msgctxt "@label"
+#~ msgid "Enable gradual"
+#~ msgstr "Graduell aktivieren"
+
+#~ msgctxt "@label"
+#~ msgid "Generate Support"
+#~ msgstr "Stützstruktur generieren"
+
+#~ msgctxt "@label"
+#~ msgid "Build Plate Adhesion"
+#~ msgstr "Druckplattenhaftung"
+
+#~ msgctxt "@label"
+#~ msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
+#~ msgstr "Sie benötigen Hilfe für Ihre Drucke? Lesen Sie die Ultimaker Anleitungen für Fehlerbehebung>"
+
+#~ msgctxt "@title:window"
+#~ msgid "Engine Log"
+#~ msgstr "Engine-Protokoll"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type"
+#~ msgstr "Druckertyp"
+
+#~ msgctxt "@label"
+#~ msgid "Use glue with this material combination"
+#~ msgstr "Für diese Materialkombination Kleber verwenden"
+
+#~ msgctxt "@label"
+#~ msgid "Check compatibility"
+#~ msgstr "Kompatibilität prüfen"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Click to check the material compatibility on Ultimaker.com."
+#~ msgstr "Klicken Sie, um die Materialkompatibilität auf Ultimaker.com zu prüfen."
+
+#~ msgctxt "description"
+#~ msgid "Shows changes since latest checked version."
+#~ msgstr "Zeigt die Änderungen seit der letzten geprüften Version an."
+
+#~ msgctxt "name"
+#~ msgid "Changelog"
+#~ msgstr "Änderungsprotokoll"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattend quality changes profile."
+#~ msgstr "Erstellt eine geglättete Qualität, verändert das Profil."
+
+#~ msgctxt "name"
+#~ msgid "Profile flatener"
+#~ msgstr "Profilglättfunktion"
+
+#~ msgctxt "description"
+#~ msgid "Ask the user once if he/she agrees with our license."
+#~ msgstr "Den Benutzer einmalig fragen, ob er unsere Lizenz akzeptiert."
+
+#~ msgctxt "name"
+#~ msgid "UserAgreement"
+#~ msgstr "UserAgreement"
+
+#~ msgctxt "@warning:status"
+#~ msgid "Please generate G-code before saving."
+#~ msgstr "Generieren Sie vor dem Speichern bitte einen G-Code."
+
#~ msgctxt "@action"
#~ msgid "Upgrade Firmware"
#~ msgstr "Firmware aktualisieren"
@@ -4993,22 +6526,6 @@ msgstr "Cura-Profil-Reader"
#~ msgid "Confirm uninstall "
#~ msgstr "Deinstallieren bestätigen "
-#~ msgctxt "@label:status"
-#~ msgid "Paused"
-#~ msgstr "Pausiert"
-
-#~ msgctxt "@action:button"
-#~ msgid "Previous"
-#~ msgstr "Zurück"
-
-#~ msgctxt "@action:button"
-#~ msgid "Next"
-#~ msgstr "Weiter"
-
-#~ msgctxt "@label"
-#~ msgid "Tip"
-#~ msgstr "Tipp"
-
#~ msgctxt "@label Print estimates: m for meters, g for grams, %4 is currency and %3 is print cost"
#~ msgid "%1m / ~ %2g / ~ %4 %3"
#~ msgstr "%1m / ~ %2g / ~ %4 %3"
@@ -5017,26 +6534,10 @@ msgstr "Cura-Profil-Reader"
#~ msgid "%1m / ~ %2g"
#~ msgstr "%1m / ~ %2g"
-#~ msgctxt "@label"
-#~ msgid "Print experiment"
-#~ msgstr "Druckexperiment"
-
-#~ msgctxt "@label"
-#~ msgid "Checklist"
-#~ msgstr "Checkliste"
-
#~ msgctxt "@title"
#~ msgid "Upgrade Firmware"
#~ msgstr "Firmware aktualisieren"
-#~ msgctxt "description"
-#~ msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
-#~ msgstr "Ermöglichen Sie Materialherstellern die Erstellung neuer Material- und Qualitätsprofile, indem Sie eine Drop-In-Benutzerschnittstelle verwenden."
-
-#~ msgctxt "name"
-#~ msgid "Print Profile Assistant"
-#~ msgstr "Druckprofil-Assistent"
-
#~ msgctxt "@action:button"
#~ msgid "Print with Doodle3D WiFi-Box"
#~ msgstr "Mit Doodle3D WLAN-Box drucken"
@@ -5129,10 +6630,6 @@ msgstr "Cura-Profil-Reader"
#~ msgid "Lost connection with the printer"
#~ msgstr "Verbindung zum Drucker wurde unterbrochen"
-#~ msgctxt "@label:status"
-#~ msgid "Unavailable"
-#~ msgstr "Nicht verfügbar"
-
#~ msgctxt "@label:status"
#~ msgid "Unknown"
#~ msgstr "Unbekannt"
diff --git a/resources/i18n/de_DE/fdmextruder.def.json.po b/resources/i18n/de_DE/fdmextruder.def.json.po
index 77ffa5631d..cc39f59f72 100644
--- a/resources/i18n/de_DE/fdmextruder.def.json.po
+++ b/resources/i18n/de_DE/fdmextruder.def.json.po
@@ -1,14 +1,14 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 14:25+0100\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-03-13 14:00+0200\n"
"Last-Translator: Bothof \n"
"Language-Team: German\n"
"Language: de_DE\n"
@@ -83,8 +83,8 @@ msgstr "G-Code Extruder-Start"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_code description"
-msgid "Start g-code to execute whenever turning the extruder on."
-msgstr "Starten Sie den G-Code jedes Mal, wenn Sie den Extruder einschalten."
+msgid "Start g-code to execute when switching to this extruder."
+msgstr "Auszuführenden G-Code beim Umschalten auf diesen Extruder starten."
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_abs label"
@@ -123,8 +123,8 @@ msgstr "G-Code Extruder-Ende"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_code description"
-msgid "End g-code to execute whenever turning the extruder off."
-msgstr "Beenden Sie den G-Code jedes Mal, wenn Sie den Extruder ausschalten."
+msgid "End g-code to execute when switching away from this extruder."
+msgstr "Auszuführenden G-Code beim Umschalten von diesem Extruder beenden."
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_abs label"
@@ -225,3 +225,11 @@ msgstr "Durchmesser"
msgctxt "material_diameter description"
msgid "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament."
msgstr "Der Durchmesser des verwendeten Filaments wird angepasst. Stellen Sie hier den Durchmesser des verwendeten Filaments ein."
+
+#~ msgctxt "machine_extruder_start_code description"
+#~ msgid "Start g-code to execute whenever turning the extruder on."
+#~ msgstr "Starten Sie den G-Code jedes Mal, wenn Sie den Extruder einschalten."
+
+#~ msgctxt "machine_extruder_end_code description"
+#~ msgid "End g-code to execute whenever turning the extruder off."
+#~ msgstr "Beenden Sie den G-Code jedes Mal, wenn Sie den Extruder ausschalten."
diff --git a/resources/i18n/de_DE/fdmprinter.def.json.po b/resources/i18n/de_DE/fdmprinter.def.json.po
index 383a7a3886..aee5ae4ace 100644
--- a/resources/i18n/de_DE/fdmprinter.def.json.po
+++ b/resources/i18n/de_DE/fdmprinter.def.json.po
@@ -1,16 +1,16 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 14:57+0200\n"
-"Last-Translator: Bothof \n"
-"Language-Team: German\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-07-29 15:51+0200\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: German , German \n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -57,7 +57,9 @@ msgctxt "machine_start_gcode description"
msgid ""
"G-code commands to be executed at the very start - separated by \n"
"."
-msgstr "G-Code-Befehle, die zu Beginn ausgeführt werden sollen – getrennt durch \n."
+msgstr ""
+"G-Code-Befehle, die zu Beginn ausgeführt werden sollen – getrennt durch \n"
+"."
#: fdmprinter.def.json
msgctxt "machine_end_gcode label"
@@ -69,7 +71,9 @@ msgctxt "machine_end_gcode description"
msgid ""
"G-code commands to be executed at the very end - separated by \n"
"."
-msgstr "G-Code-Befehle, die am Ende ausgeführt werden sollen – getrennt durch \n."
+msgstr ""
+"G-Code-Befehle, die am Ende ausgeführt werden sollen – getrennt durch \n"
+"."
#: fdmprinter.def.json
msgctxt "material_guid label"
@@ -211,6 +215,16 @@ msgctxt "machine_heated_bed description"
msgid "Whether the machine has a heated build plate present."
msgstr "Option für vorhandene beheizte Druckplatte."
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume label"
+msgid "Has Build Volume Temperature Stabilization"
+msgstr "Verfügt über Temperaturstabilisierung für den Druckraum"
+
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume description"
+msgid "Whether the machine is able to stabilize the build volume temperature."
+msgstr "Zeigt an, ob das Gerät die Temperatur im Druckraum stabilisieren kann."
+
#: fdmprinter.def.json
msgctxt "machine_center_is_zero label"
msgid "Is Center Origin"
@@ -233,7 +247,7 @@ msgstr "Anzahl der Extruder-Elemente. Ein Extruder-Element ist die Kombination a
#: fdmprinter.def.json
msgctxt "extruders_enabled_count label"
-msgid "Number of Extruders that are enabled"
+msgid "Number of Extruders That Are Enabled"
msgstr "Anzahl der aktivierten Extruder"
#: fdmprinter.def.json
@@ -243,7 +257,7 @@ msgstr "Anzahl der aktivierten Extruder-Elemente; wird automatisch in der Softwa
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter label"
-msgid "Outer nozzle diameter"
+msgid "Outer Nozzle Diameter"
msgstr "Düsendurchmesser außen"
#: fdmprinter.def.json
@@ -253,7 +267,7 @@ msgstr "Der Außendurchmesser der Düsenspitze."
#: fdmprinter.def.json
msgctxt "machine_nozzle_head_distance label"
-msgid "Nozzle length"
+msgid "Nozzle Length"
msgstr "Düsenlänge"
#: fdmprinter.def.json
@@ -263,7 +277,7 @@ msgstr "Der Höhenunterschied zwischen der Düsenspitze und dem untersten Bereic
#: fdmprinter.def.json
msgctxt "machine_nozzle_expansion_angle label"
-msgid "Nozzle angle"
+msgid "Nozzle Angle"
msgstr "Düsenwinkel"
#: fdmprinter.def.json
@@ -273,7 +287,7 @@ msgstr "Der Winkel zwischen der horizontalen Planfläche und dem konischen Teil
#: fdmprinter.def.json
msgctxt "machine_heat_zone_length label"
-msgid "Heat zone length"
+msgid "Heat Zone Length"
msgstr "Heizzonenlänge"
#: fdmprinter.def.json
@@ -303,7 +317,7 @@ msgstr "Für die Temperatursteuerung von Cura. Schalten Sie diese Funktion aus,
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed label"
-msgid "Heat up speed"
+msgid "Heat Up Speed"
msgstr "Aufheizgeschwindigkeit"
#: fdmprinter.def.json
@@ -313,7 +327,7 @@ msgstr "Die Geschwindigkeit (°C/Sek.), mit der die Düse durchschnittlich bei n
#: fdmprinter.def.json
msgctxt "machine_nozzle_cool_down_speed label"
-msgid "Cool down speed"
+msgid "Cool Down Speed"
msgstr "Abkühlgeschwindigkeit"
#: fdmprinter.def.json
@@ -333,7 +347,7 @@ msgstr "Die Mindestzeit, die ein Extruder inaktiv sein muss, bevor die Düse abk
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor label"
-msgid "G-code flavour"
+msgid "G-code Flavor"
msgstr "G-Code-Variante"
#: fdmprinter.def.json
@@ -398,7 +412,7 @@ msgstr "Definiert, ob Firmware-Einzugsbefehle (G10/G11) anstelle der E-Eigenscha
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
-msgid "Disallowed areas"
+msgid "Disallowed Areas"
msgstr "Unzulässige Bereiche"
#: fdmprinter.def.json
@@ -418,7 +432,7 @@ msgstr "Eine Liste mit Polygonen mit Bereichen, in welche die Düse nicht eintre
#: fdmprinter.def.json
msgctxt "machine_head_polygon label"
-msgid "Machine head polygon"
+msgid "Machine Head Polygon"
msgstr "Gerätekopf Polygon"
#: fdmprinter.def.json
@@ -428,7 +442,7 @@ msgstr "Eine 2D-Shilhouette des Druckkopfes (ohne Lüfterkappen)."
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon label"
-msgid "Machine head & Fan polygon"
+msgid "Machine Head & Fan Polygon"
msgstr "Gerätekopf und Lüfter Polygon"
#: fdmprinter.def.json
@@ -438,7 +452,7 @@ msgstr "Eine 2D-Shilhouette des Druckkopfes (mit Lüfterkappen)."
#: fdmprinter.def.json
msgctxt "gantry_height label"
-msgid "Gantry height"
+msgid "Gantry Height"
msgstr "Brückenhöhe"
#: fdmprinter.def.json
@@ -468,7 +482,7 @@ msgstr "Der Innendurchmesser der Düse. Verwenden Sie diese Einstellung, wenn Si
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords label"
-msgid "Offset With Extruder"
+msgid "Offset with Extruder"
msgstr "Versatz mit Extruder"
#: fdmprinter.def.json
@@ -1016,6 +1030,17 @@ msgctxt "bottom_layers description"
msgid "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number."
msgstr "Die Anzahl der unteren Schichten. Wenn diese anhand der unteren Dicke berechnet wird, wird der Wert auf eine ganze Zahl auf- oder abgerundet."
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers label"
+msgid "Initial Bottom Layers"
+msgstr "Erste untere Schichten"
+
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers description"
+msgid "The number of initial bottom layers, from the build-plate upwards. When calculated by the bottom thickness, this value is rounded to a whole number."
+msgstr "Die Anzahl der ersten Schichten, die auf die Druckplatte aufgetragen werden. Wenn diese anhand der unteren Dicke berechnet werden, wird der Wert auf eine"
+" ganze Zahl auf- oder abgerundet."
+
#: fdmprinter.def.json
msgctxt "top_bottom_pattern label"
msgid "Top/Bottom Pattern"
@@ -1266,6 +1291,56 @@ msgctxt "z_seam_type option sharpest_corner"
msgid "Sharpest Corner"
msgstr "Schärfste Kante"
+#: fdmprinter.def.json
+msgctxt "z_seam_position label"
+msgid "Z Seam Position"
+msgstr "Position der Z-Naht"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position description"
+msgid "The position near where to start printing each part in a layer."
+msgstr "Die Position in der Nähe der Stelle, an der die einzelnen Teile einer Ebene gedruckt werden sollen."
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backleft"
+msgid "Back Left"
+msgstr "Hinten links"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option back"
+msgid "Back"
+msgstr "Zurück"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backright"
+msgid "Back Right"
+msgstr "Hinten rechts"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option right"
+msgid "Right"
+msgstr "Rechts"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontright"
+msgid "Front Right"
+msgstr "Vorne rechts"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option front"
+msgid "Front"
+msgstr "Vorne"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontleft"
+msgid "Front Left"
+msgstr "Vorne links"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option left"
+msgid "Left"
+msgstr "Links"
+
#: fdmprinter.def.json
msgctxt "z_seam_x label"
msgid "Z Seam X"
@@ -1293,8 +1368,8 @@ msgstr "Präferenz Nahtkante"
#: fdmprinter.def.json
msgctxt "z_seam_corner description"
-msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
-msgstr "Definieren Sie, ob Kanten am Modell-Umriss die Nahtposition beeinflussen. Keine bedeutet, dass Kanten keinen Einfluss auf die Nahtposition haben. Naht verbergen lässt die Naht mit höherer Wahrscheinlichkeit an einer innenliegenden Kante auftreten. Naht offenlegen lässt die Naht mit höherer Wahrscheinlichkeit an einer Außenkante auftreten. Naht verbergen oder offenlegen lässt die Naht mit höherer Wahrscheinlichkeit an einer innenliegenden oder außenliegenden Kante auftreten."
+msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner. Smart Hiding allows both inside and outside corners, but chooses inside corners more frequently, if appropriate."
+msgstr "Definieren Sie, ob Kanten am Modell-Umriss die Nahtposition beeinflussen. Keine bedeutet, dass Kanten keinen Einfluss auf die Nahtposition haben. Naht verbergen lässt die Naht mit höherer Wahrscheinlichkeit an einer innenliegenden Kante auftreten. Naht offenlegen lässt die Naht mit höherer Wahrscheinlichkeit an einer Außenkante auftreten. Naht verbergen oder offenlegen lässt die Naht mit höherer Wahrscheinlichkeit an einer innenliegenden oder außenliegenden Kante auftreten. Intelligent verbergen lässt die Naht an innen- oder außenliegenden Kanten auftreten, verwendet aber – falls zweckmäßig – häufiger innenliegende Kanten."
#: fdmprinter.def.json
msgctxt "z_seam_corner option z_seam_corner_none"
@@ -1316,6 +1391,11 @@ msgctxt "z_seam_corner option z_seam_corner_any"
msgid "Hide or Expose Seam"
msgstr "Naht verbergen oder offenlegen"
+#: fdmprinter.def.json
+msgctxt "z_seam_corner option z_seam_corner_weighted"
+msgid "Smart Hiding"
+msgstr "Intelligent verbergen"
+
#: fdmprinter.def.json
msgctxt "z_seam_relative label"
msgid "Z Seam Relative"
@@ -1328,13 +1408,13 @@ msgstr "Bei Aktivierung sind die Z-Naht-Koordinaten relativ zur Mitte der jeweil
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic label"
-msgid "Ignore Small Z Gaps"
-msgstr "Schmale Z-Lücken ignorieren"
+msgid "No Skin in Z Gaps"
+msgstr "Keine Außenhaut in Z-Lücken"
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic description"
-msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
-msgstr "Wenn das Modell schmale vertikale Lücken hat, kann etwa 5 % zusätzliche Rechenzeit aufgewendet werden, um eine obere und untere Außenhaut in diesen engen Räumen zu generieren. In diesem Fall deaktivieren Sie die Einstellung."
+msgid "When the model has small vertical gaps of only a few layers, there should normally be skin around those layers in the narrow space. Enable this setting to not generate skin if the vertical gap is very small. This improves printing time and slicing time, but technically leaves infill exposed to the air."
+msgstr "Wenn das Modell kleine, nur wenige Schichten hohe vertikale Lücken aufweist, sind diese normalerweise von einer Außenhaut bedeckt. Aktivieren Sie diese Einstellung, damit bei sehr kleinen Lücken keine Außenhaut gedruckt wird. Dies verkürzt die zum Drucken und Slicen benötigte Zeit, aber die Füllung bleibt der Luft ausgesetzt."
#: fdmprinter.def.json
msgctxt "skin_outline_count label"
@@ -1353,8 +1433,8 @@ msgstr "Glätten aktivieren"
#: fdmprinter.def.json
msgctxt "ironing_enabled description"
-msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
-msgstr "Gehen Sie ein weiteres Mal über die Oberfläche, jedoch ohne Extrusionsmaterial. Damit wird der Kunststoff auf der Oberfläche weiter geschmolzen, was zu einer glatteren Oberfläche führt."
+msgid "Go over the top surface one additional time, but this time extruding very little material. This is meant to melt the plastic on top further, creating a smoother surface. The pressure in the nozzle chamber is kept high so that the creases in the surface are filled with material."
+msgstr "Gehen Sie ein weiteres Mal über die Oberfläche, aber extrudieren Sie diesmal sehr wenig Material. Dadurch wird die oberste Kunststoffschicht geschmolzen und es entsteht eine glattere Oberfläche. Der Druck in der Düsenkammer bleibt weiterhin hoch, so dass Risse in der Oberfläche mit Material gefüllt werden."
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer label"
@@ -1446,6 +1526,26 @@ msgctxt "jerk_ironing description"
msgid "The maximum instantaneous velocity change while performing ironing."
msgstr "Die maximale unmittelbare Geschwindigkeitsänderung während des Glättens."
+#: fdmprinter.def.json
+msgctxt "skin_overlap label"
+msgid "Skin Overlap Percentage"
+msgstr "Prozentsatz Außenhaut überlappen"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines, as a percentage of the line widths of the skin lines and the innermost wall. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any percentage over 50% may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "Justieren Sie die Überlappung zwischen den Wänden und den Außenhaut-Mittellinien bzw. den Endpunkten der Außenhaut-Mittellinien als Prozentwert der Linienbreite der Außenhautlinien und der inneren Wand. Eine geringe Überlappung ermöglicht die feste Verbindung der Wände mit der Außenhaut. Beachten Sie, dass bei einer einheitlichen Linienbreite von Außenhaut und Wand jeder Prozentwert über 50 % bereits dazu führen kann, dass die Außenhaut über die Wand hinausgeht, da in diesem Moment die Position der Düse des Außenhaut-Extruders möglicherweise bereits über die Wandmitte hinausgeht."
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm label"
+msgid "Skin Overlap"
+msgstr "Außenhaut überlappen"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any value over half the width of the wall may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "Justieren Sie die Überlappung zwischen den Wänden und den Außenhaut-Mittellinien bzw. den Endpunkten der Außenhaut-Mittellinien. Eine geringe Überlappung ermöglicht die feste Verbindung der Wände mit der Außenhaut. Beachten Sie, dass bei einer einheitlichen Linienbreite von Außenhaut und Wand jeder Wert über die Hälfte der Wandbreite bereits dazu führen kann, dass die Außenhaut über die Wand hinausgeht, da in diesem Moment die Position der Düse des Außenhaut-Extruders möglicherweise bereits über die Wandmitte hinausgeht."
+
#: fdmprinter.def.json
msgctxt "infill label"
msgid "Infill"
@@ -1611,6 +1711,16 @@ msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
msgstr "Das Füllmuster wird um diese Distanz entlang der Y-Achse verschoben."
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location label"
+msgid "Randomize Infill Start"
+msgstr "Füllstart randomisieren"
+
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location description"
+msgid "Randomize which infill line is printed first. This prevents one segment becoming the strongest, but it does so at the cost of an additional travel move."
+msgstr "Randomisieren Sie, welche Fülllinie zuerst gedruckt wird. So wird vermieden, dass ein Segment am stärksten ist. Allerdings muss dafür eine zusätzliche Bewegung ausgeführt werden."
+
#: fdmprinter.def.json
msgctxt "infill_multiplier label"
msgid "Infill Line Multiplier"
@@ -1631,7 +1741,9 @@ msgctxt "infill_wall_line_count description"
msgid ""
"Add extra walls around the infill area. Such walls can make top/bottom skin lines sag down less which means you need less top/bottom skin layers for the same quality at the cost of some extra material.\n"
"This feature can combine with the Connect Infill Polygons to connect all the infill into a single extrusion path without the need for travels or retractions if configured right."
-msgstr "Fügen Sie zusätzliche Wände um den Füllbereich hinzu. Derartige Wände können zu einem verringerten Absacken der oberen/unteren Außenhautlinien beitragen, was bedeutet, dass Sie weniger Außenhautschichten oben/unten bei derselben Qualität von Kosten für zusätzliches Material benötigen.\n Diese Funktion ist verknüpfbar mit „Füllungspolygone verbinden“, um alle Füllungen mit einem einzigen Extrusionspfad zu verbinden, ohne dass hierzu Vorwärtsbewegungen oder Rückzüge erforderlich sind, sofern die richtige Konfiguration gewählt wurde."
+msgstr ""
+"Fügen Sie zusätzliche Wände um den Füllbereich hinzu. Derartige Wände können zu einem verringerten Absacken der oberen/unteren Außenhautlinien beitragen, was bedeutet, dass Sie weniger Außenhautschichten oben/unten bei derselben Qualität von Kosten für zusätzliches Material benötigen.\n"
+" Diese Funktion ist verknüpfbar mit „Füllungspolygone verbinden“, um alle Füllungen mit einem einzigen Extrusionspfad zu verbinden, ohne dass hierzu Vorwärtsbewegungen oder Rückzüge erforderlich sind, sofern die richtige Konfiguration gewählt wurde."
#: fdmprinter.def.json
msgctxt "sub_div_rad_add label"
@@ -1663,26 +1775,6 @@ msgctxt "infill_overlap_mm description"
msgid "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill."
msgstr "Das Ausmaß des Überlappens zwischen der Füllung und den Wänden. Ein leichtes Überlappen ermöglicht es den Wänden, eine solide Verbindung mit der Füllung herzustellen."
-#: fdmprinter.def.json
-msgctxt "skin_overlap label"
-msgid "Skin Overlap Percentage"
-msgstr "Prozentsatz Außenhaut überlappen"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap description"
-msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
-msgstr "Das Ausmaß des Überlappens zwischen der Außenhaut und den Wänden als Prozentwert der Außenhaut-Linienbreite. Ein leichtes Überlappen ermöglicht es den Wänden, eine solide Verbindung mit der Außenhaut herzustellen. Dies ist ein Prozentwert der durchschnittlichen Linienbreiten der Außenhautlinien und der innersten Wand."
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm label"
-msgid "Skin Overlap"
-msgstr "Außenhaut überlappen"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm description"
-msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
-msgstr "Das Ausmaß des Überlappens zwischen der Außenhaut und den Wänden. Ein leichtes Überlappen ermöglicht es den Wänden, eine solide Verbindung mit der Außenhaut herzustellen."
-
#: fdmprinter.def.json
msgctxt "infill_wipe_dist label"
msgid "Infill Wipe Distance"
@@ -1863,6 +1955,16 @@ msgctxt "default_material_print_temperature description"
msgid "The default temperature used for printing. This should be the \"base\" temperature of a material. All other print temperatures should use offsets based on this value"
msgstr "Die für den Druck verwendete Standardtemperatur. Dies sollte die „Basis“-Temperatur eines Materials sein. Alle anderen Drucktemperaturen sollten anhand dieses Wertes einen Versatz verwenden"
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature label"
+msgid "Build Volume Temperature"
+msgstr "Temperatur Druckabmessung"
+
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature description"
+msgid "The temperature of the environment to print in. If this is 0, the build volume temperature will not be adjusted."
+msgstr "Die Temperatur der Druckumgebung. Beträgt der Wert 0, wird die Druckraumtemperatur nicht angepasst."
+
#: fdmprinter.def.json
msgctxt "material_print_temperature label"
msgid "Printing Temperature"
@@ -1973,6 +2075,86 @@ msgctxt "material_shrinkage_percentage description"
msgid "Shrinkage ratio in percentage."
msgstr "Schrumpfungsverhältnis in Prozent."
+#: fdmprinter.def.json
+msgctxt "material_crystallinity label"
+msgid "Crystalline Material"
+msgstr "Kristallines Material"
+
+#: fdmprinter.def.json
+msgctxt "material_crystallinity description"
+msgid "Is this material the type that breaks off cleanly when heated (crystalline), or is it the type that produces long intertwined polymer chains (non-crystalline)?"
+msgstr "Lässt sich das Material im erhitzten Zustand leicht brechen (kristallin) oder bildet es lange, verflochtene Polymerketten (nicht kristallin)?"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position label"
+msgid "Anti-ooze Retracted Position"
+msgstr "Einzugsmaß für Sickerschutz"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position description"
+msgid "How far the material needs to be retracted before it stops oozing."
+msgstr "Maß, um das das Material eingezogen werden muss, damit es nicht heraussickert."
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed label"
+msgid "Anti-ooze Retraction Speed"
+msgstr "Einzugsgeschwindigkeit für Sickerschutz"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed description"
+msgid "How fast the material needs to be retracted during a filament switch to prevent oozing."
+msgstr "Geschwindigkeit, mit der das Material beim Filamentwechsel eingezogen werden muss, damit es nicht heraussickert."
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position label"
+msgid "Break Preparation Retracted Position"
+msgstr "Einzugsmaß für Bruchvorbereitung"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position description"
+msgid "How far the filament can be stretched before it breaks, while heated."
+msgstr "Streckmaß für das Filament im erhitzten Zustand, bevor es bricht."
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed label"
+msgid "Break Preparation Retraction Speed"
+msgstr "Einzugsgeschwindigkeit für Bruchvorbereitung"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed description"
+msgid "How fast the filament needs to be retracted just before breaking it off in a retraction."
+msgstr "Geschwindigkeit, mit der das Filament eingezogen werden muss, bevor es beim Einziehen abgebrochen wird."
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position label"
+msgid "Break Retracted Position"
+msgstr "Einzugsmaß für das Brechen"
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position description"
+msgid "How far to retract the filament in order to break it cleanly."
+msgstr "Maß, um das das Filament eingezogen werden muss, damit es sauber abgebrochen werden kann."
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed label"
+msgid "Break Retraction Speed"
+msgstr "Einzugsgeschwindigkeit für das Brechen"
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed description"
+msgid "The speed at which to retract the filament in order to break it cleanly."
+msgstr "Geschwindigkeit, mit der das Filament eingezogen werden muss, damit es sauber abgebrochen werden kann."
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature label"
+msgid "Break Temperature"
+msgstr "Bruchtemperatur"
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature description"
+msgid "The temperature at which the filament is broken for a clean break."
+msgstr "Die Temperatur, bei der das Filament für eine saubere Bruchstelle gebrochen wird."
+
#: fdmprinter.def.json
msgctxt "material_flow label"
msgid "Flow"
@@ -1983,6 +2165,126 @@ msgctxt "material_flow description"
msgid "Flow compensation: the amount of material extruded is multiplied by this value."
msgstr "Fluss-Kompensation: Die extrudierte Materialmenge wird mit diesem Wert multipliziert."
+#: fdmprinter.def.json
+msgctxt "wall_material_flow label"
+msgid "Wall Flow"
+msgstr "Wandfluss"
+
+#: fdmprinter.def.json
+msgctxt "wall_material_flow description"
+msgid "Flow compensation on wall lines."
+msgstr "Durchflusskompensation an Wandlinien."
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow label"
+msgid "Outer Wall Flow"
+msgstr "Wandfluss außen"
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow description"
+msgid "Flow compensation on the outermost wall line."
+msgstr "Durchflusskompensation an der äußeren Wandlinie."
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow label"
+msgid "Inner Wall(s) Flow"
+msgstr "Wandfluss innen"
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow description"
+msgid "Flow compensation on wall lines for all wall lines except the outermost one."
+msgstr "Durchflusskompensation an allen Wandlinien bis auf die äußere."
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow label"
+msgid "Top/Bottom Flow"
+msgstr "Fluss oben/unten"
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow description"
+msgid "Flow compensation on top/bottom lines."
+msgstr "Durchflusskompensation an oberen/unteren Linien."
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow label"
+msgid "Top Surface Skin Flow"
+msgstr "Fluss Oberfläche Außenhaut"
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow description"
+msgid "Flow compensation on lines of the areas at the top of the print."
+msgstr "Durchflusskompensation an Linien von Flächen an der Oberseite des Druckobjekts."
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow label"
+msgid "Infill Flow"
+msgstr "Fluss der Füllung"
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow description"
+msgid "Flow compensation on infill lines."
+msgstr "Durchflusskompensation an Füllungslinien."
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow label"
+msgid "Skirt/Brim Flow"
+msgstr "Skirt/Brim-Fluss"
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow description"
+msgid "Flow compensation on skirt or brim lines."
+msgstr "Durchflusskompensation an Skirt- oder Brim-Linien."
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow label"
+msgid "Support Flow"
+msgstr "Stützstruktur-Fluss"
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow description"
+msgid "Flow compensation on support structure lines."
+msgstr "Durchflusskompensation an Stützstrukturlinien."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow label"
+msgid "Support Interface Flow"
+msgstr "Fluss Stützstruktur-Schnittstelle"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow description"
+msgid "Flow compensation on lines of support roof or floor."
+msgstr "Durchflusskompensation an Dach- oder Bodenlinien der Stützstruktur."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow label"
+msgid "Support Roof Flow"
+msgstr "Stützdachfluss"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow description"
+msgid "Flow compensation on support roof lines."
+msgstr "Durchflusskompensation an Stützdachlinien."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow label"
+msgid "Support Floor Flow"
+msgstr "Stützbodenfluss"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow description"
+msgid "Flow compensation on support floor lines."
+msgstr "Durchflusskompensation an Stützbodenlinien."
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow label"
+msgid "Prime Tower Flow"
+msgstr "Fluss Einzugsturm"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow description"
+msgid "Flow compensation on prime tower lines."
+msgstr "Durchflusskompensation an Einzugsturmlinien."
+
#: fdmprinter.def.json
msgctxt "material_flow_layer_0 label"
msgid "Initial Layer Flow"
@@ -2100,7 +2402,7 @@ msgstr "Stützstruktur-Einzüge einschränken"
#: fdmprinter.def.json
msgctxt "limit_support_retractions description"
-msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
+msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excessive stringing within the support structure."
msgstr "Lassen Sie den Einzug beim Vorgehen von Stützstruktur zu Stützstruktur in einer geraden Linie aus. Die Aktivierung dieser Einstellung spart Druckzeit, kann jedoch zu übermäßigem Fadenziehen innerhalb der Stützstruktur führen."
#: fdmprinter.def.json
@@ -2120,8 +2422,8 @@ msgstr "Düsenschalter Einzugsabstand"
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_amount description"
-msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
-msgstr "Der Wert für den Einzug: 0 einstellen, um keinen Einzug zu erhalten. Dies sollte generell mit der Länge der Heizzone übereinstimmen."
+msgid "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+msgstr "Der Wert für den Einzug beim Umstellen der Extruder: 0 einstellen, um keinen Einzug zu erhalten. Dies sollte generell mit der Länge der Heizzone übereinstimmen."
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_speeds label"
@@ -2153,6 +2455,16 @@ msgctxt "switch_extruder_prime_speed description"
msgid "The speed at which the filament is pushed back after a nozzle switch retraction."
msgstr "Die Geschwindigkeit, mit der das Filament während eines Düsenschaltereinzugs zurückgeschoben wird."
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount label"
+msgid "Nozzle Switch Extra Prime Amount"
+msgstr "Zusätzliche Einzugsmenge bei Düsenwechsel"
+
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount description"
+msgid "Extra material to prime after nozzle switching."
+msgstr "Nach einem Düsenwechsel zusätzlich bereitzustellendes Material."
+
#: fdmprinter.def.json
msgctxt "speed label"
msgid "Speed"
@@ -2344,14 +2656,14 @@ msgid "The speed at which the skirt and brim are printed. Normally this is done
msgstr "Die Geschwindigkeit, mit der die Skirt- und Brim-Elemente gedruckt werden. Normalerweise wird dafür die Geschwindigkeit der Basisschicht verwendet. In machen Fällen kann es jedoch vorteilhaft sein, das Skirt- oder Brim-Element mit einer anderen Geschwindigkeit zu drucken."
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override label"
-msgid "Maximum Z Speed"
-msgstr "Maximale Z-Geschwindigkeit"
+msgctxt "speed_z_hop label"
+msgid "Z Hop Speed"
+msgstr "Sprunghöhe Z"
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override description"
-msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
-msgstr "Die maximale Geschwindigkeit, mit der die Druckplatte bewegt wird. Eine Einstellung auf Null veranlasst die Verwendung der Firmware-Grundeinstellungen für die maximale Z-Geschwindigkeit."
+msgctxt "speed_z_hop description"
+msgid "The speed at which the vertical Z movement is made for Z Hops. This is typically lower than the print speed since the build plate or machine's gantry is harder to move."
+msgstr "Die Geschwindigkeit, mit der bei Z-Sprüngen die vertikale Bewegung (Z-Achse) erfolgt. Diese liegt in der Regel unterhalb der Druckgeschwindigkeit, da die Bewegung von Druckbett oder Brücke schwieriger ist."
#: fdmprinter.def.json
msgctxt "speed_slowdown_layers label"
@@ -2780,8 +3092,8 @@ msgstr "Combing-Modus"
#: fdmprinter.def.json
msgctxt "retraction_combing description"
-msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
-msgstr "Durch Combing bleibt die Düse während der Bewegung innerhalb von bereits gedruckten Bereichen. Dies führt zu einer leicht verlängerten Bewegungszeit, reduziert jedoch die Notwendigkeit von Einzügen. Wenn Combing deaktiviert ist, wird das Material eingezogen und die Düse bewegt sich in einer geraden Linie zum nächsten Punkt. Es ist außerdem möglich, das Combing über die oberen/unteren Außenhautbereiche zu vermeiden, indem nur die Füllung berücksichtigt wird. Die Option „Innerhalb der Füllung“ verhält sich genauso wie die Option „Nicht in Außenhaut“ in früheren Cura Versionen."
+msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas or to only comb within the infill."
+msgstr "Durch Combing bleibt die Düse während der Bewegung innerhalb von bereits gedruckten Bereichen. Dies führt zu einer leicht verlängerten Bewegungszeit, reduziert jedoch die Notwendigkeit von Einzügen. Wenn Combing deaktiviert ist, wird das Material eingezogen und die Düse bewegt sich in einer geraden Linie zum nächsten Punkt. Es ist außerdem möglich, das Combing über die oberen/unteren Außenhautbereiche zu vermeiden, oder nur Combing innerhalb der Füllung auszuführen."
#: fdmprinter.def.json
msgctxt "retraction_combing option off"
@@ -2853,16 +3165,6 @@ msgctxt "travel_avoid_distance description"
msgid "The distance between the nozzle and already printed parts when avoiding during travel moves."
msgstr "Der Abstand zwischen der Düse und den bereits gedruckten Teilen, wenn diese bei Bewegungen umgangen werden."
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position label"
-msgid "Start Layers with the Same Part"
-msgstr "Startet Schichten mit demselben Teil"
-
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position description"
-msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
-msgstr "Beginnen Sie in jeder Schicht mit dem Drucken des Objekts in der Nähe desselben Punkts, sodass keine neue Schicht begonnen wird, wenn das Teil gedruckt wird, mit dem die letzte Schicht geendet hat. Damit lassen sich Überhänge und kleine Teile besser herstellen, allerdings verlängert sich die Druckzeit."
-
#: fdmprinter.def.json
msgctxt "layer_start_x label"
msgid "Layer Start X"
@@ -2923,6 +3225,16 @@ msgctxt "retraction_hop_after_extruder_switch description"
msgid "After the machine switched from one extruder to the other, the build plate is lowered to create clearance between the nozzle and the print. This prevents the nozzle from leaving oozed material on the outside of a print."
msgstr "Nachdem das Gerät von einem Extruder zu einem anderen geschaltet hat, wird die Druckplatte abgesenkt, um einen Abstand zwischen der Düse und dem Druck zu bilden. Das verhindert, dass die Düse abgesondertes Material auf der Außenseite des Drucks hinterlässt."
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height label"
+msgid "Z Hop After Extruder Switch Height"
+msgstr "Z-Sprung nach Extruder-Schalterhöhe"
+
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height description"
+msgid "The height difference when performing a Z Hop after extruder switch."
+msgstr "Der Höhenunterschied bei Ausführung eines Z-Sprungs nach Extruder-Schalter."
+
#: fdmprinter.def.json
msgctxt "cooling label"
msgid "Cooling"
@@ -3193,6 +3505,11 @@ msgctxt "support_pattern option cross"
msgid "Cross"
msgstr "Quer"
+#: fdmprinter.def.json
+msgctxt "support_pattern option gyroid"
+msgid "Gyroid"
+msgstr "Gyroid"
+
#: fdmprinter.def.json
msgctxt "support_wall_count label"
msgid "Support Wall Line Count"
@@ -3254,14 +3571,14 @@ msgid "Distance between the printed initial layer support structure lines. This
msgstr "Der Abstand zwischen der ursprünglichen gedruckten Stützstrukturlinien. Diese Einstellung wird anhand der Dichte der Stützstruktur berechnet."
#: fdmprinter.def.json
-msgctxt "support_infill_angle label"
-msgid "Support Infill Line Direction"
+msgctxt "support_infill_angles label"
+msgid "Support Infill Line Directions"
msgstr "Unterstützung Linienrichtung Füllung"
#: fdmprinter.def.json
-msgctxt "support_infill_angle description"
-msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
-msgstr "Ausrichtung des Füllmusters für Unterstützung. Das Füllmuster für Unterstützung wird in der horizontalen Planfläche gedreht."
+msgctxt "support_infill_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angle 0 degrees."
+msgstr "Liste der zu verwendenden Linienrichtungen (in ganzen Zahlen). Die Elemente der Liste werden während des Aufbaus der Schichten der Reihe nach abgearbeitet. Wenn das Ende der Liste erreicht wird, wird wieder beim ersten Element begonnen. Die Listenobjekte werden durch Kommas getrennt und die gesamte Liste ist in eckige Klammern gesetzt. Standardmäßig ist eine leere Liste vorhanden, was bedeutet, dass der Standardwinkel von 0 Grad zu verwenden ist."
#: fdmprinter.def.json
msgctxt "support_brim_enable label"
@@ -3390,8 +3707,8 @@ msgstr "Abstand für Zusammenführung der Stützstrukturen"
#: fdmprinter.def.json
msgctxt "support_join_distance description"
-msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
-msgstr "Der Maximalabstand zwischen Stützstrukturen in der X- und Y-Richtung. Wenn sich einzelne Strukturen näher aneinander befinden, als dieser Wert, werden diese Strukturen in eine einzige Struktur zusammengefügt."
+msgid "The maximum distance between support structures in the X/Y directions. When separate structures are closer together than this value, the structures merge into one."
+msgstr "Der Maximalabstand zwischen Stützstrukturen in der X- und Y-Richtung. Wenn der Abstand einzelner Strukturen zueinander diesen Wert unterschreitet, werden diese Strukturen miteinander kombiniert und bilden eine Struktur."
#: fdmprinter.def.json
msgctxt "support_offset label"
@@ -3433,6 +3750,16 @@ msgctxt "gradual_support_infill_step_height description"
msgid "The height of support infill of a given density before switching to half the density."
msgstr "Die Höhe der Stützstruktur-Füllung einer bestimmten Dichte vor dem Umschalten auf die halbe Dichte."
+#: fdmprinter.def.json
+msgctxt "minimum_support_area label"
+msgid "Minimum Support Area"
+msgstr "Mindestbereich Stützstruktur"
+
+#: fdmprinter.def.json
+msgctxt "minimum_support_area description"
+msgid "Minimum area size for support polygons. Polygons which have an area smaller than this value will not be generated."
+msgstr "Mindestflächenbreite für Stützstruktur-Polygone. Polygone, die eine kleinere Fläche als diesen Wert aufweisen, werden nicht generiert."
+
#: fdmprinter.def.json
msgctxt "support_interface_enable label"
msgid "Enable Support Interface"
@@ -3658,6 +3985,97 @@ msgctxt "support_bottom_pattern option zigzag"
msgid "Zig Zag"
msgstr "Zickzack"
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area label"
+msgid "Minimum Support Interface Area"
+msgstr "Mindestbereich Stützstruktur-Schnittstelle"
+
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area description"
+msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Mindestflächenbreite für Stützstruktur-Schnittstellen-Polygone. Polygone, die eine kleinere Fläche als diesen Wert aufweisen, werden als normale Stützstruktur"
+" gedruckt."
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area label"
+msgid "Minimum Support Roof Area"
+msgstr "Mindestbereich Stützstrukturdach"
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area description"
+msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Mindestfläche für die Dächer der Stützstruktur. Polygone, die eine kleinere Fläche als diesen Wert aufweisen, werden als normale Stützstruktur gedruckt."
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area label"
+msgid "Minimum Support Floor Area"
+msgstr "Mindestbereich Stützstrukturboden"
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area description"
+msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Mindestfläche für die Dächer der Stützstruktur. Polygone, die eine kleinere Fläche als diesen Wert aufweisen, werden als normale Stützstruktur gedruckt."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset label"
+msgid "Support Interface Horizontal Expansion"
+msgstr "Horizontale Erweiterung Stützstruktur-Schnittstelle"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset description"
+msgid "Amount of offset applied to the support interface polygons."
+msgstr "Umfang des angewandten Versatzes für die Stützstruktur-Schnittstellen-Polygone."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset label"
+msgid "Support Roof Horizontal Expansion"
+msgstr "Horizontale Erweiterung Stützstrukturdach"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset description"
+msgid "Amount of offset applied to the roofs of the support."
+msgstr "Umfang des angewandten Versatzes für die Dächer der Stützstruktur."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset label"
+msgid "Support Floor Horizontal Expansion"
+msgstr "Horizontale Erweiterung Stützstrukturboden"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset description"
+msgid "Amount of offset applied to the floors of the support."
+msgstr "Umfang des angewandten Versatzes für die Böden der Stützstruktur."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles label"
+msgid "Support Interface Line Directions"
+msgstr "Richtungen der Verbindungslinien unterstützen"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Liste der zu verwendenden Linienrichtungen (in ganzen Zahlen). Die Elemente der Liste werden während des Aufbaus der Schichten der Reihe nach abgearbeitet. Wenn das Ende der Liste erreicht wird, wird wieder beim ersten Element begonnen. Die Listenobjekte werden durch Kommas getrennt und die gesamte Liste ist in eckige Klammern gesetzt. Standardmäßig ist eine leere Liste vorhanden, was bedeutet, dass herkömmliche Standardwinkel (zwischen 45 und 135- rad, falls die Verbindungsstellen ziemlich dick sind, oder 90 Grad) zu verwenden sind."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles label"
+msgid "Support Roof Line Directions"
+msgstr "Richtungen der Dachlinien unterstützen"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Liste der zu verwendenden Linienrichtungen (in ganzen Zahlen). Die Elemente der Liste werden während des Aufbaus der Schichten der Reihe nach abgearbeitet. Wenn das Ende der Liste erreicht wird, wird wieder beim ersten Element begonnen. Die Listenobjekte werden durch Kommas getrennt und die gesamte Liste ist in eckige Klammern gesetzt. Standardmäßig ist eine leere Liste vorhanden, was bedeutet, dass herkömmliche Standardwinkel (zwischen 45 und 135- rad, falls die Verbindungsstellen ziemlich dick sind, oder 90 Grad) zu verwenden sind."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles label"
+msgid "Support Floor Line Directions"
+msgstr "Richtungen der Bodenlinien unterstützen"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Liste der zu verwendenden Linienrichtungen (in ganzen Zahlen). Die Elemente der Liste werden während des Aufbaus der Schichten der Reihe nach abgearbeitet. Wenn das Ende der Liste erreicht wird, wird wieder beim ersten Element begonnen. Die Listenobjekte werden durch Kommas getrennt und die gesamte Liste ist in eckige Klammern gesetzt. Standardmäßig ist eine leere Liste vorhanden, was bedeutet, dass herkömmliche Standardwinkel (zwischen 45 und 135- rad, falls die Verbindungsstellen ziemlich dick sind, oder 90 Grad) zu verwenden sind."
+
#: fdmprinter.def.json
msgctxt "support_fan_enable label"
msgid "Fan Speed Override"
@@ -3699,13 +4117,13 @@ msgid "The diameter of a special tower."
msgstr "Der Durchmesser eines speziellen Pfeilers."
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter label"
-msgid "Minimum Diameter"
-msgstr "Mindestdurchmesser"
+msgctxt "support_tower_maximum_supported_diameter label"
+msgid "Maximum Tower-Supported Diameter"
+msgstr "Maximaler Durchmesser für Stützpfeiler"
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter description"
-msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+msgctxt "support_tower_maximum_supported_diameter description"
+msgid "Maximum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
msgstr "Der Mindestdurchmesser in den X/Y-Richtungen eines kleinen Bereichs, der durch einen speziellen Stützpfeiler gestützt wird."
#: fdmprinter.def.json
@@ -3828,7 +4246,9 @@ msgctxt "skirt_gap description"
msgid ""
"The horizontal distance between the skirt and the first layer of the print.\n"
"This is the minimum distance. Multiple skirt lines will extend outwards from this distance."
-msgstr "Der horizontale Abstand zwischen dem Skirt und der ersten Schicht des Drucks.\nEs handelt sich dabei um den Mindestabstand. Ab diesem Abstand werden mehrere Skirt-Linien in äußerer Richtung angebracht."
+msgstr ""
+"Der horizontale Abstand zwischen dem Skirt und der ersten Schicht des Drucks.\n"
+"Es handelt sich dabei um den Mindestabstand. Ab diesem Abstand werden mehrere Skirt-Linien in äußerer Richtung angebracht."
#: fdmprinter.def.json
msgctxt "skirt_brim_minimal_length label"
@@ -4200,16 +4620,6 @@ msgctxt "prime_tower_enable description"
msgid "Print a tower next to the print which serves to prime the material after each nozzle switch."
msgstr "Drucken Sie einen Turm neben dem Druck, der zum Einziehen des Materials nach jeder Düsenschaltung dient."
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular label"
-msgid "Circular Prime Tower"
-msgstr "Einzugsturm kreisförmig"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular description"
-msgid "Make the prime tower as a circular shape."
-msgstr "Macht den Einzugsturm zu einer Kreisform."
-
#: fdmprinter.def.json
msgctxt "prime_tower_size label"
msgid "Prime Tower Size"
@@ -4250,16 +4660,6 @@ msgctxt "prime_tower_position_y description"
msgid "The y coordinate of the position of the prime tower."
msgstr "Die Y-Koordinate der Position des Einzugsturms."
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow label"
-msgid "Prime Tower Flow"
-msgstr "Fluss Einzugsturm"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow description"
-msgid "Flow compensation: the amount of material extruded is multiplied by this value."
-msgstr "Fluss-Kompensation: Die extrudierte Materialmenge wird mit diesem Wert multipliziert."
-
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled label"
msgid "Wipe Inactive Nozzle on Prime Tower"
@@ -4270,6 +4670,16 @@ msgctxt "prime_tower_wipe_enabled description"
msgid "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower."
msgstr "Nach dem Drucken des Einzugsturms mit einer Düse wird das ausgetretene Material von der anderen Düse am Einzugsturm abgewischt."
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable label"
+msgid "Prime Tower Brim"
+msgstr "Brim Einzugsturm"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable description"
+msgid "Prime-towers might need the extra adhesion afforded by a brim even if the model doesn't. Presently can't be used with the 'Raft' adhesion-type."
+msgstr "Einzugstürme benötigen möglicherweise zusätzliche Haftung in Form eines Brims, auch wenn das Modell selbst dies nicht benötigt. Kann derzeit nicht mit dem „Raft“-Haftungstyp verwendet werden."
+
#: fdmprinter.def.json
msgctxt "ooze_shield_enabled label"
msgid "Enable Ooze Shield"
@@ -4390,6 +4800,36 @@ msgctxt "remove_empty_first_layers description"
msgid "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle."
msgstr "Entfernen Sie die leeren Schichten unter der ersten gedruckten Schicht, sofern vorhanden. Die Deaktivierung dieser Einstellung kann zu leeren ersten Schichten führen, wenn die Einstellung der Slicing-Toleranz auf Exklusiv oder Mittel gesetzt wurde."
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution label"
+msgid "Maximum Resolution"
+msgstr "Maximale Auflösung"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution description"
+msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
+msgstr "Die Mindestgröße eines Linienabschnitts nach dem Slicen. Wenn Sie diesen Wert erhöhen, führt dies zu einer niedrigeren Auslösung des Mesh. Damit kann der Drucker die erforderliche Geschwindigkeit für die Verarbeitung des G-Codes beibehalten; außerdem wird die Slice-Geschwindigkeit erhöht, indem Details des Mesh entfernt werden, die ohnehin nicht verarbeitet werden können."
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution label"
+msgid "Maximum Travel Resolution"
+msgstr "Maximale Bewegungsauflösung"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution description"
+msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
+msgstr "Die maximale Größe eines Bewegungsliniensegments nach dem Slicen. Wenn Sie diesen Wert erhöhen, weisen die Fahrtbewegungen weniger glatte Kanten aus. Das ermöglicht dem Drucker, die für die Verarbeitung eines G-Codes erforderliche Geschwindigkeit aufrechtzuerhalten, allerdings kann das Modell damit auch weniger akkurat werden."
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation label"
+msgid "Maximum Deviation"
+msgstr "Maximale Abweichung"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation description"
+msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution, so if the two conflict the Maximum Deviation will always be held true."
+msgstr "Die maximal zulässige Abweichung bei Reduzierung der maximalen Auflösung. Wenn Sie diesen Wert erhöhen, wird der Druck ungenauer, der G-Code wird jedoch kleiner. Die maximale Abweichung ist eine Grenze für die maximale Auflösung. Wenn die beiden Werte sich widersprechen, wird stets die maximale Abweichung eingehalten."
+
#: fdmprinter.def.json
msgctxt "blackmagic label"
msgid "Special Modes"
@@ -4552,8 +4992,8 @@ msgstr "Spiralisieren der äußeren Konturen glätten"
#: fdmprinter.def.json
msgctxt "smooth_spiralized_contours description"
-msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
-msgstr "Glättet die spiralförmigen Konturen, um die Sichtbarkeit der Z-Naht zu reduzieren (die Z-Naht sollte auf dem Druck kaum sichtbar sein, ist jedoch in der Schichtenansicht erkennbar). Beachten Sie, dass das Glätten dazu neigt, feine Oberflächendetails zu verwischen."
+msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+msgstr "Glättet die spiralförmigen Konturen, um die Sichtbarkeit der Z-Naht zu reduzieren (die Z-Naht sollte am Druckobjekt kaum sichtbar sein, ist jedoch in der Schichtenansicht erkennbar). Beachten Sie, dass beim Glätten feine Oberflächendetails verwischt werden."
#: fdmprinter.def.json
msgctxt "relative_extrusion label"
@@ -4765,26 +5205,6 @@ msgctxt "minimum_polygon_circumference description"
msgid "Polygons in sliced layers that have a circumference smaller than this amount will be filtered out. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details."
msgstr "Polygone in geschnittenen Schichten, die einen Umfang unter diesem Wert haben, werden ausgefiltert. Niedrigere Werte führen zu einem Mesh mit höherer Auflösung zulasten der Slicing-Zeit. Dies gilt in erster Linie für SLA-Drucker mit höherer Auflösung und sehr kleine 3D-Modelle mit zahlreichen Details."
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution label"
-msgid "Maximum Resolution"
-msgstr "Maximale Auflösung"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution description"
-msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
-msgstr "Die Mindestgröße eines Linienabschnitts nach dem Slicen. Wenn Sie diesen Wert erhöhen, führt dies zu einer niedrigeren Auslösung des Mesh. Damit kann der Drucker die erforderliche Geschwindigkeit für die Verarbeitung des G-Codes beibehalten; außerdem wird die Slice-Geschwindigkeit erhöht, indem Details des Mesh entfernt werden, die ohnehin nicht verarbeitet werden können."
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution label"
-msgid "Maximum Travel Resolution"
-msgstr "Maximale Bewegungsauflösung"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution description"
-msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
-msgstr "Die maximale Größe eines Bewegungsliniensegments nach dem Slicen. Wenn Sie diesen Wert erhöhen, weisen die Fahrtbewegungen weniger glatte Kanten aus. Das ermöglicht dem Drucker, die für die Verarbeitung eines G-Codes erforderliche Geschwindigkeit aufrechtzuerhalten, allerdings kann das Modell damit auch weniger akkurat werden."
-
#: fdmprinter.def.json
msgctxt "support_skip_some_zags label"
msgid "Break Up Support In Chunks"
@@ -4925,16 +5345,6 @@ msgctxt "coasting_speed description"
msgid "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops."
msgstr "Die Geschwindigkeit, mit der die Bewegung während des Coasting erfolgt, in Relation zur Geschwindigkeit des Extrusionswegs. Ein Wert leicht unter 100 % wird empfohlen, da während der Coasting-Bewegung der Druck in den Bowden-Röhren abfällt."
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation label"
-msgid "Alternate Skin Rotation"
-msgstr "Wechselnde Rotation der Außenhaut"
-
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation description"
-msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
-msgstr "Die Richtung, in welcher die oberen/unteren Schichten gedruckt werden, wird abgewechselt. Normalerweise werden diese nur diagonal gedruckt. Diese Einstellung fügt die Nur-X- und Nur-Y-Richtung zu."
-
#: fdmprinter.def.json
msgctxt "cross_infill_pocket_size label"
msgid "Cross 3D Pocket Size"
@@ -5042,8 +5452,8 @@ msgstr "Konische Stützstruktur aktivieren"
#: fdmprinter.def.json
msgctxt "support_conical_enabled description"
-msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
-msgstr "Experimentelle Funktion: Macht die Bereiche der Stützstruktur am Boden kleiner als beim Überhang."
+msgid "Make support areas smaller at the bottom than at the overhang."
+msgstr "Macht die Bereiche der Stützstruktur am Boden kleiner als beim Überhang."
#: fdmprinter.def.json
msgctxt "support_conical_angle label"
@@ -5107,23 +5517,24 @@ msgstr "Der durchschnittliche Abstand zwischen den willkürlich auf jedes Linien
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset label"
-msgid "Flow rate compensation max extrusion offset"
+msgid "Flow Rate Compensation Max Extrusion Offset"
msgstr "Ausgleich Durchflussrate max. Extrusionswirkung"
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset description"
-msgid "The maximum distance in mm to compensate."
-msgstr "Die maximale Distanz in mm für den Ausgleich."
+msgid "The maximum distance in mm to move the filament to compensate for changes in flow rate."
+msgstr "Die maximale Strecke (in mm), die das Filament bewegt werden kann, um Änderungen der Durchflussrate zu kompensieren."
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor label"
-msgid "Flow rate compensation factor"
+msgid "Flow Rate Compensation Factor"
msgstr "Ausgleichsfaktor Durchflussrate"
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor description"
-msgid "The multiplication factor for the flow rate -> distance translation."
-msgstr "Der Multiplikationsfaktor für die Übersetzung Durchflussrate -> Distanz."
+msgid "How far to move the filament in order to compensate for changes in flow rate, as a percentage of how far the filament would move in one second of extrusion."
+msgstr "Wie weit das Filament bewegt werden kann, um Änderungen der Durchflussrate zu kompensieren – als Prozentsatz der Strecke, die das Filament sich während"
+" einer Sekunde Extrusion bewegen würde."
#: fdmprinter.def.json
msgctxt "wireframe_enabled label"
@@ -5275,7 +5686,9 @@ msgctxt "wireframe_up_half_speed description"
msgid ""
"Distance of an upward move which is extruded with half speed.\n"
"This can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing."
-msgstr "Die Strecke einer Aufwärtsbewegung, die mit halber Geschwindigkeit extrudiert wird.\nDies kann zu einer besseren Haftung an vorhergehenden Schichten führen, während gleichzeitig ein Überhitzen des Materials in diesen Schichten vermieden wird. Dies gilt nur für das Drucken mit Drahtstruktur."
+msgstr ""
+"Die Strecke einer Aufwärtsbewegung, die mit halber Geschwindigkeit extrudiert wird.\n"
+"Dies kann zu einer besseren Haftung an vorhergehenden Schichten führen, während gleichzeitig ein Überhitzen des Materials in diesen Schichten vermieden wird. Dies gilt nur für das Drucken mit Drahtstruktur."
#: fdmprinter.def.json
msgctxt "wireframe_top_jump label"
@@ -5384,7 +5797,7 @@ msgstr "Der Abstand zwischen der Düse und den horizontalen Abwärtslinien. Bei
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
-msgid "Use adaptive layers"
+msgid "Use Adaptive Layers"
msgstr "Anpassschichten verwenden"
#: fdmprinter.def.json
@@ -5394,7 +5807,7 @@ msgstr "Die Funktion Anpassschichten berechnet die Schichthöhe je nach Form des
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
-msgid "Adaptive layers maximum variation"
+msgid "Adaptive Layers Maximum Variation"
msgstr "Maximale Abweichung für Anpassschichten"
#: fdmprinter.def.json
@@ -5404,7 +5817,7 @@ msgstr "Die max. zulässige Höhendifferenz von der Basisschichthöhe."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
-msgid "Adaptive layers variation step size"
+msgid "Adaptive Layers Variation Step Size"
msgstr "Abweichung Schrittgröße für Anpassschichten"
#: fdmprinter.def.json
@@ -5414,13 +5827,14 @@ msgstr "Der Höhenunterscheid der nächsten Schichthöhe im Vergleich zur vorher
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
-msgid "Adaptive layers threshold"
-msgstr "Schwellenwert Anpassschichten"
+msgid "Adaptive Layers Topography Size"
+msgstr "Topographische Größe der Anpassschichten"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
-msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
-msgstr "Das ist der Schwellenwert, der definiert, ob eine kleinere Schicht verwendet wird oder nicht. Dieser Wert wird mit dem der stärksten Neigung in einer Schicht verglichen."
+msgid "Target horizontal distance between two adjacent layers. Reducing this setting causes thinner layers to be used to bring the edges of the layers closer together."
+msgstr "Horizontaler Abstand zwischen zwei angrenzenden Schichten. Bei Einstellung eines niedrigeren Werts werden dünnere Schichten aufgetragen, damit die Kanten"
+" der Schichten enger aneinander liegen."
#: fdmprinter.def.json
msgctxt "wall_overhang_angle label"
@@ -5429,8 +5843,9 @@ msgstr "Winkel für überhängende Wände"
#: fdmprinter.def.json
msgctxt "wall_overhang_angle description"
-msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
-msgstr "Wände, die über diesen Winkel hinaus hängen, werden mithilfe der Einstellungen für Winkel für überhängende Wände gedruckt. Wenn der Wert 90 beträgt, werden keine Wände als überhängend behandelt."
+msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging. Overhang that gets supported by support will not be treated as overhang either."
+msgstr "Wände, die über diesen Winkel hinaus hängen, werden mithilfe der Einstellungen für Winkel für überhängende Wände gedruckt. Wenn der Wert 90 beträgt, werden"
+" keine Wände als überhängend behandelt. Überhänge, die von Stützstrukturen gestützt werden, werden ebenfalls nicht als Überhang behandelt."
#: fdmprinter.def.json
msgctxt "wall_overhang_speed_factor label"
@@ -5632,6 +6047,198 @@ msgctxt "bridge_fan_speed_3 description"
msgid "Percentage fan speed to use when printing the third bridge skin layer."
msgstr "Prozentwert der Lüfterdrehzahl für das Drucken der dritten Brücken-Außenhautschicht."
+#: fdmprinter.def.json
+msgctxt "clean_between_layers label"
+msgid "Wipe Nozzle Between Layers"
+msgstr "Düse zwischen den Schichten abwischen"
+
+#: fdmprinter.def.json
+msgctxt "clean_between_layers description"
+msgid "Whether to include nozzle wipe G-Code between layers. Enabling this setting could influence behavior of retract at layer change. Please use Wipe Retraction settings to control retraction at layers where the wipe script will be working."
+msgstr "Option für das Einfügen eines G-Codes für das Abwischen der Düse zwischen den Schichten. Die Aktivierung dieser Einstellung könnte das Einzugsverhalten beim Schichtenwechsel beeinflussen. Verwenden Sie bitte die Einstellungen für Abwischen bei Einzug, um das Einziehen bei Schichten zu steuern, bei denen das Skript für Wischen aktiv wird."
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe label"
+msgid "Material Volume Between Wipes"
+msgstr "Materialmenge zwischen den Wischvorgängen"
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe description"
+msgid "Maximum material, that can be extruded before another nozzle wipe is initiated."
+msgstr "Die maximale Materialmenge, die extrudiert werden kann, bevor die Düse ein weiteres Mal abgewischt wird."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable label"
+msgid "Wipe Retraction Enable"
+msgstr "Abwischen bei Einzug aktivieren"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable description"
+msgid "Retract the filament when the nozzle is moving over a non-printed area."
+msgstr "Das Filament wird eingezogen, wenn sich die Düse über einen nicht zu bedruckenden Bereich bewegt."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount label"
+msgid "Wipe Retraction Distance"
+msgstr "Einzugsabstand für Abwischen"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount description"
+msgid "Amount to retract the filament so it does not ooze during the wipe sequence."
+msgstr "Wert, um den das Filament eingezogen wird, damit es während des Abwischens nicht austritt."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount label"
+msgid "Wipe Retraction Extra Prime Amount"
+msgstr "Zusätzliche Zurückschiebemenge nach Einzug für Abwischen"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount description"
+msgid "Some material can ooze away during a wipe travel moves, which can be compensated for here."
+msgstr "Während einer Bewegung für den Abwischvorgang kann Material wegsickern, was hier kompensiert werden kann."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed label"
+msgid "Wipe Retraction Speed"
+msgstr "Einzugsgeschwindigkeit für Abwischen"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed description"
+msgid "The speed at which the filament is retracted and primed during a wipe retraction move."
+msgstr "Die Geschwindigkeit, mit der das Filament während einer Einzugsbewegung eingezogen und während einer Einzugsbewegung für Abwischen zurückgeschoben wird."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed label"
+msgid "Wipe Retraction Retract Speed"
+msgstr "Einzugsgeschwindigkeit (Einzug) für Abwischen"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed description"
+msgid "The speed at which the filament is retracted during a wipe retraction move."
+msgstr "Die Geschwindigkeit, mit der das Filament während einer Einzugsbewegung für Abwischen eingezogen wird."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed label"
+msgid "Retraction Prime Speed"
+msgstr "Einzugsgeschwindigkeit (Einzug)"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed description"
+msgid "The speed at which the filament is primed during a wipe retraction move."
+msgstr "Die Geschwindigkeit, mit der das Filament während einer Einzugsbewegung vorbereitet wird."
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause label"
+msgid "Wipe Pause"
+msgstr "Abwischen pausieren"
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause description"
+msgid "Pause after the unretract."
+msgstr "Pausieren nach Aufhebung des Einzugs."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable label"
+msgid "Wipe Z Hop When Retracted"
+msgstr "Z-Sprung beim Einziehen - Abwischen"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable description"
+msgid "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate."
+msgstr "Nach dem Einzug wird das Druckbett gesenkt, um einen Abstand zwischen Düse und Druck herzustellen. Das verhindert, dass die Düse den Druck während der Bewegungen anschlägt und verringert die Möglichkeit, dass der Druck vom Druckbett heruntergestoßen wird."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount label"
+msgid "Wipe Z Hop Height"
+msgstr "Z-Sprung Höhe - Abwischen"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount description"
+msgid "The height difference when performing a Z Hop."
+msgstr "Der Höhenunterschied bei Ausführung eines Z-Sprungs."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed label"
+msgid "Wipe Hop Speed"
+msgstr "Sprunghöhe - Abwischen"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed description"
+msgid "Speed to move the z-axis during the hop."
+msgstr "Geschwindigkeit für das Verfahren der Z-Achse während des Sprungs."
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x label"
+msgid "Wipe Brush X Position"
+msgstr "X-Position für Bürste - Abwischen"
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x description"
+msgid "X location where wipe script will start."
+msgstr "X-Position, an der das Skript für Abwischen startet."
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count label"
+msgid "Wipe Repeat Count"
+msgstr "Wiederholungszähler - Abwischen"
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count description"
+msgid "Number of times to move the nozzle across the brush."
+msgstr "Anzahl der Wiederholungen für das Bewegen der Düse über der Bürste."
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance label"
+msgid "Wipe Move Distance"
+msgstr "Abstand Wischbewegung"
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance description"
+msgid "The distance to move the head back and forth across the brush."
+msgstr "Die Strecke, die der Kopf durch Vorwärts- und Rückwärtsbewegung über die Bürste hinweg fährt."
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size label"
+msgid "Small Hole Max Size"
+msgstr "Max. Lochdurchmesser"
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size description"
+msgid "Holes and part outlines with a diameter smaller than this will be printed using Small Feature Speed."
+msgstr "Löcher und Teilkonturen mit einem kleineren Durchmesser werden mit Small Feature Speed gedruckt."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length label"
+msgid "Small Feature Max Length"
+msgstr "Max. Detaillänge"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length description"
+msgid "Feature outlines that are shorter than this length will be printed using Small Feature Speed."
+msgstr "Teile, die kleiner sind als dieser Wert, werden in Detailgeschwindigkeit gedruckt."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor label"
+msgid "Small Feature Speed"
+msgstr "Detailgeschwindigkeit"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor description"
+msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "Bei kleinen Details wird die Geschwindigkeit auf diesen Prozentsatz der normalen Druckgeschwindigkeit gesetzt. Durch eine niedrigere Druckgeschwindigkeit"
+" können die Haftung und die Genauigkeit verbessert werden."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 label"
+msgid "Small Feature Initial Layer Speed"
+msgstr "Geschwindigkeit der ersten Schicht von Details"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 description"
+msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "Bei kleinen Details wird die Geschwindigkeit bei der ersten Schicht auf diesen Prozentsatz der normalen Druckgeschwindigkeit gesetzt. Durch eine niedrigere"
+" Druckgeschwindigkeit können die Haftung und die Genauigkeit verbessert werden."
+
#: fdmprinter.def.json
msgctxt "command_line_settings label"
msgid "Command Line Settings"
@@ -5692,6 +6299,234 @@ msgctxt "mesh_rotation_matrix description"
msgid "Transformation matrix to be applied to the model when loading it from file."
msgstr "Transformationsmatrix, die beim Laden aus der Datei auf das Modell angewandt wird."
+#~ msgctxt "minimum_interface_area description"
+#~ msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Mindestflächenbreite für Stützstruktur-Schnittstellen-Polygone. Polygone, die eine kleinere Fläche als diesen Wert aufweisen, werden nicht generiert."
+
+#~ msgctxt "minimum_roof_area description"
+#~ msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Mindestflächenbreite für die Dächer der Stützstruktur. Polygone, die eine kleinere Fläche als diesen Wert aufweisen, werden nicht generiert."
+
+#~ msgctxt "minimum_bottom_area description"
+#~ msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Mindestflächenbreite für die Böden der Stützstruktur. Polygone, die eine kleinere Fläche als diesen Wert aufweisen, werden nicht generiert."
+
+#~ msgctxt "skin_alternate_rotation label"
+#~ msgid "Alternate Skin Rotation"
+#~ msgstr "Wechselnde Rotation der Außenhaut"
+
+#~ msgctxt "skin_alternate_rotation description"
+#~ msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
+#~ msgstr "Die Richtung, in welcher die oberen/unteren Schichten gedruckt werden, wird abgewechselt. Normalerweise werden diese nur diagonal gedruckt. Diese Einstellung fügt die Nur-X- und Nur-Y-Richtung zu."
+
+#~ msgctxt "flow_rate_max_extrusion_offset label"
+#~ msgid "Flow rate compensation max extrusion offset"
+#~ msgstr "Ausgleich Durchflussrate max. Extrusionswirkung"
+
+#~ msgctxt "flow_rate_max_extrusion_offset description"
+#~ msgid "The maximum distance in mm to compensate."
+#~ msgstr "Die maximale Distanz in mm für den Ausgleich."
+
+#~ msgctxt "flow_rate_extrusion_offset_factor label"
+#~ msgid "Flow rate compensation factor"
+#~ msgstr "Ausgleichsfaktor Durchflussrate"
+
+#~ msgctxt "flow_rate_extrusion_offset_factor description"
+#~ msgid "The multiplication factor for the flow rate -> distance translation."
+#~ msgstr "Der Multiplikationsfaktor für die Übersetzung Durchflussrate -> Distanz."
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive Layers Threshold"
+#~ msgstr "Schwellenwert Anpassschichten"
+
+#~ msgctxt "adaptive_layer_height_threshold description"
+#~ msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
+#~ msgstr "Das ist der Schwellenwert, der definiert, ob eine kleinere Schicht verwendet wird oder nicht. Dieser Wert wird mit dem der stärksten Neigung in einer Schicht verglichen."
+
+#~ msgctxt "wall_overhang_angle description"
+#~ msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
+#~ msgstr "Wände, die über diesen Winkel hinaus hängen, werden mithilfe der Einstellungen für Winkel für überhängende Wände gedruckt. Wenn der Wert 90 beträgt, werden keine Wände als überhängend behandelt."
+
+#~ msgctxt "small_feature_speed_factor description"
+#~ msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "Bei kleinen Details wird die Geschwindigkeit auf diesen Prozentsatz der normalen Druckgeschwindigkeit gesetzt. Durch eine niedrigere Druckgeschwindigkeit kann die Haftung und die Genauigkeit verbessert werden."
+
+#~ msgctxt "small_feature_speed_factor_0 label"
+#~ msgid "First Layer Speed"
+#~ msgstr "Geschwindigkeit für erste Schicht"
+
+#~ msgctxt "small_feature_speed_factor_0 description"
+#~ msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "Bei kleinen Details wird die Geschwindigkeit bei der ersten Schicht auf diesen Prozentsatz der normalen Druckgeschwindigkeit gesetzt. Durch eine niedrigere Druckgeschwindigkeit kann die Haftung und die Genauigkeit verbessert werden."
+
+#~ msgctxt "ironing_enabled description"
+#~ msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
+#~ msgstr "Gehen Sie ein weiteres Mal über die Oberfläche, jedoch ohne Extrusionsmaterial. Damit wird der Kunststoff auf der Oberfläche weiter geschmolzen, was zu einer glatteren Oberfläche führt."
+
+#~ msgctxt "start_layers_at_same_position label"
+#~ msgid "Start Layers with the Same Part"
+#~ msgstr "Startet Schichten mit demselben Teil"
+
+#~ msgctxt "start_layers_at_same_position description"
+#~ msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
+#~ msgstr "Beginnen Sie in jeder Schicht mit dem Drucken des Objekts in der Nähe desselben Punkts, sodass keine neue Schicht begonnen wird, wenn das Teil gedruckt wird, mit dem die letzte Schicht geendet hat. Damit lassen sich Überhänge und kleine Teile besser herstellen, allerdings verlängert sich die Druckzeit."
+
+#~ msgctxt "support_infill_angles description"
+#~ msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
+#~ msgstr "Ausrichtung des Füllmusters für Unterstützung. Das Füllmuster für Unterstützung wird in der horizontalen Planfläche gedreht."
+
+#~ msgctxt "meshfix_maximum_deviation description"
+#~ msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller."
+#~ msgstr "Die maximal zulässige Abweichung bei Reduzierung der Auflösung für die Einstellung der maximalen Auflösung. Wenn Sie diesen Wert erhöhen, wird der Druck ungenauer, der G-Code wird jedoch kleiner."
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code Flavour"
+#~ msgstr "G-Code-Variante"
+
+#~ msgctxt "z_seam_corner description"
+#~ msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
+#~ msgstr "Definieren Sie, ob Kanten am Modell-Umriss die Nahtposition beeinflussen. Keine bedeutet, dass Kanten keinen Einfluss auf die Nahtposition haben. Naht verbergen lässt die Naht mit höherer Wahrscheinlichkeit an einer innenliegenden Kante auftreten. Naht offenlegen lässt die Naht mit höherer Wahrscheinlichkeit an einer Außenkante auftreten. Naht verbergen oder offenlegen lässt die Naht mit höherer Wahrscheinlichkeit an einer innenliegenden oder außenliegenden Kante auftreten."
+
+#~ msgctxt "skin_no_small_gaps_heuristic label"
+#~ msgid "Ignore Small Z Gaps"
+#~ msgstr "Schmale Z-Lücken ignorieren"
+
+#~ msgctxt "skin_no_small_gaps_heuristic description"
+#~ msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
+#~ msgstr "Wenn das Modell schmale vertikale Lücken hat, kann etwa 5 % zusätzliche Rechenzeit aufgewendet werden, um eine obere und untere Außenhaut in diesen engen Räumen zu generieren. In diesem Fall deaktivieren Sie die Einstellung."
+
+#~ msgctxt "build_volume_temperature description"
+#~ msgid "The temperature used for build volume. If this is 0, the build volume temperature will not be adjusted."
+#~ msgstr "Die für die Druckabmessung verwendete Temperatur. Wenn dieser Wert 0 beträgt, wird die Temperatur der Druckabmessung nicht angepasst."
+
+#~ msgctxt "limit_support_retractions description"
+#~ msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
+#~ msgstr "Lassen Sie den Einzug beim Vorgehen von Stützstruktur zu Stützstruktur in einer geraden Linie aus. Die Aktivierung dieser Einstellung spart Druckzeit, kann jedoch zu übermäßigem Fadenziehen innerhalb der Stützstruktur führen."
+
+#~ msgctxt "max_feedrate_z_override label"
+#~ msgid "Maximum Z Speed"
+#~ msgstr "Maximale Z-Geschwindigkeit"
+
+#~ msgctxt "max_feedrate_z_override description"
+#~ msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
+#~ msgstr "Die maximale Geschwindigkeit, mit der die Druckplatte bewegt wird. Eine Einstellung auf Null veranlasst die Verwendung der Firmware-Grundeinstellungen für die maximale Z-Geschwindigkeit."
+
+#~ msgctxt "support_join_distance description"
+#~ msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
+#~ msgstr "Der Maximalabstand zwischen Stützstrukturen in der X- und Y-Richtung. Wenn sich einzelne Strukturen näher aneinander befinden, als dieser Wert, werden diese Strukturen in eine einzige Struktur zusammengefügt."
+
+#~ msgctxt "support_minimal_diameter label"
+#~ msgid "Minimum Diameter"
+#~ msgstr "Mindestdurchmesser"
+
+#~ msgctxt "support_minimal_diameter description"
+#~ msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+#~ msgstr "Der Mindestdurchmesser in den X/Y-Richtungen eines kleinen Bereichs, der durch einen speziellen Stützpfeiler gestützt wird."
+
+#~ msgctxt "prime_tower_circular label"
+#~ msgid "Circular Prime Tower"
+#~ msgstr "Einzugsturm kreisförmig"
+
+#~ msgctxt "prime_tower_circular description"
+#~ msgid "Make the prime tower as a circular shape."
+#~ msgstr "Macht den Einzugsturm zu einer Kreisform."
+
+#~ msgctxt "prime_tower_flow description"
+#~ msgid "Flow compensation: the amount of material extruded is multiplied by this value."
+#~ msgstr "Fluss-Kompensation: Die extrudierte Materialmenge wird mit diesem Wert multipliziert."
+
+#~ msgctxt "smooth_spiralized_contours description"
+#~ msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+#~ msgstr "Glättet die spiralförmigen Konturen, um die Sichtbarkeit der Z-Naht zu reduzieren (die Z-Naht sollte auf dem Druck kaum sichtbar sein, ist jedoch in der Schichtenansicht erkennbar). Beachten Sie, dass das Glätten dazu neigt, feine Oberflächendetails zu verwischen."
+
+#~ msgctxt "support_conical_enabled description"
+#~ msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
+#~ msgstr "Experimentelle Funktion: Macht die Bereiche der Stützstruktur am Boden kleiner als beim Überhang."
+
+#~ msgctxt "extruders_enabled_count label"
+#~ msgid "Number of Extruders that are enabled"
+#~ msgstr "Anzahl der aktivierten Extruder"
+
+#~ msgctxt "machine_nozzle_tip_outer_diameter label"
+#~ msgid "Outer nozzle diameter"
+#~ msgstr "Düsendurchmesser außen"
+
+#~ msgctxt "machine_nozzle_head_distance label"
+#~ msgid "Nozzle length"
+#~ msgstr "Düsenlänge"
+
+#~ msgctxt "machine_nozzle_expansion_angle label"
+#~ msgid "Nozzle angle"
+#~ msgstr "Düsenwinkel"
+
+#~ msgctxt "machine_heat_zone_length label"
+#~ msgid "Heat zone length"
+#~ msgstr "Heizzonenlänge"
+
+#~ msgctxt "machine_nozzle_heat_up_speed label"
+#~ msgid "Heat up speed"
+#~ msgstr "Aufheizgeschwindigkeit"
+
+#~ msgctxt "machine_nozzle_cool_down_speed label"
+#~ msgid "Cool down speed"
+#~ msgstr "Abkühlgeschwindigkeit"
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code flavour"
+#~ msgstr "G-Code-Variante"
+
+#~ msgctxt "machine_disallowed_areas label"
+#~ msgid "Disallowed areas"
+#~ msgstr "Unzulässige Bereiche"
+
+#~ msgctxt "machine_head_polygon label"
+#~ msgid "Machine head polygon"
+#~ msgstr "Gerätekopf Polygon"
+
+#~ msgctxt "machine_head_with_fans_polygon label"
+#~ msgid "Machine head & Fan polygon"
+#~ msgstr "Gerätekopf und Lüfter Polygon"
+
+#~ msgctxt "gantry_height label"
+#~ msgid "Gantry height"
+#~ msgstr "Brückenhöhe"
+
+#~ msgctxt "machine_use_extruder_offset_to_offset_coords label"
+#~ msgid "Offset With Extruder"
+#~ msgstr "Versatz mit Extruder"
+
+#~ msgctxt "adaptive_layer_height_enabled label"
+#~ msgid "Use adaptive layers"
+#~ msgstr "Anpassschichten verwenden"
+
+#~ msgctxt "adaptive_layer_height_variation label"
+#~ msgid "Adaptive layers maximum variation"
+#~ msgstr "Maximale Abweichung für Anpassschichten"
+
+#~ msgctxt "adaptive_layer_height_variation_step label"
+#~ msgid "Adaptive layers variation step size"
+#~ msgstr "Abweichung Schrittgröße für Anpassschichten"
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive layers threshold"
+#~ msgstr "Schwellenwert Anpassschichten"
+
+#~ msgctxt "skin_overlap description"
+#~ msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
+#~ msgstr "Das Ausmaß des Überlappens zwischen der Außenhaut und den Wänden als Prozentwert der Außenhaut-Linienbreite. Ein leichtes Überlappen ermöglicht es den Wänden, eine solide Verbindung mit der Außenhaut herzustellen. Dies ist ein Prozentwert der durchschnittlichen Linienbreiten der Außenhautlinien und der innersten Wand."
+
+#~ msgctxt "skin_overlap_mm description"
+#~ msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
+#~ msgstr "Das Ausmaß des Überlappens zwischen der Außenhaut und den Wänden. Ein leichtes Überlappen ermöglicht es den Wänden, eine solide Verbindung mit der Außenhaut herzustellen."
+
+#~ msgctxt "switch_extruder_retraction_amount description"
+#~ msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+#~ msgstr "Der Wert für den Einzug: 0 einstellen, um keinen Einzug zu erhalten. Dies sollte generell mit der Länge der Heizzone übereinstimmen."
+
+#~ msgctxt "retraction_combing description"
+#~ msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
+#~ msgstr "Durch Combing bleibt die Düse während der Bewegung innerhalb von bereits gedruckten Bereichen. Dies führt zu einer leicht verlängerten Bewegungszeit, reduziert jedoch die Notwendigkeit von Einzügen. Wenn Combing deaktiviert ist, wird das Material eingezogen und die Düse bewegt sich in einer geraden Linie zum nächsten Punkt. Es ist außerdem möglich, das Combing über die oberen/unteren Außenhautbereiche zu vermeiden, indem nur die Füllung berücksichtigt wird. Die Option „Innerhalb der Füllung“ verhält sich genauso wie die Option „Nicht in Außenhaut“ in früheren Cura Versionen."
+
#~ msgctxt "connect_skin_polygons description"
#~ msgid "Connect top/bottom skin paths where they run next to each other. For the concentric pattern enabling this setting greatly reduces the travel time, but because the connections can happend midway over infill this feature can reduce the top surface quality."
#~ msgstr "Außenhaut-Pfade oben/unten verbinden, wenn sie nebeneinander laufen. Bei konzentrischen Mustern reduziert die Aktivierung dieser Einstellung die Durchlaufzeit erheblich. Da die Verbindungen jedoch auf halbem Weg über der Füllung erfolgen können, kann diese Funktion die Oberflächenqualität reduzieren."
diff --git a/resources/i18n/es_ES/cura.po b/resources/i18n/es_ES/cura.po
index e6b5867e39..f971746925 100644
--- a/resources/i18n/es_ES/cura.po
+++ b/resources/i18n/es_ES/cura.po
@@ -1,24 +1,24 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0100\n"
-"PO-Revision-Date: 2018-09-28 14:55+0200\n"
-"Last-Translator: Bothof \n"
-"Language-Team: Spanish\n"
+"POT-Creation-Date: 2019-11-05 13:13+0100\n"
+"PO-Revision-Date: 2019-07-29 15:51+0200\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: Spanish , Spanish \n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.2.3\n"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:22
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:30
msgctxt "@action"
msgid "Machine Settings"
msgstr "Ajustes de la máquina"
@@ -40,23 +40,23 @@ msgctxt "@item:inlistbox"
msgid "G-code File"
msgstr "Archivo GCode"
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:67
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:66
msgctxt "@error:not supported"
msgid "GCodeWriter does not support non-text mode."
msgstr "GCodeWriter no es compatible con el modo sin texto."
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:73
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:89
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:72
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:88
msgctxt "@warning:status"
msgid "Please prepare G-code before exporting."
msgstr "Prepare el Gcode antes de la exportación."
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:30
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:31
msgctxt "@info:title"
msgid "3D Model Assistant"
msgstr "Asistente del modelo 3D"
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:80
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:92
#, python-brace-format
msgctxt "@info:status"
msgid ""
@@ -64,68 +64,56 @@ msgid ""
"
{model_names}
\n"
"
Find out how to ensure the best possible print quality and reliability.
"
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py:25
msgctxt "@action"
msgid "Update Firmware"
msgstr "Actualizar firmware"
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:23
-msgctxt "@item:inmenu"
-msgid "Flatten active settings"
-msgstr "Aplanar ajustes activos"
+#: /home/ruben/Projects/Cura/plugins/AMFReader/__init__.py:15
+msgctxt "@item:inlistbox"
+msgid "AMF File"
+msgstr "Archivo AMF"
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:35
-msgctxt "@info:status"
-msgid "Profile has been flattened & activated."
-msgstr "El perfil se ha aplanado y activado."
-
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:32
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:42
msgctxt "@item:inmenu"
msgid "USB printing"
msgstr "Impresión USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:33
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:43
msgctxt "@action:button Preceded by 'Ready to'."
msgid "Print via USB"
msgstr "Imprimir mediante USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:34
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:44
msgctxt "@info:tooltip"
msgid "Print via USB"
msgstr "Imprimir mediante USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:69
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:80
msgctxt "@info:status"
msgid "Connected via USB"
msgstr "Conectado mediante USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:92
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:105
msgctxt "@label"
msgid "A USB print is in progress, closing Cura will stop this print. Are you sure?"
msgstr "Se está realizando una impresión con USB, si cierra Cura detendrá la impresión. ¿Desea continuar?"
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/install/X3GWriter/__init__.py:15
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/__init__.py:15
-msgctxt "X3G Writer File Description"
-msgid "X3G File"
-msgstr "Archivo X3G"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid "A print is still in progress. Cura cannot start another print via USB until the previous print has completed."
+msgstr "Todavía hay una impresión en curso. Cura no puede iniciar otra impresión a través de USB hasta que se haya completado la impresión anterior."
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:16
-msgctxt "X3g Writer Plugin Description"
-msgid "Writes X3g to files"
-msgstr "Escribe X3g en archivos"
-
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:21
-msgctxt "X3g Writer File Description"
-msgid "X3g File"
-msgstr "Archivo X3g"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid "Print in Progress"
+msgstr "Impresión en curso"
#: /home/ruben/Projects/Cura/plugins/GCodeGzWriter/__init__.py:17
#: /home/ruben/Projects/Cura/plugins/GCodeGzReader/__init__.py:17
@@ -139,6 +127,7 @@ msgid "GCodeGzWriter does not support text mode."
msgstr "GCodeGzWriter no es compatible con el modo texto."
#: /home/ruben/Projects/Cura/plugins/UFPWriter/__init__.py:28
+#: /home/ruben/Projects/Cura/plugins/UFPReader/__init__.py:22
msgctxt "@item:inlistbox"
msgid "Ultimaker Format Package"
msgstr "Paquete de formato Ultimaker"
@@ -160,7 +149,7 @@ msgid "Save to Removable Drive {0}"
msgstr "Guardar en unidad extraíble {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:64
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:133
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py:107
msgctxt "@info:status"
msgid "There are no file formats available to write with!"
msgstr "¡No hay formatos de archivo disponibles con los que escribir!"
@@ -197,9 +186,9 @@ msgid "Could not save to removable drive {0}: {1}"
msgstr "No se pudo guardar en unidad extraíble {0}: {1}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:137
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:133
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:140
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1607
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:139
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:146
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1668
msgctxt "@info:title"
msgid "Error"
msgstr "Error"
@@ -228,8 +217,9 @@ msgstr "Expulsar dispositivo extraíble {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:151
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:163
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1597
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1695
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1658
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1758
msgctxt "@info:title"
msgid "Warning"
msgstr "Advertencia"
@@ -256,232 +246,164 @@ msgctxt "@item:intext"
msgid "Removable Drive"
msgstr "Unidad extraíble"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:73
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:88
-msgctxt "@action:button Preceded by 'Ready to'."
-msgid "Print over network"
-msgstr "Imprimir a través de la red"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:74
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:89
-msgctxt "@properties:tooltip"
-msgid "Print over network"
-msgstr "Imprime a través de la red"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:87
-msgctxt "@info:status"
-msgid "Connected over the network."
-msgstr "Conectado a través de la red."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:90
-msgctxt "@info:status"
-msgid "Connected over the network. Please approve the access request on the printer."
-msgstr "Conectado a través de la red. Apruebe la solicitud de acceso en la impresora."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:92
-msgctxt "@info:status"
-msgid "Connected over the network. No access to control the printer."
-msgstr "Conectado a través de la red. No hay acceso para controlar la impresora."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:97
-msgctxt "@info:status"
-msgid "Access to the printer requested. Please approve the request on the printer"
-msgstr "Acceso a la impresora solicitado. Apruebe la solicitud en la impresora"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:100
-msgctxt "@info:title"
-msgid "Authentication status"
-msgstr "Estado de la autenticación"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:102
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:108
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:112
-msgctxt "@info:title"
-msgid "Authentication Status"
-msgstr "Estado de la autenticación"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:103
-msgctxt "@action:button"
-msgid "Retry"
-msgstr "Volver a intentar"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:104
-msgctxt "@info:tooltip"
-msgid "Re-send the access request"
-msgstr "Reenvía la solicitud de acceso"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:107
-msgctxt "@info:status"
-msgid "Access to the printer accepted"
-msgstr "Acceso a la impresora aceptado"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:111
-msgctxt "@info:status"
-msgid "No access to print with this printer. Unable to send print job."
-msgstr "No hay acceso para imprimir con esta impresora. No se puede enviar el trabajo de impresión."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:113
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:33
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:70
-msgctxt "@action:button"
-msgid "Request Access"
-msgstr "Solicitar acceso"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:115
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:34
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:71
-msgctxt "@info:tooltip"
-msgid "Send access request to the printer"
-msgstr "Envía la solicitud de acceso a la impresora"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:200
-msgctxt "@label"
-msgid "Unable to start a new print job."
-msgstr "No se puede iniciar un nuevo trabajo de impresión."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:202
-msgctxt "@label"
-msgid "There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. Please resolve this issues before continuing."
-msgstr "Un problema con la configuración de Ultimaker impide iniciar la impresión. Soluciónelo antes de continuar."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:208
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:230
-msgctxt "@window:title"
-msgid "Mismatched configuration"
-msgstr "Configuración desajustada"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:222
-msgctxt "@label"
-msgid "Are you sure you wish to print with the selected configuration?"
-msgstr "¿Seguro que desea imprimir con la configuración seleccionada?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:224
-msgctxt "@label"
-msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "La configuración o calibración de la impresora y de Cura no coinciden. Para obtener el mejor resultado, segmente siempre los PrintCores y los materiales que se insertan en la impresora."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:251
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:199
-msgctxt "@info:status"
-msgid "Sending new jobs (temporarily) blocked, still sending the previous print job."
-msgstr "Envío de nuevos trabajos (temporalmente) bloqueado; se sigue enviando el trabajo de impresión previo."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:258
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:218
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:234
-msgctxt "@info:status"
-msgid "Sending data to printer"
-msgstr "Enviando datos a la impresora"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:259
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:219
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:235
-msgctxt "@info:title"
-msgid "Sending Data"
-msgstr "Enviando datos"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:260
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:236
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:80
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:381
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:20
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:143
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:391
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:87
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:279
-msgctxt "@action:button"
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:323
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No Printcore loaded in slot {slot_number}"
-msgstr "No se ha cargado ningún PrintCore en la ranura {slot_number}."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:329
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No material loaded in slot {slot_number}"
-msgstr "No se ha cargado ningún material en la ranura {slot_number}."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:352
-#, python-brace-format
-msgctxt "@label"
-msgid "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}"
-msgstr "PrintCore distinto (Cura: {cura_printcore_name}, impresora: {remote_printcore_name}) seleccionado para extrusor {extruder_id}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:361
-#, python-brace-format
-msgctxt "@label"
-msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
-msgstr "Material distinto (Cura: {0}, impresora: {1}) seleccionado para extrusor {2}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:547
-msgctxt "@window:title"
-msgid "Sync with your printer"
-msgstr "Sincronizar con la impresora"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:549
-msgctxt "@label"
-msgid "Would you like to use your current printer configuration in Cura?"
-msgstr "¿Desea utilizar la configuración actual de su impresora en Cura?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:551
-msgctxt "@label"
-msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "Los PrintCores o los materiales de la impresora difieren de los del proyecto actual. Para obtener el mejor resultado, segmente siempre los PrintCores y materiales que se hayan insertado en la impresora."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:91
-msgctxt "@info:status"
-msgid "Connected over the network"
-msgstr "Conectado a través de la red"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:303
-msgctxt "@info:status"
-msgid "Print job was successfully sent to the printer."
-msgstr "El trabajo de impresión se ha enviado correctamente a la impresora."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:305
-msgctxt "@info:title"
-msgid "Data Sent"
-msgstr "Fecha de envío"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:306
-msgctxt "@action:button"
-msgid "View in Monitor"
-msgstr "Ver en pantalla"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:422
-#, python-brace-format
-msgctxt "@info:status"
-msgid "Printer '{printer_name}' has finished printing '{job_name}'."
-msgstr "{printer_name} ha terminado de imprimir «{job_name}»."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:424
-#, python-brace-format
-msgctxt "@info:status"
-msgid "The print job '{job_name}' was finished."
-msgstr "El trabajo de impresión '{job_name}' ha terminado."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:425
-msgctxt "@info:status"
-msgid "Print finished"
-msgstr "Impresión terminada"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py:26
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py:26
msgctxt "@action"
msgid "Connect via Network"
msgstr "Conectar a través de la red"
-#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:13
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:57
+msgctxt "@action:button Preceded by 'Ready to'."
+msgid "Print over network"
+msgstr "Imprimir a través de la red"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:58
+msgctxt "@properties:tooltip"
+msgid "Print over network"
+msgstr "Imprime a través de la red"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:59
+msgctxt "@info:status"
+msgid "Connected over the network"
+msgstr "Conectado a través de la red"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:15
+msgctxt "@info:status"
+msgid "Please wait until the current job has been sent."
+msgstr "Espere hasta que se envíe el trabajo actual."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:16
+msgctxt "@info:title"
+msgid "Print error"
+msgstr "Error de impresión"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:21
+msgctxt "@info:title"
+msgid "New cloud printers found"
+msgstr "Se han encontrado nuevas impresoras en la nube"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:22
+msgctxt "@info:message"
+msgid "New printers have been found connected to your account, you can find them in your list of discovered printers."
+msgstr "Se han encontrado nuevas impresoras conectadas a tu cuenta; puedes verlas en la lista de impresoras descubiertas."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:27
+msgctxt "@info:option_text"
+msgid "Do not show this message again"
+msgstr "No volver a mostrar este mensaje"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:27
+#, python-brace-format
+msgctxt "@info:status"
+msgid "You are attempting to connect to {0} but it is not the host of a group. You can visit the web page to configure it as a group host."
+msgstr "Está intentando conectarse a {0} pero ese no es el host de un grupo. Puede visitar la página web para configurarlo como host de grupo."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:30
+msgctxt "@info:title"
+msgid "Not a group host"
+msgstr "No es un host de grupo"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:35
+msgctxt "@action"
+msgid "Configure group"
+msgstr "Configurar grupo"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:27
+msgctxt "@info:status"
+msgid "Send and monitor print jobs from anywhere using your Ultimaker account."
+msgstr "Envíe y supervise sus trabajos de impresión desde cualquier lugar a través de su cuenta de Ultimaker."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:33
+msgctxt "@info:status Ultimaker Cloud should not be translated."
+msgid "Connect to Ultimaker Cloud"
+msgstr "Conectar a Ultimaker Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:36
+msgctxt "@action"
+msgid "Get started"
+msgstr "Empezar"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:14
+msgctxt "@info:status"
+msgid "Sending Print Job"
+msgstr "Enviando trabajo de impresión"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:15
+msgctxt "@info:status"
+msgid "Uploading print job to printer."
+msgstr "Cargando el trabajo de impresión a la impresora."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:15
+msgctxt "@info:status"
+msgid "Print job was successfully sent to the printer."
+msgstr "El trabajo de impresión se ha enviado correctamente a la impresora."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:16
+msgctxt "@info:title"
+msgid "Data Sent"
+msgstr "Fecha de envío"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:18
+msgctxt "@info:status"
+msgid "You are attempting to connect to a printer that is not running Ultimaker Connect. Please update the printer to the latest firmware."
+msgstr "Está intentando conectarse a una impresora que no está ejecutando Ultimaker Connect. Actualice la impresora al firmware más reciente."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:21
+msgctxt "@info:title"
+msgid "Update your printer"
+msgstr "Actualice su impresora"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:24
+#, python-brace-format
+msgctxt "@info:status"
+msgid "Cura has detected material profiles that were not yet installed on the host printer of group {0}."
+msgstr "Cura ha detectado perfiles de material que aún no estaban instalados en la impresora host del grupo {0}."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:26
+msgctxt "@info:title"
+msgid "Sending materials to printer"
+msgstr "Enviando materiales a la impresora"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:15
+msgctxt "@info:text"
+msgid "Could not upload the data to the printer."
+msgstr "No se han podido cargar los datos en la impresora."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:16
+msgctxt "@info:title"
+msgid "Network error"
+msgstr "Error de red"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:27
+msgctxt "@info:status"
+msgid "tomorrow"
+msgstr "mañana"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:30
+msgctxt "@info:status"
+msgid "today"
+msgstr "hoy"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:138
+msgctxt "@action:button"
+msgid "Print via Cloud"
+msgstr "Imprimir mediante Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:139
+msgctxt "@properties:tooltip"
+msgid "Print via Cloud"
+msgstr "Imprimir mediante Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:140
+msgctxt "@info:status"
+msgid "Connected via Cloud"
+msgstr "Conectado mediante Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:14
msgctxt "@item:inmenu"
msgid "Monitor"
msgstr "Supervisar"
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:119
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:125
msgctxt "@info"
msgid "Could not access update information."
msgstr "No se pudo acceder a la información actualizada."
@@ -503,22 +425,28 @@ msgctxt "@action:button"
msgid "How to update"
msgstr "Cómo actualizar"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:14
+#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:15
msgctxt "@item:inlistbox"
msgid "Layer view"
msgstr "Vista de capas"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:113
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:117
msgctxt "@info:status"
msgid "Cura does not accurately display layers when Wire Printing is enabled"
msgstr "Cura no muestra correctamente las capas si la impresión de alambre está habilitada"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:114
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:118
msgctxt "@info:title"
msgid "Simulation View"
msgstr "Vista de simulación"
#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:35
+msgctxt "@item:inmenu"
+msgid "Post Processing"
+msgstr "Posprocesamiento"
+
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:36
+msgctxt "@item:inmenu"
msgid "Modify G-Code"
msgstr "Modificar GCode"
@@ -532,36 +460,6 @@ msgctxt "@info:tooltip"
msgid "Create a volume in which supports are not printed."
msgstr "Cree un volumen que no imprima los soportes."
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:52
-msgctxt "@info"
-msgid "Cura collects anonymized usage statistics."
-msgstr "Cura recopila estadísticas de uso de forma anónima."
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:55
-msgctxt "@info:title"
-msgid "Collecting Data"
-msgstr "Recopilando datos"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:57
-msgctxt "@action:button"
-msgid "More info"
-msgstr "Más información"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:58
-msgctxt "@action:tooltip"
-msgid "See more information on what data Cura sends."
-msgstr "Obtenga más información sobre qué datos envía Cura."
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:60
-msgctxt "@action:button"
-msgid "Allow"
-msgstr "Permitir"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:61
-msgctxt "@action:tooltip"
-msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
-msgstr "Permitir a Cura enviar estadísticas de uso de forma anónima para ayudar a priorizar mejoras futuras para Cura. Se envían algunas de sus preferencias y ajustes, la versión de Cura y un resumen de los modelos que está fragmentando."
-
#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
msgid "Cura 15.04 profiles"
@@ -592,56 +490,86 @@ msgctxt "@item:inlistbox"
msgid "GIF Image"
msgstr "Imagen GIF"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:15
+msgctxt "@item:inlistbox 'Open' is part of the name of this file format."
+msgid "Open Compressed Triangle Mesh"
+msgstr "Open Compressed Triangle Mesh"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:19
+msgctxt "@item:inlistbox"
+msgid "COLLADA Digital Asset Exchange"
+msgstr "COLLADA Digital Asset Exchange"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:23
+msgctxt "@item:inlistbox"
+msgid "glTF Binary"
+msgstr "glTF binario"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:27
+msgctxt "@item:inlistbox"
+msgid "glTF Embedded JSON"
+msgstr "glTF incrustado JSON"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:36
+msgctxt "@item:inlistbox"
+msgid "Stanford Triangle Format"
+msgstr "Stanford Triangle Format"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:40
+msgctxt "@item:inlistbox"
+msgid "Compressed COLLADA Digital Asset Exchange"
+msgstr "COLLADA Digital Asset Exchange comprimido"
+
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
msgctxt "@info:status"
msgid "Unable to slice with the current material as it is incompatible with the selected machine or configuration."
msgstr "No se puede segmentar con el material actual, ya que es incompatible con el dispositivo o la configuración seleccionados."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:363
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:387
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:396
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:405
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:414
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
msgctxt "@info:title"
msgid "Unable to slice"
msgstr "No se puede segmentar"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:361
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice with the current settings. The following settings have errors: {0}"
msgstr "Los ajustes actuales no permiten la segmentación. Los siguientes ajustes contienen errores: {0}"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:385
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice due to some per-model settings. The following settings have errors on one or more models: {error_labels}"
msgstr "Los ajustes de algunos modelos no permiten la segmentación. Los siguientes ajustes contienen errores en uno o más modelos: {error_labels}."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:394
msgctxt "@info:status"
msgid "Unable to slice because the prime tower or prime position(s) are invalid."
msgstr "No se puede segmentar porque la torre auxiliar o la posición o posiciones de preparación no son válidas."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:403
#, python-format
msgctxt "@info:status"
msgid "Unable to slice because there are objects associated with disabled Extruder %s."
msgstr "No se puede segmentar porque hay objetos asociados al extrusor %s que está deshabilitado."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:412
msgctxt "@info:status"
-msgid "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."
-msgstr "No hay nada que segmentar porque ninguno de los modelos se adapta al volumen de impresión. Escale o rote los modelos para que se adapten."
+msgid "Nothing to slice because none of the models fit the build volume or are assigned to a disabled extruder. Please scale or rotate models to fit, or enable an extruder."
+msgstr "No hay nada que segmentar porque ninguno de los modelos se adapta al volumen de impresión o los modelos están asignados a un extrusor deshabilitado. Escale o rote los modelos para que se adapten o habilite un extrusor."
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:50
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:status"
msgid "Processing Layers"
msgstr "Procesando capas"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:title"
msgid "Information"
msgstr "Información"
@@ -656,14 +584,12 @@ msgctxt "@info:tooltip"
msgid "Configure Per Model Settings"
msgstr "Configurar ajustes por modelo"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:175
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:575
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:186
msgctxt "@title:tab"
msgid "Recommended"
msgstr "Recomendado"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:177
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:580
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:188
msgctxt "@title:tab"
msgid "Custom"
msgstr "Personalizado"
@@ -674,19 +600,19 @@ msgctxt "@item:inlistbox"
msgid "3MF File"
msgstr "Archivo 3MF"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:190
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:714
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:198
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:651
msgctxt "@label"
msgid "Nozzle"
msgstr "Tobera"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:468
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:496
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Project file {0} contains an unknown machine type {1}. Cannot import the machine. Models will be imported instead."
-msgstr "El archivo del proyecto{0} contiene un tipo de máquina desconocida {1}. No se puede importar la máquina, en su lugar, se importarán los modelos."
+msgstr "El archivo del proyecto {0} contiene un tipo de máquina desconocida {1}. No se puede importar la máquina, en su lugar, se importarán los modelos."
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:471
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:499
msgctxt "@info:title"
msgid "Open Project File"
msgstr "Abrir archivo de proyecto"
@@ -701,22 +627,65 @@ msgctxt "@item:inlistbox"
msgid "G File"
msgstr "Archivo G"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:324
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:335
msgctxt "@info:status"
msgid "Parsing G-code"
msgstr "Analizar GCode"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:326
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:474
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:337
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:491
msgctxt "@info:title"
msgid "G-code Details"
msgstr "Datos de GCode"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:472
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:489
msgctxt "@info:generic"
msgid "Make sure the g-code is suitable for your printer and printer configuration before sending the file to it. The g-code representation may not be accurate."
msgstr "Asegúrese de que el GCode es adecuado para la impresora y para su configuración antes de enviar el archivo a la misma. Es posible que la representación del GCode no sea precisa."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:64
+msgctxt "@item:inmenu"
+msgid "Manage backups"
+msgstr "Administrar copias de seguridad"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:107
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:113
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:104
+msgctxt "@info:title"
+msgid "Backup"
+msgstr "Copia de seguridad"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+msgctxt "@info:backup_status"
+msgid "There was an error listing your backups."
+msgstr "Se ha producido un error al obtener sus copias de seguridad."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:132
+msgctxt "@info:backup_status"
+msgid "There was an error trying to restore your backup."
+msgstr "Se ha producido un error al intentar restaurar su copia de seguridad."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:15
+msgctxt "@info:title"
+msgid "Backups"
+msgstr "Copias de seguridad"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:27
+msgctxt "@info:backup_status"
+msgid "Uploading your backup..."
+msgstr "Cargando su copia de seguridad..."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:36
+msgctxt "@info:backup_status"
+msgid "There was an error while uploading your backup."
+msgstr "Se ha producido un error al cargar su copia de seguridad."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:39
+msgctxt "@info:backup_status"
+msgid "Your backup has finished uploading."
+msgstr "Su copia de seguridad ha terminado de cargarse."
+
#: /home/ruben/Projects/Cura/plugins/CuraProfileWriter/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
@@ -738,330 +707,453 @@ msgctxt "@error:zip"
msgid "Error writing 3mf file."
msgstr "Error al escribir el archivo 3MF."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelection.py:17
+#: /home/ruben/Projects/Cura/plugins/PreviewStage/__init__.py:13
+msgctxt "@item:inmenu"
+msgid "Preview"
+msgstr "Vista previa"
+
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelection.py:18
msgctxt "@action"
msgid "Select upgrades"
msgstr "Seleccionar actualizaciones"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py:14
-msgctxt "@action"
-msgid "Checkup"
-msgstr "Comprobación"
-
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.py:21
msgctxt "@action"
msgid "Level build plate"
msgstr "Nivelar placa de impresión"
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:82
-msgctxt "@tooltip"
-msgid "Outer Wall"
-msgstr "Pared exterior"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:83
-msgctxt "@tooltip"
-msgid "Inner Walls"
-msgstr "Paredes interiores"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:84
-msgctxt "@tooltip"
-msgid "Skin"
-msgstr "Forro"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:85
-msgctxt "@tooltip"
-msgid "Infill"
-msgstr "Relleno"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:86
-msgctxt "@tooltip"
-msgid "Support Infill"
-msgstr "Relleno de soporte"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:87
-msgctxt "@tooltip"
-msgid "Support Interface"
-msgstr "Interfaz de soporte"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:88
-msgctxt "@tooltip"
-msgid "Support"
-msgstr "Soporte"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:89
-msgctxt "@tooltip"
-msgid "Skirt"
-msgstr "Falda"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:90
-msgctxt "@tooltip"
-msgid "Travel"
-msgstr "Desplazamiento"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:91
-msgctxt "@tooltip"
-msgid "Retractions"
-msgstr "Retracciones"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:92
-msgctxt "@tooltip"
-msgid "Other"
-msgstr "Otro"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:310
-#, python-brace-format
-msgctxt "@label"
-msgid "Pre-sliced file {0}"
-msgstr "Archivo {0} presegmentado"
-
-#: /home/ruben/Projects/Cura/cura/API/Account.py:71
+#: /home/ruben/Projects/Cura/cura/API/Account.py:82
msgctxt "@info:title"
msgid "Login failed"
msgstr "Fallo de inicio de sesión"
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:201
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:121
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:36
+msgctxt "@info:not supported profile"
+msgid "Not supported"
+msgstr "No compatible"
+
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:55
+msgctxt "@info:No intent profile selected"
+msgid "Default"
+msgstr "Default"
+
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:196
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:125
msgctxt "@title:window"
msgid "File Already Exists"
msgstr "El archivo ya existe"
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:202
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:122
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:197
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:126
#, python-brace-format
msgctxt "@label Don't translate the XML tag !"
msgid "The file {0} already exists. Are you sure you want to overwrite it?"
msgstr "El archivo {0} ya existe. ¿Está seguro de que desea sobrescribirlo?"
-#: /home/ruben/Projects/Cura/cura/Settings/ExtrudersModel.py:212
-msgctxt "@menuitem"
-msgid "Not overridden"
-msgstr "No reemplazado"
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:117
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:430
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:433
msgctxt "@info:status"
-msgid "The selected material is incompatible with the selected machine or configuration."
-msgstr "El material seleccionado no es compatible con la máquina o la configuración seleccionada."
+msgid "Invalid file URL:"
+msgstr "URL del archivo no válida:"
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:118
-msgctxt "@info:title"
-msgid "Incompatible Material"
-msgstr "Material incompatible"
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:780
+msgctxt "@info:message Followed by a list of settings."
+msgid "Settings have been changed to match the current availability of extruders:"
+msgstr "La configuración se ha cambiado para que coincida con los extrusores disponibles en este momento:"
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:866
-#, python-format
-msgctxt "@info:generic"
-msgid "Settings have been changed to match the current availability of extruders: [%s]"
-msgstr "La configuración se ha cambiado para que coincida con los extrusores disponibles en este momento: [%s]."
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:868
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:782
msgctxt "@info:title"
msgid "Settings updated"
msgstr "Ajustes actualizados"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:131
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1334
+msgctxt "@info:title"
+msgid "Extruder(s) Disabled"
+msgstr "Extrusores deshabilitados"
+
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1457
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:99
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:86
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:182
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:223
+msgctxt "@label"
+msgid "Unknown"
+msgstr "Desconocido"
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:137
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Failed to export profile to {0}: {1}"
msgstr "Error al exportar el perfil a {0}: {1}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:138
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid "Failed to export profile to {0}: Writer plugin reported failure."
msgstr "Error al exportar el perfil a {0}: Error en el complemento de escritura."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:143
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:149
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid "Exported profile to {0}"
msgstr "Perfil exportado a {0}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:150
msgctxt "@info:title"
msgid "Export succeeded"
msgstr "Exportación correcta"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:170
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:177
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
-msgid "Failed to import profile from {0}: {1}"
-msgstr "Error al importar el perfil de {0}: {1}"
+msgctxt "@info:status Don't translate the XML tags !"
+msgid "Failed to import profile from {0}: {1}"
+msgstr "Error al importar el perfil de {0}: {1}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:190
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:181
+#, python-brace-format
+msgctxt "@info:status Don't translate the XML tags !"
+msgid "Can't import profile from {0} before a printer is added."
+msgstr "No se puede importar el perfil de {0} antes de añadir una impresora."
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:198
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "No custom profile to import in file {0}"
-msgstr "No hay ningún perfil personalizado para importar en el archivo {0}."
+msgstr "No hay ningún perfil personalizado para importar en el archivo {0}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:194
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:202
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "Failed to import profile from {0}:"
msgstr "Error al importar el perfil de {0}:"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:218
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:228
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:226
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:236
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "This profile {0} contains incorrect data, could not import it."
msgstr "Este perfil {0} contiene datos incorrectos, no se han podido importar."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:241
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:325
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags !"
-msgid "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it."
-msgstr "El equipo definido en el perfil {0} ({1}) no coincide con el equipo actual ({2}), no se ha podido importar."
-
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:312
-#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
+msgctxt "@info:status Don't translate the XML tag !"
msgid "Failed to import profile from {0}:"
msgstr "Error al importar el perfil de {0}:"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:315
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:328
#, python-brace-format
msgctxt "@info:status"
msgid "Successfully imported profile {0}"
msgstr "Perfil {0} importado correctamente"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:318
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:331
#, python-brace-format
msgctxt "@info:status"
msgid "File {0} does not contain any valid profile."
msgstr "El archivo {0} no contiene ningún perfil válido."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:321
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:334
#, python-brace-format
msgctxt "@info:status"
msgid "Profile {0} has an unknown file type or is corrupted."
msgstr "El perfil {0} tiene un tipo de archivo desconocido o está corrupto."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:339
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
msgctxt "@label"
msgid "Custom profile"
msgstr "Perfil personalizado"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:355
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:385
msgctxt "@info:status"
msgid "Profile is missing a quality type."
msgstr "Al perfil le falta un tipo de calidad."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:399
#, python-brace-format
msgctxt "@info:status"
msgid "Could not find a quality type {0} for the current configuration."
msgstr "No se ha podido encontrar un tipo de calidad {0} para la configuración actual."
-#: /home/ruben/Projects/Cura/cura/ObjectsModel.py:63
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:76
+msgctxt "@tooltip"
+msgid "Outer Wall"
+msgstr "Pared exterior"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:77
+msgctxt "@tooltip"
+msgid "Inner Walls"
+msgstr "Paredes interiores"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:78
+msgctxt "@tooltip"
+msgid "Skin"
+msgstr "Forro"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:79
+msgctxt "@tooltip"
+msgid "Infill"
+msgstr "Relleno"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:80
+msgctxt "@tooltip"
+msgid "Support Infill"
+msgstr "Relleno de soporte"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:81
+msgctxt "@tooltip"
+msgid "Support Interface"
+msgstr "Interfaz de soporte"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:82
+msgctxt "@tooltip"
+msgid "Support"
+msgstr "Soporte"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:83
+msgctxt "@tooltip"
+msgid "Skirt"
+msgstr "Falda"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:84
+msgctxt "@tooltip"
+msgid "Prime Tower"
+msgstr "Torre auxiliar"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:85
+msgctxt "@tooltip"
+msgid "Travel"
+msgstr "Desplazamiento"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:86
+msgctxt "@tooltip"
+msgid "Retractions"
+msgstr "Retracciones"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:87
+msgctxt "@tooltip"
+msgid "Other"
+msgstr "Otro"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:302
+#, python-brace-format
+msgctxt "@label"
+msgid "Pre-sliced file {0}"
+msgstr "Archivo {0} presegmentado"
+
+#: /home/ruben/Projects/Cura/cura/UI/WelcomePagesModel.py:56
+msgctxt "@action:button"
+msgid "Next"
+msgstr "Siguiente"
+
+#: /home/ruben/Projects/Cura/cura/UI/ObjectsModel.py:62
#, python-brace-format
msgctxt "@label"
msgid "Group #{group_nr}"
msgstr "N.º de grupo {group_nr}"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:65
-msgctxt "@info:title"
-msgid "Network enabled printers"
-msgstr "Impresoras de red habilitadas"
+#: /home/ruben/Projects/Cura/cura/UI/WhatsNewPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:482
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:124
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:169
+msgctxt "@action:button"
+msgid "Close"
+msgstr "Cerrar"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:80
-msgctxt "@info:title"
-msgid "Local printers"
-msgstr "Impresoras locales"
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
+msgctxt "@action:button"
+msgid "Add"
+msgstr "Agregar"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:109
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:18
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:81
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:352
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:58
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:149
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:406
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:294
+msgctxt "@action:button"
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:36
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:320
+msgctxt "@label"
+msgid "Default"
+msgstr "Default"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:39
+msgctxt "@label"
+msgid "Visual"
+msgstr "Visual"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:40
+msgctxt "@text"
+msgid "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality."
+msgstr "El perfil visual está diseñado para imprimir prototipos y modelos visuales con la intención de obtener una alta calidad visual y de superficies."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:43
+msgctxt "@label"
+msgid "Engineering"
+msgstr "Engineering"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:44
+msgctxt "@text"
+msgid "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances."
+msgstr "El perfil de ingeniería ha sido diseñado para imprimir prototipos funcionales y piezas de uso final con la intención de obtener una mayor precisión y tolerancias"
+" más precisas."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:47
+msgctxt "@label"
+msgid "Draft"
+msgstr "Boceto"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:48
+msgctxt "@text"
+msgid "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction."
+msgstr "El perfil del boceto ha sido diseñado para imprimir los prototipos iniciales y la validación del concepto con la intención de reducir el tiempo de impresión"
+" de manera considerable."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/ExtrudersModel.py:208
+msgctxt "@menuitem"
+msgid "Not overridden"
+msgstr "No reemplazado"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:357
+msgctxt "@label"
+msgid "Custom profiles"
+msgstr "Perfiles personalizados"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:391
#, python-brace-format
msgctxt "@item:inlistbox"
msgid "All Supported Types ({0})"
msgstr "Todos los tipos compatibles ({0})"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:110
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:392
msgctxt "@item:inlistbox"
msgid "All Files (*)"
msgstr "Todos los archivos (*)"
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:636
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:213
msgctxt "@label"
msgid "Custom Material"
msgstr "Material personalizado"
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:637
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:214
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:205
msgctxt "@label"
msgid "Custom"
msgstr "Personalizado"
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:81
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:116
+msgctxt "@label"
+msgid "The printer(s) below cannot be connected because they are part of a group"
+msgstr "Las siguientes impresoras no pueden conectarse porque forman parte de un grupo"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:118
+msgctxt "@label"
+msgid "Available networked printers"
+msgstr "Impresoras en red disponibles"
+
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:90
msgctxt "@info:status"
msgid "The build volume height has been reduced due to the value of the \"Print Sequence\" setting to prevent the gantry from colliding with printed models."
msgstr "La altura del volumen de impresión se ha reducido debido al valor del ajuste «Secuencia de impresión» para evitar que el caballete colisione con los modelos impresos."
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:83
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:92
msgctxt "@info:title"
msgid "Build Volume"
msgstr "Volumen de impresión"
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:98
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:99
msgctxt "@info:backup_failed"
msgid "Could not create archive from user data directory: {}"
msgstr "No se ha podido crear el archivo desde el directorio de datos de usuario: {}"
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:103
-msgctxt "@info:title"
-msgid "Backup"
-msgstr "Copia de seguridad"
-
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:113
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:114
msgctxt "@info:backup_failed"
msgid "Tried to restore a Cura backup without having proper data or meta data."
msgstr "Se ha intentado restaurar una copia de seguridad de Cura sin tener los datos o metadatos adecuados."
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:123
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:125
msgctxt "@info:backup_failed"
-msgid "Tried to restore a Cura backup that does not match your current version."
-msgstr "Se ha intentado restaurar una copia de seguridad de Cura que no coincide con la versión actual."
+msgid "Tried to restore a Cura backup that is higher than the current version."
+msgstr "Se ha intentado restaurar una copia de seguridad de Cura superior a la versión actual."
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:27
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationHelpers.py:79
+msgctxt "@message"
+msgid "Could not read response."
+msgstr "No se ha podido leer la respuesta."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+msgctxt "@info"
+msgid "Unable to reach the Ultimaker account server."
+msgstr "No se puede acceder al servidor de cuentas de Ultimaker."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:70
+msgctxt "@message"
+msgid "Please give the required permissions when authorizing this application."
+msgstr "Conceda los permisos necesarios al autorizar esta aplicación."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:77
+msgctxt "@message"
+msgid "Something unexpected happened when trying to log in, please try again."
+msgstr "Se ha producido un problema al intentar iniciar sesión, vuelva a intentarlo."
+
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:29
msgctxt "@info:status"
msgid "Multiplying and placing objects"
msgstr "Multiplicar y colocar objetos"
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:28
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:30
msgctxt "@info:title"
-msgid "Placing Object"
-msgstr "Colocando objeto"
+msgid "Placing Objects"
+msgstr "Colocando objetos"
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:96
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:103
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:149
msgctxt "@info:status"
msgid "Unable to find a location within the build volume for all objects"
msgstr "No se puede encontrar una ubicación dentro del volumen de impresión para todos los objetos"
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+msgctxt "@info:title"
+msgid "Placing Object"
+msgstr "Colocando objeto"
+
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:30
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:67
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:66
msgctxt "@info:status"
msgid "Finding new location for objects"
msgstr "Buscando nueva ubicación para los objetos"
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:34
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:71
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:70
msgctxt "@info:title"
msgid "Finding Location"
msgstr "Buscando ubicación"
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:97
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:151
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:104
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
msgctxt "@info:title"
msgid "Can't Find Location"
msgstr "No se puede encontrar la ubicación"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:87
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:83
msgctxt "@title:window"
msgid "Cura can't start"
msgstr "Cura no puede iniciarse"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:93
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:89
msgctxt "@label crash message"
msgid ""
"
Oops, Ultimaker Cura has encountered something that doesn't seem right.
\n"
@@ -1069,356 +1161,328 @@ msgid ""
"
Backups can be found in the configuration folder.
\n"
"
Please send us this Crash Report to fix the problem.
\n"
" "
-msgstr "
¡Vaya! Ultimaker Cura ha encontrado un error.
\n
Hemos detectado un error irreversible durante el inicio, posiblemente como consecuencia de varios archivos de configuración erróneos. Le recomendamos que realice una copia de seguridad y que restablezca los ajustes.
\n
Las copias de seguridad se encuentran en la carpeta de configuración.
\n
Envíenos el informe de errores para que podamos solucionar el problema.
\n "
+msgstr ""
+"
¡Vaya! Ultimaker Cura ha encontrado un error.
\n"
+"
Hemos detectado un error irreversible durante el inicio, posiblemente como consecuencia de varios archivos de configuración erróneos. Le recomendamos que realice una copia de seguridad y que restablezca los ajustes.
\n"
+"
Las copias de seguridad se encuentran en la carpeta de configuración.
\n"
+"
Envíenos el informe de errores para que podamos solucionar el problema.
"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:222
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:218
msgctxt "@title:groupbox"
msgid "Error traceback"
msgstr "Rastreabilidad de errores"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:303
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:299
msgctxt "@title:groupbox"
msgid "Logs"
msgstr "Registros"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:326
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:322
msgctxt "@title:groupbox"
-msgid "User description"
-msgstr "Descripción del usuario"
+msgid "User description (Note: Developers may not speak your language, please use English if possible)"
+msgstr "Descripción del usuario (Nota: es posible que los desarrolladores no hablen su idioma; si es posible, utilice el inglés)"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:345
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:342
msgctxt "@action:button"
msgid "Send report"
msgstr "Enviar informe"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:473
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:513
msgctxt "@info:progress"
msgid "Loading machines..."
msgstr "Cargando máquinas..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:775
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:520
+msgctxt "@info:progress"
+msgid "Setting up preferences..."
+msgstr "Configurando preferencias...."
+
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:824
msgctxt "@info:progress"
msgid "Setting up scene..."
msgstr "Configurando escena..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:811
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:859
msgctxt "@info:progress"
msgid "Loading interface..."
msgstr "Cargando interfaz..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1037
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1150
#, python-format
msgctxt "@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm."
msgid "%(width).1f x %(depth).1f x %(height).1f mm"
msgstr "%(width).1f x %(depth).1f x %(height).1f mm"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1596
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1657
#, python-brace-format
msgctxt "@info:status"
msgid "Only one G-code file can be loaded at a time. Skipped importing {0}"
msgstr "Solo se puede cargar un archivo GCode a la vez. Se omitió la importación de {0}"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1606
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1667
#, python-brace-format
msgctxt "@info:status"
msgid "Can't open any other file if G-code is loading. Skipped importing {0}"
msgstr "No se puede abrir ningún archivo si se está cargando un archivo GCode. Se omitió la importación de {0}"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1694
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1757
msgctxt "@info:status"
msgid "The selected model was too small to load."
msgstr "No se puede cargar el modelo seleccionado, es demasiado pequeño."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:61
-msgctxt "@title"
-msgid "Machine Settings"
-msgstr "Ajustes de la máquina"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:80
-msgctxt "@title:tab"
-msgid "Printer"
-msgstr "Impresora"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:99
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:56
+msgctxt "@title:label"
msgid "Printer Settings"
msgstr "Ajustes de la impresora"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:110
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:70
msgctxt "@label"
msgid "X (Width)"
msgstr "X (anchura)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:111
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:121
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:131
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:237
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:386
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:402
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:428
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:440
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:896
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:74
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:88
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:102
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:243
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:265
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:285
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:79
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:93
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:109
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:124
msgctxt "@label"
msgid "mm"
msgstr "mm"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:120
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:84
msgctxt "@label"
msgid "Y (Depth)"
msgstr "Y (profundidad)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:130
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:98
msgctxt "@label"
msgid "Z (Height)"
msgstr "Z (altura)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:142
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:112
msgctxt "@label"
msgid "Build plate shape"
msgstr "Forma de la placa de impresión"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:151
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:125
+msgctxt "@label"
msgid "Origin at center"
msgstr "Origen en el centro"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:159
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:137
+msgctxt "@label"
msgid "Heated bed"
-msgstr "Plataforma caliente"
+msgstr "Plataforma calentada"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:170
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:149
+msgctxt "@label"
+msgid "Heated build volume"
+msgstr "Volumen de impresión calentado"
+
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:161
msgctxt "@label"
msgid "G-code flavor"
msgstr "Tipo de GCode"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:183
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:185
+msgctxt "@title:label"
msgid "Printhead Settings"
msgstr "Ajustes del cabezal de impresión"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:193
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:199
msgctxt "@label"
msgid "X min"
msgstr "X mín."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:194
-msgctxt "@tooltip"
-msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distancia desde la parte izquierda del cabezal de impresión hasta el centro de la tobera. Se usa para evitar que colisionen la impresión anterior con el cabezal de impresión al imprimir «de uno en uno»."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:219
msgctxt "@label"
msgid "Y min"
msgstr "Y mín."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:204
-msgctxt "@tooltip"
-msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distancia desde la parte frontal del cabezal de impresión hasta el centro de la tobera. Se usa para evitar que colisionen la impresión anterior con el cabezal de impresión al imprimir «de uno en uno»."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:213
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:239
msgctxt "@label"
msgid "X max"
msgstr "X máx."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:214
-msgctxt "@tooltip"
-msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distancia desde la parte derecha del cabezal de impresión hasta el centro de la tobera. Se usa para evitar que colisionen la impresión anterior con el cabezal de impresión al imprimir «de uno en uno»."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:261
msgctxt "@label"
msgid "Y max"
msgstr "Y máx."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:224
-msgctxt "@tooltip"
-msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distancia desde la parte trasera del cabezal de impresión hasta el centro de la tobera. Se usa para evitar que colisionen la impresión anterior con el cabezal de impresión al imprimir «de uno en uno»."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:236
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:281
msgctxt "@label"
-msgid "Gantry height"
-msgstr "Altura del caballete"
+msgid "Gantry Height"
+msgstr "Altura del puente"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:238
-msgctxt "@tooltip"
-msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
-msgstr "Diferencia de altura entre la punta de la tobera y el sistema del puente (ejes X e Y). Se usa para evitar que colisionen la impresión anterior con el caballete al imprimir «de uno en uno»."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:257
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:295
msgctxt "@label"
msgid "Number of Extruders"
msgstr "Número de extrusores"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:313
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:355
+msgctxt "@title:label"
msgid "Start G-code"
msgstr "Iniciar GCode"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:323
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very start."
-msgstr "Los comandos de GCode que se ejecutarán justo al inicio."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:332
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:366
+msgctxt "@title:label"
msgid "End G-code"
msgstr "Finalizar GCode"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:342
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very end."
-msgstr "Los comandos de GCode que se ejecutarán justo al final."
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:42
+msgctxt "@title:tab"
+msgid "Printer"
+msgstr "Impresora"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:373
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:63
+msgctxt "@title:label"
msgid "Nozzle Settings"
msgstr "Ajustes de la tobera"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:385
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:75
msgctxt "@label"
msgid "Nozzle size"
msgstr "Tamaño de la tobera"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:401
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:89
msgctxt "@label"
msgid "Compatible material diameter"
msgstr "Diámetro del material compatible"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:403
-msgctxt "@tooltip"
-msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
-msgstr "El diámetro nominal del filamento compatible con la impresora. El diámetro exacto se sobrescribirá según el material o el perfil."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:427
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:105
msgctxt "@label"
msgid "Nozzle offset X"
msgstr "Desplazamiento de la tobera sobre el eje X"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:439
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:120
msgctxt "@label"
msgid "Nozzle offset Y"
msgstr "Desplazamiento de la tobera sobre el eje Y"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:451
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:135
msgctxt "@label"
msgid "Cooling Fan Number"
msgstr "Número de ventilador de enfriamiento"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:452
-msgctxt "@label"
-msgid ""
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:472
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:162
+msgctxt "@title:label"
msgid "Extruder Start G-code"
msgstr "GCode inicial del extrusor"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:490
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:176
+msgctxt "@title:label"
msgid "Extruder End G-code"
msgstr "GCode final del extrusor"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
msgctxt "@action:button"
msgid "Install"
msgstr "Instalar"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:20
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
msgctxt "@action:button"
msgid "Installed"
msgstr "Instalado"
@@ -1428,69 +1492,82 @@ msgctxt "@info"
msgid "Could not connect to the Cura Package database. Please check your connection."
msgstr "No se ha podido conectar con la base de datos del Paquete Cura. Compruebe la conexión."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:38
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:28
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/SmallRatingWidget.qml:27
+msgctxt "@label"
+msgid "ratings"
+msgstr "calificaciones"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:30
msgctxt "@title:tab"
msgid "Plugins"
msgstr "Complementos"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:75
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:42
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:66
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:77
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:44
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:89
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:417
msgctxt "@title:tab"
msgid "Materials"
msgstr "Materiales"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:79
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+msgctxt "@label"
+msgid "Your rating"
+msgstr "Su calificación"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:99
msgctxt "@label"
msgid "Version"
msgstr "Versión"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:85
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:106
msgctxt "@label"
msgid "Last updated"
msgstr "Última actualización"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:113
msgctxt "@label"
msgid "Author"
msgstr "Autor"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:120
msgctxt "@label"
msgid "Downloads"
msgstr "Descargas"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:116
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:158
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:258
-msgctxt "@label"
-msgid "Unknown"
-msgstr "Desconocido"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:56
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to install or update"
+msgstr "Inicie sesión para realizar la instalación o la actualización"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:44
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:30
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:80
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Buy material spools"
+msgstr "Comprar bobinas de material"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:96
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:34
msgctxt "@action:button"
msgid "Update"
msgstr "Actualizar"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:45
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:35
msgctxt "@action:button"
msgid "Updating"
msgstr "Actualizando"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:98
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:36
msgctxt "@action:button"
msgid "Updated"
msgstr "Actualizado"
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/Toolbox.qml:13
msgctxt "@title"
-msgid "Toolbox"
-msgstr "Cuadro de herramientas"
+msgid "Marketplace"
+msgstr "Marketplace"
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml:25
msgctxt "@action:button"
@@ -1517,52 +1594,67 @@ msgctxt "@text:window"
msgid "Profiles"
msgstr "Perfiles"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:89
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:90
msgctxt "@action:button"
msgid "Confirm"
msgstr "Confirmar"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to login first before you can rate"
+msgstr "Debe iniciar sesión antes de enviar sus calificaciones"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to install the package before you can rate"
+msgstr "Debe instalar el paquete antes de enviar sus calificaciones"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:19
msgctxt "@info"
msgid "You will need to restart Cura before changes in packages have effect."
msgstr "Tendrá que reiniciar Cura para que los cambios de los paquetes surtan efecto."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:45
msgctxt "@info:button"
msgid "Quit Cura"
msgstr "Salir de Cura"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Contributions"
msgstr "Contribuciones de la comunidad"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Plugins"
msgstr "Complementos de la comunidad"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:43
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:40
msgctxt "@label"
msgid "Generic Materials"
msgstr "Materiales genéricos"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:56
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:59
msgctxt "@title:tab"
msgid "Installed"
msgstr "Instalado"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:22
msgctxt "@label"
msgid "Will install upon restarting"
msgstr "Se instalará después de reiniciar"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:53
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to update"
+msgstr "Inicie sesión para realizar la actualización"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Downgrade"
msgstr "Degradar"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Uninstall"
msgstr "Desinstalar"
@@ -1578,14 +1670,17 @@ msgid ""
"This plugin contains a license.\n"
"You need to accept this license to install this plugin.\n"
"Do you agree with the terms below?"
-msgstr "Este complemento incluye una licencia.\nDebe aceptar dicha licencia para instalar el complemento.\n¿Acepta las condiciones que aparecen a continuación?"
+msgstr ""
+"Este complemento incluye una licencia.\n"
+"Debe aceptar dicha licencia para instalar el complemento.\n"
+"¿Acepta las condiciones que aparecen a continuación?"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:54
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:55
msgctxt "@action:button"
msgid "Accept"
msgstr "Aceptar"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:65
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:66
msgctxt "@action:button"
msgid "Decline"
msgstr "Rechazar"
@@ -1595,22 +1690,62 @@ msgctxt "@label"
msgid "Featured"
msgstr "Destacado"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:34
msgctxt "@label"
msgid "Compatibility"
msgstr "Compatibilidad"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:124
+msgctxt "@label:table_header"
+msgid "Machine"
+msgstr "Máquina"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:137
+msgctxt "@label:table_header"
+msgid "Build Plate"
+msgstr "Placa de impresión"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:143
+msgctxt "@label:table_header"
+msgid "Support"
+msgstr "Soporte"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:149
+msgctxt "@label:table_header"
+msgid "Quality"
+msgstr "Calidad"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:170
+msgctxt "@action:label"
+msgid "Technical Data Sheet"
+msgstr "Especificaciones técnicas"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:179
+msgctxt "@action:label"
+msgid "Safety Data Sheet"
+msgstr "Especificaciones de seguridad"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:188
+msgctxt "@action:label"
+msgid "Printing Guidelines"
+msgstr "Directrices de impresión"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:197
+msgctxt "@action:label"
+msgid "Website"
+msgstr "Sitio web"
+
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml:16
msgctxt "@info"
msgid "Fetching packages..."
msgstr "Buscando paquetes..."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:88
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:91
msgctxt "@label"
msgid "Website"
msgstr "Sitio web"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:94
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:98
msgctxt "@label"
msgid "Email"
msgstr "Correo electrónico"
@@ -1618,24 +1753,7 @@ msgstr "Correo electrónico"
#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.qml:22
msgctxt "@info:tooltip"
msgid "Some things could be problematic in this print. Click to see tips for adjustment."
-msgstr "Algunos elementos pueden causar problemas durante la impresión. Haga clic para ver consejos sobre cómo ajustarla."
-
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18
-msgctxt "@label"
-msgid "Changelog"
-msgstr "Registro de cambios"
-
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:37
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:53
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:467
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:514
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:121
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:166
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:38
-msgctxt "@action:button"
-msgid "Close"
-msgstr "Cerrar"
+msgstr "Algunos elementos pueden causar problemas durante la impresión. Haga clic para ver consejos sobre cómo ajustarlos."
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:31
msgctxt "@title"
@@ -1712,423 +1830,505 @@ msgctxt "@label"
msgid "Firmware update failed due to missing firmware."
msgstr "Se ha producido un error al actualizar el firmware porque falta el firmware."
-#: /home/ruben/Projects/Cura/plugins/UserAgreement/UserAgreement.qml:16
-msgctxt "@title:window"
-msgid "User Agreement"
-msgstr "Acuerdo de usuario"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:155
+msgctxt "@label link to Connect and Cloud interfaces"
+msgid "Manage printer"
+msgstr "Administrar impresora"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:46
-msgctxt "@window:title"
-msgid "Existing Connection"
-msgstr "Conexión existente"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:192
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:183
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:153
+msgctxt "@label"
+msgid "Glass"
+msgstr "Vidrio"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:48
-msgctxt "@message:text"
-msgid "This printer/group is already added to Cura. Please select another printer/group."
-msgstr "Esta impresora o grupo de impresoras ya se ha añadido a Cura. Seleccione otra impresora o grupo de impresoras."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:256
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:514
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:248
+msgctxt "@info"
+msgid "Please update your printer's firmware to manage the queue remotely."
+msgstr "Actualice el firmware de la impresora para gestionar la cola de forma remota."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:65
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:289
+msgctxt "@info"
+msgid "The webcam is not available because you are monitoring a cloud printer."
+msgstr "La cámara web no se encuentra disponible porque está supervisando una impresora en la nube."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:348
+msgctxt "@label:status"
+msgid "Loading..."
+msgstr "Cargando..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:352
+msgctxt "@label:status"
+msgid "Unavailable"
+msgstr "No disponible"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:356
+msgctxt "@label:status"
+msgid "Unreachable"
+msgstr "No se puede conectar"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:360
+msgctxt "@label:status"
+msgid "Idle"
+msgstr "Sin actividad"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:401
+msgctxt "@label"
+msgid "Untitled"
+msgstr "Sin título"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:422
+msgctxt "@label"
+msgid "Anonymous"
+msgstr "Anónimo"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:449
+msgctxt "@label:status"
+msgid "Requires configuration changes"
+msgstr "Debe cambiar la configuración"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:487
+msgctxt "@action:button"
+msgid "Details"
+msgstr "Detalles"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:132
+msgctxt "@label"
+msgid "Unavailable printer"
+msgstr "Impresora no disponible"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:134
+msgctxt "@label"
+msgid "First available"
+msgstr "Primera disponible"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:31
+msgctxt "@label"
+msgid "Queued"
+msgstr "En cola"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:67
+msgctxt "@label link to connect manager"
+msgid "Manage in browser"
+msgstr "Gestionar en el navegador"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:100
+msgctxt "@label"
+msgid "There are no print jobs in the queue. Slice and send a job to add one."
+msgstr "No hay trabajos de impresión en la cola. Segmentar y enviar un trabajo para añadir uno."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:115
+msgctxt "@label"
+msgid "Print jobs"
+msgstr "Trabajos de impresión"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:131
+msgctxt "@label"
+msgid "Total print time"
+msgstr "Tiempo de impresión total"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:147
+msgctxt "@label"
+msgid "Waiting for"
+msgstr "Esperando"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:45
msgctxt "@title:window"
msgid "Connect to Networked Printer"
msgstr "Conectar con la impresora en red"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:75
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
msgctxt "@label"
-msgid ""
-"To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
-"\n"
-"Select your printer from the list below:"
-msgstr "Para imprimir directamente en la impresora a través de la red, asegúrese de que esta está conectada a la red utilizando un cable de red o conéctela a la red wifi. Si no conecta Cura con la impresora, también puede utilizar una unidad USB para transferir archivos GCode a la impresora.\n\nSeleccione la impresora de la siguiente lista:"
+msgid "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer."
+msgstr "Para imprimir directamente a través de la red, asegúrese de que la impresora está conectada a la red mediante un cable de red o conéctela a la red wifi. Si no conecta Cura con la impresora, también puede utilizar una unidad USB para transferir archivos GCode a la impresora."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:85
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:42
-msgctxt "@action:button"
-msgid "Add"
-msgstr "Agregar"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
+msgctxt "@label"
+msgid "Select your printer from the list below:"
+msgstr "Seleccione la impresora en la lista siguiente:"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:95
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:77
msgctxt "@action:button"
msgid "Edit"
msgstr "Editar"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:106
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:128
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:117
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:88
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:138
msgctxt "@action:button"
msgid "Remove"
msgstr "Eliminar"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:114
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:96
msgctxt "@action:button"
msgid "Refresh"
msgstr "Actualizar"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:207
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:176
msgctxt "@label"
msgid "If your printer is not listed, read the network printing troubleshooting guide"
msgstr "Si la impresora no aparece en la lista, lea la guía de solución de problemas de impresión y red"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:234
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:205
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:258
msgctxt "@label"
msgid "Type"
msgstr "Tipo"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:271
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:274
msgctxt "@label"
msgid "Firmware version"
msgstr "Versión de firmware"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:290
msgctxt "@label"
msgid "Address"
msgstr "Dirección"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:305
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:263
msgctxt "@label"
msgid "This printer is not set up to host a group of printers."
msgstr "Esta impresora no está configurada para alojar un grupo de impresoras."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:309
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:267
msgctxt "@label"
msgid "This printer is the host for a group of %1 printers."
msgstr "Esta impresora aloja un grupo de %1 impresoras."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:319
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:278
msgctxt "@label"
msgid "The printer at this address has not yet responded."
msgstr "La impresora todavía no ha respondido en esta dirección."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:324
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
msgctxt "@action:button"
msgid "Connect"
msgstr "Conectar"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:338
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:296
+msgctxt "@title:window"
+msgid "Invalid IP address"
+msgstr "Dirección IP no válida"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:146
+msgctxt "@text"
+msgid "Please enter a valid IP address."
+msgstr "Introduzca una dirección IP válida."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:308
msgctxt "@title:window"
msgid "Printer Address"
msgstr "Dirección de la impresora"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
-msgctxt "@alabel"
-msgid "Enter the IP address or hostname of your printer on the network."
-msgstr "Introduzca la dirección IP o el nombre de host de la impresora en red."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:102
+msgctxt "@label"
+msgid "Enter the IP address of your printer on the network."
+msgstr "Introduzca la dirección IP de la impresora en la red."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:390
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:132
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:138
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:181
msgctxt "@action:button"
msgid "OK"
msgstr "Aceptar"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:44
-msgctxt "@action:button"
-msgid "Print"
-msgstr "Imprimir"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:47
-msgctxt "@title:window"
-msgid "Print over network"
-msgstr "Imprimir a través de la red"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:79
-msgctxt "@label"
-msgid "Printer selection"
-msgstr "Selección de la impresora"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:173
-msgctxt "@label"
-msgid "Not available"
-msgstr "No disponible"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:175
-msgctxt "@label"
-msgid "Unreachable"
-msgstr "No se puede conectar"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:180
-msgctxt "@label"
-msgid "Available"
-msgstr "Disponible"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:37
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:44
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:46
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:78
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:90
msgctxt "@label:status"
msgid "Aborted"
msgstr "Cancelado"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:39
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:80
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:82
msgctxt "@label:status"
msgid "Finished"
msgstr "Terminado"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:84
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:86
msgctxt "@label:status"
-msgid "Preparing"
-msgstr "Preparando"
+msgid "Preparing..."
+msgstr "Preparando..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:48
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:88
msgctxt "@label:status"
-msgid "Pausing"
-msgstr "Pausando"
+msgid "Aborting..."
+msgstr "Cancelando..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:52
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:92
msgctxt "@label:status"
-msgid "Resuming"
-msgstr "Reanudando"
+msgid "Pausing..."
+msgstr "Pausando..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:54
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:94
+msgctxt "@label:status"
+msgid "Paused"
+msgstr "En pausa"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:96
+msgctxt "@label:status"
+msgid "Resuming..."
+msgstr "Reanudando..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:98
msgctxt "@label:status"
msgid "Action required"
msgstr "Acción requerida"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:213
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:100
+msgctxt "@label:status"
+msgid "Finishes %1 at %2"
+msgstr "Termina el %1 a las %2"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:11
+msgctxt "@title:window"
+msgid "Print over network"
+msgstr "Imprimir a través de la red"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:52
+msgctxt "@action:button"
+msgid "Print"
+msgstr "Imprimir"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:80
msgctxt "@label"
-msgid "Waiting for: Unavailable printer"
-msgstr "Esperando: impresora no disponible"
+msgid "Printer selection"
+msgstr "Selección de la impresora"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:215
-msgctxt "@label"
-msgid "Waiting for: First available"
-msgstr "Esperando: primera disponible"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:217
-msgctxt "@label"
-msgid "Waiting for: "
-msgstr "Esperando: "
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:299
-msgctxt "@label"
-msgid "Configuration change"
-msgstr "Cambio de configuración"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:365
-msgctxt "@label"
-msgid "The assigned printer, %1, requires the following configuration change(s):"
-msgstr "Es necesario modificar la siguiente configuración de la impresora asignada %1:"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:367
-msgctxt "@label"
-msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
-msgstr "Se ha asignado la impresora 1%, pero el trabajo tiene una configuración de material desconocido."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:375
-msgctxt "@label"
-msgid "Change material %1 from %2 to %3."
-msgstr "Cambiar material %1, de %2 a %3."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:378
-msgctxt "@label"
-msgid "Load %3 as material %1 (This cannot be overridden)."
-msgstr "Cargar %3 como material %1 (no se puede anular)."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:381
-msgctxt "@label"
-msgid "Change print core %1 from %2 to %3."
-msgstr "Cambiar print core %1, de %2 a %3."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:384
-msgctxt "@label"
-msgid "Change build plate to %1 (This cannot be overridden)."
-msgstr "Cambiar la placa de impresión a %1 (no se puede anular)."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:404
-msgctxt "@label"
-msgid "Override"
-msgstr "Anular"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:432
-msgctxt "@label"
-msgid "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?"
-msgstr "Iniciar un trabajo de impresión con una configuración no compatible puede causar daños en su impresora 3D. ¿Seguro de que desea sobrescribir la configuración e imprimir %1?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:435
-msgctxt "@window:title"
-msgid "Override configuration configuration and start print"
-msgstr "Sobrescribir la configuración e iniciar la impresión"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:466
-msgctxt "@label"
-msgid "Glass"
-msgstr "Vidrio"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:469
-msgctxt "@label"
-msgid "Aluminum"
-msgstr "Aluminio"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:39
-msgctxt "@label link to connect manager"
-msgid "Manage queue"
-msgstr "Administrar cola"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:60
-msgctxt "@label"
-msgid "Queued"
-msgstr "En cola"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:36
-msgctxt "@label"
-msgid "Printing"
-msgstr "Imprimiendo"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:49
-msgctxt "@label link to connect manager"
-msgid "Manage printers"
-msgstr "Administrar impresoras"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:115
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:54
msgctxt "@label"
msgid "Move to top"
msgstr "Mover al principio"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:124
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:70
msgctxt "@label"
msgid "Delete"
msgstr "Borrar"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:100
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:289
msgctxt "@label"
msgid "Resume"
msgstr "Reanudar"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:102
+msgctxt "@label"
+msgid "Pausing..."
+msgstr "Pausando..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:104
+msgctxt "@label"
+msgid "Resuming..."
+msgstr "Reanudando..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:106
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:284
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:293
msgctxt "@label"
msgid "Pause"
msgstr "Pausar"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:146
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
+msgctxt "@label"
+msgid "Aborting..."
+msgstr "Cancelando..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
msgctxt "@label"
msgid "Abort"
msgstr "Cancelar"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:178
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:143
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to move %1 to the top of the queue?"
msgstr "¿Seguro que desea mover %1 al principio de la cola?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:179
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:144
msgctxt "@window:title"
msgid "Move print job to top"
msgstr "Mover trabajo de impresión al principio"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:188
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:153
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to delete %1?"
msgstr "¿Seguro que desea borrar %1?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:189
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:154
msgctxt "@window:title"
msgid "Delete print job"
msgstr "Borrar trabajo de impresión"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:198
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:163
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to abort %1?"
msgstr "¿Seguro que desea cancelar %1?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:199
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:164
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:335
msgctxt "@window:title"
msgid "Abort print"
msgstr "Cancela la impresión"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:43
-msgctxt "@info:tooltip"
-msgid "Connect to a printer"
-msgstr "Conecta a una impresora"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:20
+msgctxt "@title:window"
+msgid "Configuration Changes"
+msgstr "Cambios de configuración"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:121
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:27
msgctxt "@action:button"
-msgid "Activate Configuration"
-msgstr "Activar configuración"
+msgid "Override"
+msgstr "Anular"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:122
-msgctxt "@info:tooltip"
-msgid "Load the configuration of the printer into Cura"
-msgstr "Carga la configuración de la impresora en Cura"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:85
+msgctxt "@label"
+msgid "The assigned printer, %1, requires the following configuration change:"
+msgid_plural "The assigned printer, %1, requires the following configuration changes:"
+msgstr[0] "Es necesario realizar el siguiente cambio de configuración en la impresora asignada %1:"
+msgstr[1] "Es necesario realizar los siguientes cambios de configuración en la impresora asignada %1:"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:130
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:89
+msgctxt "@label"
+msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
+msgstr "Se ha asignado la impresora %1, pero el trabajo tiene una configuración de material desconocido."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:99
+msgctxt "@label"
+msgid "Change material %1 from %2 to %3."
+msgstr "Cambiar material %1, de %2 a %3."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:102
+msgctxt "@label"
+msgid "Load %3 as material %1 (This cannot be overridden)."
+msgstr "Cargar %3 como material %1 (no se puede anular)."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:105
+msgctxt "@label"
+msgid "Change print core %1 from %2 to %3."
+msgstr "Cambiar print core %1, de %2 a %3."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:108
+msgctxt "@label"
+msgid "Change build plate to %1 (This cannot be overridden)."
+msgstr "Cambiar la placa de impresión a %1 (no se puede anular)."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:115
+msgctxt "@label"
+msgid "Override will use the specified settings with the existing printer configuration. This may result in a failed print."
+msgstr "Al sobrescribir la configuración se usarán los ajustes especificados con la configuración de impresora existente. Esto podría provocar un fallo en la impresión."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:156
+msgctxt "@label"
+msgid "Aluminum"
+msgstr "Aluminio"
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:100
+msgctxt "@info"
+msgid ""
+"Please make sure your printer has a connection:\n"
+"- Check if the printer is turned on.\n"
+"- Check if the printer is connected to the network.\n"
+"- Check if you are signed in to discover cloud-connected printers."
+msgstr ""
+"Asegúrese de que la impresora está conectada:\n"
+"- Compruebe que la impresora está encendida.\n"
+"- Compruebe que la impresora está conectada a la red.\n"
+"- Compruebe que ha iniciado sesión para ver impresoras conectadas a la nube."
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:117
+msgctxt "@info"
+msgid "Please connect your printer to the network."
+msgstr "Conecte su impresora a la red."
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:156
+msgctxt "@label link to technical assistance"
+msgid "View user manuals online"
+msgstr "Ver manuales de usuario en línea"
+
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:20
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:49
msgctxt "@label"
msgid "Color scheme"
msgstr "Combinación de colores"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:145
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:107
msgctxt "@label:listbox"
msgid "Material Color"
msgstr "Color del material"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:149
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:111
msgctxt "@label:listbox"
msgid "Line Type"
msgstr "Tipo de línea"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:153
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:115
msgctxt "@label:listbox"
msgid "Feedrate"
msgstr "Velocidad"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:157
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:119
msgctxt "@label:listbox"
msgid "Layer thickness"
msgstr "Grosor de la capa"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:198
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:156
msgctxt "@label"
msgid "Compatibility Mode"
msgstr "Modo de compatibilidad"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:284
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:230
msgctxt "@label"
-msgid "Show Travels"
-msgstr "Mostrar desplazamientos"
+msgid "Travels"
+msgstr "Desplazamientos"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:290
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:236
msgctxt "@label"
-msgid "Show Helpers"
-msgstr "Mostrar asistentes"
+msgid "Helpers"
+msgstr "Asistentes"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:296
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:242
msgctxt "@label"
-msgid "Show Shell"
-msgstr "Mostrar perímetro"
+msgid "Shell"
+msgstr "Perímetro"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:302
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:248
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:65
msgctxt "@label"
-msgid "Show Infill"
-msgstr "Mostrar relleno"
+msgid "Infill"
+msgstr "Relleno"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:355
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:298
msgctxt "@label"
msgid "Only Show Top Layers"
msgstr "Mostrar solo capas superiores"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:366
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:308
msgctxt "@label"
msgid "Show 5 Detailed Layers On Top"
msgstr "Mostrar cinco capas detalladas en la parte superior"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:379
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:322
msgctxt "@label"
msgid "Top / Bottom"
msgstr "Superior o inferior"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:383
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:326
msgctxt "@label"
msgid "Inner Wall"
msgstr "Pared interior"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:448
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:384
msgctxt "@label"
msgid "min"
msgstr "mín."
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:500
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:433
msgctxt "@label"
msgid "max"
msgstr "máx."
@@ -2143,40 +2343,40 @@ msgctxt "@label"
msgid "Post Processing Scripts"
msgstr "Secuencias de comandos de posprocesamiento"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:227
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:233
msgctxt "@action"
msgid "Add a script"
msgstr "Añadir secuencia de comando"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:273
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:279
msgctxt "@label"
msgid "Settings"
msgstr "Ajustes"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:477
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:493
msgctxt "@info:tooltip"
msgid "Change active post-processing scripts"
msgstr "Cambia las secuencias de comandos de posprocesamiento"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:16
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:17
msgctxt "@title:window"
msgid "More information on anonymous data collection"
msgstr "Más información sobre la recopilación de datos anónimos"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:66
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:74
msgctxt "@text:window"
-msgid "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent."
-msgstr "Cura envía datos anónimos a Ultimaker para mejorar la calidad de impresión y la experiencia de usuario. A continuación, hay un ejemplo de todos los datos que se han enviado."
+msgid "Ultimaker Cura collects anonymous data in order to improve the print quality and user experience. Below is an example of all the data that is shared:"
+msgstr "Ultimaker Cura recopila datos anónimos para mejorar la calidad de impresión y la experiencia de usuario. A continuación, hay un ejemplo de todos los datos que se comparten:"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:101
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:109
msgctxt "@text:window"
-msgid "I don't want to send these data"
-msgstr "No quiero enviar estos datos"
+msgid "I don't want to send anonymous data"
+msgstr "No deseo enviar datos anónimos"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:111
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:118
msgctxt "@text:window"
-msgid "Allow sending these data to Ultimaker and help us improve Cura"
-msgstr "Permita enviar estos datos a Ultimaker y ayúdenos a mejorar Cura"
+msgid "Allow sending anonymous data"
+msgstr "Permitir el envío de datos anónimos"
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:19
msgctxt "@title:window"
@@ -2225,19 +2425,19 @@ msgstr "Profundidad (mm)"
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:126
msgctxt "@info:tooltip"
-msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
-msgstr "De manera predeterminada, los píxeles blancos representan los puntos altos de la malla y los píxeles negros representan los puntos bajos de la malla. Cambie esta opción para invertir el comportamiento de tal manera que los píxeles negros representen los puntos altos de la malla y los píxeles blancos representen los puntos bajos de la malla."
-
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
-msgctxt "@item:inlistbox"
-msgid "Lighter is higher"
-msgstr "Cuanto más claro más alto"
+msgid "For lithophanes dark pixels should correspond to thicker locations in order to block more light coming through. For height maps lighter pixels signify higher terrain, so lighter pixels should correspond to thicker locations in the generated 3D model."
+msgstr "Para las litofanías, los píxeles oscuros deben coincidir con ubicaciones más gruesas para bloquear la entrada de más luz. En los mapas de altura, los píxeles más claros se corresponden con un terreno más alto, por lo que dichos píxeles deben coincidir con ubicaciones más gruesas en el modelo 3D generado."
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
msgctxt "@item:inlistbox"
msgid "Darker is higher"
msgstr "Cuanto más oscuro más alto"
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
+msgctxt "@item:inlistbox"
+msgid "Lighter is higher"
+msgstr "Cuanto más claro más alto"
+
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:149
msgctxt "@info:tooltip"
msgid "The amount of smoothing to apply to the image."
@@ -2248,81 +2448,80 @@ msgctxt "@action:label"
msgid "Smoothing"
msgstr "Suavizado"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:37
-msgctxt "@label"
-msgid "Mesh Type"
-msgstr "Tipo de malla"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:68
-msgctxt "@label"
-msgid "Normal model"
-msgstr "Modelo normal"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:75
-msgctxt "@label"
-msgid "Print as support"
-msgstr "Imprimir como soporte"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:83
-msgctxt "@label"
-msgid "Don't support overlap with other models"
-msgstr "No crear soporte en otros modelos (por superposición)"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:91
-msgctxt "@label"
-msgid "Modify settings for overlap with other models"
-msgstr "Modificar ajustes de otros modelos (por superposición)"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:99
-msgctxt "@label"
-msgid "Modify settings for infill of other models"
-msgstr "Modificar ajustes del relleno de otros modelos"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:347
-msgctxt "@action:button"
-msgid "Select settings"
-msgstr "Seleccionar ajustes"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:389
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:13
msgctxt "@title:window"
msgid "Select Settings to Customize for this model"
msgstr "Seleccionar ajustes o personalizar este modelo"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:437
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:98
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:56
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:94
msgctxt "@label:textbox"
msgid "Filter..."
msgstr "Filtrar..."
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:451
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:70
msgctxt "@label:checkbox"
msgid "Show all"
msgstr "Mostrar todo"
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:44
+msgctxt "@label"
+msgid "Mesh Type"
+msgstr "Tipo de malla"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:85
+msgctxt "@label"
+msgid "Normal model"
+msgstr "Modelo normal"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:97
+msgctxt "@label"
+msgid "Print as support"
+msgstr "Imprimir como soporte"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:109
+msgctxt "@label"
+msgid "Modify settings for overlaps"
+msgstr "Modificar los ajustes de las superposiciones"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:121
+msgctxt "@label"
+msgid "Don't support overlaps"
+msgstr "No es compatible con superposiciones"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:145
+msgctxt "@action:checkbox"
+msgid "Infill only"
+msgstr "Solo relleno"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:368
+msgctxt "@action:button"
+msgid "Select settings"
+msgstr "Seleccionar ajustes"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:14
msgctxt "@title:window"
msgid "Open Project"
msgstr "Abrir proyecto"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:58
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Update/override existing profile"
msgid "Update existing"
msgstr "Actualizar existente"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:59
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Save settings in a new profile"
msgid "Create new"
msgstr "Crear nuevo"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:70
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:73
msgctxt "@action:title"
msgid "Summary - Cura Project"
msgstr "Resumen: proyecto de Cura"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:92
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:97
msgctxt "@action:label"
msgid "Printer settings"
msgstr "Ajustes de la impresora"
@@ -2338,20 +2537,25 @@ msgctxt "@action:ComboBox option"
msgid "Update"
msgstr "Actualizar"
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
+msgctxt "@action:ComboBox option"
+msgid "Create new"
+msgstr "Crear nuevo"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:143
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:105
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:106
msgctxt "@action:label"
msgid "Type"
msgstr "Tipo"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:159
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
msgctxt "@action:label"
msgid "Printer Group"
msgstr "Grupo de impresoras"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:180
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:196
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:220
msgctxt "@action:label"
msgid "Profile settings"
msgstr "Ajustes del perfil"
@@ -2362,226 +2566,222 @@ msgid "How should the conflict in the profile be resolved?"
msgstr "¿Cómo debería solucionarse el conflicto en el perfil?"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:216
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:220
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:323
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:244
msgctxt "@action:label"
msgid "Name"
msgstr "Nombre"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:231
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:204
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:261
+msgctxt "@action:label"
+msgid "Intent"
+msgstr "Intent"
+
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:246
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:228
msgctxt "@action:label"
msgid "Not in profile"
msgstr "No está en el perfil"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:236
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:209
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:251
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:233
msgctxt "@action:label"
msgid "%1 override"
msgid_plural "%1 overrides"
msgstr[0] "%1 sobrescrito"
msgstr[1] "%1 sobrescritos"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:247
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:262
msgctxt "@action:label"
msgid "Derivative from"
msgstr "Derivado de"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:252
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:267
msgctxt "@action:label"
msgid "%1, %2 override"
msgid_plural "%1, %2 overrides"
msgstr[0] "%1, %2 sobrescrito"
msgstr[1] "%1, %2 sobrescritos"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:268
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:283
msgctxt "@action:label"
msgid "Material settings"
msgstr "Ajustes del material"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:284
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:299
msgctxt "@info:tooltip"
msgid "How should the conflict in the material be resolved?"
msgstr "¿Cómo debería solucionarse el conflicto en el material?"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:327
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:237
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:342
msgctxt "@action:label"
msgid "Setting visibility"
msgstr "Visibilidad de los ajustes"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:336
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:351
msgctxt "@action:label"
msgid "Mode"
msgstr "Modo"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:352
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:246
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:367
msgctxt "@action:label"
msgid "Visible settings:"
msgstr "Ajustes visibles:"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:357
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:251
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:372
msgctxt "@action:label"
msgid "%1 out of %2"
msgstr "%1 de un total de %2"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:383
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:398
msgctxt "@action:warning"
msgid "Loading a project will clear all models on the build plate."
msgstr "Si carga un proyecto, se borrarán todos los modelos de la placa de impresión."
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:401
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:416
msgctxt "@action:button"
msgid "Open"
msgstr "Abrir"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:26
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:25
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:28
msgctxt "@title"
-msgid "Select Printer Upgrades"
-msgstr "Seleccionar actualizaciones de impresora"
+msgid "My Backups"
+msgstr "Mis copias de seguridad"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:38
-msgctxt "@label"
-msgid "Please select any upgrades made to this Ultimaker 2."
-msgstr "Seleccione cualquier actualización de este Ultimaker 2."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:38
+msgctxt "@empty_state"
+msgid "You don't have any backups currently. Use the 'Backup Now' button to create one."
+msgstr "Actualmente no posee ninguna copia de seguridad. Utilice el botón de Realizar copia de seguridad ahora para crear una."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:47
-msgctxt "@label"
-msgid "Olsson Block"
-msgstr "Bloque Olsson"
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:60
+msgctxt "@backup_limit_info"
+msgid "During the preview phase, you'll be limited to 5 visible backups. Remove a backup to see older ones."
+msgstr "Durante la fase de vista previa, solo se mostrarán 5 copias de seguridad. Elimine una copia de seguridad para ver copias de seguridad antiguas."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:27
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:34
+msgctxt "@description"
+msgid "Backup and synchronize your Cura settings."
+msgstr "Realice una copia de seguridad y sincronice sus ajustes de Cura."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:51
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:68
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:138
+msgctxt "@button"
+msgid "Sign in"
+msgstr "Iniciar sesión"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/main.qml:24
+msgctxt "@title:window"
+msgid "Cura Backups"
+msgstr "Copias de seguridad de Cura"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:21
+msgctxt "@backuplist:label"
+msgid "Cura Version"
+msgstr "Versión de Cura"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:29
+msgctxt "@backuplist:label"
+msgid "Machines"
+msgstr "Máquinas"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:37
+msgctxt "@backuplist:label"
+msgid "Materials"
+msgstr "Materiales"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:45
+msgctxt "@backuplist:label"
+msgid "Profiles"
+msgstr "Perfiles"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:53
+msgctxt "@backuplist:label"
+msgid "Plugins"
+msgstr "Complementos"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:71
+msgctxt "@button"
+msgid "Restore"
+msgstr "Restaurar"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:99
+msgctxt "@dialog:title"
+msgid "Delete Backup"
+msgstr "Eliminar copia de seguridad"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:100
+msgctxt "@dialog:info"
+msgid "Are you sure you want to delete this backup? This cannot be undone."
+msgstr "¿Seguro que desea eliminar esta copia de seguridad? Esta acción no se puede deshacer."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:108
+msgctxt "@dialog:title"
+msgid "Restore Backup"
+msgstr "Restaurar copia de seguridad"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:109
+msgctxt "@dialog:info"
+msgid "You will need to restart Cura before your backup is restored. Do you want to close Cura now?"
+msgstr "Deberá reiniciar Cura para restaurar su copia de seguridad. ¿Desea cerrar Cura ahora?"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:22
+msgctxt "@button"
+msgid "Want more?"
+msgstr "¿Desea obtener más información?"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:31
+msgctxt "@button"
+msgid "Backup Now"
+msgstr "Realizar copia de seguridad ahora"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:43
+msgctxt "@checkbox:description"
+msgid "Auto Backup"
+msgstr "Copia de seguridad automática"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:44
+msgctxt "@checkbox:description"
+msgid "Automatically create a backup each day that Cura is started."
+msgstr "Crea una copia de seguridad de forma automática cada día que inicia Cura."
+
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:30
msgctxt "@title"
msgid "Build Plate Leveling"
msgstr "Nivelación de la placa de impresión"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:38
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:44
msgctxt "@label"
msgid "To make sure your prints will come out great, you can now adjust your buildplate. When you click 'Move to Next Position' the nozzle will move to the different positions that can be adjusted."
msgstr "Ahora puede ajustar la placa de impresión para asegurarse de que sus impresiones salgan muy bien. Al hacer clic en 'Mover a la siguiente posición', la tobera se trasladará a las diferentes posiciones que se pueden ajustar."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:47
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:57
msgctxt "@label"
msgid "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle."
msgstr "Para cada posición: inserte una hoja de papel debajo de la tobera y ajuste la altura de la placa de impresión. La altura de la placa de impresión es correcta cuando el papel queda ligeramente sujeto por la punta de la tobera."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:62
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:75
msgctxt "@action:button"
msgid "Start Build Plate Leveling"
msgstr "Iniciar nivelación de la placa de impresión"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:74
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:87
msgctxt "@action:button"
msgid "Move to Next Position"
msgstr "Mover a la siguiente posición"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:37
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:30
msgctxt "@label"
msgid "Please select any upgrades made to this Ultimaker Original"
msgstr "Seleccione cualquier actualización de Ultimaker Original"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:45
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:41
msgctxt "@label"
msgid "Heated Build Plate (official kit or self-built)"
msgstr "Placa de impresión caliente (kit oficial o construida por usted mismo)"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:27
-msgctxt "@title"
-msgid "Check Printer"
-msgstr "Comprobar impresora"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:39
-msgctxt "@label"
-msgid "It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional"
-msgstr "Es una buena idea hacer un par de comprobaciones en su Ultimaker. Puede omitir este paso si usted sabe que su máquina funciona correctamente"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:53
-msgctxt "@action:button"
-msgid "Start Printer Check"
-msgstr "Iniciar comprobación de impresora"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:80
-msgctxt "@label"
-msgid "Connection: "
-msgstr "Conexión: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Connected"
-msgstr "Conectado"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Not connected"
-msgstr "Sin conexión"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:99
-msgctxt "@label"
-msgid "Min endstop X: "
-msgstr "Parada final mín. en X: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-msgctxt "@info:status"
-msgid "Works"
-msgstr "Funciona"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:173
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Not checked"
-msgstr "Sin comprobar"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:120
-msgctxt "@label"
-msgid "Min endstop Y: "
-msgstr "Parada final mín. en Y: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:141
-msgctxt "@label"
-msgid "Min endstop Z: "
-msgstr "Parada final mín. en Z: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:163
-msgctxt "@label"
-msgid "Nozzle temperature check: "
-msgstr "Comprobación de la temperatura de la tobera: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Stop Heating"
-msgstr "Detener calentamiento"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Start Heating"
-msgstr "Iniciar calentamiento"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:223
-msgctxt "@label"
-msgid "Build plate temperature check:"
-msgstr "Comprobación de la temperatura de la placa de impresión:"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Checked"
-msgstr "Comprobada"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:284
-msgctxt "@label"
-msgid "Everything is in order! You're done with your CheckUp."
-msgstr "¡Todo correcto! Ha terminado con la comprobación."
-
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:119
msgctxt "@label:MonitorStatus"
msgid "Not connected to a printer"
@@ -2593,7 +2793,6 @@ msgid "Printer does not accept commands"
msgstr "La impresora no acepta comandos"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:133
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:197
msgctxt "@label:MonitorStatus"
msgid "In maintenance. Please check the printer"
msgstr "En mantenimiento. Compruebe la impresora"
@@ -2604,19 +2803,16 @@ msgid "Lost connection with the printer"
msgstr "Se ha perdido la conexión con la impresora"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:146
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:187
msgctxt "@label:MonitorStatus"
msgid "Printing..."
msgstr "Imprimiendo..."
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:149
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:189
msgctxt "@label:MonitorStatus"
msgid "Paused"
msgstr "En pausa"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:152
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:191
msgctxt "@label:MonitorStatus"
msgid "Preparing..."
msgstr "Preparando..."
@@ -2636,233 +2832,176 @@ msgctxt "@label"
msgid "Are you sure you want to abort the print?"
msgstr "¿Está seguro de que desea cancelar la impresión?"
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:15
-msgctxt "@title:window"
-msgid "Discard or Keep changes"
-msgstr "Descartar o guardar cambios"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:57
-msgctxt "@text:window"
-msgid ""
-"You have customized some profile settings.\n"
-"Would you like to keep or discard those settings?"
-msgstr "Ha personalizado parte de los ajustes del perfil.\n¿Desea descartar los cambios o guardarlos?"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:110
-msgctxt "@title:column"
-msgid "Profile settings"
-msgstr "Ajustes del perfil"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:117
-msgctxt "@title:column"
-msgid "Default"
-msgstr "Valor predeterminado"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:124
-msgctxt "@title:column"
-msgid "Customized"
-msgstr "Valor personalizado"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:157
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:637
-msgctxt "@option:discardOrKeep"
-msgid "Always ask me this"
-msgstr "Preguntar siempre"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:158
-msgctxt "@option:discardOrKeep"
-msgid "Discard and never ask again"
-msgstr "Descartar y no volver a preguntar"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:159
-msgctxt "@option:discardOrKeep"
-msgid "Keep and never ask again"
-msgstr "Guardar y no volver a preguntar"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:196
-msgctxt "@action:button"
-msgid "Discard"
-msgstr "Descartar"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:209
-msgctxt "@action:button"
-msgid "Keep"
-msgstr "Guardar"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:222
-msgctxt "@action:button"
-msgid "Create New Profile"
-msgstr "Crear nuevo perfil"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:71
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:72
msgctxt "@title"
msgid "Information"
msgstr "Información"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:100
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
msgctxt "@title:window"
msgid "Confirm Diameter Change"
msgstr "Confirmar cambio de diámetro"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:102
msgctxt "@label (%1 is a number)"
msgid "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?"
msgstr "El nuevo diámetro del filamento está ajustado en %1 mm y no es compatible con el extrusor actual. ¿Desea continuar?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:128
msgctxt "@label"
msgid "Display Name"
msgstr "Mostrar nombre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:143
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:138
msgctxt "@label"
msgid "Brand"
msgstr "Marca"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:148
msgctxt "@label"
msgid "Material Type"
msgstr "Tipo de material"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:158
msgctxt "@label"
msgid "Color"
msgstr "Color"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:212
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:208
msgctxt "@label"
msgid "Properties"
msgstr "Propiedades"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:214
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:210
msgctxt "@label"
msgid "Density"
msgstr "Densidad"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:229
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:225
msgctxt "@label"
msgid "Diameter"
msgstr "Diámetro"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:263
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:259
msgctxt "@label"
msgid "Filament Cost"
msgstr "Coste del filamento"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:280
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:276
msgctxt "@label"
msgid "Filament weight"
-msgstr "Anchura del filamento"
+msgstr "Peso del filamento"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:298
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:294
msgctxt "@label"
msgid "Filament length"
msgstr "Longitud del filamento"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:307
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:303
msgctxt "@label"
msgid "Cost per Meter"
msgstr "Coste por metro"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:321
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:317
msgctxt "@label"
msgid "This material is linked to %1 and shares some of its properties."
msgstr "Este material está vinculado a %1 y comparte alguna de sus propiedades."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:328
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:324
msgctxt "@label"
msgid "Unlink Material"
msgstr "Desvincular material"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:335
msgctxt "@label"
msgid "Description"
msgstr "Descripción"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:352
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:348
msgctxt "@label"
msgid "Adhesion Information"
msgstr "Información sobre adherencia"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:378
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:19
msgctxt "@label"
msgid "Print settings"
msgstr "Ajustes de impresión"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:84
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:35
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:108
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:40
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:84
msgctxt "@action:button"
msgid "Activate"
msgstr "Activar"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:126
msgctxt "@action:button"
msgid "Create"
msgstr "Crear"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:140
msgctxt "@action:button"
msgid "Duplicate"
msgstr "Duplicado"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:141
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:170
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:167
msgctxt "@action:button"
msgid "Import"
msgstr "Importar"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:154
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:184
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:179
msgctxt "@action:button"
msgid "Export"
msgstr "Exportar"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:233
msgctxt "@action:label"
msgid "Printer"
msgstr "Impresora"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:262
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:274
msgctxt "@title:window"
msgid "Confirm Remove"
msgstr "Confirmar eliminación"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:263
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:240
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:300
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:275
msgctxt "@label (%1 is object name)"
msgid "Are you sure you wish to remove %1? This cannot be undone!"
msgstr "¿Seguro que desea eliminar %1? ¡Esta acción no se puede deshacer!"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:277
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:285
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:314
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:322
msgctxt "@title:window"
msgid "Import Material"
msgstr "Importar material"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:286
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:323
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Could not import material %1: %2"
msgstr "No se pudo importar el material en %1: %2"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:290
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:327
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully imported material %1"
msgstr "El material se ha importado correctamente en %1"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:316
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:345
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:353
msgctxt "@title:window"
msgid "Export Material"
msgstr "Exportar material"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:320
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:357
msgctxt "@info:status Don't translate the XML tags and !"
msgid "Failed to export material to %1: %2"
msgstr "Se ha producido un error al exportar el material a %1: %2"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:326
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:363
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully exported material to %1"
msgstr "El material se ha exportado correctamente a %1"
@@ -2872,817 +3011,784 @@ msgctxt "@title:tab"
msgid "Setting Visibility"
msgstr "Visibilidad de los ajustes"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:46
msgctxt "@label:textbox"
msgid "Check all"
msgstr "Comprobar todo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:47
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:61
msgctxt "@info:status"
msgid "Calculated"
msgstr "Calculado"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:60
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:75
msgctxt "@title:column"
msgid "Setting"
msgstr "Ajustes"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
msgctxt "@title:column"
msgid "Profile"
msgstr "Perfil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:74
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:89
msgctxt "@title:column"
msgid "Current"
msgstr "Actual"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:97
msgctxt "@title:column"
msgid "Unit"
msgstr "Unidad"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:15
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:410
msgctxt "@title:tab"
msgid "General"
msgstr "General"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:132
msgctxt "@label"
msgid "Interface"
msgstr "Interfaz"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:143
msgctxt "@label"
msgid "Language:"
msgstr "Idioma:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:221
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:210
msgctxt "@label"
msgid "Currency:"
msgstr "Moneda:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:235
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:223
msgctxt "@label"
msgid "Theme:"
msgstr "Tema:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:292
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:279
msgctxt "@label"
msgid "You will need to restart the application for these changes to have effect."
msgstr "Tendrá que reiniciar la aplicación para que estos cambios tengan efecto."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:309
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:296
msgctxt "@info:tooltip"
msgid "Slice automatically when changing settings."
msgstr "Segmentar automáticamente al cambiar los ajustes."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:317
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:304
msgctxt "@option:check"
msgid "Slice automatically"
msgstr "Segmentar automáticamente"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:318
msgctxt "@label"
msgid "Viewport behavior"
msgstr "Comportamiento de la ventanilla"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:326
msgctxt "@info:tooltip"
msgid "Highlight unsupported areas of the model in red. Without support these areas will not print properly."
msgstr "Resaltar en rojo las áreas del modelo sin soporte. Sin soporte, estas áreas no se imprimirán correctamente."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:335
msgctxt "@option:check"
msgid "Display overhang"
msgstr "Mostrar voladizos"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:355
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:343
msgctxt "@info:tooltip"
msgid "Moves the camera so the model is in the center of the view when a model is selected"
msgstr "Mueve la cámara de manera que el modelo se encuentre en el centro de la vista cuando se selecciona un modelo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
msgctxt "@action:button"
msgid "Center camera when item is selected"
msgstr "Centrar cámara cuando se selecciona elemento"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:369
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:358
msgctxt "@info:tooltip"
msgid "Should the default zoom behavior of cura be inverted?"
msgstr "¿Se debería invertir el comportamiento predeterminado del zoom de cura?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:363
msgctxt "@action:button"
msgid "Invert the direction of camera zoom."
msgstr "Invertir la dirección del zoom de la cámara."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
msgctxt "@info:tooltip"
msgid "Should zooming move in the direction of the mouse?"
msgstr "¿Debería moverse el zoom en la dirección del ratón?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:389
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
+msgctxt "@info:tooltip"
+msgid "Zooming towards the mouse is not supported in the orthographic perspective."
+msgstr "Hacer zoom en la dirección del ratón no es compatible con la perspectiva ortográfica."
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
msgctxt "@action:button"
msgid "Zoom toward mouse direction"
msgstr "Hacer zoom en la dirección del ratón"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:399
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:410
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved so that they no longer intersect?"
msgstr "¿Deben moverse los modelos en la plataforma de modo que no se crucen?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:404
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:415
msgctxt "@option:check"
msgid "Ensure models are kept apart"
-msgstr "Asegúrese de que lo modelos están separados"
+msgstr "Asegúrese de que los modelos están separados"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:413
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:424
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved down to touch the build plate?"
msgstr "¿Deben moverse los modelos del área de impresión de modo que no toquen la placa de impresión?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:418
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:429
msgctxt "@option:check"
msgid "Automatically drop models to the build plate"
msgstr "Arrastrar modelos a la placa de impresión de forma automática"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:430
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:441
msgctxt "@info:tooltip"
msgid "Show caution message in g-code reader."
msgstr "Se muestra el mensaje de advertencia en el lector de GCode."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:439
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:450
msgctxt "@option:check"
msgid "Caution message in g-code reader"
msgstr "Mensaje de advertencia en el lector de GCode"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:447
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:458
msgctxt "@info:tooltip"
msgid "Should layer be forced into compatibility mode?"
msgstr "¿Debe forzarse el modo de compatibilidad de la capa?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:452
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:463
msgctxt "@option:check"
msgid "Force layer view compatibility mode (restart required)"
msgstr "Forzar modo de compatibilidad de la vista de capas (necesario reiniciar)"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:468
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:473
+msgctxt "@info:tooltip"
+msgid "Should Cura open at the location it was closed?"
+msgstr "¿Debería abrirse Cura en el lugar donde se cerró?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:478
+msgctxt "@option:check"
+msgid "Restore window position on start"
+msgstr "Restaurar la posición de la ventana al inicio"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:488
+msgctxt "@info:tooltip"
+msgid "What type of camera rendering should be used?"
+msgstr "¿Qué tipo de renderizado de cámara debería usarse?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+msgctxt "@window:text"
+msgid "Camera rendering:"
+msgstr "Renderizado de cámara:"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:506
+msgid "Perspective"
+msgstr "Perspectiva"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:507
+msgid "Orthographic"
+msgstr "Ortográfica"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:538
msgctxt "@label"
msgid "Opening and saving files"
msgstr "Abrir y guardar archivos"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:475
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:545
msgctxt "@info:tooltip"
msgid "Should models be scaled to the build volume if they are too large?"
msgstr "¿Deben ajustarse los modelos al volumen de impresión si son demasiado grandes?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:550
msgctxt "@option:check"
msgid "Scale large models"
msgstr "Escalar modelos de gran tamaño"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:490
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:560
msgctxt "@info:tooltip"
msgid "An model may appear extremely small if its unit is for example in meters rather than millimeters. Should these models be scaled up?"
msgstr "Un modelo puede mostrarse demasiado pequeño si su unidad son metros en lugar de milímetros, por ejemplo. ¿Deben escalarse estos modelos?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:565
msgctxt "@option:check"
msgid "Scale extremely small models"
msgstr "Escalar modelos demasiado pequeños"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:505
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:575
msgctxt "@info:tooltip"
msgid "Should models be selected after they are loaded?"
msgstr "¿Se deberían seleccionar los modelos después de haberse cargado?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:510
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:580
msgctxt "@option:check"
msgid "Select models when loaded"
msgstr "Seleccionar modelos al abrirlos"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:520
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:590
msgctxt "@info:tooltip"
msgid "Should a prefix based on the printer name be added to the print job name automatically?"
msgstr "¿Debe añadirse automáticamente un prefijo basado en el nombre de la impresora al nombre del trabajo de impresión?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:525
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:595
msgctxt "@option:check"
msgid "Add machine prefix to job name"
msgstr "Agregar prefijo de la máquina al nombre del trabajo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:535
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:605
msgctxt "@info:tooltip"
msgid "Should a summary be shown when saving a project file?"
msgstr "¿Mostrar un resumen al guardar un archivo de proyecto?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
msgctxt "@option:check"
msgid "Show summary dialog when saving project"
msgstr "Mostrar un cuadro de diálogo de resumen al guardar el proyecto"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:619
msgctxt "@info:tooltip"
msgid "Default behavior when opening a project file"
msgstr "Comportamiento predeterminado al abrir un archivo del proyecto"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:557
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:627
msgctxt "@window:text"
msgid "Default behavior when opening a project file: "
msgstr "Comportamiento predeterminado al abrir un archivo del proyecto: "
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:571
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:641
msgctxt "@option:openProject"
msgid "Always ask me this"
msgstr "Preguntar siempre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:572
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:642
msgctxt "@option:openProject"
msgid "Always open as a project"
msgstr "Abrir siempre como un proyecto"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:573
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:643
msgctxt "@option:openProject"
msgid "Always import models"
msgstr "Importar modelos siempre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:679
msgctxt "@info:tooltip"
msgid "When you have made changes to a profile and switched to a different one, a dialog will be shown asking whether you want to keep your modifications or not, or you can choose a default behaviour and never show that dialog again."
msgstr "Si ha realizado cambios en un perfil y, a continuación, ha cambiado a otro, aparecerá un cuadro de diálogo que le preguntará si desea guardar o descartar los cambios. También puede elegir el comportamiento predeterminado, así ese cuadro de diálogo no volverá a aparecer."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:618
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:688
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:52
msgctxt "@label"
msgid "Profiles"
msgstr "Perfiles"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:623
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:693
msgctxt "@window:text"
msgid "Default behavior for changed setting values when switching to a different profile: "
msgstr "Comportamiento predeterminado para los valores modificados al cambiar a otro perfil: "
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:638
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:707
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:157
+msgctxt "@option:discardOrKeep"
+msgid "Always ask me this"
+msgstr "Preguntar siempre"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:708
msgctxt "@option:discardOrKeep"
msgid "Always discard changed settings"
msgstr "Descartar siempre los ajustes modificados"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:639
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:709
msgctxt "@option:discardOrKeep"
msgid "Always transfer changed settings to new profile"
msgstr "Transferir siempre los ajustes modificados al nuevo perfil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:673
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:743
msgctxt "@label"
msgid "Privacy"
msgstr "Privacidad"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:681
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:750
msgctxt "@info:tooltip"
msgid "Should Cura check for updates when the program is started?"
msgstr "¿Debe Cura buscar actualizaciones cuando se abre el programa?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:686
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:755
msgctxt "@option:check"
msgid "Check for updates on start"
msgstr "Buscar actualizaciones al iniciar"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:697
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:765
msgctxt "@info:tooltip"
msgid "Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored."
msgstr "¿Deben enviarse datos anónimos sobre la impresión a Ultimaker? Tenga en cuenta que no se envían ni almacenan modelos, direcciones IP ni otra información de identificación personal."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:702
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:770
msgctxt "@option:check"
msgid "Send (anonymous) print information"
msgstr "Enviar información (anónima) de impresión"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:711
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:779
msgctxt "@action:button"
msgid "More information"
msgstr "Más información"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:729
-msgctxt "@label"
-msgid "Experimental"
-msgstr "Experimental"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:736
-msgctxt "@info:tooltip"
-msgid "Use multi build plate functionality"
-msgstr "Utilizar funcionalidad de placa de impresión múltiple"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:741
-msgctxt "@option:check"
-msgid "Use multi build plate functionality (restart required)"
-msgstr "Utilizar funcionalidad de placa de impresión múltiple (reinicio requerido)"
-
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:16
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:415
msgctxt "@title:tab"
msgid "Printers"
msgstr "Impresoras"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:63
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
msgctxt "@action:button"
msgid "Rename"
msgstr "Cambiar nombre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:147
-msgctxt "@label"
-msgid "Printer type:"
-msgstr "Tipo de impresora:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:156
-msgctxt "@label"
-msgid "Connection:"
-msgstr "Conexión:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:162
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
-msgctxt "@info:status"
-msgid "The printer is not connected."
-msgstr "La impresora no está conectada."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:168
-msgctxt "@label"
-msgid "State:"
-msgstr "Estado:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:181
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for a printjob"
-msgstr "Esperando un trabajo de impresión"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:193
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for someone to clear the build plate"
-msgstr "Esperando a que alguien limpie la placa de impresión"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:199
-msgctxt "@label:MonitorStatus"
-msgid "Aborting print..."
-msgstr "Cancelando impresión..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:553
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:34
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:419
msgctxt "@title:tab"
msgid "Profiles"
msgstr "Perfiles"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:104
msgctxt "@label"
msgid "Create"
msgstr "Crear"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:102
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:121
msgctxt "@label"
msgid "Duplicate"
msgstr "Duplicado"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:174
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:202
msgctxt "@title:window"
msgid "Create Profile"
msgstr "Crear perfil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:204
+msgctxt "@info"
+msgid "Please provide a name for this profile."
+msgstr "Introduzca un nombre para este perfil."
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:260
msgctxt "@title:window"
msgid "Duplicate Profile"
msgstr "Duplicar perfil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:256
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:291
msgctxt "@title:window"
msgid "Rename Profile"
msgstr "Cambiar nombre de perfil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:304
msgctxt "@title:window"
msgid "Import Profile"
msgstr "Importar perfil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:333
msgctxt "@title:window"
msgid "Export Profile"
msgstr "Exportar perfil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:350
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:396
msgctxt "@label %1 is printer name"
msgid "Printer: %1"
msgstr "Impresora: %1"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Protected profiles"
-msgstr "Perfiles protegidos"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Custom profiles"
-msgstr "Perfiles personalizados"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:554
msgctxt "@action:button"
msgid "Update profile with current settings/overrides"
msgstr "Actualizar perfil con ajustes o sobrescrituras actuales"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:487
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:561
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:257
msgctxt "@action:button"
msgid "Discard current changes"
msgstr "Descartar cambios actuales"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:504
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:580
msgctxt "@action:label"
msgid "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below."
msgstr "Este perfil utiliza los ajustes predeterminados especificados por la impresora, por eso no aparece ningún ajuste o sobrescritura en la lista que se ve a continuación."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:511
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:588
msgctxt "@action:label"
msgid "Your current settings match the selected profile."
msgstr "Los ajustes actuales coinciden con el perfil seleccionado."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:530
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:606
msgctxt "@title:tab"
msgid "Global Settings"
msgstr "Ajustes globales"
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:18
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:953
-msgctxt "@title:window"
-msgid "Add Printer"
-msgstr "Agregar impresora"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:195
-msgctxt "@label"
-msgid "Printer Name:"
-msgstr "Nombre de la impresora:"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:219
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/MainWindowHeader.qml:90
msgctxt "@action:button"
-msgid "Add Printer"
-msgstr "Agregar impresora"
+msgid "Marketplace"
+msgstr "Marketplace"
-#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:84
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:27
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&File"
+msgstr "&Archivo"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:31
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Edit"
+msgstr "&Edición"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:48
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
+msgctxt "@title:menu menubar:toplevel"
+msgid "&View"
+msgstr "&Ver"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Settings"
+msgstr "A&justes"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:55
+msgctxt "@title:menu menubar:toplevel"
+msgid "E&xtensions"
+msgstr "E&xtensiones"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:89
+msgctxt "@title:menu menubar:toplevel"
+msgid "P&references"
+msgstr "Pre&ferencias"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:97
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Help"
+msgstr "A&yuda"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:124
+msgctxt "@title:window"
+msgid "New project"
+msgstr "Nuevo proyecto"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:125
+msgctxt "@info:question"
+msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
+msgstr "¿Está seguro de que desea iniciar un nuevo proyecto? Esto borrará la placa de impresión y cualquier ajuste no guardado."
+
+#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:88
msgctxt "@text Print job name"
msgid "Untitled"
msgstr "Sin título"
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:15
-msgctxt "@title:window"
-msgid "About Cura"
-msgstr "Acerca de Cura"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:55
-msgctxt "@label"
-msgid "version: %1"
-msgstr "versión: %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:69
-msgctxt "@label"
-msgid "End-to-end solution for fused filament 3D printing."
-msgstr "Solución completa para la impresión 3D de filamento fundido."
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:82
-msgctxt "@info:credit"
-msgid ""
-"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
-"Cura proudly uses the following open source projects:"
-msgstr "Ultimaker B.V. ha desarrollado Cura en cooperación con la comunidad.\nCura se enorgullece de utilizar los siguientes proyectos de código abierto:"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:132
-msgctxt "@label"
-msgid "Graphical user interface"
-msgstr "Interfaz gráfica de usuario (GUI)"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:133
-msgctxt "@label"
-msgid "Application framework"
-msgstr "Entorno de la aplicación"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:134
-msgctxt "@label"
-msgid "G-code generator"
-msgstr "Generador de GCode"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:135
-msgctxt "@label"
-msgid "Interprocess communication library"
-msgstr "Biblioteca de comunicación entre procesos"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:137
-msgctxt "@label"
-msgid "Programming language"
-msgstr "Lenguaje de programación"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:138
-msgctxt "@label"
-msgid "GUI framework"
-msgstr "Entorno de la GUI"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139
-msgctxt "@label"
-msgid "GUI framework bindings"
-msgstr "Enlaces del entorno de la GUI"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:140
-msgctxt "@label"
-msgid "C/C++ Binding library"
-msgstr "Biblioteca de enlaces C/C++"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:141
-msgctxt "@label"
-msgid "Data interchange format"
-msgstr "Formato de intercambio de datos"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:142
-msgctxt "@label"
-msgid "Support library for scientific computing"
-msgstr "Biblioteca de apoyo para cálculos científicos"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:143
-msgctxt "@label"
-msgid "Support library for faster math"
-msgstr "Biblioteca de apoyo para cálculos más rápidos"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:144
-msgctxt "@label"
-msgid "Support library for handling STL files"
-msgstr "Biblioteca de apoyo para gestionar archivos STL"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:145
-msgctxt "@label"
-msgid "Support library for handling planar objects"
-msgstr "Biblioteca de compatibilidad para trabajar con objetos planos"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:146
-msgctxt "@label"
-msgid "Support library for handling triangular meshes"
-msgstr "Biblioteca de compatibilidad para trabajar con mallas triangulares"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:147
-msgctxt "@label"
-msgid "Support library for analysis of complex networks"
-msgstr "Biblioteca de compatibilidad para analizar redes complejas"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:148
-msgctxt "@label"
-msgid "Support library for handling 3MF files"
-msgstr "Biblioteca de compatibilidad para trabajar con archivos 3MF"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:149
-msgctxt "@label"
-msgid "Support library for file metadata and streaming"
-msgstr "Biblioteca de compatibilidad para metadatos y transmisión de archivos"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:150
-msgctxt "@label"
-msgid "Serial communication library"
-msgstr "Biblioteca de comunicación en serie"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:151
-msgctxt "@label"
-msgid "ZeroConf discovery library"
-msgstr "Biblioteca de detección para Zeroconf"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:152
-msgctxt "@label"
-msgid "Polygon clipping library"
-msgstr "Biblioteca de recorte de polígonos"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:153
-msgctxt "@Label"
-msgid "Python HTTP library"
-msgstr "Biblioteca HTTP de Python"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:155
-msgctxt "@label"
-msgid "Font"
-msgstr "Fuente"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:156
-msgctxt "@label"
-msgid "SVG icons"
-msgstr "Iconos SVG"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:157
-msgctxt "@label"
-msgid "Linux cross-distribution application deployment"
-msgstr "Implementación de la aplicación de distribución múltiple de Linux"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:42
-msgctxt "@label"
-msgid "Profile:"
-msgstr "Perfil:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:104
-msgctxt "@tooltip"
-msgid ""
-"Some setting/override values are different from the values stored in the profile.\n"
-"\n"
-"Click to open the profile manager."
-msgstr "Algunos valores de los ajustes o sobrescrituras son distintos a los valores almacenados en el perfil.\n\nHaga clic para abrir el administrador de perfiles."
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:200
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:68
msgctxt "@label:textbox"
-msgid "Search..."
-msgstr "Buscar..."
+msgid "Search settings"
+msgstr "Buscar ajustes"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:545
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:462
msgctxt "@action:menu"
msgid "Copy value to all extruders"
msgstr "Copiar valor en todos los extrusores"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:554
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:471
msgctxt "@action:menu"
msgid "Copy all changed values to all extruders"
msgstr "Copiar todos los valores cambiados en todos los extrusores"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:591
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:508
msgctxt "@action:menu"
msgid "Hide this setting"
msgstr "Ocultar este ajuste"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:521
msgctxt "@action:menu"
msgid "Don't show this setting"
msgstr "No mostrar este ajuste"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:613
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:525
msgctxt "@action:menu"
msgid "Keep this setting visible"
msgstr "Mostrar este ajuste"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:637
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:417
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:434
msgctxt "@action:menu"
msgid "Configure setting visibility..."
msgstr "Configurar visibilidad de los ajustes..."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:644
-msgctxt "@action:inmenu"
-msgid "Collapse All"
-msgstr "Contraer todo"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:649
-msgctxt "@action:inmenu"
-msgid "Expand All"
-msgstr "Ampliar todo"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:253
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:237
msgctxt "@label"
msgid ""
"Some hidden settings use values different from their normal calculated value.\n"
"\n"
"Click to make these settings visible."
-msgstr "Algunos ajustes ocultos utilizan valores diferentes de los valores normales calculados.\n\nHaga clic para mostrar estos ajustes."
+msgstr ""
+"Algunos ajustes ocultos utilizan valores diferentes de los valores normales calculados.\n"
+"\n"
+"Haga clic para mostrar estos ajustes."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:81
+msgctxt "@label"
+msgid "This setting is not used because all the settings that it influences are overridden."
+msgstr "Este ajuste no se utiliza porque los ajustes a los que afecta están sobrescritos."
+
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:86
msgctxt "@label Header for list of settings."
msgid "Affects"
msgstr "Afecta a"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:91
msgctxt "@label Header for list of settings."
msgid "Affected By"
msgstr "Afectado por"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:187
msgctxt "@label"
msgid "This setting is always shared between all extruders. Changing it here will change the value for all extruders."
msgstr "Este ajuste siempre se comparte entre extrusores. Si lo modifica, modificará el valor de todos los extrusores."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:158
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:191
msgctxt "@label"
msgid "The value is resolved from per-extruder values "
msgstr "El valor se resuelve según los valores de los extrusores. "
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:189
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:230
msgctxt "@label"
msgid ""
"This setting has a value that is different from the profile.\n"
"\n"
"Click to restore the value of the profile."
-msgstr "Este ajuste tiene un valor distinto del perfil.\n\nHaga clic para restaurar el valor del perfil."
+msgstr ""
+"Este ajuste tiene un valor distinto del perfil.\n"
+"\n"
+"Haga clic para restaurar el valor del perfil."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:281
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:329
msgctxt "@label"
msgid ""
"This setting is normally calculated, but it currently has an absolute value set.\n"
"\n"
"Click to restore the calculated value."
-msgstr "Este ajuste se calcula normalmente pero actualmente tiene un valor absoluto establecido.\n\nHaga clic para restaurar el valor calculado."
+msgstr ""
+"Este ajuste se calcula normalmente pero actualmente tiene un valor absoluto establecido.\n"
+"\n"
+"Haga clic para restaurar el valor calculado."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/NoIntentIcon.qml:31
+msgctxt "@label %1 is filled in with the type of a profile. %2 is filled with a list of numbers (eg '1' or '1, 2')"
+msgid "There is no %1 profile for the configuration in extruder %2. The default intent will be used instead"
+msgid_plural "There is no %1 profile for the configurations in extruders %2. The default intent will be used instead"
+msgstr[0] ""
+msgstr[1] ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:144
+msgctxt "@button"
+msgid "Recommended"
+msgstr "Recomendado"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:158
+msgctxt "@button"
+msgid "Custom"
+msgstr "Personalizado"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:193
+msgctxt "@label"
+msgid "Gradual infill"
+msgstr "Relleno gradual"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:232
+msgctxt "@label"
+msgid "Gradual infill will gradually increase the amount of infill towards the top."
+msgstr "Un relleno gradual aumentará gradualmente la cantidad de relleno hacia arriba."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:30
+msgctxt "@label"
+msgid "Support"
+msgstr "Soporte"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:71
+msgctxt "@label"
+msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
+msgstr "Generar estructuras para soportar piezas del modelo que tengan voladizos. Sin estas estructuras, estas piezas se romperían durante la impresión."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:29
+msgctxt "@label"
+msgid "Adhesion"
+msgstr "Adherencia"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:74
+msgctxt "@label"
+msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
+msgstr "Habilita la impresión de un borde o una balsa. Esta opción agregará un área plana alrededor del objeto, que es fácil de cortar después."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:81
+msgctxt "@tooltip"
+msgid "You have modified some profile settings. If you want to change these go to custom mode."
+msgstr "Ha modificado algunos ajustes del perfil. Si desea cambiarlos, hágalo en el modo personalizado."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:13
+msgctxt "@label:Should be short"
+msgid "On"
+msgstr "Encendido"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:14
+msgctxt "@label:Should be short"
+msgid "Off"
+msgstr "Apagado"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:33
+msgctxt "@label"
+msgid "Experimental"
+msgstr "Experimental"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:47
+msgctxt "@label"
+msgid "Profile"
+msgstr "Perfil"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:172
+msgctxt "@tooltip"
+msgid ""
+"Some setting/override values are different from the values stored in the profile.\n"
+"\n"
+"Click to open the profile manager."
+msgstr ""
+"Algunos valores de los ajustes o sobrescrituras son distintos a los valores almacenados en el perfil.\n"
+"\n"
+"Haga clic para abrir el administrador de perfiles."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:160
+msgctxt "@label:header"
+msgid "Custom profiles"
+msgstr "Perfiles personalizados"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:21
+msgctxt "@label shown when we load a Gcode file"
+msgid "Print setup disabled. G-code file can not be modified."
+msgstr "Configuración de impresión deshabilitada. No se puede modificar el archivo GCode."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:52
msgctxt "@label"
msgid "Printer control"
msgstr "Control de impresoras"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:144
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:67
msgctxt "@label"
msgid "Jog Position"
msgstr "Posición de desplazamiento"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:85
msgctxt "@label"
msgid "X/Y"
msgstr "X/Y"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:192
msgctxt "@label"
msgid "Z"
msgstr "Z"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:257
msgctxt "@label"
msgid "Jog Distance"
msgstr "Distancia de desplazamiento"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:443
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:301
msgctxt "@label"
msgid "Send G-code"
msgstr "Enviar GCode"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:506
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:365
msgctxt "@tooltip of G-code command input"
msgid "Send a custom G-code command to the connected printer. Press 'enter' to send the command."
msgstr "Envíe un comando de GCode personalizado a la impresora conectada. Pulse «Intro» para enviar el comando."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:272
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:41
msgctxt "@label"
msgid "Extruder"
msgstr "Extrusor"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:71
msgctxt "@tooltip"
msgid "The target temperature of the hotend. The hotend will heat up or cool down towards this temperature. If this is 0, the hotend heating is turned off."
msgstr "Temperatura objetivo del extremo caliente. El extremo caliente se calentará o enfriará en función de esta temperatura. Si el valor es 0, el calentamiento del extremo caliente se desactivará."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:98
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:103
msgctxt "@tooltip"
msgid "The current temperature of this hotend."
msgstr "Temperatura actual de este extremo caliente."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:172
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:177
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the hotend to."
msgstr "Temperatura a la que se va a precalentar el extremo caliente."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:336
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:341
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:332
msgctxt "@button Cancel pre-heating"
msgid "Cancel"
msgstr "Cancelar"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:339
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:344
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:335
msgctxt "@button"
msgid "Pre-heat"
msgstr "Precalentar"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:365
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:370
msgctxt "@tooltip of pre-heat"
msgid "Heat the hotend in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the hotend to heat up when you're ready to print."
msgstr "Caliente el extremo caliente antes de imprimir. Puede continuar ajustando la impresión durante el calentamiento, así no tendrá que esperar a que el extremo caliente se caliente para poder imprimir."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:401
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:406
msgctxt "@tooltip"
msgid "The colour of the material in this extruder."
msgstr "Color del material en este extrusor."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:433
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:438
msgctxt "@tooltip"
msgid "The material in this extruder."
msgstr "Material en este extrusor."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:465
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:470
msgctxt "@tooltip"
msgid "The nozzle inserted in this extruder."
msgstr "Tobera insertada en este extrusor."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:25
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:493
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
+msgctxt "@info:status"
+msgid "The printer is not connected."
+msgstr "La impresora no está conectada."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:26
msgctxt "@label"
msgid "Build plate"
msgstr "Placa de impresión"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:56
msgctxt "@tooltip"
msgid "The target temperature of the heated bed. The bed will heat up or cool down towards this temperature. If this is 0, the bed heating is turned off."
msgstr "Temperatura objetivo de la plataforma calentada. La plataforma se calentará o enfriará en función de esta temperatura. Si el valor es 0, el calentamiento de la plataforma se desactivará."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:88
msgctxt "@tooltip"
msgid "The current temperature of the heated bed."
msgstr "Temperatura actual de la plataforma caliente."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:160
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:161
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the bed to."
msgstr "Temperatura a la que se va a precalentar la plataforma."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:361
msgctxt "@tooltip of pre-heat"
msgid "Heat the bed in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the bed to heat up when you're ready to print."
msgstr "Caliente la plataforma antes de imprimir. Puede continuar ajustando la impresión durante el calentamiento, así no tendrá que esperar a que la plataforma se caliente para poder imprimir."
@@ -3692,12 +3798,12 @@ msgctxt "@label:category menu label"
msgid "Material"
msgstr "Material"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:37
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:46
msgctxt "@label:category menu label"
msgid "Favorites"
msgstr "Favoritos"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:71
msgctxt "@label:category menu label"
msgid "Generic"
msgstr "Genérico"
@@ -3712,17 +3818,52 @@ msgctxt "@label:category menu label"
msgid "Local printers"
msgstr "Impresoras locales"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
-msgctxt "@title:menu menubar:toplevel"
-msgid "&View"
-msgstr "&Ver"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:15
+msgctxt "@title:menu menubar:settings"
+msgid "&Printer"
+msgstr "&Impresora"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:42
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:27
+msgctxt "@title:menu"
+msgid "&Material"
+msgstr "&Material"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:36
+msgctxt "@action:inmenu"
+msgid "Set as Active Extruder"
+msgstr "Definir como extrusor activo"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:42
+msgctxt "@action:inmenu"
+msgid "Enable Extruder"
+msgstr "Habilitar extrusor"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:49
+msgctxt "@action:inmenu"
+msgid "Disable Extruder"
+msgstr "Deshabilitar extrusor"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:19
msgctxt "@action:inmenu menubar:view"
msgid "&Camera position"
msgstr "&Posición de la cámara"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:58
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:44
+msgctxt "@action:inmenu menubar:view"
+msgid "Camera view"
+msgstr "Vista de cámara"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:47
+msgctxt "@action:inmenu menubar:view"
+msgid "Perspective"
+msgstr "Perspectiva"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:59
+msgctxt "@action:inmenu menubar:view"
+msgid "Orthographic"
+msgstr "Ortográfica"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:80
msgctxt "@action:inmenu menubar:view"
msgid "&Build plate"
msgstr "P&laca de impresión"
@@ -3742,6 +3883,21 @@ msgctxt "@action:inmenu"
msgid "Manage Setting Visibility..."
msgstr "Gestionar visibilidad de los ajustes..."
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:33
+msgctxt "@title:menu menubar:file"
+msgid "&Save..."
+msgstr "&Guardar..."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:54
+msgctxt "@title:menu menubar:file"
+msgid "&Export..."
+msgstr "&Exportar..."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:65
+msgctxt "@action:inmenu menubar:file"
+msgid "Export Selection..."
+msgstr "Exportar selección..."
+
#: /home/ruben/Projects/Cura/resources/qml/Menus/ContextMenu.qml:27
msgctxt "@label"
msgid "Print Selected Model With:"
@@ -3761,654 +3917,509 @@ msgctxt "@label"
msgid "Number of Copies"
msgstr "Número de copias"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:33
-msgctxt "@label:header configurations"
-msgid "Available configurations"
-msgstr "Configuraciones disponibles"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml:18
+msgctxt "@header"
+msgid "Configurations"
+msgstr "Configuraciones"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml:28
-msgctxt "@label:extruder label"
-msgid "Extruder"
-msgstr "Extrusor"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:112
+msgctxt "@label"
+msgid "Select configuration"
+msgstr "Seleccionar configuración"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "Yes"
-msgstr "Sí"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:223
+msgctxt "@label"
+msgid "Configurations"
+msgstr "Configuraciones"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "No"
-msgstr "No"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:57
+msgctxt "@label"
+msgid "Loading available configurations from the printer..."
+msgstr "Cargando configuraciones disponibles desde la impresora..."
-#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:13
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:58
+msgctxt "@label"
+msgid "The configurations are not available because the printer is disconnected."
+msgstr "Las configuraciones no se encuentran disponibles porque la impresora no está conectada."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:25
+msgctxt "@header"
+msgid "Custom"
+msgstr "Personalizado"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:61
+msgctxt "@label"
+msgid "Printer"
+msgstr "Impresora"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:213
+msgctxt "@label"
+msgid "Enabled"
+msgstr "Habilitado"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:251
+msgctxt "@label"
+msgid "Material"
+msgstr "Material"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:378
+msgctxt "@label"
+msgid "Use glue for better adhesion with this material combination."
+msgstr "Utilice pegamento con esta combinación de materiales para lograr una mejor adhesión."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:128
+msgctxt "@label"
+msgid "This configuration is not available because %1 is not recognized. Please visit %2 to download the correct material profile."
+msgstr "Esta configuración no se encuentra disponible porque %1 es un perfil desconocido. Visite %2 para descargar el perfil de materiales correcto."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:129
+msgctxt "@label"
+msgid "Marketplace"
+msgstr "Marketplace"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:15
msgctxt "@title:menu menubar:file"
msgid "Open &Recent"
msgstr "Abrir &reciente"
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid "Print Setup"
-msgstr "Configuración de impresión"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid ""
-"Print Setup disabled\n"
-"G-code files cannot be modified"
-msgstr "Ajustes de impresión deshabilitados\nNo se pueden modificar los archivos GCode"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:340
-msgctxt "@label Hours and minutes"
-msgid "00h 00min"
-msgstr "00 h 00 min"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:358
-msgctxt "@tooltip"
-msgid "Time specification"
-msgstr "Especificación de tiempos"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:440
-msgctxt "@label"
-msgid "Cost specification"
-msgstr "Especificación de costes"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:445
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:454
-msgctxt "@label m for meter"
-msgid "%1m"
-msgstr "%1 m"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:446
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:455
-msgctxt "@label g for grams"
-msgid "%1g"
-msgstr "%1 g"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:453
-msgctxt "@label"
-msgid "Total:"
-msgstr "Total:"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:576
-msgctxt "@tooltip"
-msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
-msgstr "Configuración de impresión recomendada
Imprimir con los ajustes recomendados para la impresora, el material y la calidad seleccionados."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:581
-msgctxt "@tooltip"
-msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
-msgstr "Configuración de impresión personalizada
Imprimir con un control muy detallado del proceso de segmentación."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:140
msgctxt "@label"
msgid "Active print"
msgstr "Activar impresión"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:148
msgctxt "@label"
msgid "Job Name"
msgstr "Nombre del trabajo"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:156
msgctxt "@label"
msgid "Printing Time"
msgstr "Tiempo de impresión"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:130
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:164
msgctxt "@label"
msgid "Estimated time left"
msgstr "Tiempo restante estimado"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:79
+#: /home/ruben/Projects/Cura/resources/qml/ViewsSelector.qml:50
+msgctxt "@label"
+msgid "View type"
+msgstr "Ver tipo"
+
+#: /home/ruben/Projects/Cura/resources/qml/ObjectSelector.qml:59
+msgctxt "@label"
+msgid "Object list"
+msgstr "Lista de objetos"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:22
+msgctxt "@label The argument is a username."
+msgid "Hi %1"
+msgstr "Hola, %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:33
+msgctxt "@button"
+msgid "Ultimaker account"
+msgstr "Cuenta de Ultimaker"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:42
+msgctxt "@button"
+msgid "Sign out"
+msgstr "Cerrar sesión"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/AccountWidget.qml:24
+msgctxt "@action:button"
+msgid "Sign in"
+msgstr "Iniciar sesión"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:40
+msgctxt "@label"
+msgid "The next generation 3D printing workflow"
+msgstr "El flujo de trabajo de impresión 3D de próxima generación"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:51
+msgctxt "@text"
+msgid ""
+"- Send print jobs to Ultimaker printers outside your local network\n"
+"- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+"- Get exclusive access to print profiles from leading brands"
+msgstr ""
+"- Envíe trabajos de impresión a impresoras Ultimaker fuera de su red local\n"
+"- Guarde su configuración de Ultimaker Cura en la nube para poder usarla en cualquier lugar\n"
+"- Disfrute de acceso exclusivo a perfiles de impresión de marcas líderes"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:78
+msgctxt "@button"
+msgid "Create account"
+msgstr "Crear cuenta"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:59
+msgctxt "@label"
+msgid "No time estimation available"
+msgstr "Ningún cálculo de tiempo disponible"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:77
+msgctxt "@label"
+msgid "No cost estimation available"
+msgstr "Ningún cálculo de costes disponible"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:127
+msgctxt "@button"
+msgid "Preview"
+msgstr "Vista previa"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:55
+msgctxt "@label:PrintjobStatus"
+msgid "Slicing..."
+msgstr "Segmentando..."
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:67
+msgctxt "@label:PrintjobStatus"
+msgid "Unable to slice"
+msgstr "No se puede segmentar"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Processing"
+msgstr "Procesando"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Slice"
+msgstr "Segmentación"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:104
+msgctxt "@label"
+msgid "Start the slicing process"
+msgstr "Iniciar el proceso de segmentación"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:118
+msgctxt "@button"
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:31
+msgctxt "@label"
+msgid "Time estimation"
+msgstr "Estimación de tiempos"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:114
+msgctxt "@label"
+msgid "Material estimation"
+msgstr "Estimación de material"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:164
+msgctxt "@label m for meter"
+msgid "%1m"
+msgstr "%1 m"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:165
+msgctxt "@label g for grams"
+msgid "%1g"
+msgstr "%1 g"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Connected printers"
+msgstr "Impresoras conectadas"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Preset printers"
+msgstr "Impresoras preconfiguradas"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:166
+msgctxt "@button"
+msgid "Add printer"
+msgstr "Agregar impresora"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:182
+msgctxt "@button"
+msgid "Manage printers"
+msgstr "Administrar impresoras"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:81
+msgctxt "@action:inmenu"
+msgid "Show Online Troubleshooting Guide"
+msgstr "Mostrar Guía de resolución de problemas en línea"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:88
msgctxt "@action:inmenu"
msgid "Toggle Full Screen"
msgstr "Alternar pantalla completa"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:86
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+msgctxt "@action:inmenu"
+msgid "Exit Full Screen"
+msgstr "Salir de modo de pantalla completa"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:103
msgctxt "@action:inmenu menubar:edit"
msgid "&Undo"
msgstr "Des&hacer"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
msgctxt "@action:inmenu menubar:edit"
msgid "&Redo"
msgstr "&Rehacer"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:123
msgctxt "@action:inmenu menubar:file"
msgid "&Quit"
msgstr "&Salir"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:131
msgctxt "@action:inmenu menubar:view"
msgid "3D View"
msgstr "Vista en 3D"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:138
msgctxt "@action:inmenu menubar:view"
msgid "Front View"
msgstr "Vista frontal"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:128
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:145
msgctxt "@action:inmenu menubar:view"
msgid "Top View"
msgstr "Vista superior"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:135
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:152
msgctxt "@action:inmenu menubar:view"
msgid "Left Side View"
msgstr "Vista del lado izquierdo"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:159
msgctxt "@action:inmenu menubar:view"
msgid "Right Side View"
msgstr "Vista del lado derecho"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:149
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:166
msgctxt "@action:inmenu"
msgid "Configure Cura..."
msgstr "Configurar Cura..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:156
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:173
msgctxt "@action:inmenu menubar:printer"
msgid "&Add Printer..."
msgstr "&Agregar impresora..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:179
msgctxt "@action:inmenu menubar:printer"
msgid "Manage Pr&inters..."
msgstr "Adm&inistrar impresoras ..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:169
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:186
msgctxt "@action:inmenu"
msgid "Manage Materials..."
msgstr "Administrar materiales..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:177
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:195
msgctxt "@action:inmenu menubar:profile"
msgid "&Update profile with current settings/overrides"
msgstr "&Actualizar perfil con ajustes o sobrescrituras actuales"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:185
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
msgctxt "@action:inmenu menubar:profile"
msgid "&Discard current changes"
msgstr "&Descartar cambios actuales"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:197
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:215
msgctxt "@action:inmenu menubar:profile"
msgid "&Create profile from current settings/overrides..."
msgstr "&Crear perfil a partir de ajustes o sobrescrituras actuales..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:221
msgctxt "@action:inmenu menubar:profile"
msgid "Manage Profiles..."
msgstr "Administrar perfiles..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:210
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:229
msgctxt "@action:inmenu menubar:help"
msgid "Show Online &Documentation"
msgstr "Mostrar &documentación en línea"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:218
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:237
msgctxt "@action:inmenu menubar:help"
msgid "Report a &Bug"
msgstr "Informar de un &error"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:226
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:245
+msgctxt "@action:inmenu menubar:help"
+msgid "What's New"
+msgstr "Novedades"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:251
msgctxt "@action:inmenu menubar:help"
msgid "About..."
msgstr "Acerca de..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:233
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:258
msgctxt "@action:inmenu menubar:edit"
msgid "Delete Selected Model"
msgid_plural "Delete Selected Models"
msgstr[0] "Eliminar modelo seleccionado"
msgstr[1] "Eliminar modelos seleccionados"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:243
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:268
msgctxt "@action:inmenu menubar:edit"
msgid "Center Selected Model"
msgid_plural "Center Selected Models"
msgstr[0] "Centrar modelo seleccionado"
msgstr[1] "Centrar modelos seleccionados"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:277
msgctxt "@action:inmenu menubar:edit"
msgid "Multiply Selected Model"
msgid_plural "Multiply Selected Models"
msgstr[0] "Multiplicar modelo seleccionado"
msgstr[1] "Multiplicar modelos seleccionados"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:261
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:286
msgctxt "@action:inmenu"
msgid "Delete Model"
msgstr "Eliminar modelo"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:294
msgctxt "@action:inmenu"
msgid "Ce&nter Model on Platform"
msgstr "Ce&ntrar modelo en plataforma"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:275
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:300
msgctxt "@action:inmenu menubar:edit"
msgid "&Group Models"
msgstr "A&grupar modelos"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:320
msgctxt "@action:inmenu menubar:edit"
msgid "Ungroup Models"
msgstr "Desagrupar modelos"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:305
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:330
msgctxt "@action:inmenu menubar:edit"
msgid "&Merge Models"
msgstr "Co&mbinar modelos"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:315
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:340
msgctxt "@action:inmenu"
msgid "&Multiply Model..."
msgstr "&Multiplicar modelo..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:322
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:347
msgctxt "@action:inmenu menubar:edit"
msgid "Select All Models"
msgstr "Seleccionar todos los modelos"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:332
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:357
msgctxt "@action:inmenu menubar:edit"
msgid "Clear Build Plate"
msgstr "Borrar placa de impresión"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:342
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:367
msgctxt "@action:inmenu menubar:file"
msgid "Reload All Models"
msgstr "Recargar todos los modelos"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:376
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models To All Build Plates"
msgstr "Organizar todos los modelos en todas las placas de impresión"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:358
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:383
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models"
msgstr "Organizar todos los modelos"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:366
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:391
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange Selection"
msgstr "Organizar selección"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:373
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:398
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Positions"
msgstr "Restablecer las posiciones de todos los modelos"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:380
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:405
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Transformations"
msgstr "Restablecer las transformaciones de todos los modelos"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:387
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:412
msgctxt "@action:inmenu menubar:file"
msgid "&Open File(s)..."
msgstr "&Abrir archivo(s)..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:395
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:420
msgctxt "@action:inmenu menubar:file"
msgid "&New Project..."
msgstr "&Nuevo proyecto..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:402
-msgctxt "@action:inmenu menubar:help"
-msgid "Show Engine &Log..."
-msgstr "&Mostrar registro del motor..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:410
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:427
msgctxt "@action:inmenu menubar:help"
msgid "Show Configuration Folder"
msgstr "Mostrar carpeta de configuración"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:424
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:441
msgctxt "@action:menu"
-msgid "Browse packages..."
-msgstr "Examinar paquetes..."
+msgid "&Marketplace"
+msgstr "&Marketplace"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:431
-msgctxt "@action:inmenu menubar:view"
-msgid "Expand/Collapse Sidebar"
-msgstr "Expandir/contraer barra lateral"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:27
-msgctxt "@label:PrintjobStatus"
-msgid "Please load a 3D model"
-msgstr "Cargue un modelo en 3D"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:37
-msgctxt "@label:PrintjobStatus"
-msgid "Ready to slice"
-msgstr "Preparado para segmentar"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:39
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing..."
-msgstr "Segmentando..."
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:41
-msgctxt "@label:PrintjobStatus %1 is target operation"
-msgid "Ready to %1"
-msgstr "Listo para %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:43
-msgctxt "@label:PrintjobStatus"
-msgid "Unable to Slice"
-msgstr "No se puede segmentar"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:45
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing unavailable"
-msgstr "No se puede segmentar"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Slice current printjob"
-msgstr "Fragmentar trabajo de impresión actual"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Cancel slicing process"
-msgstr "Cancelar proceso de fragmentación"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Prepare"
-msgstr "Preparar"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:320
-msgctxt "@info:tooltip"
-msgid "Select the active output device"
-msgstr "Seleccione el dispositivo de salida activo"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:19
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:767
-msgctxt "@title:window"
-msgid "Open file(s)"
-msgstr "Abrir archivo(s)"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:64
-msgctxt "@text:window"
-msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
-msgstr "Hemos encontrado uno o más archivos del proyecto entre los archivos que ha seleccionado. Solo puede abrir los archivos de proyecto de uno en uno. Le recomendamos que solo importe modelos de esos archivos. ¿Desea continuar?"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:99
-msgctxt "@action:button"
-msgid "Import all as models"
-msgstr "Importar todos como modelos"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:19
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:24
msgctxt "@title:window"
msgid "Ultimaker Cura"
msgstr "Ultimaker Cura"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:103
-msgctxt "@title:menu menubar:toplevel"
-msgid "&File"
-msgstr "&Archivo"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:121
-msgctxt "@title:menu menubar:file"
-msgid "&Save..."
-msgstr "&Guardar..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:142
-msgctxt "@title:menu menubar:file"
-msgid "&Export..."
-msgstr "&Exportar..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:153
-msgctxt "@action:inmenu menubar:file"
-msgid "Export Selection..."
-msgstr "Exportar selección..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:174
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Edit"
-msgstr "&Edición"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:191
-msgctxt "@title:menu"
-msgid "&View"
-msgstr "&Ver"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:196
-msgctxt "@title:menu"
-msgid "&Settings"
-msgstr "A&justes"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:198
-msgctxt "@title:menu menubar:settings"
-msgid "&Printer"
-msgstr "&Impresora"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:207
-msgctxt "@title:menu"
-msgid "&Material"
-msgstr "&Material"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:216
-msgctxt "@action:inmenu"
-msgid "Set as Active Extruder"
-msgstr "Definir como extrusor activo"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:222
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:188
-msgctxt "@action:inmenu"
-msgid "Enable Extruder"
-msgstr "Habilitar extrusor"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:229
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:194
-msgctxt "@action:inmenu"
-msgid "Disable Extruder"
-msgstr "Deshabilitar extrusor"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:241
-msgctxt "@title:menu"
-msgid "&Build plate"
-msgstr "&Placa de impresión"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:242
-msgctxt "@title:settings"
-msgid "&Profile"
-msgstr "&Perfil"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:252
-msgctxt "@title:menu menubar:toplevel"
-msgid "E&xtensions"
-msgstr "E&xtensiones"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:286
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Toolbox"
-msgstr "&Cuadro de herramientas"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:294
-msgctxt "@title:menu menubar:toplevel"
-msgid "P&references"
-msgstr "Pre&ferencias"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:302
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Help"
-msgstr "A&yuda"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:232
msgctxt "@label"
msgid "This package will be installed after restarting."
msgstr "Este paquete se instalará después de reiniciar."
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:377
-msgctxt "@action:button"
-msgid "Open File"
-msgstr "Abrir archivo"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:547
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:413
msgctxt "@title:tab"
msgid "Settings"
msgstr "Ajustes"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:593
-msgctxt "@title:window"
-msgid "New project"
-msgstr "Nuevo proyecto"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:594
-msgctxt "@info:question"
-msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
-msgstr "¿Está seguro de que desea iniciar un nuevo proyecto? Esto borrará la placa de impresión y cualquier ajuste no guardado."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:722
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:538
msgctxt "@title:window"
msgid "Closing Cura"
msgstr "Cerrando Cura"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:723
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:735
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
msgctxt "@label"
msgid "Are you sure you want to exit Cura?"
msgstr "¿Seguro que desea salir de Cura?"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:868
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:589
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:19
+msgctxt "@title:window"
+msgid "Open file(s)"
+msgstr "Abrir archivo(s)"
+
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:695
msgctxt "@window:title"
msgid "Install Package"
msgstr "Instalar paquete"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:875
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:703
msgctxt "@title:window"
msgid "Open File(s)"
msgstr "Abrir archivo(s)"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:878
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:706
msgctxt "@text:window"
msgid "We have found one or more G-Code files within the files you have selected. You can only open one G-Code file at a time. If you want to open a G-Code file, please just select only one."
msgstr "Hemos encontrado uno o más archivos de GCode entre los archivos que ha seleccionado. Solo puede abrir los archivos GCode de uno en uno. Si desea abrir un archivo GCode, seleccione solo uno."
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:14
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:809
msgctxt "@title:window"
-msgid "Save Project"
-msgstr "Guardar proyecto"
+msgid "Add Printer"
+msgstr "Agregar impresora"
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:137
-msgctxt "@action:label"
-msgid "Build plate"
-msgstr "Placa de impresión"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:169
-msgctxt "@action:label"
-msgid "Extruder %1"
-msgstr "Extrusor %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:179
-msgctxt "@action:label"
-msgid "%1 & material"
-msgstr "%1 y material"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:268
-msgctxt "@action:label"
-msgid "Don't show project summary on save again"
-msgstr "No mostrar resumen de proyecto al guardar de nuevo"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:287
-msgctxt "@action:button"
-msgid "Save"
-msgstr "Guardar"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:192
-msgctxt "@label"
-msgid "Layer Height"
-msgstr "Altura de capa"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:277
-msgctxt "@tooltip"
-msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
-msgstr "Este perfil de calidad no está disponible para la configuración de material y de tobera actual. Cámbiela para poder habilitar este perfil de calidad"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:450
-msgctxt "@tooltip"
-msgid "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab"
-msgstr "Hay un perfil personalizado activado en este momento. Para habilitar el control deslizante de calidad, seleccione un perfil de calidad predeterminado en la pestaña Personalizado"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:467
-msgctxt "@label"
-msgid "Print Speed"
-msgstr "Velocidad de impresión"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:479
-msgctxt "@label"
-msgid "Slower"
-msgstr "Más lento"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:490
-msgctxt "@label"
-msgid "Faster"
-msgstr "Más rápido"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:518
-msgctxt "@tooltip"
-msgid "You have modified some profile settings. If you want to change these go to custom mode."
-msgstr "Ha modificado algunos ajustes del perfil. Si desea cambiarlos, hágalo en el modo personalizado."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:541
-msgctxt "@label"
-msgid "Infill"
-msgstr "Relleno"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:777
-msgctxt "@label"
-msgid "Gradual infill will gradually increase the amount of infill towards the top."
-msgstr "Un relleno gradual aumentará gradualmente la cantidad de relleno hacia arriba."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:791
-msgctxt "@label"
-msgid "Enable gradual"
-msgstr "Habilitar gradual"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:858
-msgctxt "@label"
-msgid "Generate Support"
-msgstr "Generar soporte"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:892
-msgctxt "@label"
-msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
-msgstr "Generar estructuras para soportar piezas del modelo que tengan voladizos. Sin estas estructuras, estas piezas se romperían durante la impresión."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:964
-msgctxt "@label"
-msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
-msgstr "Seleccione qué extrusor se utilizará como soporte. Esta opción formará estructuras de soporte por debajo del modelo para evitar que éste se combe o la impresión se haga en el aire."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:987
-msgctxt "@label"
-msgid "Build Plate Adhesion"
-msgstr "Adherencia de la placa de impresión"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1042
-msgctxt "@label"
-msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
-msgstr "Habilita la impresión de un borde o una balsa. Esta opción agregará un área plana alrededor del objeto, que es fácil de cortar después."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1082
-msgctxt "@label"
-msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
-msgstr "¿Necesita ayuda para mejorar sus impresiones? Lea las Guías de solución de problemas de Ultimaker"
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:817
+msgctxt "@title:window"
+msgid "What's New"
+msgstr "Novedades"
#: /home/ruben/Projects/Cura/resources/qml/ExtruderButton.qml:16
msgctxt "@label %1 is filled in with the name of an extruder"
@@ -4417,75 +4428,503 @@ msgid_plural "Print Selected Models with %1"
msgstr[0] "Imprimir modelo seleccionado con %1"
msgstr[1] "Imprimir modelos seleccionados con %1"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:20
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:15
+msgctxt "@title:window"
+msgid "Discard or Keep changes"
+msgstr "Descartar o guardar cambios"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:57
+msgctxt "@text:window"
+msgid ""
+"You have customized some profile settings.\n"
+"Would you like to keep or discard those settings?"
+msgstr ""
+"Ha personalizado parte de los ajustes del perfil.\n"
+"¿Desea descartar los cambios o guardarlos?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:110
+msgctxt "@title:column"
+msgid "Profile settings"
+msgstr "Ajustes del perfil"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:117
+msgctxt "@title:column"
+msgid "Default"
+msgstr "Valor predeterminado"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:124
+msgctxt "@title:column"
+msgid "Customized"
+msgstr "Valor personalizado"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:158
+msgctxt "@option:discardOrKeep"
+msgid "Discard and never ask again"
+msgstr "Descartar y no volver a preguntar"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:159
+msgctxt "@option:discardOrKeep"
+msgid "Keep and never ask again"
+msgstr "Guardar y no volver a preguntar"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:196
+msgctxt "@action:button"
+msgid "Discard"
+msgstr "Descartar"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:209
+msgctxt "@action:button"
+msgid "Keep"
+msgstr "Guardar"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:222
+msgctxt "@action:button"
+msgid "Create New Profile"
+msgstr "Crear nuevo perfil"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:15
+msgctxt "@title:window"
+msgid "About Cura"
+msgstr "Acerca de Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:57
+msgctxt "@label"
+msgid "version: %1"
+msgstr "versión: %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:72
+msgctxt "@label"
+msgid "End-to-end solution for fused filament 3D printing."
+msgstr "Solución completa para la impresión 3D de filamento fundido."
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:85
+msgctxt "@info:credit"
+msgid ""
+"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
+"Cura proudly uses the following open source projects:"
+msgstr ""
+"Ultimaker B.V. ha desarrollado Cura en cooperación con la comunidad.\n"
+"Cura se enorgullece de utilizar los siguientes proyectos de código abierto:"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:135
+msgctxt "@label"
+msgid "Graphical user interface"
+msgstr "Interfaz gráfica de usuario (GUI)"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:136
+msgctxt "@label"
+msgid "Application framework"
+msgstr "Entorno de la aplicación"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:137
+msgctxt "@label"
+msgid "G-code generator"
+msgstr "Generador de GCode"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:138
+msgctxt "@label"
+msgid "Interprocess communication library"
+msgstr "Biblioteca de comunicación entre procesos"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:140
+msgctxt "@label"
+msgid "Programming language"
+msgstr "Lenguaje de programación"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:141
+msgctxt "@label"
+msgid "GUI framework"
+msgstr "Entorno de la GUI"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:142
+msgctxt "@label"
+msgid "GUI framework bindings"
+msgstr "Enlaces del entorno de la GUI"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:143
+msgctxt "@label"
+msgid "C/C++ Binding library"
+msgstr "Biblioteca de enlaces C/C++"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:144
+msgctxt "@label"
+msgid "Data interchange format"
+msgstr "Formato de intercambio de datos"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:145
+msgctxt "@label"
+msgid "Support library for scientific computing"
+msgstr "Biblioteca de apoyo para cálculos científicos"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:146
+msgctxt "@label"
+msgid "Support library for faster math"
+msgstr "Biblioteca de apoyo para cálculos más rápidos"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:147
+msgctxt "@label"
+msgid "Support library for handling STL files"
+msgstr "Biblioteca de apoyo para gestionar archivos STL"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:148
+msgctxt "@label"
+msgid "Support library for handling planar objects"
+msgstr "Biblioteca de compatibilidad para trabajar con objetos planos"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:149
+msgctxt "@label"
+msgid "Support library for handling triangular meshes"
+msgstr "Biblioteca de compatibilidad para trabajar con mallas triangulares"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:150
+msgctxt "@label"
+msgid "Support library for analysis of complex networks"
+msgstr "Biblioteca de compatibilidad para analizar redes complejas"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:151
+msgctxt "@label"
+msgid "Support library for handling 3MF files"
+msgstr "Biblioteca de compatibilidad para trabajar con archivos 3MF"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:152
+msgctxt "@label"
+msgid "Support library for file metadata and streaming"
+msgstr "Biblioteca de compatibilidad para metadatos y transmisión de archivos"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:153
+msgctxt "@label"
+msgid "Serial communication library"
+msgstr "Biblioteca de comunicación en serie"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:154
+msgctxt "@label"
+msgid "ZeroConf discovery library"
+msgstr "Biblioteca de detección para Zeroconf"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:155
+msgctxt "@label"
+msgid "Polygon clipping library"
+msgstr "Biblioteca de recorte de polígonos"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:156
+msgctxt "@Label"
+msgid "Python HTTP library"
+msgstr "Biblioteca HTTP de Python"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:158
+msgctxt "@label"
+msgid "Font"
+msgstr "Fuente"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:159
+msgctxt "@label"
+msgid "SVG icons"
+msgstr "Iconos SVG"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:160
+msgctxt "@label"
+msgid "Linux cross-distribution application deployment"
+msgstr "Implementación de la aplicación de distribución múltiple de Linux"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:64
+msgctxt "@text:window"
+msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
+msgstr "Hemos encontrado uno o más archivos del proyecto entre los archivos que ha seleccionado. Solo puede abrir los archivos de proyecto de uno en uno. Le recomendamos que solo importe modelos de esos archivos. ¿Desea continuar?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:99
+msgctxt "@action:button"
+msgid "Import all as models"
+msgstr "Importar todos como modelos"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:15
+msgctxt "@title:window"
+msgid "Save Project"
+msgstr "Guardar proyecto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:177
+msgctxt "@action:label"
+msgid "Extruder %1"
+msgstr "Extrusor %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:192
+msgctxt "@action:label"
+msgid "%1 & material"
+msgstr "%1 y material"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:194
+msgctxt "@action:label"
+msgid "Material"
+msgstr "Material"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:283
+msgctxt "@action:label"
+msgid "Don't show project summary on save again"
+msgstr "No mostrar resumen de proyecto al guardar de nuevo"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:302
+msgctxt "@action:button"
+msgid "Save"
+msgstr "Guardar"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:20
msgctxt "@title:window"
msgid "Open project file"
msgstr "Abrir archivo de proyecto"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:93
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:93
msgctxt "@text:window"
msgid "This is a Cura project file. Would you like to open it as a project or import the models from it?"
msgstr "Este es un archivo de proyecto Cura. ¿Le gustaría abrirlo como un proyecto o importar sus modelos?"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:103
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:103
msgctxt "@text:window"
msgid "Remember my choice"
msgstr "Recordar mi selección"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:122
msgctxt "@action:button"
msgid "Open as project"
msgstr "Abrir como proyecto"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:131
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:131
msgctxt "@action:button"
msgid "Import models"
msgstr "Importar modelos"
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15
-msgctxt "@title:window"
-msgid "Engine Log"
-msgstr "Registro del motor"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:70
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DropDownWidget.qml:93
msgctxt "@label"
-msgid "Printer type"
-msgstr "Tipo de impresora"
+msgid "Empty"
+msgstr "Vacío"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:376
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:24
msgctxt "@label"
-msgid "Material"
-msgstr "Material"
+msgid "Add a printer"
+msgstr "Agregar una impresora"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:543
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:39
msgctxt "@label"
-msgid "Use glue with this material combination"
-msgstr "Utilizar pegamento con esta combinación de materiales"
+msgid "Add a networked printer"
+msgstr "Agregar una impresora en red"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:575
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:81
msgctxt "@label"
-msgid "Check compatibility"
-msgstr "Comprobar compatibilidad"
+msgid "Add a non-networked printer"
+msgstr "Agregar una impresora fuera de red"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:593
-msgctxt "@tooltip"
-msgid "Click to check the material compatibility on Ultimaker.com."
-msgstr "Haga clic para comprobar la compatibilidad de los materiales en Utimaker.com."
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:70
+msgctxt "@label"
+msgid "Add printer by IP address"
+msgstr "Agregar impresora por dirección IP"
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:211
-msgctxt "@option:check"
-msgid "See only current build plate"
-msgstr "Ver solo placa de impresión actual"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:133
+msgctxt "@text"
+msgid "Place enter your printer's IP address."
+msgstr "Introduzca la dirección IP de su impresora."
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:227
-msgctxt "@action:button"
-msgid "Arrange to all build plates"
-msgstr "Organizar todas las placas de impresión"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:158
+msgctxt "@button"
+msgid "Add"
+msgstr "Agregar"
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:247
-msgctxt "@action:button"
-msgid "Arrange current build plate"
-msgstr "Organizar placa de impresión actual"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:204
+msgctxt "@label"
+msgid "Could not connect to device."
+msgstr "No se ha podido conectar al dispositivo."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:208
+msgctxt "@label"
+msgid "The printer at this address has not responded yet."
+msgstr "La impresora todavía no ha respondido en esta dirección."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:240
+msgctxt "@label"
+msgid "This printer cannot be added because it's an unknown printer or it's not the host of a group."
+msgstr "No se puede agregar la impresora porque es desconocida o no aloja un grupo."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:329
+msgctxt "@button"
+msgid "Back"
+msgstr "Atrás"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:342
+msgctxt "@button"
+msgid "Connect"
+msgstr "Conectar"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/FirstStartMachineActionsContent.qml:77
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:123
+msgctxt "@button"
+msgid "Next"
+msgstr "Siguiente"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:23
+msgctxt "@label"
+msgid "User Agreement"
+msgstr "Acuerdo de usuario"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:56
+msgctxt "@button"
+msgid "Agree"
+msgstr "Estoy de acuerdo"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:70
+msgctxt "@button"
+msgid "Decline and close"
+msgstr "Rechazar y cerrar"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:24
+msgctxt "@label"
+msgid "Help us to improve Ultimaker Cura"
+msgstr "Ayúdenos a mejorar Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:57
+msgctxt "@text"
+msgid "Ultimaker Cura collects anonymous data to improve print quality and user experience, including:"
+msgstr "Ultimaker Cura recopila datos anónimos para mejorar la calidad de impresión y la experiencia de usuario, entre otros:"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:71
+msgctxt "@text"
+msgid "Machine types"
+msgstr "Tipos de máquina"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:77
+msgctxt "@text"
+msgid "Material usage"
+msgstr "Uso de material"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:83
+msgctxt "@text"
+msgid "Number of slices"
+msgstr "Número de segmentos"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:89
+msgctxt "@text"
+msgid "Print settings"
+msgstr "Ajustes de impresión"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:102
+msgctxt "@text"
+msgid "Data collected by Ultimaker Cura will not contain any personal information."
+msgstr "Los datos recopilados por Ultimaker Cura no contendrán información personal."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:103
+msgctxt "@text"
+msgid "More information"
+msgstr "Más información"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WhatsNewContent.qml:24
+msgctxt "@label"
+msgid "What's new in Ultimaker Cura"
+msgstr "Novedades en Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:42
+msgctxt "@label"
+msgid "There is no printer found over your network."
+msgstr "No se ha encontrado ninguna impresora en su red."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:179
+msgctxt "@label"
+msgid "Refresh"
+msgstr "Actualizar"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:190
+msgctxt "@label"
+msgid "Add printer by IP"
+msgstr "Agregar impresora por IP"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:223
+msgctxt "@label"
+msgid "Troubleshooting"
+msgstr "Solución de problemas"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:211
+msgctxt "@label"
+msgid "Printer name"
+msgstr "Nombre de la impresora"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:224
+msgctxt "@text"
+msgid "Please give your printer a name"
+msgstr "Indique un nombre para su impresora"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:36
+msgctxt "@label"
+msgid "Ultimaker Cloud"
+msgstr "Ultimaker Cloud"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:77
+msgctxt "@text"
+msgid "The next generation 3D printing workflow"
+msgstr "El flujo de trabajo de impresión 3D de próxima generación"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:94
+msgctxt "@text"
+msgid "- Send print jobs to Ultimaker printers outside your local network"
+msgstr "- Envíe trabajos de impresión a impresoras Ultimaker fuera de su red local"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:97
+msgctxt "@text"
+msgid "- Store your Ultimaker Cura settings in the cloud for use anywhere"
+msgstr "- Guarde su configuración de Ultimaker Cura en la nube para poder usarla en cualquier lugar"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:100
+msgctxt "@text"
+msgid "- Get exclusive access to print profiles from leading brands"
+msgstr "- Disfrute de acceso exclusivo a perfiles de impresión de marcas líderes"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:119
+msgctxt "@button"
+msgid "Finish"
+msgstr "Finalizar"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:128
+msgctxt "@button"
+msgid "Create an account"
+msgstr "Crear una cuenta"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:29
+msgctxt "@label"
+msgid "Welcome to Ultimaker Cura"
+msgstr "Le damos la bienvenida a Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:47
+msgctxt "@text"
+msgid ""
+"Please follow these steps to set up\n"
+"Ultimaker Cura. This will only take a few moments."
+msgstr ""
+"Siga estos pasos para configurar\n"
+"Ultimaker Cura. Solo le llevará unos minutos."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:58
+msgctxt "@button"
+msgid "Get started"
+msgstr "Empezar"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:27
+msgctxt "@info:tooltip"
+msgid "3D View"
+msgstr "Vista en 3D"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:40
+msgctxt "@info:tooltip"
+msgid "Front View"
+msgstr "Vista frontal"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:53
+msgctxt "@info:tooltip"
+msgid "Top View"
+msgstr "Vista superior"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:66
+msgctxt "@info:tooltip"
+msgid "Left View"
+msgstr "Vista del lado izquierdo"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:79
+msgctxt "@info:tooltip"
+msgid "Right View"
+msgstr "Vista del lado derecho"
#: MachineSettingsAction/plugin.json
msgctxt "description"
@@ -4547,26 +4986,6 @@ msgctxt "name"
msgid "Model Checker"
msgstr "Comprobador de modelos"
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "description"
-msgid "Dump the contents of all settings to a HTML file."
-msgstr "Vuelva el contenido de todas las configuraciones en un archivo HTML."
-
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "name"
-msgid "God Mode"
-msgstr "God Mode"
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "description"
-msgid "Shows changes since latest checked version."
-msgstr "Muestra los cambios desde la última versión comprobada."
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "name"
-msgid "Changelog"
-msgstr "Registro de cambios"
-
#: FirmwareUpdater/plugin.json
msgctxt "description"
msgid "Provides a machine actions for updating firmware."
@@ -4577,15 +4996,15 @@ msgctxt "name"
msgid "Firmware Updater"
msgstr "Actualizador de firmware"
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "description"
-msgid "Create a flattend quality changes profile."
-msgstr "Crear un perfil de cambios de calidad aplanado."
+msgid "Provides support for reading AMF files."
+msgstr "Proporciona asistencia para leer archivos AMF."
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "name"
-msgid "Profile flatener"
-msgstr "Aplanador de perfil"
+msgid "AMF Reader"
+msgstr "Lector de AMF"
#: USBPrinting/plugin.json
msgctxt "description"
@@ -4597,26 +5016,6 @@ msgctxt "name"
msgid "USB printing"
msgstr "Impresión USB"
-#: UserAgreement/plugin.json
-msgctxt "description"
-msgid "Ask the user once if he/she agrees with our license."
-msgstr "Preguntar al usuario una vez si acepta la licencia."
-
-#: UserAgreement/plugin.json
-msgctxt "name"
-msgid "UserAgreement"
-msgstr "UserAgreement"
-
-#: X3GWriter/plugin.json
-msgctxt "description"
-msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
-msgstr "Permite guardar el segmento resultante como un archivo X3G para dar compatibilidad a impresoras que leen este formato (Malyan, Makerbot y otras impresoras basadas en Sailfish)."
-
-#: X3GWriter/plugin.json
-msgctxt "name"
-msgid "X3GWriter"
-msgstr "X3GWriter"
-
#: GCodeGzWriter/plugin.json
msgctxt "description"
msgid "Writes g-code to a compressed archive."
@@ -4659,13 +5058,13 @@ msgstr "Complemento de dispositivo de salida de unidad extraíble"
#: UM3NetworkPrinting/plugin.json
msgctxt "description"
-msgid "Manages network connections to Ultimaker 3 printers."
-msgstr "Gestiona las conexiones de red a las impresoras Ultimaker 3."
+msgid "Manages network connections to Ultimaker networked printers."
+msgstr "Gestiona las conexiones de red de las impresoras Ultimaker conectadas."
#: UM3NetworkPrinting/plugin.json
msgctxt "name"
-msgid "UM3 Network Connection"
-msgstr "Conexión de red UM3"
+msgid "Ultimaker Network Connection"
+msgstr "Conexión en red de Ultimaker"
#: MonitorStage/plugin.json
msgctxt "description"
@@ -4727,6 +5126,16 @@ msgctxt "name"
msgid "Support Eraser"
msgstr "Borrador de soporte"
+#: UFPReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading Ultimaker Format Packages."
+msgstr "Proporciona soporte para la lectura de paquetes de formato Ultimaker."
+
+#: UFPReader/plugin.json
+msgctxt "name"
+msgid "UFP Reader"
+msgstr "Lector de UFP"
+
#: SliceInfoPlugin/plugin.json
msgctxt "description"
msgid "Submits anonymous slice info. Can be disabled through preferences."
@@ -4787,6 +5196,16 @@ msgctxt "name"
msgid "Version Upgrade 3.3 to 3.4"
msgstr "Actualización de la versión 3.3 a la 3.4"
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.3 to Cura 4.4."
+msgstr "Actualiza la configuración de Cura 4.3 a Cura 4.4."
+
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.3 to 4.4"
+msgstr "Actualización de la versión 4.3 a la 4.4"
+
#: VersionUpgrade/VersionUpgrade25to26/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.5 to Cura 2.6."
@@ -4807,6 +5226,16 @@ msgctxt "name"
msgid "Version Upgrade 2.7 to 3.0"
msgstr "Actualización de la versión 2.7 a la 3.0"
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 3.5 to Cura 4.0."
+msgstr "Actualiza la configuración de Cura 3.5 a Cura 4.0."
+
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 3.5 to 4.0"
+msgstr "Actualización de la versión 3.5 a la 4.0"
+
#: VersionUpgrade/VersionUpgrade34to35/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.4 to Cura 3.5."
@@ -4817,6 +5246,16 @@ msgctxt "name"
msgid "Version Upgrade 3.4 to 3.5"
msgstr "Actualización de la versión 3.4 a la 3.5"
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.0 to Cura 4.1."
+msgstr "Actualiza la configuración de Cura 4.0 a Cura 4.1."
+
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.0 to 4.1"
+msgstr "Actualización de la versión 4.0 a la 4.1"
+
#: VersionUpgrade/VersionUpgrade30to31/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.0 to Cura 3.1."
@@ -4827,6 +5266,16 @@ msgctxt "name"
msgid "Version Upgrade 3.0 to 3.1"
msgstr "Actualización de la versión 3.0 a la 3.1"
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.1 to Cura 4.2."
+msgstr "Actualiza la configuración de Cura 4.1 a Cura 4.2."
+
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.1 to 4.2"
+msgstr "Actualización de la versión 4.1 a la 4.2"
+
#: VersionUpgrade/VersionUpgrade26to27/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.6 to Cura 2.7."
@@ -4857,6 +5306,16 @@ msgctxt "name"
msgid "Version Upgrade 2.2 to 2.4"
msgstr "Actualización de la versión 2.2 a la 2.4"
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.2 to Cura 4.3."
+msgstr "Actualiza la configuración de Cura 4.2 a Cura 4.3."
+
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.2 to 4.3"
+msgstr "Actualización de la versión 4.2 a la 4.3"
+
#: ImageReader/plugin.json
msgctxt "description"
msgid "Enables ability to generate printable geometry from 2D image files."
@@ -4867,6 +5326,16 @@ msgctxt "name"
msgid "Image Reader"
msgstr "Lector de imágenes"
+#: TrimeshReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading model files."
+msgstr "Proporciona asistencia para leer archivos 3D."
+
+#: TrimeshReader/plugin.json
+msgctxt "name"
+msgid "Trimesh Reader"
+msgstr "Lector Trimesh"
+
#: CuraEngineBackend/plugin.json
msgctxt "description"
msgid "Provides the link to the CuraEngine slicing backend."
@@ -4917,6 +5386,16 @@ msgctxt "name"
msgid "G-code Reader"
msgstr "Lector de GCode"
+#: CuraDrive/plugin.json
+msgctxt "description"
+msgid "Backup and restore your configuration."
+msgstr "Realice una copia de seguridad de su configuración y restáurela."
+
+#: CuraDrive/plugin.json
+msgctxt "name"
+msgid "Cura Backups"
+msgstr "Copias de seguridad de Cura"
+
#: CuraProfileWriter/plugin.json
msgctxt "description"
msgid "Provides support for exporting Cura profiles."
@@ -4937,6 +5416,16 @@ msgctxt "name"
msgid "3MF Writer"
msgstr "Escritor de 3MF"
+#: PreviewStage/plugin.json
+msgctxt "description"
+msgid "Provides a preview stage in Cura."
+msgstr "Proporciona una fase de vista previa en Cura."
+
+#: PreviewStage/plugin.json
+msgctxt "name"
+msgid "Preview Stage"
+msgstr "Fase de vista previa"
+
#: UltimakerMachineActions/plugin.json
msgctxt "description"
msgid "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.)."
@@ -4957,9 +5446,29 @@ msgctxt "name"
msgid "Cura Profile Reader"
msgstr "Lector de perfiles de Cura"
-#~ msgctxt "@warning:status"
-#~ msgid "Please generate G-code before saving."
-#~ msgstr "Genere un G-code antes de guardar."
+#~ msgctxt "@item:inmenu"
+#~ msgid "Flatten active settings"
+#~ msgstr "Aplanar ajustes activos"
+
+#~ msgctxt "@info:status"
+#~ msgid "Profile has been flattened & activated."
+#~ msgstr "El perfil se ha aplanado y activado."
+
+#~ msgctxt "X3g Writer Plugin Description"
+#~ msgid "Writes X3g to files"
+#~ msgstr "Escribe X3g en archivos"
+
+#~ msgctxt "X3g Writer File Description"
+#~ msgid "X3g File"
+#~ msgstr "Archivo X3g"
+
+#~ msgctxt "X3G Writer File Description"
+#~ msgid "X3G File"
+#~ msgstr "Archivo X3G"
+
+#~ msgctxt "@item:inlistbox"
+#~ msgid "Open Compressed Triangle Mesh"
+#~ msgstr ""
#~ msgctxt "@item:inmenu"
#~ msgid "Profile Assistant"
@@ -4969,6 +5478,1032 @@ msgstr "Lector de perfiles de Cura"
#~ msgid "Profile Assistant"
#~ msgstr "Asistente del perfil"
+#~ msgctxt "@action:button"
+#~ msgid "Retry"
+#~ msgstr "Volver a intentar"
+
+#~ msgctxt "@label:table_header"
+#~ msgid "Print Core"
+#~ msgstr "Print core"
+
+#~ msgctxt "@label"
+#~ msgid "Don't support overlap with other models"
+#~ msgstr "No crear soporte en otros modelos (por superposición)"
+
+#~ msgctxt "@label"
+#~ msgid "Modify settings for overlap with other models"
+#~ msgstr "Modificar ajustes de otros modelos (por superposición)"
+
+#~ msgctxt "@label"
+#~ msgid "Modify settings for infill of other models"
+#~ msgstr "Modificar ajustes del relleno de otros modelos"
+
+#~ msgctxt "@action:ComboBox option"
+#~ msgid "Update existing"
+#~ msgstr "Actualizar existente"
+
+#~ msgctxt "@label"
+#~ msgid "Not supported"
+#~ msgstr "No compatible"
+
+#~ msgctxt "@action:button"
+#~ msgid "Previous"
+#~ msgstr "Anterior"
+
+#~ msgctxt "@label"
+#~ msgid "Tip"
+#~ msgstr "Consejo"
+
+#~ msgctxt "@label"
+#~ msgid "Print experiment"
+#~ msgstr "Ensayo de impresión"
+
+#~ msgctxt "@label"
+#~ msgid "Checklist"
+#~ msgstr "Lista de verificación"
+
+#~ msgctxt "@label"
+#~ msgid "Please select any upgrades made to this Ultimaker 2."
+#~ msgstr "Seleccione cualquier actualización de este Ultimaker 2."
+
+#~ msgctxt "@label"
+#~ msgid "Olsson Block"
+#~ msgstr "Bloque Olsson"
+
+#~ msgctxt "@window:text"
+#~ msgid "Camera rendering: "
+#~ msgstr "Renderizado de cámara: "
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Use multi build plate functionality"
+#~ msgstr "Utilizar funcionalidad de placa de impresión múltiple"
+
+#~ msgctxt "@option:check"
+#~ msgid "Use multi build plate functionality (restart required)"
+#~ msgstr "Utilizar funcionalidad de placa de impresión múltiple (reinicio requerido)"
+
+#~ msgctxt "@label"
+#~ msgid "Default profiles"
+#~ msgstr "Perfiles predeterminados"
+
+#~ msgctxt "@label:textbox"
+#~ msgid "search settings"
+#~ msgstr "buscar ajustes"
+
+#~ msgctxt "@label"
+#~ msgid "Layer Height"
+#~ msgstr "Altura de capa"
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile."
+#~ msgstr "Este perfil de calidad no se encuentra disponible para su configuración de material y tobera actual. Cámbielas para poder habilitar este perfil de calidad."
+
+#~ msgctxt "@tooltip"
+#~ msgid "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab"
+#~ msgstr "Hay un perfil personalizado activado en este momento. Para habilitar el control deslizante de calidad, seleccione un perfil de calidad predeterminado en la pestaña Personalizado"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Build plate"
+#~ msgstr "&Placa de impresión"
+
+#~ msgctxt "@title:settings"
+#~ msgid "&Profile"
+#~ msgstr "&Perfil"
+
+#~ msgctxt "@action:label"
+#~ msgid "Build plate"
+#~ msgstr "Placa de impresión"
+
+#~ msgctxt "description"
+#~ msgid "Dump the contents of all settings to a HTML file."
+#~ msgstr "Vuelva el contenido de todas las configuraciones en un archivo HTML."
+
+#~ msgctxt "name"
+#~ msgid "God Mode"
+#~ msgstr "God Mode"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattened quality changes profile."
+#~ msgstr "Crear un perfil de cambios de calidad aplanado."
+
+#~ msgctxt "name"
+#~ msgid "Profile Flattener"
+#~ msgstr "Aplanador de perfil"
+
+#~ msgctxt "description"
+#~ msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
+#~ msgstr "Permite a los fabricantes de material crear nuevos perfiles de material y calidad mediante una IU integrada."
+
+#~ msgctxt "name"
+#~ msgid "Print Profile Assistant"
+#~ msgstr "Imprimir asistente del perfil"
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network."
+#~ msgstr "Conectado a través de la red."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. Please approve the access request on the printer."
+#~ msgstr "Conectado a través de la red. Apruebe la solicitud de acceso en la impresora."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. No access to control the printer."
+#~ msgstr "Conectado a través de la red. No hay acceso para controlar la impresora."
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer requested. Please approve the request on the printer"
+#~ msgstr "Acceso a la impresora solicitado. Apruebe la solicitud en la impresora"
+
+#~ msgctxt "@info:title"
+#~ msgid "Authentication status"
+#~ msgstr "Estado de la autenticación"
+
+#~ msgctxt "@info:title"
+#~ msgid "Authentication Status"
+#~ msgstr "Estado de la autenticación"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Re-send the access request"
+#~ msgstr "Reenvía la solicitud de acceso"
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer accepted"
+#~ msgstr "Acceso a la impresora aceptado"
+
+#~ msgctxt "@info:status"
+#~ msgid "No access to print with this printer. Unable to send print job."
+#~ msgstr "No hay acceso para imprimir con esta impresora. No se puede enviar el trabajo de impresión."
+
+#~ msgctxt "@action:button"
+#~ msgid "Request Access"
+#~ msgstr "Solicitar acceso"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Send access request to the printer"
+#~ msgstr "Envía la solicitud de acceso a la impresora"
+
+#~ msgctxt "@label"
+#~ msgid "Unable to start a new print job."
+#~ msgstr "No se puede iniciar un nuevo trabajo de impresión."
+
+#~ msgctxt "@label"
+#~ msgid "There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. Please resolve this issues before continuing."
+#~ msgstr "Un problema con la configuración de Ultimaker impide iniciar la impresión. Soluciónelo antes de continuar."
+
+#~ msgctxt "@window:title"
+#~ msgid "Mismatched configuration"
+#~ msgstr "Configuración desajustada"
+
+#~ msgctxt "@label"
+#~ msgid "Are you sure you wish to print with the selected configuration?"
+#~ msgstr "¿Seguro que desea imprimir con la configuración seleccionada?"
+
+#~ msgctxt "@label"
+#~ msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "La configuración o calibración de la impresora y de Cura no coinciden. Para obtener el mejor resultado, segmente siempre los PrintCores y los materiales que se insertan en la impresora."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending new jobs (temporarily) blocked, still sending the previous print job."
+#~ msgstr "Envío de nuevos trabajos (temporalmente) bloqueado; se sigue enviando el trabajo de impresión previo."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending data to printer"
+#~ msgstr "Enviando datos a la impresora"
+
+#~ msgctxt "@info:title"
+#~ msgid "Sending Data"
+#~ msgstr "Enviando datos"
+
+#~ msgctxt "@info:status"
+#~ msgid "No Printcore loaded in slot {slot_number}"
+#~ msgstr "No se ha cargado ningún PrintCore en la ranura {slot_number}."
+
+#~ msgctxt "@info:status"
+#~ msgid "No material loaded in slot {slot_number}"
+#~ msgstr "No se ha cargado ningún material en la ranura {slot_number}."
+
+#~ msgctxt "@label"
+#~ msgid "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}"
+#~ msgstr "PrintCore distinto (Cura: {cura_printcore_name}, impresora: {remote_printcore_name}) seleccionado para extrusor {extruder_id}"
+
+#~ msgctxt "@label"
+#~ msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
+#~ msgstr "Material distinto (Cura: {0}, impresora: {1}) seleccionado para extrusor {2}"
+
+#~ msgctxt "@window:title"
+#~ msgid "Sync with your printer"
+#~ msgstr "Sincronizar con la impresora"
+
+#~ msgctxt "@label"
+#~ msgid "Would you like to use your current printer configuration in Cura?"
+#~ msgstr "¿Desea utilizar la configuración actual de su impresora en Cura?"
+
+#~ msgctxt "@label"
+#~ msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "Los PrintCores o los materiales de la impresora difieren de los del proyecto actual. Para obtener el mejor resultado, segmente siempre los PrintCores y materiales que se hayan insertado en la impresora."
+
+#~ msgctxt "@action:button"
+#~ msgid "View in Monitor"
+#~ msgstr "Ver en pantalla"
+
+#~ msgctxt "@info:status"
+#~ msgid "Printer '{printer_name}' has finished printing '{job_name}'."
+#~ msgstr "{printer_name} ha terminado de imprimir «{job_name}»."
+
+#~ msgctxt "@info:status"
+#~ msgid "The print job '{job_name}' was finished."
+#~ msgstr "El trabajo de impresión '{job_name}' ha terminado."
+
+#~ msgctxt "@info:status"
+#~ msgid "Print finished"
+#~ msgstr "Impresión terminada"
+
+#~ msgctxt "@label:material"
+#~ msgid "Empty"
+#~ msgstr "Vacío"
+
+#~ msgctxt "@label:material"
+#~ msgid "Unknown"
+#~ msgstr "Desconocido"
+
+#~ msgctxt "@info:title"
+#~ msgid "Cloud error"
+#~ msgstr "Error de Cloud"
+
+#~ msgctxt "@info:status"
+#~ msgid "Could not export print job."
+#~ msgstr "No se ha podido exportar el trabajo de impresión."
+
+#~ msgctxt "@info:description"
+#~ msgid "There was an error connecting to the cloud."
+#~ msgstr "Se ha producido un error al conectarse a la nube."
+
+#~ msgctxt "@info:status"
+#~ msgid "Uploading via Ultimaker Cloud"
+#~ msgstr "Cargando a través de Ultimaker Cloud"
+
+#~ msgctxt "@info:status Ultimaker Cloud is a brand name and shouldn't be translated."
+#~ msgid "Connect to Ultimaker Cloud"
+#~ msgstr "Conectar a Ultimaker Cloud"
+
+#~ msgctxt "@action"
+#~ msgid "Don't ask me again for this printer."
+#~ msgstr "No volver a preguntarme para esta impresora."
+
+#~ msgctxt "@info:status"
+#~ msgid "You can now send and monitor print jobs from anywhere using your Ultimaker account."
+#~ msgstr "Ahora ya puede enviar y supervisar sus trabajos de impresión desde cualquier lugar a través de su cuenta de Ultimaker."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected!"
+#~ msgstr "¡Conectado!"
+
+#~ msgctxt "@action"
+#~ msgid "Review your connection"
+#~ msgstr "Revise su conexión"
+
+#~ msgctxt "@info:status Don't translate the XML tags !"
+#~ msgid "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it."
+#~ msgstr "El equipo definido en el perfil {0} ({1}) no coincide con el equipo actual ({2}), no se ha podido importar."
+
+#~ msgctxt "@info:status Don't translate the XML tags or !"
+#~ msgid "Failed to import profile from {0}:"
+#~ msgstr "Error al importar el perfil de {0}:"
+
+#~ msgctxt "@window:title"
+#~ msgid "Existing Connection"
+#~ msgstr "Conexión existente"
+
+#~ msgctxt "@message:text"
+#~ msgid "This printer/group is already added to Cura. Please select another printer/group."
+#~ msgstr "Esta impresora o grupo de impresoras ya se ha añadido a Cura. Seleccione otra impresora o grupo de impresoras."
+
+#~ msgctxt "@label"
+#~ msgid "Enter the IP address or hostname of your printer on the network."
+#~ msgstr "Introduzca la dirección IP o el nombre de host de la impresora en la red."
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Connect to a printer"
+#~ msgstr "Conecta a una impresora"
+
+#~ msgctxt "@title"
+#~ msgid "Cura Settings Guide"
+#~ msgstr "Guía de ajustes de Cura"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Zooming towards the mouse is not supported in the orthogonal perspective."
+#~ msgstr "Hacer zoom en la dirección del ratón no es compatible con la perspectiva ortogonal."
+
+#~ msgid "Orthogonal"
+#~ msgstr "Ortográfica"
+
+#~ msgctxt "description"
+#~ msgid "Manages network connections to Ultimaker 3 printers."
+#~ msgstr "Gestiona las conexiones de red a las impresoras Ultimaker 3."
+
+#~ msgctxt "name"
+#~ msgid "UM3 Network Connection"
+#~ msgstr "Conexión de red UM3"
+
+#~ msgctxt "description"
+#~ msgid "Provides extra information and explanations about settings in Cura, with images and animations."
+#~ msgstr "Proporciona información y explicaciones adicionales sobre los ajustes de Cura con imágenes y animaciones."
+
+#~ msgctxt "name"
+#~ msgid "Settings Guide"
+#~ msgstr "Guía de ajustes"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Cura Settings Guide"
+#~ msgstr "Guía de ajustes de Cura"
+
+#~ msgctxt "@info:generic"
+#~ msgid "Settings have been changed to match the current availability of extruders: [%s]"
+#~ msgstr "La configuración se ha cambiado para que coincida con los extrusores disponibles en este momento: [%s]."
+
+#~ msgctxt "@title:groupbox"
+#~ msgid "User description"
+#~ msgstr "Descripción del usuario"
+
+#~ msgctxt "@info"
+#~ msgid "These options are not available because you are monitoring a cloud printer."
+#~ msgstr "Estas opciones no se encuentran disponibles porque está supervisando una impresora en la nube."
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Go to Cura Connect"
+#~ msgstr "Ir a Cura Connect"
+
+#~ msgctxt "@info"
+#~ msgid "All jobs are printed."
+#~ msgstr "Se han imprimido todos los trabajos."
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "View print history"
+#~ msgstr "Ver historial de impresión"
+
+#~ msgctxt "@label"
+#~ msgid ""
+#~ "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
+#~ "\n"
+#~ "Select your printer from the list below:"
+#~ msgstr ""
+#~ "Para imprimir directamente en la impresora a través de la red, asegúrese de que ésta está conectada a la red utilizando un cable de red o conéctela a la red wifi. Si no conecta Cura con la impresora, también puede utilizar una unidad USB para transferir archivos GCode a la impresora.\n"
+#~ "\n"
+#~ "Seleccione la impresora de la siguiente lista:"
+
+#~ msgctxt "@info"
+#~ msgid ""
+#~ "Please make sure your printer has a connection:\n"
+#~ "- Check if the printer is turned on.\n"
+#~ "- Check if the printer is connected to the network."
+#~ msgstr ""
+#~ "Asegúrese de que su impresora está conectada:\n"
+#~ "- Compruebe que la impresora está encendida.\n"
+#~ "- Compruebe que la impresora está conectada a la red."
+
+#~ msgctxt "@option:check"
+#~ msgid "See only current build plate"
+#~ msgstr "Ver solo placa de impresión actual"
+
+#~ msgctxt "@action:button"
+#~ msgid "Arrange to all build plates"
+#~ msgstr "Organizar todas las placas de impresión"
+
+#~ msgctxt "@action:button"
+#~ msgid "Arrange current build plate"
+#~ msgstr "Organizar placa de impresión actual"
+
+#~ msgctxt "description"
+#~ msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
+#~ msgstr "Permite guardar el segmento resultante como un archivo X3G para dar compatibilidad a impresoras que leen este formato (Malyan, Makerbot y otras impresoras basadas en Sailfish)."
+
+#~ msgctxt "name"
+#~ msgid "X3GWriter"
+#~ msgstr "X3GWriter"
+
+#~ msgctxt "description"
+#~ msgid "Reads SVG files as toolpaths, for debugging printer movements."
+#~ msgstr "Lee archivos SVG como trayectorias de herramienta para solucionar errores en los movimientos de la impresora."
+
+#~ msgctxt "name"
+#~ msgid "SVG Toolpath Reader"
+#~ msgstr "Lector de trayectoria de herramienta de SVG"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Changelog"
+#~ msgstr "Registro de cambios"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Show Changelog"
+#~ msgstr "Mostrar registro de cambios"
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending data to remote cluster"
+#~ msgstr "Enviando datos al clúster remoto"
+
+#~ msgctxt "@info:status"
+#~ msgid "Connect to Ultimaker Cloud"
+#~ msgstr "Conectar a Ultimaker Cloud"
+
+#~ msgctxt "@info"
+#~ msgid "Cura collects anonymized usage statistics."
+#~ msgstr "Cura recopila estadísticas de uso de forma anónima."
+
+#~ msgctxt "@info:title"
+#~ msgid "Collecting Data"
+#~ msgstr "Recopilando datos"
+
+#~ msgctxt "@action:button"
+#~ msgid "More info"
+#~ msgstr "Más información"
+
+#~ msgctxt "@action:tooltip"
+#~ msgid "See more information on what data Cura sends."
+#~ msgstr "Obtenga más información sobre qué datos envía Cura."
+
+#~ msgctxt "@action:button"
+#~ msgid "Allow"
+#~ msgstr "Permitir"
+
+#~ msgctxt "@action:tooltip"
+#~ msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
+#~ msgstr "Permitir a Cura enviar estadísticas de uso de forma anónima para ayudar a priorizar mejoras futuras para Cura. Se envían algunas de sus preferencias y ajustes, la versión de Cura y un resumen de los modelos que está fragmentando."
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Evaluation"
+#~ msgstr "Evaluación"
+
+#~ msgctxt "@info:title"
+#~ msgid "Network enabled printers"
+#~ msgstr "Impresoras de red habilitadas"
+
+#~ msgctxt "@info:title"
+#~ msgid "Local printers"
+#~ msgstr "Impresoras locales"
+
+#~ msgctxt "@info:backup_failed"
+#~ msgid "Tried to restore a Cura backup that does not match your current version."
+#~ msgstr "Se ha intentado restaurar una copia de seguridad de Cura que no coincide con la versión actual."
+
+#~ msgctxt "@title"
+#~ msgid "Machine Settings"
+#~ msgstr "Ajustes de la máquina"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Settings"
+#~ msgstr "Ajustes de la impresora"
+
+#~ msgctxt "@option:check"
+#~ msgid "Origin at center"
+#~ msgstr "Origen en el centro"
+
+#~ msgctxt "@option:check"
+#~ msgid "Heated bed"
+#~ msgstr "Plataforma caliente"
+
+#~ msgctxt "@label"
+#~ msgid "Printhead Settings"
+#~ msgstr "Ajustes del cabezal de impresión"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distancia desde la parte izquierda del cabezal de impresión hasta el centro de la tobera. Se usa para evitar que colisionen la impresión anterior con el cabezal de impresión al imprimir «de uno en uno»."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distancia desde la parte frontal del cabezal de impresión hasta el centro de la tobera. Se usa para evitar que colisionen la impresión anterior con el cabezal de impresión al imprimir «de uno en uno»."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distancia desde la parte derecha del cabezal de impresión hasta el centro de la tobera. Se usa para evitar que colisionen la impresión anterior con el cabezal de impresión al imprimir «de uno en uno»."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distancia desde la parte trasera del cabezal de impresión hasta el centro de la tobera. Se usa para evitar que colisionen la impresión anterior con el cabezal de impresión al imprimir «de uno en uno»."
+
+#~ msgctxt "@label"
+#~ msgid "Gantry height"
+#~ msgstr "Altura del caballete"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
+#~ msgstr "Diferencia de altura entre la punta de la tobera y el sistema del puente (ejes X e Y). Se usa para evitar que colisionen la impresión anterior con el caballete al imprimir «de uno en uno»."
+
+#~ msgctxt "@label"
+#~ msgid "Start G-code"
+#~ msgstr "Iniciar GCode"
+
+#~ msgctxt "@tooltip"
+#~ msgid "G-code commands to be executed at the very start."
+#~ msgstr "Los comandos de GCode que se ejecutarán justo al inicio."
+
+#~ msgctxt "@label"
+#~ msgid "End G-code"
+#~ msgstr "Finalizar GCode"
+
+#~ msgctxt "@tooltip"
+#~ msgid "G-code commands to be executed at the very end."
+#~ msgstr "Los comandos de GCode que se ejecutarán justo al final."
+
+#~ msgctxt "@label"
+#~ msgid "Nozzle Settings"
+#~ msgstr "Ajustes de la tobera"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
+#~ msgstr "El diámetro nominal del filamento compatible con la impresora. El diámetro exacto se sobrescribirá según el material o el perfil."
+
+#~ msgctxt "@label"
+#~ msgid "Extruder Start G-code"
+#~ msgstr "GCode inicial del extrusor"
+
+#~ msgctxt "@label"
+#~ msgid "Extruder End G-code"
+#~ msgstr "GCode final del extrusor"
+
+#~ msgctxt "@label"
+#~ msgid "Changelog"
+#~ msgstr "Registro de cambios"
+
+#~ msgctxt "@title:window"
+#~ msgid "User Agreement"
+#~ msgstr "Acuerdo de usuario"
+
+#~ msgctxt "@alabel"
+#~ msgid "Enter the IP address or hostname of your printer on the network."
+#~ msgstr "Introduzca la dirección IP o el nombre de host de la impresora en red."
+
+#~ msgctxt "@info"
+#~ msgid "Please select a network connected printer to monitor."
+#~ msgstr "Seleccione la impresora conectada a la red que desee supervisar."
+
+#~ msgctxt "@info"
+#~ msgid "Please connect your Ultimaker printer to your local network."
+#~ msgstr "Conecte su impresora Ultimaker a su red local."
+
+#~ msgctxt "@text:window"
+#~ msgid "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent."
+#~ msgstr "Cura envía datos anónimos a Ultimaker para mejorar la calidad de impresión y la experiencia de usuario. A continuación, hay un ejemplo de todos los datos que se han enviado."
+
+#~ msgctxt "@text:window"
+#~ msgid "I don't want to send this data"
+#~ msgstr "No deseo enviar estos datos"
+
+#~ msgctxt "@text:window"
+#~ msgid "Allow sending this data to Ultimaker and help us improve Cura"
+#~ msgstr "Permita que estos datos se envíen a Ultimaker y ayúdenos a mejorar Cura"
+
+#~ msgctxt "@label"
+#~ msgid "No print selected"
+#~ msgstr "No ha seleccionado ninguna impresora"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
+#~ msgstr "De manera predeterminada, los píxeles blancos representan los puntos altos de la malla y los píxeles negros representan los puntos bajos de la malla. Cambie esta opción para invertir el comportamiento de tal manera que los píxeles negros representen los puntos altos de la malla y los píxeles blancos representen los puntos bajos de la malla."
+
+#~ msgctxt "@title"
+#~ msgid "Select Printer Upgrades"
+#~ msgstr "Seleccionar actualizaciones de impresora"
+
+#~ msgctxt "@label"
+#~ msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
+#~ msgstr "Seleccione qué extrusor se utilizará como soporte. Esta opción formará estructuras de soporte por debajo del modelo para evitar que éste se combe o la impresión se haga en el aire."
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile"
+#~ msgstr "Este perfil de calidad no se encuentra disponible para su configuración de material y tobera actual. Cámbiela para poder habilitar este perfil de calidad."
+
+#~ msgctxt "@label shown when we load a Gcode file"
+#~ msgid "Print setup disabled. G code file can not be modified."
+#~ msgstr "Configuración de impresión deshabilitada. No se puede modificar el GCode."
+
+#~ msgctxt "@label"
+#~ msgid "See the material compatibility chart"
+#~ msgstr "Ver el gráfico de compatibilidad de materiales"
+
+#~ msgctxt "@label"
+#~ msgid "View types"
+#~ msgstr "Ver tipos"
+
+#~ msgctxt "@label"
+#~ msgid "Hi "
+#~ msgstr "Hola "
+
+#~ msgctxt "@text"
+#~ msgid ""
+#~ "- Send print jobs to Ultimaker printers outside your local network\n"
+#~ "- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+#~ "- Get exclusive access to material profiles from leading brands"
+#~ msgstr ""
+#~ "- Envíe trabajos de impresión a impresoras Ultimaker fuera de su red local\n"
+#~ "- Guarde su configuración de Ultimaker Cura en la nube para poder usarla en cualquier lugar\n"
+#~ "- Disfrute de acceso exclusivo a perfiles de materiales de marcas líderes"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Unable to Slice"
+#~ msgstr "No se puede segmentar"
+
+#~ msgctxt "@label"
+#~ msgid "Time specification"
+#~ msgstr "Especificación de tiempos"
+
+#~ msgctxt "@label"
+#~ msgid "Material specification"
+#~ msgstr "Especificación de materiales"
+
+#~ msgctxt "@title:tab"
+#~ msgid "Add a printer to Cura"
+#~ msgstr "Añadir una impresora a Cura"
+
+#~ msgctxt "@title:tab"
+#~ msgid ""
+#~ "Select the printer you want to use from the list below.\n"
+#~ "\n"
+#~ "If your printer is not in the list, use the \"Custom FFF Printer\" from the \"Custom\" category and adjust the settings to match your printer in the next dialog."
+#~ msgstr ""
+#~ "Seleccione la impresora que desee utilizar de la lista que se muestra a continuación.\n"
+#~ "\n"
+#~ "Si no encuentra su impresora en la lista, utilice la opción \"Custom FFF Printer\" (Impresora FFF personalizada) de la categoría Personalizado y configure los ajustes para adaptarlos a su impresora en el siguiente cuadro de diálogo."
+
+#~ msgctxt "@label"
+#~ msgid "Manufacturer"
+#~ msgstr "Fabricante"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Name"
+#~ msgstr "Nombre de la impresora"
+
+#~ msgctxt "@action:button"
+#~ msgid "Add Printer"
+#~ msgstr "Agregar impresora"
+
+#~ msgid "Modify G-Code"
+#~ msgstr "Modificar GCode"
+
+#~ msgctxt "@info:status"
+#~ msgid "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."
+#~ msgstr "No hay nada que segmentar porque ninguno de los modelos se adapta al volumen de impresión. Escale o rote los modelos para que se adapten."
+
+#~ msgctxt "@info:status"
+#~ msgid "The selected material is incompatible with the selected machine or configuration."
+#~ msgstr "El material seleccionado no es compatible con la máquina o la configuración seleccionada."
+
+#~ msgctxt "@info:title"
+#~ msgid "Incompatible Material"
+#~ msgstr "Material incompatible"
+
+#~ msgctxt "@info:status Don't translate the XML tags or !"
+#~ msgid "Failed to import profile from {0}: {1}"
+#~ msgstr "Error al importar el perfil de {0}: {1}"
+
+#~ msgctxt "@title"
+#~ msgid "Toolbox"
+#~ msgstr "Cuadro de herramientas"
+
+#~ msgctxt "@label"
+#~ msgid "Not available"
+#~ msgstr "No disponible"
+
+#~ msgctxt "@label"
+#~ msgid "Unreachable"
+#~ msgstr "No se puede conectar"
+
+#~ msgctxt "@label"
+#~ msgid "Available"
+#~ msgstr "Disponible"
+
+#~ msgctxt "@label:status"
+#~ msgid "Preparing"
+#~ msgstr "Preparando"
+
+#~ msgctxt "@label:status"
+#~ msgid "Pausing"
+#~ msgstr "Pausando"
+
+#~ msgctxt "@label:status"
+#~ msgid "Resuming"
+#~ msgstr "Reanudando"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: Unavailable printer"
+#~ msgstr "Esperando: impresora no disponible"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: First available"
+#~ msgstr "Esperando: primera disponible"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: "
+#~ msgstr "Esperando: "
+
+#~ msgctxt "@label"
+#~ msgid "Configuration change"
+#~ msgstr "Cambio de configuración"
+
+#~ msgctxt "@label"
+#~ msgid "The assigned printer, %1, requires the following configuration change(s):"
+#~ msgstr "Es necesario modificar la siguiente configuración de la impresora asignada %1:"
+
+#~ msgctxt "@label"
+#~ msgid "Override"
+#~ msgstr "Anular"
+
+#~ msgctxt "@label"
+#~ msgid "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?"
+#~ msgstr "Iniciar un trabajo de impresión con una configuración no compatible puede causar daños en su impresora 3D. ¿Seguro de que desea sobrescribir la configuración e imprimir %1?"
+
+#~ msgctxt "@window:title"
+#~ msgid "Override configuration configuration and start print"
+#~ msgstr "Sobrescribir la configuración e iniciar la impresión"
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Manage queue"
+#~ msgstr "Administrar cola"
+
+#~ msgctxt "@label"
+#~ msgid "Printing"
+#~ msgstr "Imprimiendo"
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Manage printers"
+#~ msgstr "Administrar impresoras"
+
+#~ msgctxt "@action:button"
+#~ msgid "Activate Configuration"
+#~ msgstr "Activar configuración"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Load the configuration of the printer into Cura"
+#~ msgstr "Carga la configuración de la impresora en Cura"
+
+#~ msgctxt "@label"
+#~ msgid "Show Travels"
+#~ msgstr "Mostrar desplazamientos"
+
+#~ msgctxt "@label"
+#~ msgid "Show Helpers"
+#~ msgstr "Mostrar asistentes"
+
+#~ msgctxt "@label"
+#~ msgid "Show Shell"
+#~ msgstr "Mostrar perímetro"
+
+#~ msgctxt "@label"
+#~ msgid "Show Infill"
+#~ msgstr "Mostrar relleno"
+
+#~ msgctxt "@text:window"
+#~ msgid "I don't want to send these data"
+#~ msgstr "No quiero enviar estos datos"
+
+#~ msgctxt "@text:window"
+#~ msgid "Allow sending these data to Ultimaker and help us improve Cura"
+#~ msgstr "Permita enviar estos datos a Ultimaker y ayúdenos a mejorar Cura"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type:"
+#~ msgstr "Tipo de impresora:"
+
+#~ msgctxt "@label"
+#~ msgid "Connection:"
+#~ msgstr "Conexión:"
+
+#~ msgctxt "@label"
+#~ msgid "State:"
+#~ msgstr "Estado:"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for a printjob"
+#~ msgstr "Esperando un trabajo de impresión"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for someone to clear the build plate"
+#~ msgstr "Esperando a que alguien limpie la placa de impresión"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Aborting print..."
+#~ msgstr "Cancelando impresión..."
+
+#~ msgctxt "@label"
+#~ msgid "Protected profiles"
+#~ msgstr "Perfiles protegidos"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Name:"
+#~ msgstr "Nombre de la impresora:"
+
+#~ msgctxt "@label"
+#~ msgid "Profile:"
+#~ msgstr "Perfil:"
+
+#~ msgctxt "@label:textbox"
+#~ msgid "Search..."
+#~ msgstr "Buscar..."
+
+#~ msgctxt "@action:inmenu"
+#~ msgid "Collapse All"
+#~ msgstr "Contraer todo"
+
+#~ msgctxt "@action:inmenu"
+#~ msgid "Expand All"
+#~ msgstr "Ampliar todo"
+
+#~ msgctxt "@label:header configurations"
+#~ msgid "Available configurations"
+#~ msgstr "Configuraciones disponibles"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "Extruder"
+#~ msgstr "Extrusor"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "Yes"
+#~ msgstr "Sí"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "No"
+#~ msgstr "No"
+
+#~ msgctxt "@label:listbox"
+#~ msgid "Print Setup"
+#~ msgstr "Configuración de impresión"
+
+#~ msgctxt "@label:listbox"
+#~ msgid ""
+#~ "Print Setup disabled\n"
+#~ "G-code files cannot be modified"
+#~ msgstr ""
+#~ "Ajustes de impresión deshabilitados\n"
+#~ "No se pueden modificar los archivos GCode"
+
+#~ msgctxt "@label Hours and minutes"
+#~ msgid "00h 00min"
+#~ msgstr "00 h 00 min"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Time specification"
+#~ msgstr "Especificación de tiempos"
+
+#~ msgctxt "@label"
+#~ msgid "Cost specification"
+#~ msgstr "Especificación de costes"
+
+#~ msgctxt "@label"
+#~ msgid "Total:"
+#~ msgstr "Total:"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
+#~ msgstr "Configuración de impresión recomendada
Imprimir con los ajustes recomendados para la impresora, el material y la calidad seleccionados."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
+#~ msgstr "Configuración de impresión personalizada
Imprimir con un control muy detallado del proceso de segmentación."
+
+#~ msgctxt "@action:inmenu menubar:help"
+#~ msgid "Show Engine &Log..."
+#~ msgstr "&Mostrar registro del motor..."
+
+#~ msgctxt "@action:menu"
+#~ msgid "Browse packages..."
+#~ msgstr "Examinar paquetes..."
+
+#~ msgctxt "@action:inmenu menubar:view"
+#~ msgid "Expand/Collapse Sidebar"
+#~ msgstr "Expandir/contraer barra lateral"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Please load a 3D model"
+#~ msgstr "Cargue un modelo en 3D"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Ready to slice"
+#~ msgstr "Preparado para segmentar"
+
+#~ msgctxt "@label:PrintjobStatus %1 is target operation"
+#~ msgid "Ready to %1"
+#~ msgstr "Listo para %1"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Slicing unavailable"
+#~ msgstr "No se puede segmentar"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Slice current printjob"
+#~ msgstr "Fragmentar trabajo de impresión actual"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Cancel slicing process"
+#~ msgstr "Cancelar proceso de fragmentación"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Prepare"
+#~ msgstr "Preparar"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Cancel"
+#~ msgstr "Cancelar"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Select the active output device"
+#~ msgstr "Seleccione el dispositivo de salida activo"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&View"
+#~ msgstr "&Ver"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Settings"
+#~ msgstr "A&justes"
+
+#~ msgctxt "@title:menu menubar:toplevel"
+#~ msgid "&Toolbox"
+#~ msgstr "&Cuadro de herramientas"
+
+#~ msgctxt "@action:button"
+#~ msgid "Open File"
+#~ msgstr "Abrir archivo"
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
+#~ msgstr "Este perfil de calidad no está disponible para la configuración de material y de tobera actual. Cámbiela para poder habilitar este perfil de calidad"
+
+#~ msgctxt "@label"
+#~ msgid "Print Speed"
+#~ msgstr "Velocidad de impresión"
+
+#~ msgctxt "@label"
+#~ msgid "Slower"
+#~ msgstr "Más lento"
+
+#~ msgctxt "@label"
+#~ msgid "Faster"
+#~ msgstr "Más rápido"
+
+#~ msgctxt "@label"
+#~ msgid "Enable gradual"
+#~ msgstr "Habilitar gradual"
+
+#~ msgctxt "@label"
+#~ msgid "Generate Support"
+#~ msgstr "Generar soporte"
+
+#~ msgctxt "@label"
+#~ msgid "Build Plate Adhesion"
+#~ msgstr "Adherencia de la placa de impresión"
+
+#~ msgctxt "@label"
+#~ msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
+#~ msgstr "¿Necesita ayuda para mejorar sus impresiones? Lea las Guías de solución de problemas de Ultimaker"
+
+#~ msgctxt "@title:window"
+#~ msgid "Engine Log"
+#~ msgstr "Registro del motor"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type"
+#~ msgstr "Tipo de impresora"
+
+#~ msgctxt "@label"
+#~ msgid "Use glue with this material combination"
+#~ msgstr "Utilizar pegamento con esta combinación de materiales"
+
+#~ msgctxt "@label"
+#~ msgid "Check compatibility"
+#~ msgstr "Comprobar compatibilidad"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Click to check the material compatibility on Ultimaker.com."
+#~ msgstr "Haga clic para comprobar la compatibilidad de los materiales en Utimaker.com."
+
+#~ msgctxt "description"
+#~ msgid "Shows changes since latest checked version."
+#~ msgstr "Muestra los cambios desde la última versión comprobada."
+
+#~ msgctxt "name"
+#~ msgid "Changelog"
+#~ msgstr "Registro de cambios"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattend quality changes profile."
+#~ msgstr "Crear un perfil de cambios de calidad aplanado."
+
+#~ msgctxt "name"
+#~ msgid "Profile flatener"
+#~ msgstr "Aplanador de perfil"
+
+#~ msgctxt "description"
+#~ msgid "Ask the user once if he/she agrees with our license."
+#~ msgstr "Preguntar al usuario una vez si acepta la licencia."
+
+#~ msgctxt "name"
+#~ msgid "UserAgreement"
+#~ msgstr "UserAgreement"
+
+#~ msgctxt "@warning:status"
+#~ msgid "Please generate G-code before saving."
+#~ msgstr "Genere un G-code antes de guardar."
+
#~ msgctxt "@action"
#~ msgid "Upgrade Firmware"
#~ msgstr "Actualizar firmware"
@@ -4993,22 +6528,6 @@ msgstr "Lector de perfiles de Cura"
#~ msgid "Confirm uninstall "
#~ msgstr "Confirmar desinstalación "
-#~ msgctxt "@label:status"
-#~ msgid "Paused"
-#~ msgstr "En pausa"
-
-#~ msgctxt "@action:button"
-#~ msgid "Previous"
-#~ msgstr "Anterior"
-
-#~ msgctxt "@action:button"
-#~ msgid "Next"
-#~ msgstr "Siguiente"
-
-#~ msgctxt "@label"
-#~ msgid "Tip"
-#~ msgstr "Consejo"
-
#~ msgctxt "@label Print estimates: m for meters, g for grams, %4 is currency and %3 is print cost"
#~ msgid "%1m / ~ %2g / ~ %4 %3"
#~ msgstr "%1 m/~ %2 g/~ %4 %3"
@@ -5017,26 +6536,10 @@ msgstr "Lector de perfiles de Cura"
#~ msgid "%1m / ~ %2g"
#~ msgstr "%1 m/~ %2 g"
-#~ msgctxt "@label"
-#~ msgid "Print experiment"
-#~ msgstr "Ensayo de impresión"
-
-#~ msgctxt "@label"
-#~ msgid "Checklist"
-#~ msgstr "Lista de verificación"
-
#~ msgctxt "@title"
#~ msgid "Upgrade Firmware"
#~ msgstr "Actualización de firmware"
-#~ msgctxt "description"
-#~ msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
-#~ msgstr "Permite a los fabricantes de material crear nuevos perfiles de material y calidad mediante una IU integrada."
-
-#~ msgctxt "name"
-#~ msgid "Print Profile Assistant"
-#~ msgstr "Imprimir asistente del perfil"
-
#~ msgctxt "@action:button"
#~ msgid "Print with Doodle3D WiFi-Box"
#~ msgstr "Imprimir con un enrutador Doodle3D"
@@ -5129,10 +6632,6 @@ msgstr "Lector de perfiles de Cura"
#~ msgid "Lost connection with the printer"
#~ msgstr "Se ha perdido la conexión con la impresora."
-#~ msgctxt "@label:status"
-#~ msgid "Unavailable"
-#~ msgstr "No disponible"
-
#~ msgctxt "@label:status"
#~ msgid "Unknown"
#~ msgstr "Desconocido"
@@ -5459,7 +6958,7 @@ msgstr "Lector de perfiles de Cura"
#~ msgctxt "@title:window"
#~ msgid "SolidWorks plugin: Configuration"
-#~ msgstr "Complementos de SolidWorks: configuración"
+#~ msgstr "Complemento de SolidWorks: configuración"
#~ msgctxt "@title:tab"
#~ msgid "Conversion settings"
@@ -5551,7 +7050,7 @@ msgstr "Lector de perfiles de Cura"
#~ msgctxt "description"
#~ msgid "Helps you to install an 'export to Cura' button in Siemens NX."
-#~ msgstr "Ayuda a instalar el botón para exportar a Cura en in Siemens NX."
+#~ msgstr "Ayuda a instalar el botón para exportar a Cura en Siemens NX."
#~ msgctxt "name"
#~ msgid "Siemens NX Integration"
diff --git a/resources/i18n/es_ES/fdmextruder.def.json.po b/resources/i18n/es_ES/fdmextruder.def.json.po
index 3da8d5251f..5d849cfc50 100644
--- a/resources/i18n/es_ES/fdmextruder.def.json.po
+++ b/resources/i18n/es_ES/fdmextruder.def.json.po
@@ -1,14 +1,14 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 14:25+0100\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-03-13 14:00+0200\n"
"Last-Translator: Bothof \n"
"Language-Team: Spanish\n"
"Language: es_ES\n"
@@ -83,8 +83,8 @@ msgstr "GCode inicial del extrusor"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_code description"
-msgid "Start g-code to execute whenever turning the extruder on."
-msgstr "Gcode inicial que se ejecuta cada vez que se enciende el extrusor."
+msgid "Start g-code to execute when switching to this extruder."
+msgstr "Iniciar GCode para ejecutarlo al cambiar a este extrusor."
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_abs label"
@@ -123,8 +123,8 @@ msgstr "GCode final del extrusor"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_code description"
-msgid "End g-code to execute whenever turning the extruder off."
-msgstr "Gcode final que se ejecuta cada vez que se apaga el extrusor."
+msgid "End g-code to execute when switching away from this extruder."
+msgstr "Finalizar GCode para ejecutarlo al cambiar desde este extrusor."
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_abs label"
@@ -225,3 +225,11 @@ msgstr "Diámetro"
msgctxt "material_diameter description"
msgid "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament."
msgstr "Ajusta el diámetro del filamento utilizado. Este valor debe coincidir con el diámetro del filamento utilizado."
+
+#~ msgctxt "machine_extruder_start_code description"
+#~ msgid "Start g-code to execute whenever turning the extruder on."
+#~ msgstr "Gcode inicial que se ejecuta cada vez que se enciende el extrusor."
+
+#~ msgctxt "machine_extruder_end_code description"
+#~ msgid "End g-code to execute whenever turning the extruder off."
+#~ msgstr "Gcode final que se ejecuta cada vez que se apaga el extrusor."
diff --git a/resources/i18n/es_ES/fdmprinter.def.json.po b/resources/i18n/es_ES/fdmprinter.def.json.po
index bd4ad9fd7f..fbaf241481 100644
--- a/resources/i18n/es_ES/fdmprinter.def.json.po
+++ b/resources/i18n/es_ES/fdmprinter.def.json.po
@@ -1,21 +1,21 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 14:56+0200\n"
-"Last-Translator: Bothof \n"
-"Language-Team: Spanish\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-07-29 15:51+0200\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: Spanish , Spanish \n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.2.3\n"
#: fdmprinter.def.json
msgctxt "machine_settings label"
@@ -57,7 +57,9 @@ msgctxt "machine_start_gcode description"
msgid ""
"G-code commands to be executed at the very start - separated by \n"
"."
-msgstr "Los comandos de GCode que se ejecutarán justo al inicio separados por - \n."
+msgstr ""
+"Los comandos de GCode que se ejecutarán justo al inicio separados por - \n"
+"."
#: fdmprinter.def.json
msgctxt "machine_end_gcode label"
@@ -69,7 +71,9 @@ msgctxt "machine_end_gcode description"
msgid ""
"G-code commands to be executed at the very end - separated by \n"
"."
-msgstr "Los comandos de GCode que se ejecutarán justo al final separados por -\n."
+msgstr ""
+"Los comandos de GCode que se ejecutarán justo al final separados por -\n"
+"."
#: fdmprinter.def.json
msgctxt "material_guid label"
@@ -211,6 +215,16 @@ msgctxt "machine_heated_bed description"
msgid "Whether the machine has a heated build plate present."
msgstr "Indica si la máquina tiene una placa de impresión caliente."
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume label"
+msgid "Has Build Volume Temperature Stabilization"
+msgstr "Tiene estabilización de temperatura del volumen de impresión"
+
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume description"
+msgid "Whether the machine is able to stabilize the build volume temperature."
+msgstr "Si la máquina puede estabilizar la temperatura del volumen de impresión."
+
#: fdmprinter.def.json
msgctxt "machine_center_is_zero label"
msgid "Is Center Origin"
@@ -233,7 +247,7 @@ msgstr "Número de trenes extrusores. Un tren extrusor está formado por un alim
#: fdmprinter.def.json
msgctxt "extruders_enabled_count label"
-msgid "Number of Extruders that are enabled"
+msgid "Number of Extruders That Are Enabled"
msgstr "Número de extrusores habilitados"
#: fdmprinter.def.json
@@ -243,7 +257,7 @@ msgstr "Número de trenes extrusores habilitados y configurados en el software d
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter label"
-msgid "Outer nozzle diameter"
+msgid "Outer Nozzle Diameter"
msgstr "Diámetro exterior de la tobera"
#: fdmprinter.def.json
@@ -253,7 +267,7 @@ msgstr "Diámetro exterior de la punta de la tobera."
#: fdmprinter.def.json
msgctxt "machine_nozzle_head_distance label"
-msgid "Nozzle length"
+msgid "Nozzle Length"
msgstr "Longitud de la tobera"
#: fdmprinter.def.json
@@ -263,7 +277,7 @@ msgstr "Diferencia de altura entre la punta de la tobera y la parte más baja de
#: fdmprinter.def.json
msgctxt "machine_nozzle_expansion_angle label"
-msgid "Nozzle angle"
+msgid "Nozzle Angle"
msgstr "Ángulo de la tobera"
#: fdmprinter.def.json
@@ -273,7 +287,7 @@ msgstr "Ángulo entre el plano horizontal y la parte cónica que hay justo encim
#: fdmprinter.def.json
msgctxt "machine_heat_zone_length label"
-msgid "Heat zone length"
+msgid "Heat Zone Length"
msgstr "Longitud de la zona térmica"
#: fdmprinter.def.json
@@ -303,7 +317,7 @@ msgstr "Para controlar la temperatura desde Cura. Si va a controlar la temperatu
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed label"
-msgid "Heat up speed"
+msgid "Heat Up Speed"
msgstr "Velocidad de calentamiento"
#: fdmprinter.def.json
@@ -313,7 +327,7 @@ msgstr "Velocidad (°C/s) de calentamiento de la tobera calculada como una media
#: fdmprinter.def.json
msgctxt "machine_nozzle_cool_down_speed label"
-msgid "Cool down speed"
+msgid "Cool Down Speed"
msgstr "Velocidad de enfriamiento"
#: fdmprinter.def.json
@@ -333,7 +347,7 @@ msgstr "Tiempo mínimo que un extrusor debe permanecer inactivo antes de que la
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor label"
-msgid "G-code flavour"
+msgid "G-code Flavor"
msgstr "Tipo de GCode"
#: fdmprinter.def.json
@@ -398,7 +412,7 @@ msgstr "Utilizar o no los comandos de retracción de firmware (G10/G11) en lugar
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
-msgid "Disallowed areas"
+msgid "Disallowed Areas"
msgstr "Áreas no permitidas"
#: fdmprinter.def.json
@@ -418,7 +432,7 @@ msgstr "Lista de polígonos con áreas en las que la tobera no tiene permitido e
#: fdmprinter.def.json
msgctxt "machine_head_polygon label"
-msgid "Machine head polygon"
+msgid "Machine Head Polygon"
msgstr "Polígono del cabezal de la máquina"
#: fdmprinter.def.json
@@ -428,7 +442,7 @@ msgstr "Silueta 2D del cabezal de impresión (sin incluir las tapas del ventilad
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon label"
-msgid "Machine head & Fan polygon"
+msgid "Machine Head & Fan Polygon"
msgstr "Polígono del cabezal de la máquina y del ventilador"
#: fdmprinter.def.json
@@ -438,7 +452,7 @@ msgstr "Silueta 2D del cabezal de impresión (incluidas las tapas del ventilador
#: fdmprinter.def.json
msgctxt "gantry_height label"
-msgid "Gantry height"
+msgid "Gantry Height"
msgstr "Altura del puente"
#: fdmprinter.def.json
@@ -468,7 +482,7 @@ msgstr "Diámetro interior de la tobera. Cambie este ajuste cuando utilice un ta
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords label"
-msgid "Offset With Extruder"
+msgid "Offset with Extruder"
msgstr "Desplazamiento con extrusor"
#: fdmprinter.def.json
@@ -1016,6 +1030,17 @@ msgctxt "bottom_layers description"
msgid "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number."
msgstr "Número de capas inferiores. Al calcularlo por el grosor inferior, este valor se redondea a un número entero."
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers label"
+msgid "Initial Bottom Layers"
+msgstr "Capas inferiores iniciales"
+
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers description"
+msgid "The number of initial bottom layers, from the build-plate upwards. When calculated by the bottom thickness, this value is rounded to a whole number."
+msgstr "El número de capas inferiores iniciales, desde la capa de impresión hacia arriba. Al calcularlo por el grosor inferior, este valor se redondea a un número"
+" entero."
+
#: fdmprinter.def.json
msgctxt "top_bottom_pattern label"
msgid "Top/Bottom Pattern"
@@ -1266,6 +1291,56 @@ msgctxt "z_seam_type option sharpest_corner"
msgid "Sharpest Corner"
msgstr "Esquina más pronunciada"
+#: fdmprinter.def.json
+msgctxt "z_seam_position label"
+msgid "Z Seam Position"
+msgstr "Posición de costura en Z"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position description"
+msgid "The position near where to start printing each part in a layer."
+msgstr "La posición cerca de donde comenzará la impresión de cada parte de una capa."
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backleft"
+msgid "Back Left"
+msgstr "Posterior izquierda"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option back"
+msgid "Back"
+msgstr "Posterior"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backright"
+msgid "Back Right"
+msgstr "Posterior derecha"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option right"
+msgid "Right"
+msgstr "Derecha"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontright"
+msgid "Front Right"
+msgstr "Delantera derecha"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option front"
+msgid "Front"
+msgstr "Delantera"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontleft"
+msgid "Front Left"
+msgstr "Delantera izquierda"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option left"
+msgid "Left"
+msgstr "Izquierda"
+
#: fdmprinter.def.json
msgctxt "z_seam_x label"
msgid "Z Seam X"
@@ -1293,8 +1368,8 @@ msgstr "Preferencia de esquina de costura"
#: fdmprinter.def.json
msgctxt "z_seam_corner description"
-msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
-msgstr "Controlar si las esquinas del contorno del modelo influyen en la posición de la costura. «Ninguno» significa que las esquinas no influyen en la posición de la costura. «Ocultar costura» significa que es probable que la costura se realice en una esquina interior. «Mostrar costura» significa que es probable que la costura sea en una esquina exterior. «Ocultar o mostrar costura» significa que es probable que la costura se realice en una esquina interior o exterior."
+msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner. Smart Hiding allows both inside and outside corners, but chooses inside corners more frequently, if appropriate."
+msgstr "Controlar si las esquinas del contorno del modelo influyen en la posición de la costura. «Ninguno» significa que las esquinas no influyen en la posición de la costura. «Ocultar costura» significa que es probable que la costura se realice en una esquina interior. «Mostrar costura» significa que es probable que la costura se realice en una esquina exterior. «Ocultar o mostrar costura» significa que es probable que la costura se realice en una esquina interior o exterior. «Costura inteligente» permite realizar la costura en ambas esquinas, pero opta con más frecuencia por las esquinas interiores, si resulta oportuno."
#: fdmprinter.def.json
msgctxt "z_seam_corner option z_seam_corner_none"
@@ -1316,6 +1391,11 @@ msgctxt "z_seam_corner option z_seam_corner_any"
msgid "Hide or Expose Seam"
msgstr "Ocultar o mostrar costura"
+#: fdmprinter.def.json
+msgctxt "z_seam_corner option z_seam_corner_weighted"
+msgid "Smart Hiding"
+msgstr "Costura inteligente"
+
#: fdmprinter.def.json
msgctxt "z_seam_relative label"
msgid "Z Seam Relative"
@@ -1328,13 +1408,13 @@ msgstr "Cuando se habilita, las coordenadas de la costura en z son relativas al
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic label"
-msgid "Ignore Small Z Gaps"
-msgstr "Ignorar los pequeños huecos en Z"
+msgid "No Skin in Z Gaps"
+msgstr "Sin forro en huecos en Z"
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic description"
-msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
-msgstr "Cuando el modelo tiene pequeños huecos verticales, el tiempo de cálculo puede aumentar alrededor de un 5 % para generar el forro superior e inferior en estos espacios estrechos. En tal caso, desactive este ajuste."
+msgid "When the model has small vertical gaps of only a few layers, there should normally be skin around those layers in the narrow space. Enable this setting to not generate skin if the vertical gap is very small. This improves printing time and slicing time, but technically leaves infill exposed to the air."
+msgstr "Cuando el modelo tiene pequeños huecos verticales de solo unas pocas capas, normalmente suele haber forro alrededor de ellas en el espacio estrecho. Active este ajuste para no generar forro si el hueco vertical es muy pequeño. Esto mejora el tiempo de impresión y de segmentación, pero deja el relleno expuesto al aire."
#: fdmprinter.def.json
msgctxt "skin_outline_count label"
@@ -1353,8 +1433,8 @@ msgstr "Habilitar alisado"
#: fdmprinter.def.json
msgctxt "ironing_enabled description"
-msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
-msgstr "Pasar por la superficie superior una vez más, pero sin extruir material, para derretir la parte externa del plástico y crear una superficie más lisa."
+msgid "Go over the top surface one additional time, but this time extruding very little material. This is meant to melt the plastic on top further, creating a smoother surface. The pressure in the nozzle chamber is kept high so that the creases in the surface are filled with material."
+msgstr "Pasar por la superficie superior una vez más, pero esta vez extruyendo muy poco material, para derretir la capa superior del plástico y crear una superficie más lisa. La presión de la cámara en la boquilla se mantiene alta para que los pliegues de la superficie se llenen de material."
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer label"
@@ -1446,6 +1526,26 @@ msgctxt "jerk_ironing description"
msgid "The maximum instantaneous velocity change while performing ironing."
msgstr "Cambio en la velocidad instantánea máxima durante el alisado."
+#: fdmprinter.def.json
+msgctxt "skin_overlap label"
+msgid "Skin Overlap Percentage"
+msgstr "Porcentaje de superposición del forro"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines, as a percentage of the line widths of the skin lines and the innermost wall. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any percentage over 50% may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "Ajuste la cantidad de superposición entre las paredes y (los extremos de) las líneas centrales del forro, como un porcentaje de los anchos de las líneas del forro y la pared más profunda. Una ligera superposición permite que las paredes estén firmemente unidas al forro. Tenga en cuenta que, con un mismo ancho de la línea del forro y la pared, cualquier porcentaje superior al 50 % ya puede provocar que cualquier forro sobrepase la pared, debido a que en ese punto la posición de la tobera del extrusor del forro ya puede sobrepasar la mitad de la pared."
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm label"
+msgid "Skin Overlap"
+msgstr "Superposición del forro"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any value over half the width of the wall may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "Ajuste la cantidad de superposición entre las paredes y (los extremos de) las líneas centrales del forro. Una ligera superposición permite que las paredes estén firmemente unidas al forro. Tenga en cuenta que, con un mismo ancho de la línea del forro y la pared, cualquier valor superior a la mitad del ancho de la pared ya puede provocar que cualquier forro sobrepase la pared, debido a que en ese punto la posición de la tobera del extrusor del forro ya puede sobrepasar la mitad de la pared."
+
#: fdmprinter.def.json
msgctxt "infill label"
msgid "Infill"
@@ -1604,13 +1704,23 @@ msgstr "El patrón de relleno se mueve esta distancia a lo largo del eje X."
#: fdmprinter.def.json
msgctxt "infill_offset_y label"
msgid "Infill Y Offset"
-msgstr "Desplazamiento del relleno sobre el eje X"
+msgstr "Desplazamiento del relleno sobre el eje Y"
#: fdmprinter.def.json
msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
msgstr "El patrón de relleno se mueve esta distancia a lo largo del eje Y."
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location label"
+msgid "Randomize Infill Start"
+msgstr "Comienzo de relleno aleatorio"
+
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location description"
+msgid "Randomize which infill line is printed first. This prevents one segment becoming the strongest, but it does so at the cost of an additional travel move."
+msgstr "Determine qué línea de relleno se imprime primero. Esto evita que un segmento se convierta en el más fuerte, pero a expensas de un movimiento adicional."
+
#: fdmprinter.def.json
msgctxt "infill_multiplier label"
msgid "Infill Line Multiplier"
@@ -1631,7 +1741,9 @@ msgctxt "infill_wall_line_count description"
msgid ""
"Add extra walls around the infill area. Such walls can make top/bottom skin lines sag down less which means you need less top/bottom skin layers for the same quality at the cost of some extra material.\n"
"This feature can combine with the Connect Infill Polygons to connect all the infill into a single extrusion path without the need for travels or retractions if configured right."
-msgstr "Agregar paredes adicionales alrededor del área de relleno. Estas paredes pueden hacer que las líneas del forro superior/inferior se aflojen menos, lo que significa que necesitaría menos capas de forro superior/inferior para obtener la misma calidad utilizando algo más de material.\nPuede utilizar esta función junto a la de Conectar polígonos de relleno para conectar todo el relleno en una única trayectoria de extrusión sin necesidad de desplazamientos ni retracciones si se configura correctamente."
+msgstr ""
+"Agregar paredes adicionales alrededor del área de relleno. Estas paredes pueden hacer que las líneas del forro superior/inferior se aflojen menos, lo que significa que necesitaría menos capas de forro superior/inferior para obtener la misma calidad utilizando algo más de material.\n"
+"Puede utilizar esta función junto a la de Conectar polígonos de relleno para conectar todo el relleno en una única trayectoria de extrusión sin necesidad de desplazamientos ni retracciones si se configura correctamente."
#: fdmprinter.def.json
msgctxt "sub_div_rad_add label"
@@ -1663,26 +1775,6 @@ msgctxt "infill_overlap_mm description"
msgid "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill."
msgstr "Cantidad de superposición entre el relleno y las paredes. Una ligera superposición permite que las paredes conecten firmemente con el relleno."
-#: fdmprinter.def.json
-msgctxt "skin_overlap label"
-msgid "Skin Overlap Percentage"
-msgstr "Porcentaje de superposición del forro"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap description"
-msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
-msgstr "La cantidad de superposición entre el forro y las paredes son un porcentaje del ancho de la línea de forro. Una ligera superposición permite que las paredes estén firmemente unidas al forro. Este es el porcentaje de la media de los anchos de las líneas del forro y la pared más profunda."
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm label"
-msgid "Skin Overlap"
-msgstr "Superposición del forro"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm description"
-msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
-msgstr "Cantidad de superposición entre el forro y las paredes. Una ligera superposición permite que las paredes conecten firmemente con el forro."
-
#: fdmprinter.def.json
msgctxt "infill_wipe_dist label"
msgid "Infill Wipe Distance"
@@ -1863,6 +1955,16 @@ msgctxt "default_material_print_temperature description"
msgid "The default temperature used for printing. This should be the \"base\" temperature of a material. All other print temperatures should use offsets based on this value"
msgstr "La temperatura predeterminada que se utiliza para imprimir. Debería ser la temperatura básica del material. Las demás temperaturas de impresión deberían calcularse a partir de este valor"
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature label"
+msgid "Build Volume Temperature"
+msgstr "Temperatura de volumen de impresión"
+
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature description"
+msgid "The temperature of the environment to print in. If this is 0, the build volume temperature will not be adjusted."
+msgstr "La temperatura del entorno de impresión. Si el valor es 0, la temperatura de volumen de impresión no se ajustará."
+
#: fdmprinter.def.json
msgctxt "material_print_temperature label"
msgid "Printing Temperature"
@@ -1973,6 +2075,86 @@ msgctxt "material_shrinkage_percentage description"
msgid "Shrinkage ratio in percentage."
msgstr "Índice de compresión en porcentaje."
+#: fdmprinter.def.json
+msgctxt "material_crystallinity label"
+msgid "Crystalline Material"
+msgstr "Material cristalino"
+
+#: fdmprinter.def.json
+msgctxt "material_crystallinity description"
+msgid "Is this material the type that breaks off cleanly when heated (crystalline), or is it the type that produces long intertwined polymer chains (non-crystalline)?"
+msgstr "¿Es este el tipo de material que se desprende limpiamente cuando se calienta (cristalino) o el que produce largas cadenas de polímeros entrelazadas (no cristalino)?"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position label"
+msgid "Anti-ooze Retracted Position"
+msgstr "Velocidad de retracción antirrezumado"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position description"
+msgid "How far the material needs to be retracted before it stops oozing."
+msgstr "Hasta dónde tiene que retraerse el material antes de detener el rezumado."
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed label"
+msgid "Anti-ooze Retraction Speed"
+msgstr "Velocidad de retracción antirrezumado"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed description"
+msgid "How fast the material needs to be retracted during a filament switch to prevent oozing."
+msgstr "Con qué velocidad tiene que retraerse el material durante un cambio de filamento para evitar el rezumado."
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position label"
+msgid "Break Preparation Retracted Position"
+msgstr "Posición retraída de preparación de rotura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position description"
+msgid "How far the filament can be stretched before it breaks, while heated."
+msgstr "Hasta dónde puede estirarse el filamento antes de que se rompa mientras se calienta."
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed label"
+msgid "Break Preparation Retraction Speed"
+msgstr "Velocidad de retracción de preparación de rotura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed description"
+msgid "How fast the filament needs to be retracted just before breaking it off in a retraction."
+msgstr "Con qué velocidad debe retraerse el filamento justo antes de romperse en una retracción."
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position label"
+msgid "Break Retracted Position"
+msgstr "Posición retraída de rotura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position description"
+msgid "How far to retract the filament in order to break it cleanly."
+msgstr "Hasta dónde debe retraerse el filamento para que se rompa limpiamente."
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed label"
+msgid "Break Retraction Speed"
+msgstr "Velocidad de retracción de rotura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed description"
+msgid "The speed at which to retract the filament in order to break it cleanly."
+msgstr "Velocidad a la que debe retraerse el filamento para que se rompa limpiamente."
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature label"
+msgid "Break Temperature"
+msgstr "Temperatura de rotura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature description"
+msgid "The temperature at which the filament is broken for a clean break."
+msgstr "Temperatura a la que se rompe el filamento de forma limpia."
+
#: fdmprinter.def.json
msgctxt "material_flow label"
msgid "Flow"
@@ -1983,6 +2165,126 @@ msgctxt "material_flow description"
msgid "Flow compensation: the amount of material extruded is multiplied by this value."
msgstr "Compensación de flujo: la cantidad de material extruido se multiplica por este valor."
+#: fdmprinter.def.json
+msgctxt "wall_material_flow label"
+msgid "Wall Flow"
+msgstr "Flujo de pared"
+
+#: fdmprinter.def.json
+msgctxt "wall_material_flow description"
+msgid "Flow compensation on wall lines."
+msgstr "Compensación de flujo en líneas de pared."
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow label"
+msgid "Outer Wall Flow"
+msgstr "Flujo de pared exterior"
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow description"
+msgid "Flow compensation on the outermost wall line."
+msgstr "Compensación de flujo en la línea de pared más externa."
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow label"
+msgid "Inner Wall(s) Flow"
+msgstr "Flujo de pared o paredes interiores"
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow description"
+msgid "Flow compensation on wall lines for all wall lines except the outermost one."
+msgstr "Compensación de flujo en líneas de pared para todas las líneas excepto la más externa."
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow label"
+msgid "Top/Bottom Flow"
+msgstr "Flujo superior o inferior"
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow description"
+msgid "Flow compensation on top/bottom lines."
+msgstr "Compensación de flujo en las líneas superiores o inferiores."
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow label"
+msgid "Top Surface Skin Flow"
+msgstr "Flujo de forro de superficie superior"
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow description"
+msgid "Flow compensation on lines of the areas at the top of the print."
+msgstr "Compensación de flujo en líneas de las áreas superiores de la impresión."
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow label"
+msgid "Infill Flow"
+msgstr "Flujo de relleno"
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow description"
+msgid "Flow compensation on infill lines."
+msgstr "Compensación de flujo en líneas de relleno."
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow label"
+msgid "Skirt/Brim Flow"
+msgstr "Flujo de falda/borde"
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow description"
+msgid "Flow compensation on skirt or brim lines."
+msgstr "Compensación de flujo en líneas de falda o borde."
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow label"
+msgid "Support Flow"
+msgstr "Flujo de soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow description"
+msgid "Flow compensation on support structure lines."
+msgstr "Compensación de flujo en líneas de estructura de soporte."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow label"
+msgid "Support Interface Flow"
+msgstr "Flujo de interfaz de soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow description"
+msgid "Flow compensation on lines of support roof or floor."
+msgstr "Compensación de flujo en líneas de techo o suelo de soporte."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow label"
+msgid "Support Roof Flow"
+msgstr "Flujo de techo de soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow description"
+msgid "Flow compensation on support roof lines."
+msgstr "Compensación de flujo en líneas de techo de soporte."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow label"
+msgid "Support Floor Flow"
+msgstr "Flujo de suelo de soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow description"
+msgid "Flow compensation on support floor lines."
+msgstr "Compensación de flujo en líneas de suelo de soporte."
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow label"
+msgid "Prime Tower Flow"
+msgstr "Flujo de la torre auxiliar"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow description"
+msgid "Flow compensation on prime tower lines."
+msgstr "Compensación de flujo en líneas de la torre auxiliar."
+
#: fdmprinter.def.json
msgctxt "material_flow_layer_0 label"
msgid "Initial Layer Flow"
@@ -2100,7 +2402,7 @@ msgstr "Limitar las retracciones de soporte"
#: fdmprinter.def.json
msgctxt "limit_support_retractions description"
-msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
+msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excessive stringing within the support structure."
msgstr "Omitir la retracción al moverse de soporte a soporte en línea recta. Habilitar este ajuste ahorra tiempo de impresión pero puede ocasionar un encordado excesivo en la estructura de soporte."
#: fdmprinter.def.json
@@ -2120,8 +2422,8 @@ msgstr "Distancia de retracción del cambio de tobera"
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_amount description"
-msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
-msgstr "Distancia de la retracción: utilice el valor cero para que no haya retracción. Por norma general, este valor debe ser igual a la longitud de la zona de calentamiento."
+msgid "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+msgstr "Distancia de la retracción al cambiar los extrusores. Utilice el valor 0 para que no haya retracción. Por norma general, este valor debe ser igual a la longitud de la zona de calentamiento."
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_speeds label"
@@ -2153,6 +2455,16 @@ msgctxt "switch_extruder_prime_speed description"
msgid "The speed at which the filament is pushed back after a nozzle switch retraction."
msgstr "Velocidad a la que se retrae el filamento durante una retracción del cambio de tobera."
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount label"
+msgid "Nozzle Switch Extra Prime Amount"
+msgstr "Volumen de cebado adicional tras cambio de tobera"
+
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount description"
+msgid "Extra material to prime after nozzle switching."
+msgstr "Material adicional que debe cebarse tras el cambio de tobera."
+
#: fdmprinter.def.json
msgctxt "speed label"
msgid "Speed"
@@ -2344,14 +2656,14 @@ msgid "The speed at which the skirt and brim are printed. Normally this is done
msgstr "Velocidad a la que se imprimen la falda y el borde. Normalmente, esto se hace a la velocidad de la capa inicial, pero a veces es posible que se prefiera imprimir la falda o el borde a una velocidad diferente."
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override label"
-msgid "Maximum Z Speed"
-msgstr "Velocidad máxima de Z"
+msgctxt "speed_z_hop label"
+msgid "Z Hop Speed"
+msgstr "Velocidad del salto en Z"
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override description"
-msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
-msgstr "Velocidad máxima a la que se mueve la placa de impresión. Definir este valor en 0 hace que la impresión utilice los valores predeterminados de la velocidad máxima de Z."
+msgctxt "speed_z_hop description"
+msgid "The speed at which the vertical Z movement is made for Z Hops. This is typically lower than the print speed since the build plate or machine's gantry is harder to move."
+msgstr "Velocidad a la que se realiza el movimiento vertical en la dirección Z para los saltos en Z. Suele ser inferior a la velocidad de impresión porque la placa de impresión o el puente de la máquina es más difícil de desplazar."
#: fdmprinter.def.json
msgctxt "speed_slowdown_layers label"
@@ -2780,8 +3092,8 @@ msgstr "Modo Peinada"
#: fdmprinter.def.json
msgctxt "retraction_combing description"
-msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
-msgstr "La opción de peinada mantiene la tobera dentro de las áreas ya impresas al desplazarse. Esto ocasiona movimientos de desplazamiento ligeramente más largos, pero reduce la necesidad de realizar retracciones. Si se desactiva la opción de peinada, el material se retraerá y la tobera se moverá en línea recta hasta el siguiente punto. Otra posibilidad es evitar la peinada en áreas de forro superiores/inferiores y además peinar solo en el relleno. La opción de «Sobre el relleno» actúa exactamente igual que la «No está en el forro» de las versiones de Cura anteriores."
+msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas or to only comb within the infill."
+msgstr "La opción de peinada mantiene la tobera dentro de las áreas ya impresas al desplazarse. Esto ocasiona movimientos de desplazamiento ligeramente más largos, pero reduce la necesidad de realizar retracciones. Si se desactiva la opción de peinada, el material se retraerá y la tobera se moverá en línea recta hasta el siguiente punto. Otra posibilidad es evitar la peinada en áreas de forro superiores/inferiores o peinar solo en el relleno."
#: fdmprinter.def.json
msgctxt "retraction_combing option off"
@@ -2853,16 +3165,6 @@ msgctxt "travel_avoid_distance description"
msgid "The distance between the nozzle and already printed parts when avoiding during travel moves."
msgstr "Distancia entre la tobera y las partes ya impresas, cuando se evita durante movimientos de desplazamiento."
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position label"
-msgid "Start Layers with the Same Part"
-msgstr "Comenzar capas con la misma parte"
-
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position description"
-msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
-msgstr "En cada capa, comenzar imprimiendo el objeto cerca del mismo punto, de forma que no se comienza una capa imprimiendo la pieza en la que finalizó la capa anterior. Esto permite mejorar los voladizos y las partes pequeñas, a costa de un mayor tiempo de impresión."
-
#: fdmprinter.def.json
msgctxt "layer_start_x label"
msgid "Layer Start X"
@@ -2923,6 +3225,16 @@ msgctxt "retraction_hop_after_extruder_switch description"
msgid "After the machine switched from one extruder to the other, the build plate is lowered to create clearance between the nozzle and the print. This prevents the nozzle from leaving oozed material on the outside of a print."
msgstr "Cuando la máquina cambia de un extrusor a otro, la placa de impresión se baja para crear holgura entre la tobera y la impresión. Esto impide que el material rezumado quede fuera de la impresión."
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height label"
+msgid "Z Hop After Extruder Switch Height"
+msgstr "Salto en Z tras altura de cambio de extrusor"
+
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height description"
+msgid "The height difference when performing a Z Hop after extruder switch."
+msgstr "Diferencia de altura cuando se realiza un salto en Z después de un cambio de extrusor."
+
#: fdmprinter.def.json
msgctxt "cooling label"
msgid "Cooling"
@@ -3193,6 +3505,11 @@ msgctxt "support_pattern option cross"
msgid "Cross"
msgstr "Cruz"
+#: fdmprinter.def.json
+msgctxt "support_pattern option gyroid"
+msgid "Gyroid"
+msgstr "Giroide"
+
#: fdmprinter.def.json
msgctxt "support_wall_count label"
msgid "Support Wall Line Count"
@@ -3254,14 +3571,14 @@ msgid "Distance between the printed initial layer support structure lines. This
msgstr "Distancia entre las líneas de estructuras del soporte de la capa inicial impresas. Este ajuste se calcula por la densidad del soporte."
#: fdmprinter.def.json
-msgctxt "support_infill_angle label"
-msgid "Support Infill Line Direction"
+msgctxt "support_infill_angles label"
+msgid "Support Infill Line Directions"
msgstr "Dirección de línea de relleno de soporte"
#: fdmprinter.def.json
-msgctxt "support_infill_angle description"
-msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
-msgstr "Orientación del patrón de relleno para soportes. El patrón de relleno de soporte se gira en el plano horizontal."
+msgctxt "support_infill_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angle 0 degrees."
+msgstr "Una lista de los valores enteros de las direcciones de línea que se van a utilizar. Los elementos de la lista se usan secuencialmente a medida que avanzan las capas y cuando se alcanza el final de la lista, comienza de nuevo desde el principio. Los elementos de la lista están separados por comas y toda la lista aparece entre corchetes. El valor predeterminado es una lista vacía, lo que significa que se usa el ángulo predeterminado de 0 grados."
#: fdmprinter.def.json
msgctxt "support_brim_enable label"
@@ -3390,8 +3707,8 @@ msgstr "Distancia de unión del soporte"
#: fdmprinter.def.json
msgctxt "support_join_distance description"
-msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
-msgstr "Distancia máxima entre las estructuras del soporte en las direcciones X/Y. Cuando estructuras separadas están más cerca entre sí que de este valor, las estructuras se combinan en una."
+msgid "The maximum distance between support structures in the X/Y directions. When separate structures are closer together than this value, the structures merge into one."
+msgstr "Distancia máxima entre las estructuras del soporte en las direcciones X/Y. Cuando las estructuras separadas están más cerca entre sí que este valor, se combinan en una."
#: fdmprinter.def.json
msgctxt "support_offset label"
@@ -3433,6 +3750,16 @@ msgctxt "gradual_support_infill_step_height description"
msgid "The height of support infill of a given density before switching to half the density."
msgstr "Altura del relleno de soporte de una determinada densidad antes de cambiar a la mitad de la densidad."
+#: fdmprinter.def.json
+msgctxt "minimum_support_area label"
+msgid "Minimum Support Area"
+msgstr "Área del soporte mínima"
+
+#: fdmprinter.def.json
+msgctxt "minimum_support_area description"
+msgid "Minimum area size for support polygons. Polygons which have an area smaller than this value will not be generated."
+msgstr "Tamaño del área mínima para los polígonos del soporte. No se generarán polígonos que posean un área de menor tamaño que este valor."
+
#: fdmprinter.def.json
msgctxt "support_interface_enable label"
msgid "Enable Support Interface"
@@ -3658,6 +3985,97 @@ msgctxt "support_bottom_pattern option zigzag"
msgid "Zig Zag"
msgstr "Zigzag"
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area label"
+msgid "Minimum Support Interface Area"
+msgstr "Área de la interfaz de soporte mínima"
+
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area description"
+msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Tamaño del área mínima para los polígonos de la interfaz de soporte. Los polígonos que posean un área de menor tamaño que este valor se imprimirán como"
+" soporte normal."
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area label"
+msgid "Minimum Support Roof Area"
+msgstr "Área de los techos del soporte mínima"
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area description"
+msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Tamaño del área mínima para los techos del soporte. Los polígonos que posean un área de menor tamaño que este valor se imprimirán como soporte normal."
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area label"
+msgid "Minimum Support Floor Area"
+msgstr "Área de los suelos del soporte mínima"
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area description"
+msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Tamaño del área mínima para los suelos del soporte. Los polígonos que posean un área de menor tamaño que este valor se imprimirán como soporte normal."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset label"
+msgid "Support Interface Horizontal Expansion"
+msgstr "Expansión horizontal de la interfaz de soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset description"
+msgid "Amount of offset applied to the support interface polygons."
+msgstr "Cantidad de desplazamiento aplicado a los polígonos de la interfaz de soporte."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset label"
+msgid "Support Roof Horizontal Expansion"
+msgstr "Expansión horizontal de los techos del soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset description"
+msgid "Amount of offset applied to the roofs of the support."
+msgstr "Cantidad de desplazamiento aplicado a los techos del soporte."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset label"
+msgid "Support Floor Horizontal Expansion"
+msgstr "Expansión horizontal de los suelos de soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset description"
+msgid "Amount of offset applied to the floors of the support."
+msgstr "Cantidad de desplazamiento aplicado a los suelos del soporte."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles label"
+msgid "Support Interface Line Directions"
+msgstr "Direcciones de línea de interfaz de soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Una lista de los valores enteros de las direcciones de línea que se van a utilizar. Los elementos de la lista se usan secuencialmente a medida que avanzan las capas y cuando se alcanza el final de la lista, comienza de nuevo desde el principio. Los elementos de la lista están separados por comas y toda la lista aparece entre corchetes. El valor predeterminado es una lista vacía, lo que significa que se utilizan los ángulos estándar (que varían entre 45 y 135 grados si las interfaces son bastante gruesas o de 90 grados en otro caso)."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles label"
+msgid "Support Roof Line Directions"
+msgstr "Direcciones de línea del techo de soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Una lista de los valores enteros de las direcciones de línea que se van a utilizar. Los elementos de la lista se usan secuencialmente a medida que avanzan las capas y cuando se alcanza el final de la lista, comienza de nuevo desde el principio. Los elementos de la lista están separados por comas y toda la lista aparece entre corchetes. El valor predeterminado es una lista vacía, lo que significa que se utilizan los ángulos estándar (que varían entre 45 y 135 grados si las interfaces son bastante gruesas o de 90 grados en otro caso)."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles label"
+msgid "Support Floor Line Directions"
+msgstr "Direcciones de línea del suelo de soporte"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Una lista de los valores enteros de las direcciones de línea que se van a utilizar. Los elementos de la lista se usan secuencialmente a medida que avanzan las capas y cuando se alcanza el final de la lista, comienza de nuevo desde el principio. Los elementos de la lista están separados por comas y toda la lista aparece entre corchetes. El valor predeterminado es una lista vacía, lo que significa que se utilizan los ángulos estándar (que varían entre 45 y 135 grados si las interfaces son bastante gruesas o de 90 grados en otro caso)."
+
#: fdmprinter.def.json
msgctxt "support_fan_enable label"
msgid "Fan Speed Override"
@@ -3699,14 +4117,14 @@ msgid "The diameter of a special tower."
msgstr "Diámetro de una torre especial."
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter label"
-msgid "Minimum Diameter"
-msgstr "Diámetro mínimo"
+msgctxt "support_tower_maximum_supported_diameter label"
+msgid "Maximum Tower-Supported Diameter"
+msgstr "Diámetro máximo soportado por la torre"
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter description"
-msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
-msgstr "Diámetro mínimo en las direcciones X/Y de una pequeña área que soportará una torre de soporte especializada."
+msgctxt "support_tower_maximum_supported_diameter description"
+msgid "Maximum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+msgstr "Diámetro máximo en las direcciones X/Y de una pequeña área que debe ser soportada por una torre de soporte especializada."
#: fdmprinter.def.json
msgctxt "support_tower_roof_angle label"
@@ -3828,7 +4246,9 @@ msgctxt "skirt_gap description"
msgid ""
"The horizontal distance between the skirt and the first layer of the print.\n"
"This is the minimum distance. Multiple skirt lines will extend outwards from this distance."
-msgstr "La distancia horizontal entre la falda y la primera capa de la impresión.\nSe trata de la distancia mínima. Múltiples líneas de falda se extenderán hacia el exterior a partir de esta distancia."
+msgstr ""
+"La distancia horizontal entre la falda y la primera capa de la impresión.\n"
+"Se trata de la distancia mínima. Múltiples líneas de falda se extenderán hacia el exterior a partir de esta distancia."
#: fdmprinter.def.json
msgctxt "skirt_brim_minimal_length label"
@@ -4200,16 +4620,6 @@ msgctxt "prime_tower_enable description"
msgid "Print a tower next to the print which serves to prime the material after each nozzle switch."
msgstr "Imprimir una torre junto a la impresión que sirve para preparar el material tras cada cambio de tobera."
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular label"
-msgid "Circular Prime Tower"
-msgstr "Torre auxiliar circular"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular description"
-msgid "Make the prime tower as a circular shape."
-msgstr "Hacer que la torre auxiliar sea circular."
-
#: fdmprinter.def.json
msgctxt "prime_tower_size label"
msgid "Prime Tower Size"
@@ -4250,16 +4660,6 @@ msgctxt "prime_tower_position_y description"
msgid "The y coordinate of the position of the prime tower."
msgstr "Coordenada Y de la posición de la torre auxiliar."
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow label"
-msgid "Prime Tower Flow"
-msgstr "Flujo de la torre auxiliar"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow description"
-msgid "Flow compensation: the amount of material extruded is multiplied by this value."
-msgstr "Compensación de flujo: la cantidad de material extruido se multiplica por este valor."
-
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled label"
msgid "Wipe Inactive Nozzle on Prime Tower"
@@ -4270,6 +4670,16 @@ msgctxt "prime_tower_wipe_enabled description"
msgid "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower."
msgstr "Tras imprimir la torre auxiliar con una tobera, limpie el material rezumado de la otra tobera de la torre auxiliar."
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable label"
+msgid "Prime Tower Brim"
+msgstr "Borde de la torre auxiliar"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable description"
+msgid "Prime-towers might need the extra adhesion afforded by a brim even if the model doesn't. Presently can't be used with the 'Raft' adhesion-type."
+msgstr "Puede que las torres auxiliares necesiten la adherencia adicional que proporciona un borde, aunque no sea requisito del modelo. Actualmente, no se puede usar con el tipo de adherencia «balsa»."
+
#: fdmprinter.def.json
msgctxt "ooze_shield_enabled label"
msgid "Enable Ooze Shield"
@@ -4390,6 +4800,36 @@ msgctxt "remove_empty_first_layers description"
msgid "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle."
msgstr "Eliminar (si las hubiera) las capas vacías por debajo de la primera capa impresa. Deshabilitar este ajuste puede hacer que aparezcan primeras capas vacías si el ajuste de tolerancia de segmentación está establecido en Exclusiva o Medio."
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution label"
+msgid "Maximum Resolution"
+msgstr "Resolución máxima"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution description"
+msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
+msgstr "El tamaño mínimo de un segmento de línea tras la segmentación. Si se aumenta, la resolución de la malla será menor. Esto puede permitir a la impresora mantener la velocidad que necesita para procesar GCode y aumentará la velocidad de segmentación al eliminar detalles de la malla que, de todas formas, no puede procesar."
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution label"
+msgid "Maximum Travel Resolution"
+msgstr "Resolución de desplazamiento máximo"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution description"
+msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
+msgstr "El tamaño mínimo de un segmento de línea de desplazamiento tras la segmentación. Si se aumenta, los movimientos de desplazamiento tendrán esquinas menos suavizadas. Esto puede le permite a la impresora mantener la velocidad que necesita para procesar GCode pero puede ocasionar que evitar el modelo sea menos preciso."
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation label"
+msgid "Maximum Deviation"
+msgstr "Desviación máxima"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation description"
+msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution, so if the two conflict the Maximum Deviation will always be held true."
+msgstr "La desviación máxima permitida al reducir la resolución en el ajuste de la resolución máxima. Si se aumenta el valor, la impresión será menos precisa pero el GCode será más pequeño. La desviación máxima es un límite para la resolución máxima, por lo que si las dos entran en conflicto, la desviación máxima siempre tendrá prioridad."
+
#: fdmprinter.def.json
msgctxt "blackmagic label"
msgid "Special Modes"
@@ -4552,8 +4992,8 @@ msgstr "Contornos espiralizados suaves"
#: fdmprinter.def.json
msgctxt "smooth_spiralized_contours description"
-msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
-msgstr "Suavice los contornos espiralizados para reducir la visibilidad de la costura Z (la costura Z debería ser apenas visible en la impresora pero seguirá siendo visible en la vista de capas). Tenga en cuenta que la suavización tenderá a desdibujar detalles finos de la superficie."
+msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+msgstr "Suaviza los contornos espiralizados para reducir la visibilidad de la costura Z (la costura Z debería ser apenas visible en la impresora pero seguirá siendo visible en la vista de capas). Tenga en cuenta que la suavización tenderá a desdibujar detalles finos de la superficie."
#: fdmprinter.def.json
msgctxt "relative_extrusion label"
@@ -4765,26 +5205,6 @@ msgctxt "minimum_polygon_circumference description"
msgid "Polygons in sliced layers that have a circumference smaller than this amount will be filtered out. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details."
msgstr "Se filtran los polígonos en capas segmentadas que tienen una circunferencia más pequeña que esta. Los valores más pequeños suponen una resolución de malla mayor a costa de un tiempo de segmentación. Está indicado, sobre todo, para impresoras SLA y modelos 3D muy pequeños con muchos detalles."
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution label"
-msgid "Maximum Resolution"
-msgstr "Resolución máxima"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution description"
-msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
-msgstr "El tamaño mínimo de un segmento de línea tras la segmentación. Si se aumenta, la resolución de la malla será menor. Esto puede permitir a la impresora mantener la velocidad que necesita para procesar GCode y aumentará la velocidad de segmentación al eliminar detalles de la malla que, de todas formas, no puede procesar."
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution label"
-msgid "Maximum Travel Resolution"
-msgstr "Resolución de desplazamiento máximo"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution description"
-msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
-msgstr "El tamaño mínimo de un segmento de línea de desplazamiento tras la segmentación. Si se aumenta, los movimientos de desplazamiento tendrán esquinas menos suavizadas. Esto puede le permite a la impresora mantener la velocidad que necesita para procesar GCode pero puede ocasionar que evitar el modelo sea menos preciso."
-
#: fdmprinter.def.json
msgctxt "support_skip_some_zags label"
msgid "Break Up Support In Chunks"
@@ -4925,16 +5345,6 @@ msgctxt "coasting_speed description"
msgid "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops."
msgstr "Velocidad a la que se desplaza durante el depósito por inercia con relación a la velocidad de la trayectoria de extrusión. Se recomienda un valor ligeramente por debajo del 100%, ya que la presión en el tubo guía disminuye durante el movimiento depósito por inercia."
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation label"
-msgid "Alternate Skin Rotation"
-msgstr "Alternar la rotación del forro"
-
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation description"
-msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
-msgstr "Alterna la dirección en la que se imprimen las capas superiores/inferiores. Normalmente, se imprimen únicamente en diagonal. Este ajuste añade las direcciones solo X y solo Y."
-
#: fdmprinter.def.json
msgctxt "cross_infill_pocket_size label"
msgid "Cross 3D Pocket Size"
@@ -5042,8 +5452,8 @@ msgstr "Activar soporte cónico"
#: fdmprinter.def.json
msgctxt "support_conical_enabled description"
-msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
-msgstr "Función experimental: hace áreas de soporte más pequeñas en la parte inferior que en el voladizo."
+msgid "Make support areas smaller at the bottom than at the overhang."
+msgstr "Hace que las áreas de soporte sean más pequeñas en la parte inferior que en el voladizo."
#: fdmprinter.def.json
msgctxt "support_conical_angle label"
@@ -5107,23 +5517,24 @@ msgstr "Distancia media entre los puntos aleatorios introducidos en cada segment
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset label"
-msgid "Flow rate compensation max extrusion offset"
+msgid "Flow Rate Compensation Max Extrusion Offset"
msgstr "Desplazamiento de extrusión máximo del factor de compensación del caudal"
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset description"
-msgid "The maximum distance in mm to compensate."
-msgstr "Distancia máxima en mm que se va a compensar."
+msgid "The maximum distance in mm to move the filament to compensate for changes in flow rate."
+msgstr "La distancia máxima en mm para mover el filamento con el fin de compensar los cambios en el caudal."
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor label"
-msgid "Flow rate compensation factor"
+msgid "Flow Rate Compensation Factor"
msgstr "Factor de compensación del caudal"
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor description"
-msgid "The multiplication factor for the flow rate -> distance translation."
-msgstr "La multiplicación factor por caudal da como resultado la conversión de distancia."
+msgid "How far to move the filament in order to compensate for changes in flow rate, as a percentage of how far the filament would move in one second of extrusion."
+msgstr "La distancia para mover el filamento con el fin de compensar los cambios en el caudal, como porcentaje de la distancia a la que se movería el filamento"
+" en un segundo de extrusión."
#: fdmprinter.def.json
msgctxt "wireframe_enabled label"
@@ -5275,7 +5686,9 @@ msgctxt "wireframe_up_half_speed description"
msgid ""
"Distance of an upward move which is extruded with half speed.\n"
"This can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing."
-msgstr "Distancia de un movimiento ascendente que se extrude a media velocidad.\nEsto puede causar una mejor adherencia a las capas anteriores, aunque no calienta demasiado el material en esas capas. Solo se aplica a la impresión de alambre."
+msgstr ""
+"Distancia de un movimiento ascendente que se extrude a media velocidad.\n"
+"Esto puede causar una mejor adherencia a las capas anteriores, aunque no calienta demasiado el material en esas capas. Solo se aplica a la impresión de alambre."
#: fdmprinter.def.json
msgctxt "wireframe_top_jump label"
@@ -5384,7 +5797,7 @@ msgstr "Distancia entre la tobera y líneas descendentes en horizontal. Cuanto m
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
-msgid "Use adaptive layers"
+msgid "Use Adaptive Layers"
msgstr "Utilizar capas de adaptación"
#: fdmprinter.def.json
@@ -5394,7 +5807,7 @@ msgstr "Las capas de adaptación calculan las alturas de las capas dependiendo d
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
-msgid "Adaptive layers maximum variation"
+msgid "Adaptive Layers Maximum Variation"
msgstr "Variación máxima de las capas de adaptación"
#: fdmprinter.def.json
@@ -5404,7 +5817,7 @@ msgstr "La diferencia de altura máxima permitida en comparación con la altura
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
-msgid "Adaptive layers variation step size"
+msgid "Adaptive Layers Variation Step Size"
msgstr "Tamaño de pasos de variación de las capas de adaptación"
#: fdmprinter.def.json
@@ -5414,13 +5827,14 @@ msgstr "La diferencia de altura de la siguiente altura de capa en comparación c
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
-msgid "Adaptive layers threshold"
-msgstr "Umbral de las capas de adaptación"
+msgid "Adaptive Layers Topography Size"
+msgstr "Tamaño de la topografía de las capas de adaptación"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
-msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
-msgstr "Umbral para usar o no una capa más pequeña. Este número se compara con el curtido de la pendiente más empinada de una capa."
+msgid "Target horizontal distance between two adjacent layers. Reducing this setting causes thinner layers to be used to bring the edges of the layers closer together."
+msgstr "Distancia horizontal objetivo entre dos capas adyacentes. Si se reduce este ajuste, se tendrán que utilizar capas más finas para acercar más los bordes"
+" de las capas."
#: fdmprinter.def.json
msgctxt "wall_overhang_angle label"
@@ -5429,8 +5843,9 @@ msgstr "Ángulo de voladizo de pared"
#: fdmprinter.def.json
msgctxt "wall_overhang_angle description"
-msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
-msgstr "Las paredes con un ángulo de voladizo mayor que este se imprimirán con los ajustes de voladizo de pared. Cuando el valor sea 90, no se aplicará la condición de voladizo a la pared."
+msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging. Overhang that gets supported by support will not be treated as overhang either."
+msgstr "Las paredes con un ángulo de voladizo mayor que este se imprimirán con los ajustes de voladizo de pared. Cuando el valor sea 90, no se aplicará la condición"
+" de voladizo a la pared. El voladizo que se apoya en el soporte tampoco se tratará como voladizo."
#: fdmprinter.def.json
msgctxt "wall_overhang_speed_factor label"
@@ -5632,6 +6047,197 @@ msgctxt "bridge_fan_speed_3 description"
msgid "Percentage fan speed to use when printing the third bridge skin layer."
msgstr "Velocidad del ventilador en porcentaje que se utiliza para imprimir la tercera capa del forro del puente."
+#: fdmprinter.def.json
+msgctxt "clean_between_layers label"
+msgid "Wipe Nozzle Between Layers"
+msgstr "Limpiar tobera entre capas"
+
+#: fdmprinter.def.json
+msgctxt "clean_between_layers description"
+msgid "Whether to include nozzle wipe G-Code between layers. Enabling this setting could influence behavior of retract at layer change. Please use Wipe Retraction settings to control retraction at layers where the wipe script will be working."
+msgstr "Posibilidad de incluir GCode de limpieza de tobera entre capas. Habilitar este ajuste puede influir en el comportamiento de retracción en el cambio de capa. Utilice los ajustes de retracción de limpieza para controlar la retracción en las capas donde la secuencia de limpieza estará en curso."
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe label"
+msgid "Material Volume Between Wipes"
+msgstr "Volumen de material entre limpiezas"
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe description"
+msgid "Maximum material, that can be extruded before another nozzle wipe is initiated."
+msgstr "Material máximo que puede extruirse antes de que se inicie otra limpieza de tobera."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable label"
+msgid "Wipe Retraction Enable"
+msgstr "Habilitación de retracción de limpieza"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable description"
+msgid "Retract the filament when the nozzle is moving over a non-printed area."
+msgstr "Retrae el filamento cuando la tobera se mueve sobre un área no impresa."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount label"
+msgid "Wipe Retraction Distance"
+msgstr "Distancia de retracción de limpieza"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount description"
+msgid "Amount to retract the filament so it does not ooze during the wipe sequence."
+msgstr "Cantidad para retraer el filamento para que no rezume durante la secuencia de limpieza."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount label"
+msgid "Wipe Retraction Extra Prime Amount"
+msgstr "Cantidad de cebado adicional de retracción de limpieza"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount description"
+msgid "Some material can ooze away during a wipe travel moves, which can be compensated for here."
+msgstr "Algunos materiales pueden rezumar durante el movimiento de un desplazamiento de limpieza, lo cual se puede corregir aquí."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed label"
+msgid "Wipe Retraction Speed"
+msgstr "Velocidad de retracción de limpieza"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed description"
+msgid "The speed at which the filament is retracted and primed during a wipe retraction move."
+msgstr "Velocidad a la que se retrae el filamento y se prepara durante un movimiento de retracción de limpieza."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed label"
+msgid "Wipe Retraction Retract Speed"
+msgstr "Velocidad de retracción en retracción de limpieza"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed description"
+msgid "The speed at which the filament is retracted during a wipe retraction move."
+msgstr "Velocidad a la que se retrae el filamento durante un movimiento de retracción de limpieza."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed label"
+msgid "Retraction Prime Speed"
+msgstr "Velocidad de cebado de retracción"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed description"
+msgid "The speed at which the filament is primed during a wipe retraction move."
+msgstr "Velocidad a la que se prepara el filamento durante un movimiento de retracción de limpieza."
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause label"
+msgid "Wipe Pause"
+msgstr "Pausar limpieza"
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause description"
+msgid "Pause after the unretract."
+msgstr "Pausa después de no haber retracción."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable label"
+msgid "Wipe Z Hop When Retracted"
+msgstr "Limpiar salto en Z en la retracción"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable description"
+msgid "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate."
+msgstr "Siempre que se realiza una retracción, la placa de impresión se baja para crear holgura entre la tobera y la impresión. Impide que la tobera golpee la impresión durante movimientos de desplazamiento, reduciendo las posibilidades de alcanzar la impresión de la placa de impresión."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount label"
+msgid "Wipe Z Hop Height"
+msgstr "Limpiar altura del salto en Z"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount description"
+msgid "The height difference when performing a Z Hop."
+msgstr "Diferencia de altura cuando se realiza un salto en Z."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed label"
+msgid "Wipe Hop Speed"
+msgstr "Limpiar velocidad de salto"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed description"
+msgid "Speed to move the z-axis during the hop."
+msgstr "Velocidad para mover el eje Z durante el salto."
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x label"
+msgid "Wipe Brush X Position"
+msgstr "Limpiar posición X de cepillo"
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x description"
+msgid "X location where wipe script will start."
+msgstr "Ubicación X donde se iniciará la secuencia de limpieza."
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count label"
+msgid "Wipe Repeat Count"
+msgstr "Recuento de repeticiones de limpieza"
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count description"
+msgid "Number of times to move the nozzle across the brush."
+msgstr "Número de movimientos de la tobera a lo largo del cepillo."
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance label"
+msgid "Wipe Move Distance"
+msgstr "Distancia de movimiento de limpieza"
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance description"
+msgid "The distance to move the head back and forth across the brush."
+msgstr "La distancia para mover el cabezal hacia adelante y hacia atrás a lo largo del cepillo."
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size label"
+msgid "Small Hole Max Size"
+msgstr "Tamaño máximo de agujero pequeño"
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size description"
+msgid "Holes and part outlines with a diameter smaller than this will be printed using Small Feature Speed."
+msgstr "Los agujeros y contornos de las piezas con un diámetro menor que estos se imprimen utilizando la función Velocidad de pequeñas partes."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length label"
+msgid "Small Feature Max Length"
+msgstr "Longitud máxima de pequeñas partes"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length description"
+msgid "Feature outlines that are shorter than this length will be printed using Small Feature Speed."
+msgstr "Los contornos de las partes que sean más cortos que esta longitud se imprimen utilizando la función Velocidad de pequeñas partes."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor label"
+msgid "Small Feature Speed"
+msgstr "Velocidad de pequeñas partes"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor description"
+msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "Las pequeñas partes se imprimirán a este porcentaje de su velocidad de impresión normal. Una impresión más lenta puede mejorar la adhesión y la precisión."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 label"
+msgid "Small Feature Initial Layer Speed"
+msgstr "Velocidad de la capa inicial de partes pequeñas"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 description"
+msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "Las pequeñas partes de la primera capa se imprimirán a este porcentaje de su velocidad de impresión normal. Una impresión más lenta puede mejorar la adhesión"
+" y la precisión."
+
#: fdmprinter.def.json
msgctxt "command_line_settings label"
msgid "Command Line Settings"
@@ -5692,6 +6298,234 @@ msgctxt "mesh_rotation_matrix description"
msgid "Transformation matrix to be applied to the model when loading it from file."
msgstr "Matriz de transformación que se aplicará al modelo cuando se cargue desde el archivo."
+#~ msgctxt "minimum_interface_area description"
+#~ msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Tamaño del área mínima para los polígonos de la interfaz de soporte. No se generarán polígonos que posean un área de menor tamaño que este valor."
+
+#~ msgctxt "minimum_roof_area description"
+#~ msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Tamaño del área mínima para los techos del soporte. No se generarán polígonos que posean un área de menor tamaño que este valor."
+
+#~ msgctxt "minimum_bottom_area description"
+#~ msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Tamaño del área mínima para los suelos del soporte. No se generarán polígonos que posean un área de menor tamaño que este valor."
+
+#~ msgctxt "skin_alternate_rotation label"
+#~ msgid "Alternate Skin Rotation"
+#~ msgstr "Alternar la rotación del forro"
+
+#~ msgctxt "skin_alternate_rotation description"
+#~ msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
+#~ msgstr "Alterna la dirección en la que se imprimen las capas superiores/inferiores. Normalmente, se imprimen únicamente en diagonal. Este ajuste añade las direcciones solo X y solo Y."
+
+#~ msgctxt "flow_rate_max_extrusion_offset label"
+#~ msgid "Flow rate compensation max extrusion offset"
+#~ msgstr "Desplazamiento de extrusión máximo del factor de compensación del caudal"
+
+#~ msgctxt "flow_rate_max_extrusion_offset description"
+#~ msgid "The maximum distance in mm to compensate."
+#~ msgstr "Distancia máxima en mm que se va a compensar."
+
+#~ msgctxt "flow_rate_extrusion_offset_factor label"
+#~ msgid "Flow rate compensation factor"
+#~ msgstr "Factor de compensación del caudal"
+
+#~ msgctxt "flow_rate_extrusion_offset_factor description"
+#~ msgid "The multiplication factor for the flow rate -> distance translation."
+#~ msgstr "La multiplicación factor por caudal da como resultado la conversión de distancia."
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive Layers Threshold"
+#~ msgstr "Umbral de las capas de adaptación"
+
+#~ msgctxt "adaptive_layer_height_threshold description"
+#~ msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
+#~ msgstr "Umbral para usar o no una capa más pequeña. Este número se compara con el curtido de la pendiente más empinada de una capa."
+
+#~ msgctxt "wall_overhang_angle description"
+#~ msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
+#~ msgstr "Las paredes con un ángulo de voladizo mayor que este se imprimirán con los ajustes de voladizo de pared. Cuando el valor sea 90, no se aplicará la condición de voladizo a la pared."
+
+#~ msgctxt "small_feature_speed_factor description"
+#~ msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "Las pequeñas partes se imprimirán a este porcentaje de su velocidad de impresión normal. Una impresión más lenta puede mejorar la adhesión y la precisión."
+
+#~ msgctxt "small_feature_speed_factor_0 label"
+#~ msgid "First Layer Speed"
+#~ msgstr "Velocidad de primera capa"
+
+#~ msgctxt "small_feature_speed_factor_0 description"
+#~ msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "Las pequeñas partes de la primera capa se imprimirán a este porcentaje de su velocidad de impresión normal. Una impresión más lenta puede mejorar la adhesión y la precisión."
+
+#~ msgctxt "ironing_enabled description"
+#~ msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
+#~ msgstr "Pasar por la superficie superior una vez más, pero sin extruir material, para derretir la parte externa del plástico y crear una superficie más lisa."
+
+#~ msgctxt "start_layers_at_same_position label"
+#~ msgid "Start Layers with the Same Part"
+#~ msgstr "Comenzar capas con la misma parte"
+
+#~ msgctxt "start_layers_at_same_position description"
+#~ msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
+#~ msgstr "En cada capa, comenzar imprimiendo el objeto cerca del mismo punto, de forma que no se comienza una capa imprimiendo la pieza en la que finalizó la capa anterior. Esto permite mejorar los voladizos y las partes pequeñas, a costa de un mayor tiempo de impresión."
+
+#~ msgctxt "support_infill_angles description"
+#~ msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
+#~ msgstr "Orientación del patrón de relleno para soportes. El patrón de relleno de soporte se gira en el plano horizontal."
+
+#~ msgctxt "meshfix_maximum_deviation description"
+#~ msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller."
+#~ msgstr "La desviación máxima permitida al reducir la resolución en el ajuste de resolución máxima. Si se aumenta el valor, la impresión será menos precisa pero el GCode será más pequeño."
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code Flavour"
+#~ msgstr "Tipo de GCode"
+
+#~ msgctxt "z_seam_corner description"
+#~ msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
+#~ msgstr "Controlar si las esquinas del contorno del modelo influyen en la posición de la costura. «Ninguno» significa que las esquinas no influyen en la posición de la costura. «Ocultar costura» significa que es probable que la costura se realice en una esquina interior. «Mostrar costura» significa que es probable que la costura sea en una esquina exterior. «Ocultar o mostrar costura» significa que es probable que la costura se realice en una esquina interior o exterior."
+
+#~ msgctxt "skin_no_small_gaps_heuristic label"
+#~ msgid "Ignore Small Z Gaps"
+#~ msgstr "Ignorar los pequeños huecos en Z"
+
+#~ msgctxt "skin_no_small_gaps_heuristic description"
+#~ msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
+#~ msgstr "Cuando el modelo tiene pequeños huecos verticales, el tiempo de cálculo puede aumentar alrededor de un 5 % para generar el forro superior e inferior en estos espacios estrechos. En tal caso, desactive este ajuste."
+
+#~ msgctxt "build_volume_temperature description"
+#~ msgid "The temperature used for build volume. If this is 0, the build volume temperature will not be adjusted."
+#~ msgstr "La temperatura utilizada para el volumen de impresión. Si el valor es 0, la temperatura de volumen de impresión no se ajustará."
+
+#~ msgctxt "limit_support_retractions description"
+#~ msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
+#~ msgstr "Omitir la retracción al moverse de soporte a soporte en línea recta. Habilitar este ajuste ahorra tiempo de impresión pero puede ocasionar un encordado excesivo en la estructura de soporte."
+
+#~ msgctxt "max_feedrate_z_override label"
+#~ msgid "Maximum Z Speed"
+#~ msgstr "Velocidad máxima de Z"
+
+#~ msgctxt "max_feedrate_z_override description"
+#~ msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
+#~ msgstr "Velocidad máxima a la que se mueve la placa de impresión. Definir este valor en 0 hace que la impresión utilice los valores predeterminados de la velocidad máxima de Z."
+
+#~ msgctxt "support_join_distance description"
+#~ msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
+#~ msgstr "Distancia máxima entre las estructuras del soporte en las direcciones X/Y. Cuando estructuras separadas están más cerca entre sí que de este valor, las estructuras se combinan en una."
+
+#~ msgctxt "support_minimal_diameter label"
+#~ msgid "Minimum Diameter"
+#~ msgstr "Diámetro mínimo"
+
+#~ msgctxt "support_minimal_diameter description"
+#~ msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+#~ msgstr "Diámetro mínimo en las direcciones X/Y de una pequeña área que soportará una torre de soporte especializada."
+
+#~ msgctxt "prime_tower_circular label"
+#~ msgid "Circular Prime Tower"
+#~ msgstr "Torre auxiliar circular"
+
+#~ msgctxt "prime_tower_circular description"
+#~ msgid "Make the prime tower as a circular shape."
+#~ msgstr "Hacer que la torre auxiliar sea circular."
+
+#~ msgctxt "prime_tower_flow description"
+#~ msgid "Flow compensation: the amount of material extruded is multiplied by this value."
+#~ msgstr "Compensación de flujo: la cantidad de material extruido se multiplica por este valor."
+
+#~ msgctxt "smooth_spiralized_contours description"
+#~ msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+#~ msgstr "Suavice los contornos espiralizados para reducir la visibilidad de la costura Z (la costura Z debería ser apenas visible en la impresora pero seguirá siendo visible en la vista de capas). Tenga en cuenta que la suavización tenderá a desdibujar detalles finos de la superficie."
+
+#~ msgctxt "support_conical_enabled description"
+#~ msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
+#~ msgstr "Función experimental: hace áreas de soporte más pequeñas en la parte inferior que en el voladizo."
+
+#~ msgctxt "extruders_enabled_count label"
+#~ msgid "Number of Extruders that are enabled"
+#~ msgstr "Número de extrusores habilitados"
+
+#~ msgctxt "machine_nozzle_tip_outer_diameter label"
+#~ msgid "Outer nozzle diameter"
+#~ msgstr "Diámetro exterior de la tobera"
+
+#~ msgctxt "machine_nozzle_head_distance label"
+#~ msgid "Nozzle length"
+#~ msgstr "Longitud de la tobera"
+
+#~ msgctxt "machine_nozzle_expansion_angle label"
+#~ msgid "Nozzle angle"
+#~ msgstr "Ángulo de la tobera"
+
+#~ msgctxt "machine_heat_zone_length label"
+#~ msgid "Heat zone length"
+#~ msgstr "Longitud de la zona térmica"
+
+#~ msgctxt "machine_nozzle_heat_up_speed label"
+#~ msgid "Heat up speed"
+#~ msgstr "Velocidad de calentamiento"
+
+#~ msgctxt "machine_nozzle_cool_down_speed label"
+#~ msgid "Cool down speed"
+#~ msgstr "Velocidad de enfriamiento"
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code flavour"
+#~ msgstr "Tipo de GCode"
+
+#~ msgctxt "machine_disallowed_areas label"
+#~ msgid "Disallowed areas"
+#~ msgstr "Áreas no permitidas"
+
+#~ msgctxt "machine_head_polygon label"
+#~ msgid "Machine head polygon"
+#~ msgstr "Polígono del cabezal de la máquina"
+
+#~ msgctxt "machine_head_with_fans_polygon label"
+#~ msgid "Machine head & Fan polygon"
+#~ msgstr "Polígono del cabezal de la máquina y del ventilador"
+
+#~ msgctxt "gantry_height label"
+#~ msgid "Gantry height"
+#~ msgstr "Altura del puente"
+
+#~ msgctxt "machine_use_extruder_offset_to_offset_coords label"
+#~ msgid "Offset With Extruder"
+#~ msgstr "Desplazamiento con extrusor"
+
+#~ msgctxt "adaptive_layer_height_enabled label"
+#~ msgid "Use adaptive layers"
+#~ msgstr "Utilizar capas de adaptación"
+
+#~ msgctxt "adaptive_layer_height_variation label"
+#~ msgid "Adaptive layers maximum variation"
+#~ msgstr "Variación máxima de las capas de adaptación"
+
+#~ msgctxt "adaptive_layer_height_variation_step label"
+#~ msgid "Adaptive layers variation step size"
+#~ msgstr "Tamaño de pasos de variación de las capas de adaptación"
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive layers threshold"
+#~ msgstr "Umbral de las capas de adaptación"
+
+#~ msgctxt "skin_overlap description"
+#~ msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
+#~ msgstr "La cantidad de superposición entre el forro y las paredes son un porcentaje del ancho de la línea de forro. Una ligera superposición permite que las paredes estén firmemente unidas al forro. Este es el porcentaje de la media de los anchos de las líneas del forro y la pared más profunda."
+
+#~ msgctxt "skin_overlap_mm description"
+#~ msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
+#~ msgstr "Cantidad de superposición entre el forro y las paredes. Una ligera superposición permite que las paredes conecten firmemente con el forro."
+
+#~ msgctxt "switch_extruder_retraction_amount description"
+#~ msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+#~ msgstr "Distancia de la retracción: utilice el valor cero para que no haya retracción. Por norma general, este valor debe ser igual a la longitud de la zona de calentamiento."
+
+#~ msgctxt "retraction_combing description"
+#~ msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
+#~ msgstr "La opción de peinada mantiene la tobera dentro de las áreas ya impresas al desplazarse. Esto ocasiona movimientos de desplazamiento ligeramente más largos, pero reduce la necesidad de realizar retracciones. Si se desactiva la opción de peinada, el material se retraerá y la tobera se moverá en línea recta hasta el siguiente punto. Otra posibilidad es evitar la peinada en áreas de forro superiores/inferiores y además peinar solo en el relleno. La opción de «Sobre el relleno» actúa exactamente igual que la «No está en el forro» de las versiones de Cura anteriores."
+
#~ msgctxt "connect_skin_polygons description"
#~ msgid "Connect top/bottom skin paths where they run next to each other. For the concentric pattern enabling this setting greatly reduces the travel time, but because the connections can happend midway over infill this feature can reduce the top surface quality."
#~ msgstr "Conectar las trayectorias de forro superior/inferior cuando están próximas entre sí. Al habilitar este ajuste, en el patrón concéntrico se reduce considerablemente el tiempo de desplazamiento, pero las conexiones pueden producirse en mitad del relleno, con lo que la bajaría la calidad de la superficie superior."
diff --git a/resources/i18n/fdmextruder.def.json.pot b/resources/i18n/fdmextruder.def.json.pot
index fbb003f3c6..322be35b57 100644
--- a/resources/i18n/fdmextruder.def.json.pot
+++ b/resources/i18n/fdmextruder.def.json.pot
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Uranium json setting files\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE\n"
@@ -80,7 +80,7 @@ msgstr ""
#: fdmextruder.def.json
msgctxt "machine_extruder_start_code description"
-msgid "Start g-code to execute whenever turning the extruder on."
+msgid "Start g-code to execute when switching to this extruder."
msgstr ""
#: fdmextruder.def.json
@@ -122,7 +122,7 @@ msgstr ""
#: fdmextruder.def.json
msgctxt "machine_extruder_end_code description"
-msgid "End g-code to execute whenever turning the extruder off."
+msgid "End g-code to execute when switching away from this extruder."
msgstr ""
#: fdmextruder.def.json
diff --git a/resources/i18n/fdmprinter.def.json.pot b/resources/i18n/fdmprinter.def.json.pot
index 96071d82b8..89ff364e2d 100644
--- a/resources/i18n/fdmprinter.def.json.pot
+++ b/resources/i18n/fdmprinter.def.json.pot
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Uranium json setting files\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE\n"
@@ -218,6 +218,16 @@ msgctxt "machine_heated_bed description"
msgid "Whether the machine has a heated build plate present."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume label"
+msgid "Has Build Volume Temperature Stabilization"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume description"
+msgid "Whether the machine is able to stabilize the build volume temperature."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "machine_center_is_zero label"
msgid "Is Center Origin"
@@ -244,7 +254,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "extruders_enabled_count label"
-msgid "Number of Extruders that are enabled"
+msgid "Number of Extruders That Are Enabled"
msgstr ""
#: fdmprinter.def.json
@@ -255,7 +265,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter label"
-msgid "Outer nozzle diameter"
+msgid "Outer Nozzle Diameter"
msgstr ""
#: fdmprinter.def.json
@@ -265,7 +275,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_head_distance label"
-msgid "Nozzle length"
+msgid "Nozzle Length"
msgstr ""
#: fdmprinter.def.json
@@ -277,7 +287,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_expansion_angle label"
-msgid "Nozzle angle"
+msgid "Nozzle Angle"
msgstr ""
#: fdmprinter.def.json
@@ -289,7 +299,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_heat_zone_length label"
-msgid "Heat zone length"
+msgid "Heat Zone Length"
msgstr ""
#: fdmprinter.def.json
@@ -325,7 +335,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed label"
-msgid "Heat up speed"
+msgid "Heat Up Speed"
msgstr ""
#: fdmprinter.def.json
@@ -337,7 +347,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_cool_down_speed label"
-msgid "Cool down speed"
+msgid "Cool Down Speed"
msgstr ""
#: fdmprinter.def.json
@@ -362,7 +372,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor label"
-msgid "G-code flavour"
+msgid "G-code Flavor"
msgstr ""
#: fdmprinter.def.json
@@ -429,7 +439,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
-msgid "Disallowed areas"
+msgid "Disallowed Areas"
msgstr ""
#: fdmprinter.def.json
@@ -449,7 +459,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_head_polygon label"
-msgid "Machine head polygon"
+msgid "Machine Head Polygon"
msgstr ""
#: fdmprinter.def.json
@@ -459,7 +469,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon label"
-msgid "Machine head & Fan polygon"
+msgid "Machine Head & Fan Polygon"
msgstr ""
#: fdmprinter.def.json
@@ -469,7 +479,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "gantry_height label"
-msgid "Gantry height"
+msgid "Gantry Height"
msgstr ""
#: fdmprinter.def.json
@@ -503,7 +513,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords label"
-msgid "Offset With Extruder"
+msgid "Offset with Extruder"
msgstr ""
#: fdmprinter.def.json
@@ -1111,6 +1121,18 @@ msgid ""
"value is rounded to a whole number."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers label"
+msgid "Initial Bottom Layers"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers description"
+msgid ""
+"The number of initial bottom layers, from the build-plate upwards. When "
+"calculated by the bottom thickness, this value is rounded to a whole number."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "top_bottom_pattern label"
msgid "Top/Bottom Pattern"
@@ -1412,6 +1434,56 @@ msgctxt "z_seam_type option sharpest_corner"
msgid "Sharpest Corner"
msgstr ""
+#: fdmprinter.def.json
+msgctxt "z_seam_position label"
+msgid "Z Seam Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position description"
+msgid "The position near where to start printing each part in a layer."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backleft"
+msgid "Back Left"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option back"
+msgid "Back"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backright"
+msgid "Back Right"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option right"
+msgid "Right"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontright"
+msgid "Front Right"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option front"
+msgid "Front"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontleft"
+msgid "Front Left"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option left"
+msgid "Left"
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "z_seam_x label"
msgid "Z Seam X"
@@ -1448,7 +1520,9 @@ msgid ""
"seam. None means that corners have no influence on the seam position. Hide "
"Seam makes the seam more likely to occur on an inside corner. Expose Seam "
"makes the seam more likely to occur on an outside corner. Hide or Expose "
-"Seam makes the seam more likely to occur at an inside or outside corner."
+"Seam makes the seam more likely to occur at an inside or outside corner. "
+"Smart Hiding allows both inside and outside corners, but chooses inside "
+"corners more frequently, if appropriate."
msgstr ""
#: fdmprinter.def.json
@@ -1471,6 +1545,11 @@ msgctxt "z_seam_corner option z_seam_corner_any"
msgid "Hide or Expose Seam"
msgstr ""
+#: fdmprinter.def.json
+msgctxt "z_seam_corner option z_seam_corner_weighted"
+msgid "Smart Hiding"
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "z_seam_relative label"
msgid "Z Seam Relative"
@@ -1486,15 +1565,17 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic label"
-msgid "Ignore Small Z Gaps"
+msgid "No Skin in Z Gaps"
msgstr ""
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic description"
msgid ""
-"When the model has small vertical gaps, about 5% extra computation time can "
-"be spent on generating top and bottom skin in these narrow spaces. In such "
-"case, disable the setting."
+"When the model has small vertical gaps of only a few layers, there should "
+"normally be skin around those layers in the narrow space. Enable this "
+"setting to not generate skin if the vertical gap is very small. This "
+"improves printing time and slicing time, but technically leaves infill "
+"exposed to the air."
msgstr ""
#: fdmprinter.def.json
@@ -1518,9 +1599,10 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "ironing_enabled description"
msgid ""
-"Go over the top surface one additional time, but without extruding material. "
-"This is meant to melt the plastic on top further, creating a smoother "
-"surface."
+"Go over the top surface one additional time, but this time extruding very "
+"little material. This is meant to melt the plastic on top further, creating "
+"a smoother surface. The pressure in the nozzle chamber is kept high so that "
+"the creases in the surface are filled with material."
msgstr ""
#: fdmprinter.def.json
@@ -1621,6 +1703,39 @@ msgctxt "jerk_ironing description"
msgid "The maximum instantaneous velocity change while performing ironing."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "skin_overlap label"
+msgid "Skin Overlap Percentage"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap description"
+msgid ""
+"Adjust the amount of overlap between the walls and (the endpoints of) the "
+"skin-centerlines, as a percentage of the line widths of the skin lines and "
+"the innermost wall. A slight overlap allows the walls to connect firmly to "
+"the skin. Note that, given an equal skin and wall line-width, any percentage "
+"over 50% may already cause any skin to go past the wall, because at that "
+"point the position of the nozzle of the skin-extruder may already reach past "
+"the middle of the wall."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm label"
+msgid "Skin Overlap"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm description"
+msgid ""
+"Adjust the amount of overlap between the walls and (the endpoints of) the "
+"skin-centerlines. A slight overlap allows the walls to connect firmly to the "
+"skin. Note that, given an equal skin and wall line-width, any value over "
+"half the width of the wall may already cause any skin to go past the wall, "
+"because at that point the position of the nozzle of the skin-extruder may "
+"already reach past the middle of the wall."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "infill label"
msgid "Infill"
@@ -1809,6 +1924,19 @@ msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location label"
+msgid "Randomize Infill Start"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location description"
+msgid ""
+"Randomize which infill line is printed first. This prevents one segment "
+"becoming the strongest, but it does so at the cost of an additional travel "
+"move."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "infill_multiplier label"
msgid "Infill Line Multiplier"
@@ -1877,32 +2005,6 @@ msgid ""
"allows the walls to connect firmly to the infill."
msgstr ""
-#: fdmprinter.def.json
-msgctxt "skin_overlap label"
-msgid "Skin Overlap Percentage"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap description"
-msgid ""
-"The amount of overlap between the skin and the walls as a percentage of the "
-"skin line width. A slight overlap allows the walls to connect firmly to the "
-"skin. This is a percentage of the average line widths of the skin lines and "
-"the innermost wall."
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm label"
-msgid "Skin Overlap"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm description"
-msgid ""
-"The amount of overlap between the skin and the walls. A slight overlap "
-"allows the walls to connect firmly to the skin."
-msgstr ""
-
#: fdmprinter.def.json
msgctxt "infill_wipe_dist label"
msgid "Infill Wipe Distance"
@@ -2136,6 +2238,18 @@ msgid ""
"based on this value"
msgstr ""
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature label"
+msgid "Build Volume Temperature"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature description"
+msgid ""
+"The temperature of the environment to print in. If this is 0, the build "
+"volume temperature will not be adjusted."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "material_print_temperature label"
msgid "Printing Temperature"
@@ -2259,6 +2373,94 @@ msgctxt "material_shrinkage_percentage description"
msgid "Shrinkage ratio in percentage."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "material_crystallinity label"
+msgid "Crystalline Material"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_crystallinity description"
+msgid ""
+"Is this material the type that breaks off cleanly when heated (crystalline), "
+"or is it the type that produces long intertwined polymer chains (non-"
+"crystalline)?"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position label"
+msgid "Anti-ooze Retracted Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position description"
+msgid "How far the material needs to be retracted before it stops oozing."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed label"
+msgid "Anti-ooze Retraction Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed description"
+msgid ""
+"How fast the material needs to be retracted during a filament switch to "
+"prevent oozing."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position label"
+msgid "Break Preparation Retracted Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position description"
+msgid "How far the filament can be stretched before it breaks, while heated."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed label"
+msgid "Break Preparation Retraction Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed description"
+msgid ""
+"How fast the filament needs to be retracted just before breaking it off in a "
+"retraction."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position label"
+msgid "Break Retracted Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position description"
+msgid "How far to retract the filament in order to break it cleanly."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed label"
+msgid "Break Retraction Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed description"
+msgid ""
+"The speed at which to retract the filament in order to break it cleanly."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature label"
+msgid "Break Temperature"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature description"
+msgid "The temperature at which the filament is broken for a clean break."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "material_flow label"
msgid "Flow"
@@ -2271,6 +2473,127 @@ msgid ""
"value."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "wall_material_flow label"
+msgid "Wall Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_material_flow description"
+msgid "Flow compensation on wall lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow label"
+msgid "Outer Wall Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow description"
+msgid "Flow compensation on the outermost wall line."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow label"
+msgid "Inner Wall(s) Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow description"
+msgid ""
+"Flow compensation on wall lines for all wall lines except the outermost one."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow label"
+msgid "Top/Bottom Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow description"
+msgid "Flow compensation on top/bottom lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow label"
+msgid "Top Surface Skin Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow description"
+msgid "Flow compensation on lines of the areas at the top of the print."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow label"
+msgid "Infill Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow description"
+msgid "Flow compensation on infill lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow label"
+msgid "Skirt/Brim Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow description"
+msgid "Flow compensation on skirt or brim lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow label"
+msgid "Support Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow description"
+msgid "Flow compensation on support structure lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow label"
+msgid "Support Interface Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow description"
+msgid "Flow compensation on lines of support roof or floor."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow label"
+msgid "Support Roof Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow description"
+msgid "Flow compensation on support roof lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow label"
+msgid "Support Floor Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow description"
+msgid "Flow compensation on support floor lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow label"
+msgid "Prime Tower Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow description"
+msgid "Flow compensation on prime tower lines."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "material_flow_layer_0 label"
msgid "Initial Layer Flow"
@@ -2407,7 +2730,7 @@ msgstr ""
msgctxt "limit_support_retractions description"
msgid ""
"Omit retraction when moving from support to support in a straight line. "
-"Enabling this setting saves print time, but can lead to excesive stringing "
+"Enabling this setting saves print time, but can lead to excessive stringing "
"within the support structure."
msgstr ""
@@ -2431,8 +2754,9 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_amount description"
msgid ""
-"The amount of retraction: Set at 0 for no retraction at all. This should "
-"generally be the same as the length of the heat zone."
+"The amount of retraction when switching extruders. Set to 0 for no "
+"retraction at all. This should generally be the same as the length of the "
+"heat zone."
msgstr ""
#: fdmprinter.def.json
@@ -2470,6 +2794,16 @@ msgid ""
"retraction."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount label"
+msgid "Nozzle Switch Extra Prime Amount"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount description"
+msgid "Extra material to prime after nozzle switching."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "speed label"
msgid "Speed"
@@ -2693,15 +3027,16 @@ msgid ""
msgstr ""
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override label"
-msgid "Maximum Z Speed"
+msgctxt "speed_z_hop label"
+msgid "Z Hop Speed"
msgstr ""
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override description"
+msgctxt "speed_z_hop description"
msgid ""
-"The maximum speed with which the build plate is moved. Setting this to zero "
-"causes the print to use the firmware defaults for the maximum z speed."
+"The speed at which the vertical Z movement is made for Z Hops. This is "
+"typically lower than the print speed since the build plate or machine's "
+"gantry is harder to move."
msgstr ""
#: fdmprinter.def.json
@@ -3184,9 +3519,7 @@ msgid ""
"results in slightly longer travel moves but reduces the need for "
"retractions. If combing is off, the material will retract and the nozzle "
"moves in a straight line to the next point. It is also possible to avoid "
-"combing over top/bottom skin areas and also to only comb within the infill. "
-"Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' "
-"option in earlier Cura releases."
+"combing over top/bottom skin areas or to only comb within the infill."
msgstr ""
#: fdmprinter.def.json
@@ -3267,20 +3600,6 @@ msgid ""
"during travel moves."
msgstr ""
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position label"
-msgid "Start Layers with the Same Part"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position description"
-msgid ""
-"In each layer start with printing the object near the same point, so that we "
-"don't start a new layer with printing the piece which the previous layer "
-"ended with. This makes for better overhangs and small parts, but increases "
-"printing time."
-msgstr ""
-
#: fdmprinter.def.json
msgctxt "layer_start_x label"
msgid "Layer Start X"
@@ -3354,6 +3673,16 @@ msgid ""
"prevents the nozzle from leaving oozed material on the outside of a print."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height label"
+msgid "Z Hop After Extruder Switch Height"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height description"
+msgid "The height difference when performing a Z Hop after extruder switch."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "cooling label"
msgid "Cooling"
@@ -3676,6 +4005,11 @@ msgctxt "support_pattern option cross"
msgid "Cross"
msgstr ""
+#: fdmprinter.def.json
+msgctxt "support_pattern option gyroid"
+msgid "Gyroid"
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "support_wall_count label"
msgid "Support Wall Line Count"
@@ -3751,15 +4085,18 @@ msgid ""
msgstr ""
#: fdmprinter.def.json
-msgctxt "support_infill_angle label"
-msgid "Support Infill Line Direction"
+msgctxt "support_infill_angles label"
+msgid "Support Infill Line Directions"
msgstr ""
#: fdmprinter.def.json
-msgctxt "support_infill_angle description"
+msgctxt "support_infill_angles description"
msgid ""
-"Orientation of the infill pattern for supports. The support infill pattern "
-"is rotated in the horizontal plane."
+"A list of integer line directions to use. Elements from the list are used "
+"sequentially as the layers progress and when the end of the list is reached, "
+"it starts at the beginning again. The list items are separated by commas and "
+"the whole list is contained in square brackets. Default is an empty list "
+"which means use the default angle 0 degrees."
msgstr ""
#: fdmprinter.def.json
@@ -3913,7 +4250,7 @@ msgstr ""
msgctxt "support_join_distance description"
msgid ""
"The maximum distance between support structures in the X/Y directions. When "
-"seperate structures are closer together than this value, the structures "
+"separate structures are closer together than this value, the structures "
"merge into one."
msgstr ""
@@ -3966,6 +4303,18 @@ msgid ""
"density."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "minimum_support_area label"
+msgid "Minimum Support Area"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_support_area description"
+msgid ""
+"Minimum area size for support polygons. Polygons which have an area smaller "
+"than this value will not be generated."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "support_interface_enable label"
msgid "Enable Support Interface"
@@ -4221,6 +4570,120 @@ msgctxt "support_bottom_pattern option zigzag"
msgid "Zig Zag"
msgstr ""
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area label"
+msgid "Minimum Support Interface Area"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area description"
+msgid ""
+"Minimum area size for support interface polygons. Polygons which have an "
+"area smaller than this value will be printed as normal support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area label"
+msgid "Minimum Support Roof Area"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area description"
+msgid ""
+"Minimum area size for the roofs of the support. Polygons which have an area "
+"smaller than this value will be printed as normal support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area label"
+msgid "Minimum Support Floor Area"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area description"
+msgid ""
+"Minimum area size for the floors of the support. Polygons which have an area "
+"smaller than this value will be printed as normal support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset label"
+msgid "Support Interface Horizontal Expansion"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset description"
+msgid "Amount of offset applied to the support interface polygons."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset label"
+msgid "Support Roof Horizontal Expansion"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset description"
+msgid "Amount of offset applied to the roofs of the support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset label"
+msgid "Support Floor Horizontal Expansion"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset description"
+msgid "Amount of offset applied to the floors of the support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles label"
+msgid "Support Interface Line Directions"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles description"
+msgid ""
+"A list of integer line directions to use. Elements from the list are used "
+"sequentially as the layers progress and when the end of the list is reached, "
+"it starts at the beginning again. The list items are separated by commas and "
+"the whole list is contained in square brackets. Default is an empty list "
+"which means use the default angles (alternates between 45 and 135 degrees if "
+"interfaces are quite thick or 90 degrees)."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles label"
+msgid "Support Roof Line Directions"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles description"
+msgid ""
+"A list of integer line directions to use. Elements from the list are used "
+"sequentially as the layers progress and when the end of the list is reached, "
+"it starts at the beginning again. The list items are separated by commas and "
+"the whole list is contained in square brackets. Default is an empty list "
+"which means use the default angles (alternates between 45 and 135 degrees if "
+"interfaces are quite thick or 90 degrees)."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles label"
+msgid "Support Floor Line Directions"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles description"
+msgid ""
+"A list of integer line directions to use. Elements from the list are used "
+"sequentially as the layers progress and when the end of the list is reached, "
+"it starts at the beginning again. The list items are separated by commas and "
+"the whole list is contained in square brackets. Default is an empty list "
+"which means use the default angles (alternates between 45 and 135 degrees if "
+"interfaces are quite thick or 90 degrees)."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "support_fan_enable label"
msgid "Fan Speed Override"
@@ -4269,14 +4732,14 @@ msgid "The diameter of a special tower."
msgstr ""
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter label"
-msgid "Minimum Diameter"
+msgctxt "support_tower_maximum_supported_diameter label"
+msgid "Maximum Tower-Supported Diameter"
msgstr ""
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter description"
+msgctxt "support_tower_maximum_supported_diameter description"
msgid ""
-"Minimum diameter in the X/Y directions of a small area which is to be "
+"Maximum diameter in the X/Y directions of a small area which is to be "
"supported by a specialized support tower."
msgstr ""
@@ -4851,16 +5314,6 @@ msgid ""
"each nozzle switch."
msgstr ""
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular label"
-msgid "Circular Prime Tower"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular description"
-msgid "Make the prime tower as a circular shape."
-msgstr ""
-
#: fdmprinter.def.json
msgctxt "prime_tower_size label"
msgid "Prime Tower Size"
@@ -4903,18 +5356,6 @@ msgctxt "prime_tower_position_y description"
msgid "The y coordinate of the position of the prime tower."
msgstr ""
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow label"
-msgid "Prime Tower Flow"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow description"
-msgid ""
-"Flow compensation: the amount of material extruded is multiplied by this "
-"value."
-msgstr ""
-
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled label"
msgid "Wipe Inactive Nozzle on Prime Tower"
@@ -4927,6 +5368,18 @@ msgid ""
"the other nozzle off on the prime tower."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable label"
+msgid "Prime Tower Brim"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable description"
+msgid ""
+"Prime-towers might need the extra adhesion afforded by a brim even if the "
+"model doesn't. Presently can't be used with the 'Raft' adhesion-type."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "ooze_shield_enabled label"
msgid "Enable Ooze Shield"
@@ -5077,6 +5530,49 @@ msgid ""
"setting is set to Exclusive or Middle."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution label"
+msgid "Maximum Resolution"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution description"
+msgid ""
+"The minimum size of a line segment after slicing. If you increase this, the "
+"mesh will have a lower resolution. This may allow the printer to keep up "
+"with the speed it has to process g-code and will increase slice speed by "
+"removing details of the mesh that it can't process anyway."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution label"
+msgid "Maximum Travel Resolution"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution description"
+msgid ""
+"The minimum size of a travel line segment after slicing. If you increase "
+"this, the travel moves will have less smooth corners. This may allow the "
+"printer to keep up with the speed it has to process g-code, but it may cause "
+"model avoidance to become less accurate."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation label"
+msgid "Maximum Deviation"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation description"
+msgid ""
+"The maximum deviation allowed when reducing the resolution for the Maximum "
+"Resolution setting. If you increase this, the print will be less accurate, "
+"but the g-code will be smaller. Maximum Deviation is a limit for Maximum "
+"Resolution, so if the two conflict the Maximum Deviation will always be held "
+"true."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "blackmagic label"
msgid "Special Modes"
@@ -5274,7 +5770,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "smooth_spiralized_contours description"
msgid ""
-"Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-"
+"Smooth the spiralized contours to reduce the visibility of the Z seam (the Z "
"seam should be barely visible on the print but will still be visible in the "
"layer view). Note that smoothing will tend to blur fine surface details."
msgstr ""
@@ -5541,34 +6037,6 @@ msgid ""
"and very tiny 3D models with a lot of details."
msgstr ""
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution label"
-msgid "Maximum Resolution"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution description"
-msgid ""
-"The minimum size of a line segment after slicing. If you increase this, the "
-"mesh will have a lower resolution. This may allow the printer to keep up "
-"with the speed it has to process g-code and will increase slice speed by "
-"removing details of the mesh that it can't process anyway."
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution label"
-msgid "Maximum Travel Resolution"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution description"
-msgid ""
-"The minimum size of a travel line segment after slicing. If you increase "
-"this, the travel moves will have less smooth corners. This may allow the "
-"printer to keep up with the speed it has to process g-code, but it may cause "
-"model avoidance to become less accurate."
-msgstr ""
-
#: fdmprinter.def.json
msgctxt "support_skip_some_zags label"
msgid "Break Up Support In Chunks"
@@ -5739,19 +6207,6 @@ msgid ""
"coasting move the pressure in the bowden tube drops."
msgstr ""
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation label"
-msgid "Alternate Skin Rotation"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation description"
-msgid ""
-"Alternate the direction in which the top/bottom layers are printed. Normally "
-"they are printed diagonally only. This setting adds the X-only and Y-only "
-"directions."
-msgstr ""
-
#: fdmprinter.def.json
msgctxt "cross_infill_pocket_size label"
msgid "Cross 3D Pocket Size"
@@ -5881,9 +6336,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "support_conical_enabled description"
-msgid ""
-"Experimental feature: Make support areas smaller at the bottom than at the "
-"overhang."
+msgid "Make support areas smaller at the bottom than at the overhang."
msgstr ""
#: fdmprinter.def.json
@@ -5965,22 +6418,27 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset label"
-msgid "Flow rate compensation max extrusion offset"
+msgid "Flow Rate Compensation Max Extrusion Offset"
msgstr ""
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset description"
-msgid "The maximum distance in mm to compensate."
+msgid ""
+"The maximum distance in mm to move the filament to compensate for changes in "
+"flow rate."
msgstr ""
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor label"
-msgid "Flow rate compensation factor"
+msgid "Flow Rate Compensation Factor"
msgstr ""
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor description"
-msgid "The multiplication factor for the flow rate -> distance translation."
+msgid ""
+"How far to move the filament in order to compensate for changes in flow "
+"rate, as a percentage of how far the filament would move in one second of "
+"extrusion."
msgstr ""
#: fdmprinter.def.json
@@ -6298,7 +6756,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
-msgid "Use adaptive layers"
+msgid "Use Adaptive Layers"
msgstr ""
#: fdmprinter.def.json
@@ -6310,7 +6768,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
-msgid "Adaptive layers maximum variation"
+msgid "Adaptive Layers Maximum Variation"
msgstr ""
#: fdmprinter.def.json
@@ -6320,7 +6778,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
-msgid "Adaptive layers variation step size"
+msgid "Adaptive Layers Variation Step Size"
msgstr ""
#: fdmprinter.def.json
@@ -6332,14 +6790,15 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
-msgid "Adaptive layers threshold"
+msgid "Adaptive Layers Topography Size"
msgstr ""
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
msgid ""
-"Threshold whether to use a smaller layer or not. This number is compared to "
-"the tan of the steepest slope in a layer."
+"Target horizontal distance between two adjacent layers. Reducing this "
+"setting causes thinner layers to be used to bring the edges of the layers "
+"closer together."
msgstr ""
#: fdmprinter.def.json
@@ -6351,7 +6810,9 @@ msgstr ""
msgctxt "wall_overhang_angle description"
msgid ""
"Walls that overhang more than this angle will be printed using overhanging "
-"wall settings. When the value is 90, no walls will be treated as overhanging."
+"wall settings. When the value is 90, no walls will be treated as "
+"overhanging. Overhang that gets supported by support will not be treated as "
+"overhang either."
msgstr ""
#: fdmprinter.def.json
@@ -6584,6 +7045,222 @@ msgctxt "bridge_fan_speed_3 description"
msgid "Percentage fan speed to use when printing the third bridge skin layer."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "clean_between_layers label"
+msgid "Wipe Nozzle Between Layers"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "clean_between_layers description"
+msgid ""
+"Whether to include nozzle wipe G-Code between layers. Enabling this setting "
+"could influence behavior of retract at layer change. Please use Wipe "
+"Retraction settings to control retraction at layers where the wipe script "
+"will be working."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe label"
+msgid "Material Volume Between Wipes"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe description"
+msgid ""
+"Maximum material, that can be extruded before another nozzle wipe is "
+"initiated."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable label"
+msgid "Wipe Retraction Enable"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable description"
+msgid "Retract the filament when the nozzle is moving over a non-printed area."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount label"
+msgid "Wipe Retraction Distance"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount description"
+msgid ""
+"Amount to retract the filament so it does not ooze during the wipe sequence."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount label"
+msgid "Wipe Retraction Extra Prime Amount"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount description"
+msgid ""
+"Some material can ooze away during a wipe travel moves, which can be "
+"compensated for here."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed label"
+msgid "Wipe Retraction Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed description"
+msgid ""
+"The speed at which the filament is retracted and primed during a wipe "
+"retraction move."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed label"
+msgid "Wipe Retraction Retract Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed description"
+msgid ""
+"The speed at which the filament is retracted during a wipe retraction move."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed label"
+msgid "Retraction Prime Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed description"
+msgid ""
+"The speed at which the filament is primed during a wipe retraction move."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause label"
+msgid "Wipe Pause"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause description"
+msgid "Pause after the unretract."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable label"
+msgid "Wipe Z Hop When Retracted"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable description"
+msgid ""
+"Whenever a retraction is done, the build plate is lowered to create "
+"clearance between the nozzle and the print. It prevents the nozzle from "
+"hitting the print during travel moves, reducing the chance to knock the "
+"print from the build plate."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount label"
+msgid "Wipe Z Hop Height"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount description"
+msgid "The height difference when performing a Z Hop."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed label"
+msgid "Wipe Hop Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed description"
+msgid "Speed to move the z-axis during the hop."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x label"
+msgid "Wipe Brush X Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x description"
+msgid "X location where wipe script will start."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count label"
+msgid "Wipe Repeat Count"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count description"
+msgid "Number of times to move the nozzle across the brush."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance label"
+msgid "Wipe Move Distance"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance description"
+msgid "The distance to move the head back and forth across the brush."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size label"
+msgid "Small Hole Max Size"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size description"
+msgid ""
+"Holes and part outlines with a diameter smaller than this will be printed "
+"using Small Feature Speed."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length label"
+msgid "Small Feature Max Length"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length description"
+msgid ""
+"Feature outlines that are shorter than this length will be printed using "
+"Small Feature Speed."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor label"
+msgid "Small Feature Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor description"
+msgid ""
+"Small features will be printed at this percentage of their normal print "
+"speed. Slower printing can help with adhesion and accuracy."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 label"
+msgid "Small Feature Initial Layer Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 description"
+msgid ""
+"Small features on the first layer will be printed at this percentage of "
+"their normal print speed. Slower printing can help with adhesion and "
+"accuracy."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "command_line_settings label"
msgid "Command Line Settings"
diff --git a/resources/i18n/fi_FI/cura.po b/resources/i18n/fi_FI/cura.po
index 442500f21b..bfc110737f 100644
--- a/resources/i18n/fi_FI/cura.po
+++ b/resources/i18n/fi_FI/cura.po
@@ -1,13 +1,13 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0100\n"
+"POT-Creation-Date: 2019-11-05 13:13+0100\n"
"PO-Revision-Date: 2017-09-27 12:27+0200\n"
"Last-Translator: Bothof \n"
"Language-Team: Finnish\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:22
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:30
msgctxt "@action"
msgid "Machine Settings"
msgstr "Laitteen asetukset"
@@ -38,23 +38,23 @@ msgctxt "@item:inlistbox"
msgid "G-code File"
msgstr "GCode-tiedosto"
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:67
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:66
msgctxt "@error:not supported"
msgid "GCodeWriter does not support non-text mode."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:73
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:89
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:72
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:88
msgctxt "@warning:status"
msgid "Please prepare G-code before exporting."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:30
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:31
msgctxt "@info:title"
msgid "3D Model Assistant"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:80
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:92
#, python-brace-format
msgctxt "@info:status"
msgid ""
@@ -64,65 +64,49 @@ msgid ""
"
"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:222
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:218
msgctxt "@title:groupbox"
msgid "Error traceback"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:303
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:299
msgctxt "@title:groupbox"
msgid "Logs"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:326
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:322
msgctxt "@title:groupbox"
-msgid "User description"
+msgid "User description (Note: Developers may not speak your language, please use English if possible)"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:345
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:342
msgctxt "@action:button"
msgid "Send report"
msgstr ""
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:473
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:513
msgctxt "@info:progress"
msgid "Loading machines..."
msgstr "Ladataan laitteita..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:775
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:520
+msgctxt "@info:progress"
+msgid "Setting up preferences..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:824
msgctxt "@info:progress"
msgid "Setting up scene..."
msgstr "Asetetaan näkymää..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:811
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:859
msgctxt "@info:progress"
msgid "Loading interface..."
msgstr "Ladataan käyttöliittymää..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1037
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1150
#, python-format
msgctxt "@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm."
msgid "%(width).1f x %(depth).1f x %(height).1f mm"
msgstr "%(width).1f x %(depth).1f x %(height).1f mm"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1596
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1657
#, python-brace-format
msgctxt "@info:status"
msgid "Only one G-code file can be loaded at a time. Skipped importing {0}"
msgstr "Vain yksi G-code-tiedosto voidaan ladata kerralla. Tiedoston {0} tuonti ohitettiin."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1606
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1667
#, python-brace-format
msgctxt "@info:status"
msgid "Can't open any other file if G-code is loading. Skipped importing {0}"
msgstr "Muita tiedostoja ei voida ladata, kun G-code latautuu. Tiedoston {0} tuonti ohitettiin."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1694
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1757
msgctxt "@info:status"
msgid "The selected model was too small to load."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:61
-msgctxt "@title"
-msgid "Machine Settings"
-msgstr "Laitteen asetukset"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:80
-msgctxt "@title:tab"
-msgid "Printer"
-msgstr "Tulostin"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:99
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:56
+msgctxt "@title:label"
msgid "Printer Settings"
-msgstr "Tulostimen asetukset"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:110
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:70
msgctxt "@label"
msgid "X (Width)"
msgstr "X (leveys)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:111
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:121
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:131
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:237
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:386
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:402
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:428
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:440
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:896
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:74
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:88
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:102
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:243
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:265
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:285
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:79
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:93
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:109
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:124
msgctxt "@label"
msgid "mm"
msgstr "mm"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:120
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:84
msgctxt "@label"
msgid "Y (Depth)"
msgstr "Y (syvyys)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:130
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:98
msgctxt "@label"
msgid "Z (Height)"
msgstr "Z (korkeus)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:142
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:112
msgctxt "@label"
msgid "Build plate shape"
msgstr "Alustan muoto"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:151
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:125
+msgctxt "@label"
msgid "Origin at center"
-msgstr "Alkukohta keskellä"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:159
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:137
+msgctxt "@label"
msgid "Heated bed"
-msgstr "Lämmitettävä pöytä"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:170
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:149
+msgctxt "@label"
+msgid "Heated build volume"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:161
msgctxt "@label"
msgid "G-code flavor"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:183
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:185
+msgctxt "@title:label"
msgid "Printhead Settings"
-msgstr "Tulostuspään asetukset"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:193
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:199
msgctxt "@label"
msgid "X min"
msgstr "X väh."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:194
-msgctxt "@tooltip"
-msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Etäisyys tulostuspään vasemmalta puolelta suuttimen keskikohtaan. Käytetään estämään aiempien tulosteiden ja tulostuspään yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:219
msgctxt "@label"
msgid "Y min"
msgstr "Y väh."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:204
-msgctxt "@tooltip"
-msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Etäisyys tulostuspään etupuolelta suuttimen keskikohtaan. Käytetään estämään aiempien tulosteiden ja tulostuspään yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:213
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:239
msgctxt "@label"
msgid "X max"
msgstr "X enint."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:214
-msgctxt "@tooltip"
-msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Etäisyys tulostuspään oikealta puolelta suuttimen keskikohtaan. Käytetään estämään aiempien tulosteiden ja tulostuspään yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:261
msgctxt "@label"
msgid "Y max"
msgstr "Y enint."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:224
-msgctxt "@tooltip"
-msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Etäisyys tulostuspään takapuolelta suuttimen keskikohtaan. Käytetään estämään aiempien tulosteiden ja tulostuspään yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:236
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:281
msgctxt "@label"
-msgid "Gantry height"
-msgstr "Korokkeen korkeus"
+msgid "Gantry Height"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:238
-msgctxt "@tooltip"
-msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
-msgstr "Suuttimen kärjen ja korokejärjestelmän (X- ja Y-akselit) välinen korkeusero. Käytetään estämään aiempien tulosteiden ja korokkeen yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:257
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:295
msgctxt "@label"
msgid "Number of Extruders"
msgstr "Suulakkeiden määrä"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:313
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:355
+msgctxt "@title:label"
msgid "Start G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:323
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very start."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:332
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:366
+msgctxt "@title:label"
msgid "End G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:342
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very end."
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:42
+msgctxt "@title:tab"
+msgid "Printer"
+msgstr "Tulostin"
+
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:63
+msgctxt "@title:label"
+msgid "Nozzle Settings"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:373
-msgctxt "@label"
-msgid "Nozzle Settings"
-msgstr "Suutinasetukset"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:385
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:75
msgctxt "@label"
msgid "Nozzle size"
msgstr "Suuttimen koko"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:401
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:89
msgctxt "@label"
msgid "Compatible material diameter"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:403
-msgctxt "@tooltip"
-msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
-msgstr "Tulostimen tukema tulostuslangan nimellinen halkaisija. Materiaali ja/tai profiili korvaa tarkan halkaisijan."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:427
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:105
msgctxt "@label"
msgid "Nozzle offset X"
msgstr "Suuttimen X-siirtymä"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:439
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:120
msgctxt "@label"
msgid "Nozzle offset Y"
msgstr "Suuttimen Y-siirtymä"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:451
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:135
msgctxt "@label"
msgid "Cooling Fan Number"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:452
-msgctxt "@label"
-msgid ""
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:472
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:162
+msgctxt "@title:label"
msgid "Extruder Start G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:490
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:176
+msgctxt "@title:label"
msgid "Extruder End G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
msgctxt "@action:button"
msgid "Install"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:20
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
msgctxt "@action:button"
msgid "Installed"
msgstr "Asennettu"
@@ -1426,68 +1476,81 @@ msgctxt "@info"
msgid "Could not connect to the Cura Package database. Please check your connection."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:38
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:28
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/SmallRatingWidget.qml:27
+msgctxt "@label"
+msgid "ratings"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:30
msgctxt "@title:tab"
msgid "Plugins"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:75
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:42
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:66
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:77
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:44
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:89
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:417
msgctxt "@title:tab"
msgid "Materials"
msgstr "Materiaalit"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:79
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+msgctxt "@label"
+msgid "Your rating"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:99
msgctxt "@label"
msgid "Version"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:85
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:106
msgctxt "@label"
msgid "Last updated"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:113
msgctxt "@label"
msgid "Author"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:120
msgctxt "@label"
msgid "Downloads"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:116
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:158
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:258
-msgctxt "@label"
-msgid "Unknown"
-msgstr "Tuntematon"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:56
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to install or update"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:44
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:30
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:80
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Buy material spools"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:96
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:34
msgctxt "@action:button"
msgid "Update"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:45
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:35
msgctxt "@action:button"
msgid "Updating"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:98
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:36
msgctxt "@action:button"
msgid "Updated"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/Toolbox.qml:13
msgctxt "@title"
-msgid "Toolbox"
+msgid "Marketplace"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml:25
@@ -1515,52 +1578,67 @@ msgctxt "@text:window"
msgid "Profiles"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:89
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:90
msgctxt "@action:button"
msgid "Confirm"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to login first before you can rate"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to install the package before you can rate"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:19
msgctxt "@info"
msgid "You will need to restart Cura before changes in packages have effect."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:45
msgctxt "@info:button"
msgid "Quit Cura"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Contributions"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Plugins"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:43
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:40
msgctxt "@label"
msgid "Generic Materials"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:56
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:59
msgctxt "@title:tab"
msgid "Installed"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:22
msgctxt "@label"
msgid "Will install upon restarting"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:53
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to update"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Downgrade"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Uninstall"
msgstr ""
@@ -1578,12 +1656,12 @@ msgid ""
"Do you agree with the terms below?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:54
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:55
msgctxt "@action:button"
msgid "Accept"
msgstr "Hyväksy"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:65
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:66
msgctxt "@action:button"
msgid "Decline"
msgstr "Hylkää"
@@ -1593,22 +1671,62 @@ msgctxt "@label"
msgid "Featured"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:34
msgctxt "@label"
msgid "Compatibility"
msgstr ""
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:124
+msgctxt "@label:table_header"
+msgid "Machine"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:137
+msgctxt "@label:table_header"
+msgid "Build Plate"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:143
+msgctxt "@label:table_header"
+msgid "Support"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:149
+msgctxt "@label:table_header"
+msgid "Quality"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:170
+msgctxt "@action:label"
+msgid "Technical Data Sheet"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:179
+msgctxt "@action:label"
+msgid "Safety Data Sheet"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:188
+msgctxt "@action:label"
+msgid "Printing Guidelines"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:197
+msgctxt "@action:label"
+msgid "Website"
+msgstr ""
+
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml:16
msgctxt "@info"
msgid "Fetching packages..."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:88
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:91
msgctxt "@label"
msgid "Website"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:94
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:98
msgctxt "@label"
msgid "Email"
msgstr ""
@@ -1618,23 +1736,6 @@ msgctxt "@info:tooltip"
msgid "Some things could be problematic in this print. Click to see tips for adjustment."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18
-msgctxt "@label"
-msgid "Changelog"
-msgstr "Muutosloki"
-
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:37
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:53
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:467
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:514
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:121
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:166
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:38
-msgctxt "@action:button"
-msgid "Close"
-msgstr "Sulje"
-
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:31
msgctxt "@title"
msgid "Update Firmware"
@@ -1710,426 +1811,501 @@ msgctxt "@label"
msgid "Firmware update failed due to missing firmware."
msgstr "Laiteohjelmiston päivitys epäonnistui puuttuvan laiteohjelmiston takia."
-#: /home/ruben/Projects/Cura/plugins/UserAgreement/UserAgreement.qml:16
-msgctxt "@title:window"
-msgid "User Agreement"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:155
+msgctxt "@label link to Connect and Cloud interfaces"
+msgid "Manage printer"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:46
-msgctxt "@window:title"
-msgid "Existing Connection"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:192
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:183
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:153
+msgctxt "@label"
+msgid "Glass"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:48
-msgctxt "@message:text"
-msgid "This printer/group is already added to Cura. Please select another printer/group."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:256
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:514
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:248
+msgctxt "@info"
+msgid "Please update your printer's firmware to manage the queue remotely."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:65
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:289
+msgctxt "@info"
+msgid "The webcam is not available because you are monitoring a cloud printer."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:348
+msgctxt "@label:status"
+msgid "Loading..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:352
+msgctxt "@label:status"
+msgid "Unavailable"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:356
+msgctxt "@label:status"
+msgid "Unreachable"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:360
+msgctxt "@label:status"
+msgid "Idle"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:401
+msgctxt "@label"
+msgid "Untitled"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:422
+msgctxt "@label"
+msgid "Anonymous"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:449
+msgctxt "@label:status"
+msgid "Requires configuration changes"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:487
+msgctxt "@action:button"
+msgid "Details"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:132
+msgctxt "@label"
+msgid "Unavailable printer"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:134
+msgctxt "@label"
+msgid "First available"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:31
+msgctxt "@label"
+msgid "Queued"
+msgstr "Jonossa"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:67
+msgctxt "@label link to connect manager"
+msgid "Manage in browser"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:100
+msgctxt "@label"
+msgid "There are no print jobs in the queue. Slice and send a job to add one."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:115
+msgctxt "@label"
+msgid "Print jobs"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:131
+msgctxt "@label"
+msgid "Total print time"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:147
+msgctxt "@label"
+msgid "Waiting for"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:45
msgctxt "@title:window"
msgid "Connect to Networked Printer"
msgstr "Yhdistä verkkotulostimeen"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:75
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
msgctxt "@label"
-msgid ""
-"To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
-"\n"
-"Select your printer from the list below:"
+msgid "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer."
msgstr ""
-"Tulosta suoraan tulostimeen verkon kautta yhdistämällä tulostin verkkoon verkkokaapelilla tai yhdistämällä tulostin Wi-Fi-verkkoon. Jos Curaa ei yhdistetä tulostimeen, GCode-tiedostot voidaan silti siirtää tulostimeen USB-aseman avulla.\n"
-"\n"
-"Valitse tulostin alla olevasta luettelosta:"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:85
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:42
-msgctxt "@action:button"
-msgid "Add"
-msgstr "Lisää"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
+msgctxt "@label"
+msgid "Select your printer from the list below:"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:95
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:77
msgctxt "@action:button"
msgid "Edit"
msgstr "Muokkaa"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:106
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:128
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:117
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:88
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:138
msgctxt "@action:button"
msgid "Remove"
msgstr "Poista"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:114
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:96
msgctxt "@action:button"
msgid "Refresh"
msgstr "Päivitä"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:207
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:176
msgctxt "@label"
msgid "If your printer is not listed, read the network printing troubleshooting guide"
msgstr "Jos tulostinta ei ole luettelossa, lue verkkotulostuksen vianetsintäopas"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:234
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:205
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:258
msgctxt "@label"
msgid "Type"
msgstr "Tyyppi"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:271
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:274
msgctxt "@label"
msgid "Firmware version"
msgstr "Laiteohjelmistoversio"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:290
msgctxt "@label"
msgid "Address"
msgstr "Osoite"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:305
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:263
msgctxt "@label"
msgid "This printer is not set up to host a group of printers."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:309
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:267
msgctxt "@label"
msgid "This printer is the host for a group of %1 printers."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:319
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:278
msgctxt "@label"
msgid "The printer at this address has not yet responded."
msgstr "Tämän osoitteen tulostin ei ole vielä vastannut."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:324
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
msgctxt "@action:button"
msgid "Connect"
msgstr "Yhdistä"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:338
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:296
+msgctxt "@title:window"
+msgid "Invalid IP address"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:146
+msgctxt "@text"
+msgid "Please enter a valid IP address."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:308
msgctxt "@title:window"
msgid "Printer Address"
msgstr "Tulostimen osoite"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
-msgctxt "@alabel"
-msgid "Enter the IP address or hostname of your printer on the network."
-msgstr "Anna verkon tulostimen IP-osoite tai isäntänimi."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:102
+msgctxt "@label"
+msgid "Enter the IP address of your printer on the network."
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:390
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:132
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:138
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:181
msgctxt "@action:button"
msgid "OK"
msgstr "OK"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:44
-msgctxt "@action:button"
-msgid "Print"
-msgstr "Tulosta"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:47
-msgctxt "@title:window"
-msgid "Print over network"
-msgstr "Tulosta verkon kautta"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:79
-msgctxt "@label"
-msgid "Printer selection"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:173
-msgctxt "@label"
-msgid "Not available"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:175
-msgctxt "@label"
-msgid "Unreachable"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:180
-msgctxt "@label"
-msgid "Available"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:37
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:44
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:46
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:78
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:90
msgctxt "@label:status"
msgid "Aborted"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:39
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:80
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:82
msgctxt "@label:status"
msgid "Finished"
msgstr "Valmis"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:84
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:86
msgctxt "@label:status"
-msgid "Preparing"
-msgstr "Valmistellaan"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:48
-msgctxt "@label:status"
-msgid "Pausing"
+msgid "Preparing..."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:52
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:88
msgctxt "@label:status"
-msgid "Resuming"
+msgid "Aborting..."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:54
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:92
+msgctxt "@label:status"
+msgid "Pausing..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:94
+msgctxt "@label:status"
+msgid "Paused"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:96
+msgctxt "@label:status"
+msgid "Resuming..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:98
msgctxt "@label:status"
msgid "Action required"
msgstr "Vaatii toimenpiteitä"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:213
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:100
+msgctxt "@label:status"
+msgid "Finishes %1 at %2"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:11
+msgctxt "@title:window"
+msgid "Print over network"
+msgstr "Tulosta verkon kautta"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:52
+msgctxt "@action:button"
+msgid "Print"
+msgstr "Tulosta"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:80
msgctxt "@label"
-msgid "Waiting for: Unavailable printer"
+msgid "Printer selection"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:215
-msgctxt "@label"
-msgid "Waiting for: First available"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:217
-msgctxt "@label"
-msgid "Waiting for: "
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:299
-msgctxt "@label"
-msgid "Configuration change"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:365
-msgctxt "@label"
-msgid "The assigned printer, %1, requires the following configuration change(s):"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:367
-msgctxt "@label"
-msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:375
-msgctxt "@label"
-msgid "Change material %1 from %2 to %3."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:378
-msgctxt "@label"
-msgid "Load %3 as material %1 (This cannot be overridden)."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:381
-msgctxt "@label"
-msgid "Change print core %1 from %2 to %3."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:384
-msgctxt "@label"
-msgid "Change build plate to %1 (This cannot be overridden)."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:404
-msgctxt "@label"
-msgid "Override"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:432
-msgctxt "@label"
-msgid "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:435
-msgctxt "@window:title"
-msgid "Override configuration configuration and start print"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:466
-msgctxt "@label"
-msgid "Glass"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:469
-msgctxt "@label"
-msgid "Aluminum"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:39
-msgctxt "@label link to connect manager"
-msgid "Manage queue"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:60
-msgctxt "@label"
-msgid "Queued"
-msgstr "Jonossa"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:36
-msgctxt "@label"
-msgid "Printing"
-msgstr "Tulostetaan"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:49
-msgctxt "@label link to connect manager"
-msgid "Manage printers"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:115
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:54
msgctxt "@label"
msgid "Move to top"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:124
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:70
msgctxt "@label"
msgid "Delete"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:100
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:289
msgctxt "@label"
msgid "Resume"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:102
+msgctxt "@label"
+msgid "Pausing..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:104
+msgctxt "@label"
+msgid "Resuming..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:106
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:284
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:293
msgctxt "@label"
msgid "Pause"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:146
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
+msgctxt "@label"
+msgid "Aborting..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
msgctxt "@label"
msgid "Abort"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:178
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:143
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to move %1 to the top of the queue?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:179
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:144
msgctxt "@window:title"
msgid "Move print job to top"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:188
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:153
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to delete %1?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:189
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:154
msgctxt "@window:title"
msgid "Delete print job"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:198
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:163
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to abort %1?"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:199
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:164
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:335
msgctxt "@window:title"
msgid "Abort print"
msgstr "Keskeytä tulostus"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:43
-msgctxt "@info:tooltip"
-msgid "Connect to a printer"
-msgstr "Yhdistä tulostimeen"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:20
+msgctxt "@title:window"
+msgid "Configuration Changes"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:121
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:27
msgctxt "@action:button"
-msgid "Activate Configuration"
-msgstr "Aktivoi määritys"
+msgid "Override"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:122
-msgctxt "@info:tooltip"
-msgid "Load the configuration of the printer into Cura"
-msgstr "Lataa tulostimen määritys Curaan"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:85
+msgctxt "@label"
+msgid "The assigned printer, %1, requires the following configuration change:"
+msgid_plural "The assigned printer, %1, requires the following configuration changes:"
+msgstr[0] ""
+msgstr[1] ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:130
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:89
+msgctxt "@label"
+msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:99
+msgctxt "@label"
+msgid "Change material %1 from %2 to %3."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:102
+msgctxt "@label"
+msgid "Load %3 as material %1 (This cannot be overridden)."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:105
+msgctxt "@label"
+msgid "Change print core %1 from %2 to %3."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:108
+msgctxt "@label"
+msgid "Change build plate to %1 (This cannot be overridden)."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:115
+msgctxt "@label"
+msgid "Override will use the specified settings with the existing printer configuration. This may result in a failed print."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:156
+msgctxt "@label"
+msgid "Aluminum"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:100
+msgctxt "@info"
+msgid ""
+"Please make sure your printer has a connection:\n"
+"- Check if the printer is turned on.\n"
+"- Check if the printer is connected to the network.\n"
+"- Check if you are signed in to discover cloud-connected printers."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:117
+msgctxt "@info"
+msgid "Please connect your printer to the network."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:156
+msgctxt "@label link to technical assistance"
+msgid "View user manuals online"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:20
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:49
msgctxt "@label"
msgid "Color scheme"
msgstr "Värimalli"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:145
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:107
msgctxt "@label:listbox"
msgid "Material Color"
msgstr "Materiaalin väri"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:149
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:111
msgctxt "@label:listbox"
msgid "Line Type"
msgstr "Linjojen tyyppi"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:153
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:115
msgctxt "@label:listbox"
msgid "Feedrate"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:157
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:119
msgctxt "@label:listbox"
msgid "Layer thickness"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:198
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:156
msgctxt "@label"
msgid "Compatibility Mode"
msgstr "Yhteensopivuustila"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:284
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:230
msgctxt "@label"
-msgid "Show Travels"
-msgstr "Näytä siirtoliikkeet"
+msgid "Travels"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:290
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:236
msgctxt "@label"
-msgid "Show Helpers"
-msgstr "Näytä avustimet"
+msgid "Helpers"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:296
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:242
msgctxt "@label"
-msgid "Show Shell"
-msgstr "Näytä kuori"
+msgid "Shell"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:302
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:248
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:65
msgctxt "@label"
-msgid "Show Infill"
-msgstr "Näytä täyttö"
+msgid "Infill"
+msgstr "Täyttö"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:355
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:298
msgctxt "@label"
msgid "Only Show Top Layers"
msgstr "Näytä vain yläkerrokset"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:366
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:308
msgctxt "@label"
msgid "Show 5 Detailed Layers On Top"
msgstr "Näytä 5 yksityiskohtaista kerrosta ylhäällä"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:379
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:322
msgctxt "@label"
msgid "Top / Bottom"
msgstr "Yläosa/alaosa"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:383
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:326
msgctxt "@label"
msgid "Inner Wall"
msgstr "Sisäseinämä"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:448
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:384
msgctxt "@label"
msgid "min"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:500
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:433
msgctxt "@label"
msgid "max"
msgstr ""
@@ -2144,39 +2320,39 @@ msgctxt "@label"
msgid "Post Processing Scripts"
msgstr "Jälkikäsittelykomentosarjat"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:227
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:233
msgctxt "@action"
msgid "Add a script"
msgstr "Lisää komentosarja"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:273
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:279
msgctxt "@label"
msgid "Settings"
msgstr "Asetukset"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:477
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:493
msgctxt "@info:tooltip"
msgid "Change active post-processing scripts"
msgstr "Muuta aktiivisia jälkikäsittelykomentosarjoja"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:16
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:17
msgctxt "@title:window"
msgid "More information on anonymous data collection"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:66
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:74
msgctxt "@text:window"
-msgid "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent."
+msgid "Ultimaker Cura collects anonymous data in order to improve the print quality and user experience. Below is an example of all the data that is shared:"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:101
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:109
msgctxt "@text:window"
-msgid "I don't want to send these data"
+msgid "I don't want to send anonymous data"
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:111
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:118
msgctxt "@text:window"
-msgid "Allow sending these data to Ultimaker and help us improve Cura"
+msgid "Allow sending anonymous data"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:19
@@ -2226,19 +2402,19 @@ msgstr "Syvyys (mm)"
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:126
msgctxt "@info:tooltip"
-msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
-msgstr "Oletuksena valkoiset pikselit edustavat verkossa korkeita pisteitä ja mustat pikselit edustavat verkossa matalia pisteitä. Muuta asetus, jos haluat, että mustat pikselit edustavat verkossa korkeita pisteitä ja valkoiset pikselit edustavat verkossa matalia pisteitä."
-
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
-msgctxt "@item:inlistbox"
-msgid "Lighter is higher"
-msgstr "Vaaleampi on korkeampi"
+msgid "For lithophanes dark pixels should correspond to thicker locations in order to block more light coming through. For height maps lighter pixels signify higher terrain, so lighter pixels should correspond to thicker locations in the generated 3D model."
+msgstr ""
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
msgctxt "@item:inlistbox"
msgid "Darker is higher"
msgstr "Tummempi on korkeampi"
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
+msgctxt "@item:inlistbox"
+msgid "Lighter is higher"
+msgstr "Vaaleampi on korkeampi"
+
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:149
msgctxt "@info:tooltip"
msgid "The amount of smoothing to apply to the image."
@@ -2249,81 +2425,80 @@ msgctxt "@action:label"
msgid "Smoothing"
msgstr "Tasoitus"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:37
-msgctxt "@label"
-msgid "Mesh Type"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:68
-msgctxt "@label"
-msgid "Normal model"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:75
-msgctxt "@label"
-msgid "Print as support"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:83
-msgctxt "@label"
-msgid "Don't support overlap with other models"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:91
-msgctxt "@label"
-msgid "Modify settings for overlap with other models"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:99
-msgctxt "@label"
-msgid "Modify settings for infill of other models"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:347
-msgctxt "@action:button"
-msgid "Select settings"
-msgstr "Valitse asetukset"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:389
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:13
msgctxt "@title:window"
msgid "Select Settings to Customize for this model"
msgstr "Valitse tätä mallia varten mukautettavat asetukset"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:437
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:98
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:56
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:94
msgctxt "@label:textbox"
msgid "Filter..."
msgstr "Suodatin..."
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:451
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:70
msgctxt "@label:checkbox"
msgid "Show all"
msgstr "Näytä kaikki"
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:44
+msgctxt "@label"
+msgid "Mesh Type"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:85
+msgctxt "@label"
+msgid "Normal model"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:97
+msgctxt "@label"
+msgid "Print as support"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:109
+msgctxt "@label"
+msgid "Modify settings for overlaps"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:121
+msgctxt "@label"
+msgid "Don't support overlaps"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:145
+msgctxt "@action:checkbox"
+msgid "Infill only"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:368
+msgctxt "@action:button"
+msgid "Select settings"
+msgstr "Valitse asetukset"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:14
msgctxt "@title:window"
msgid "Open Project"
msgstr "Avaa projekti"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:58
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Update/override existing profile"
msgid "Update existing"
-msgstr "Päivitä nykyinen"
+msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:59
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Save settings in a new profile"
msgid "Create new"
-msgstr "Luo uusi"
+msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:70
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:73
msgctxt "@action:title"
msgid "Summary - Cura Project"
msgstr "Yhteenveto – Cura-projekti"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:92
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:97
msgctxt "@action:label"
msgid "Printer settings"
msgstr "Tulostimen asetukset"
@@ -2339,20 +2514,25 @@ msgctxt "@action:ComboBox option"
msgid "Update"
msgstr ""
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
+msgctxt "@action:ComboBox option"
+msgid "Create new"
+msgstr "Luo uusi"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:143
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:105
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:106
msgctxt "@action:label"
msgid "Type"
msgstr "Tyyppi"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:159
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
msgctxt "@action:label"
msgid "Printer Group"
msgstr ""
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:180
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:196
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:220
msgctxt "@action:label"
msgid "Profile settings"
msgstr "Profiilin asetukset"
@@ -2363,226 +2543,222 @@ msgid "How should the conflict in the profile be resolved?"
msgstr "Miten profiilin ristiriita pitäisi ratkaista?"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:216
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:220
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:323
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:244
msgctxt "@action:label"
msgid "Name"
msgstr "Nimi"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:231
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:204
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:261
+msgctxt "@action:label"
+msgid "Intent"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:246
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:228
msgctxt "@action:label"
msgid "Not in profile"
msgstr "Ei profiilissa"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:236
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:209
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:251
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:233
msgctxt "@action:label"
msgid "%1 override"
msgid_plural "%1 overrides"
msgstr[0] "%1 ohitus"
msgstr[1] "%1 ohitusta"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:247
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:262
msgctxt "@action:label"
msgid "Derivative from"
msgstr "Johdettu seuraavista"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:252
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:267
msgctxt "@action:label"
msgid "%1, %2 override"
msgid_plural "%1, %2 overrides"
msgstr[0] "%1, %2 ohitus"
msgstr[1] "%1, %2 ohitusta"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:268
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:283
msgctxt "@action:label"
msgid "Material settings"
msgstr "Materiaaliasetukset"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:284
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:299
msgctxt "@info:tooltip"
msgid "How should the conflict in the material be resolved?"
msgstr "Miten materiaalin ristiriita pitäisi ratkaista?"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:327
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:237
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:342
msgctxt "@action:label"
msgid "Setting visibility"
msgstr "Asetusten näkyvyys"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:336
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:351
msgctxt "@action:label"
msgid "Mode"
msgstr "Tila"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:352
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:246
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:367
msgctxt "@action:label"
msgid "Visible settings:"
msgstr "Näkyvät asetukset:"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:357
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:251
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:372
msgctxt "@action:label"
msgid "%1 out of %2"
msgstr "%1/%2"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:383
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:398
msgctxt "@action:warning"
msgid "Loading a project will clear all models on the build plate."
msgstr ""
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:401
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:416
msgctxt "@action:button"
msgid "Open"
msgstr "Avaa"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:26
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:25
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:28
msgctxt "@title"
-msgid "Select Printer Upgrades"
-msgstr "Valitse tulostimen päivitykset"
+msgid "My Backups"
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:38
-msgctxt "@label"
-msgid "Please select any upgrades made to this Ultimaker 2."
-msgstr "Valitse tähän Ultimaker 2 -laitteeseen tehdyt päivitykset."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:38
+msgctxt "@empty_state"
+msgid "You don't have any backups currently. Use the 'Backup Now' button to create one."
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:47
-msgctxt "@label"
-msgid "Olsson Block"
-msgstr "Olsson Block -lämmitysosa"
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:60
+msgctxt "@backup_limit_info"
+msgid "During the preview phase, you'll be limited to 5 visible backups. Remove a backup to see older ones."
+msgstr ""
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:27
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:34
+msgctxt "@description"
+msgid "Backup and synchronize your Cura settings."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:51
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:68
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:138
+msgctxt "@button"
+msgid "Sign in"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/main.qml:24
+msgctxt "@title:window"
+msgid "Cura Backups"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:21
+msgctxt "@backuplist:label"
+msgid "Cura Version"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:29
+msgctxt "@backuplist:label"
+msgid "Machines"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:37
+msgctxt "@backuplist:label"
+msgid "Materials"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:45
+msgctxt "@backuplist:label"
+msgid "Profiles"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:53
+msgctxt "@backuplist:label"
+msgid "Plugins"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:71
+msgctxt "@button"
+msgid "Restore"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:99
+msgctxt "@dialog:title"
+msgid "Delete Backup"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:100
+msgctxt "@dialog:info"
+msgid "Are you sure you want to delete this backup? This cannot be undone."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:108
+msgctxt "@dialog:title"
+msgid "Restore Backup"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:109
+msgctxt "@dialog:info"
+msgid "You will need to restart Cura before your backup is restored. Do you want to close Cura now?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:22
+msgctxt "@button"
+msgid "Want more?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:31
+msgctxt "@button"
+msgid "Backup Now"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:43
+msgctxt "@checkbox:description"
+msgid "Auto Backup"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:44
+msgctxt "@checkbox:description"
+msgid "Automatically create a backup each day that Cura is started."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:30
msgctxt "@title"
msgid "Build Plate Leveling"
msgstr "Alustan tasaaminen"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:38
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:44
msgctxt "@label"
msgid "To make sure your prints will come out great, you can now adjust your buildplate. When you click 'Move to Next Position' the nozzle will move to the different positions that can be adjusted."
msgstr "Voit säätää alustaa, jotta tulosteista tulisi hyviä. Kun napsautat \"Siirry seuraavaan positioon\", suutin siirtyy eri positioihin, joita voidaan säätää."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:47
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:57
msgctxt "@label"
msgid "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle."
msgstr "Laita paperinpala kussakin positiossa suuttimen alle ja säädä tulostusalustan korkeus. Tulostusalustan korkeus on oikea, kun suuttimen kärki juuri ja juuri osuu paperiin."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:62
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:75
msgctxt "@action:button"
msgid "Start Build Plate Leveling"
msgstr "Aloita alustan tasaaminen"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:74
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:87
msgctxt "@action:button"
msgid "Move to Next Position"
msgstr "Siirry seuraavaan positioon"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:37
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:30
msgctxt "@label"
msgid "Please select any upgrades made to this Ultimaker Original"
msgstr "Valitse tähän Ultimaker Original -laitteeseen tehdyt päivitykset"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:45
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:41
msgctxt "@label"
msgid "Heated Build Plate (official kit or self-built)"
msgstr "Lämmitettävä alusta (virallinen sarja tai itse rakennettu)"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:27
-msgctxt "@title"
-msgid "Check Printer"
-msgstr "Tarkista tulostin"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:39
-msgctxt "@label"
-msgid "It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional"
-msgstr "Ultimakerille on hyvä tehdä muutamia toimintatarkastuksia. Voit jättää tämän vaiheen väliin, jos tiedät laitteesi olevan toimintakunnossa"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:53
-msgctxt "@action:button"
-msgid "Start Printer Check"
-msgstr "Aloita tulostintarkistus"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:80
-msgctxt "@label"
-msgid "Connection: "
-msgstr "Yhteys: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Connected"
-msgstr "Yhdistetty"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Not connected"
-msgstr "Ei yhteyttä"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:99
-msgctxt "@label"
-msgid "Min endstop X: "
-msgstr "Min. päätyraja X: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-msgctxt "@info:status"
-msgid "Works"
-msgstr "Toimii"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:173
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Not checked"
-msgstr "Ei tarkistettu"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:120
-msgctxt "@label"
-msgid "Min endstop Y: "
-msgstr "Min. päätyraja Y: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:141
-msgctxt "@label"
-msgid "Min endstop Z: "
-msgstr "Min. päätyraja Z: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:163
-msgctxt "@label"
-msgid "Nozzle temperature check: "
-msgstr "Suuttimen lämpötilatarkistus: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Stop Heating"
-msgstr "Lopeta lämmitys"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Start Heating"
-msgstr "Aloita lämmitys"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:223
-msgctxt "@label"
-msgid "Build plate temperature check:"
-msgstr "Alustan lämpötilan tarkistus:"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Checked"
-msgstr "Tarkistettu"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:284
-msgctxt "@label"
-msgid "Everything is in order! You're done with your CheckUp."
-msgstr "Kaikki on kunnossa! CheckUp on valmis."
-
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:119
msgctxt "@label:MonitorStatus"
msgid "Not connected to a printer"
@@ -2594,7 +2770,6 @@ msgid "Printer does not accept commands"
msgstr "Tulostin ei hyväksy komentoja"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:133
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:197
msgctxt "@label:MonitorStatus"
msgid "In maintenance. Please check the printer"
msgstr "Huolletaan. Tarkista tulostin"
@@ -2605,19 +2780,16 @@ msgid "Lost connection with the printer"
msgstr "Yhteys tulostimeen menetetty"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:146
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:187
msgctxt "@label:MonitorStatus"
msgid "Printing..."
msgstr "Tulostetaan..."
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:149
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:189
msgctxt "@label:MonitorStatus"
msgid "Paused"
msgstr "Keskeytetty"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:152
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:191
msgctxt "@label:MonitorStatus"
msgid "Preparing..."
msgstr "Valmistellaan..."
@@ -2637,235 +2809,176 @@ msgctxt "@label"
msgid "Are you sure you want to abort the print?"
msgstr "Haluatko varmasti keskeyttää tulostuksen?"
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:15
-msgctxt "@title:window"
-msgid "Discard or Keep changes"
-msgstr "Hylkää tai säilytä muutokset"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:57
-msgctxt "@text:window"
-msgid ""
-"You have customized some profile settings.\n"
-"Would you like to keep or discard those settings?"
-msgstr ""
-"Olet mukauttanut profiilin asetuksia.\n"
-"Haluatko säilyttää vai hylätä nämä asetukset?"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:110
-msgctxt "@title:column"
-msgid "Profile settings"
-msgstr "Profiilin asetukset"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:117
-msgctxt "@title:column"
-msgid "Default"
-msgstr "Oletusarvo"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:124
-msgctxt "@title:column"
-msgid "Customized"
-msgstr "Mukautettu"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:157
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:637
-msgctxt "@option:discardOrKeep"
-msgid "Always ask me this"
-msgstr "Kysy aina"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:158
-msgctxt "@option:discardOrKeep"
-msgid "Discard and never ask again"
-msgstr "Hylkää äläkä kysy uudelleen"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:159
-msgctxt "@option:discardOrKeep"
-msgid "Keep and never ask again"
-msgstr "Säilytä äläkä kysy uudelleen"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:196
-msgctxt "@action:button"
-msgid "Discard"
-msgstr "Hylkää"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:209
-msgctxt "@action:button"
-msgid "Keep"
-msgstr "Säilytä"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:222
-msgctxt "@action:button"
-msgid "Create New Profile"
-msgstr "Luo uusi profiili"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:71
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:72
msgctxt "@title"
msgid "Information"
msgstr "Tiedot"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:100
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
msgctxt "@title:window"
msgid "Confirm Diameter Change"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:102
msgctxt "@label (%1 is a number)"
msgid "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:128
msgctxt "@label"
msgid "Display Name"
msgstr "Näytä nimi"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:143
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:138
msgctxt "@label"
msgid "Brand"
msgstr "Merkki"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:148
msgctxt "@label"
msgid "Material Type"
msgstr "Materiaalin tyyppi"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:158
msgctxt "@label"
msgid "Color"
msgstr "Väri"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:212
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:208
msgctxt "@label"
msgid "Properties"
msgstr "Ominaisuudet"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:214
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:210
msgctxt "@label"
msgid "Density"
msgstr "Tiheys"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:229
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:225
msgctxt "@label"
msgid "Diameter"
msgstr "Läpimitta"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:263
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:259
msgctxt "@label"
msgid "Filament Cost"
msgstr "Tulostuslangan hinta"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:280
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:276
msgctxt "@label"
msgid "Filament weight"
msgstr "Tulostuslangan paino"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:298
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:294
msgctxt "@label"
msgid "Filament length"
msgstr "Tulostuslangan pituus"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:307
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:303
msgctxt "@label"
msgid "Cost per Meter"
msgstr "Hinta metriä kohden"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:321
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:317
msgctxt "@label"
msgid "This material is linked to %1 and shares some of its properties."
msgstr "Materiaali on linkitetty kohteeseen %1 ja niillä on joitain samoja ominaisuuksia."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:328
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:324
msgctxt "@label"
msgid "Unlink Material"
msgstr "Poista materiaalin linkitys"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:335
msgctxt "@label"
msgid "Description"
msgstr "Kuvaus"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:352
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:348
msgctxt "@label"
msgid "Adhesion Information"
msgstr "Tarttuvuustiedot"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:378
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:19
msgctxt "@label"
msgid "Print settings"
msgstr "Tulostusasetukset"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:84
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:35
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:108
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:40
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:84
msgctxt "@action:button"
msgid "Activate"
msgstr "Aktivoi"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:126
msgctxt "@action:button"
msgid "Create"
msgstr "Luo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:140
msgctxt "@action:button"
msgid "Duplicate"
msgstr "Jäljennös"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:141
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:170
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:167
msgctxt "@action:button"
msgid "Import"
msgstr "Tuo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:154
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:184
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:179
msgctxt "@action:button"
msgid "Export"
msgstr "Vie"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:233
msgctxt "@action:label"
msgid "Printer"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:262
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:274
msgctxt "@title:window"
msgid "Confirm Remove"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:263
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:240
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:300
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:275
msgctxt "@label (%1 is object name)"
msgid "Are you sure you wish to remove %1? This cannot be undone!"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:277
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:285
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:314
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:322
msgctxt "@title:window"
msgid "Import Material"
msgstr "Tuo materiaali"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:286
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:323
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Could not import material %1: %2"
msgstr "Materiaalin tuominen epäonnistui: %1: %2"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:290
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:327
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully imported material %1"
msgstr "Materiaalin tuominen onnistui: %1"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:316
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:345
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:353
msgctxt "@title:window"
msgid "Export Material"
msgstr "Vie materiaali"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:320
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:357
msgctxt "@info:status Don't translate the XML tags and !"
msgid "Failed to export material to %1: %2"
msgstr "Materiaalin vieminen epäonnistui kohteeseen %1: %2"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:326
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:363
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully exported material to %1"
msgstr "Materiaalin vieminen onnistui kohteeseen %1"
@@ -2875,669 +2988,521 @@ msgctxt "@title:tab"
msgid "Setting Visibility"
msgstr "Näkyvyyden asettaminen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:46
msgctxt "@label:textbox"
msgid "Check all"
msgstr "Tarkista kaikki"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:47
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:61
msgctxt "@info:status"
msgid "Calculated"
msgstr "Laskettu"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:60
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:75
msgctxt "@title:column"
msgid "Setting"
msgstr "Asetus"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
msgctxt "@title:column"
msgid "Profile"
msgstr "Profiili"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:74
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:89
msgctxt "@title:column"
msgid "Current"
msgstr "Nykyinen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:97
msgctxt "@title:column"
msgid "Unit"
msgstr "Yksikkö"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:15
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:410
msgctxt "@title:tab"
msgid "General"
msgstr "Yleiset"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:132
msgctxt "@label"
msgid "Interface"
msgstr "Käyttöliittymä"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:143
msgctxt "@label"
msgid "Language:"
msgstr "Kieli:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:221
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:210
msgctxt "@label"
msgid "Currency:"
msgstr "Valuutta:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:235
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:223
msgctxt "@label"
msgid "Theme:"
msgstr "Teema:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:292
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:279
msgctxt "@label"
msgid "You will need to restart the application for these changes to have effect."
msgstr "Sovellus on käynnistettävä uudelleen, jotta nämä muutokset tulevat voimaan."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:309
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:296
msgctxt "@info:tooltip"
msgid "Slice automatically when changing settings."
msgstr "Viipaloi automaattisesti, kun asetuksia muutetaan."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:317
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:304
msgctxt "@option:check"
msgid "Slice automatically"
msgstr "Viipaloi automaattisesti"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:318
msgctxt "@label"
msgid "Viewport behavior"
msgstr "Näyttöikkunan käyttäytyminen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:326
msgctxt "@info:tooltip"
msgid "Highlight unsupported areas of the model in red. Without support these areas will not print properly."
msgstr "Korosta mallin vailla tukea olevat alueet punaisella. Ilman tukea nämä alueet eivät tulostu kunnolla."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:335
msgctxt "@option:check"
msgid "Display overhang"
msgstr "Näytä uloke"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:355
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:343
msgctxt "@info:tooltip"
msgid "Moves the camera so the model is in the center of the view when a model is selected"
msgstr "Siirtää kameraa siten, että valittuna oleva malli on näkymän keskellä."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
msgctxt "@action:button"
msgid "Center camera when item is selected"
msgstr "Keskitä kamera kun kohde on valittu"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:369
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:358
msgctxt "@info:tooltip"
msgid "Should the default zoom behavior of cura be inverted?"
msgstr "Pitääkö Curan oletusarvoinen zoom-toimintatapa muuttaa päinvastaiseksi?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:363
msgctxt "@action:button"
msgid "Invert the direction of camera zoom."
msgstr "Käännä kameran zoomin suunta päinvastaiseksi."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
msgctxt "@info:tooltip"
msgid "Should zooming move in the direction of the mouse?"
msgstr "Tuleeko zoomauksen siirtyä hiiren suuntaan?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:389
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
+msgctxt "@info:tooltip"
+msgid "Zooming towards the mouse is not supported in the orthographic perspective."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
msgctxt "@action:button"
msgid "Zoom toward mouse direction"
msgstr "Zoomaa hiiren suuntaan"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:399
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:410
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved so that they no longer intersect?"
msgstr "Pitäisikö alustalla olevia malleja siirtää niin, etteivät ne enää leikkaa toisiaan?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:404
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:415
msgctxt "@option:check"
msgid "Ensure models are kept apart"
msgstr "Varmista, että mallit ovat erillään"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:413
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:424
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved down to touch the build plate?"
msgstr "Pitäisikö tulostusalueella olevia malleja siirtää alas niin, että ne koskettavat tulostusalustaa?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:418
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:429
msgctxt "@option:check"
msgid "Automatically drop models to the build plate"
msgstr "Pudota mallit automaattisesti alustalle"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:430
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:441
msgctxt "@info:tooltip"
msgid "Show caution message in g-code reader."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:439
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:450
msgctxt "@option:check"
msgid "Caution message in g-code reader"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:447
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:458
msgctxt "@info:tooltip"
msgid "Should layer be forced into compatibility mode?"
msgstr "Pakotetaanko kerros yhteensopivuustilaan?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:452
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:463
msgctxt "@option:check"
msgid "Force layer view compatibility mode (restart required)"
msgstr "Pakota kerrosnäkymän yhteensopivuustila (vaatii uudelleenkäynnistyksen)"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:468
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:473
+msgctxt "@info:tooltip"
+msgid "Should Cura open at the location it was closed?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:478
+msgctxt "@option:check"
+msgid "Restore window position on start"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:488
+msgctxt "@info:tooltip"
+msgid "What type of camera rendering should be used?"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+msgctxt "@window:text"
+msgid "Camera rendering:"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:506
+msgid "Perspective"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:507
+msgid "Orthographic"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:538
msgctxt "@label"
msgid "Opening and saving files"
msgstr "Tiedostojen avaaminen ja tallentaminen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:475
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:545
msgctxt "@info:tooltip"
msgid "Should models be scaled to the build volume if they are too large?"
msgstr "Pitäisikö mallit skaalata tulostustilavuuteen, jos ne ovat liian isoja?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:550
msgctxt "@option:check"
msgid "Scale large models"
msgstr "Skaalaa suuret mallit"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:490
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:560
msgctxt "@info:tooltip"
msgid "An model may appear extremely small if its unit is for example in meters rather than millimeters. Should these models be scaled up?"
msgstr "Malli voi vaikuttaa erittäin pieneltä, jos sen koko on ilmoitettu esimerkiksi metreissä eikä millimetreissä. Pitäisikö nämä mallit suurentaa?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:565
msgctxt "@option:check"
msgid "Scale extremely small models"
msgstr "Skaalaa erittäin pienet mallit"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:505
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:575
msgctxt "@info:tooltip"
msgid "Should models be selected after they are loaded?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:510
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:580
msgctxt "@option:check"
msgid "Select models when loaded"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:520
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:590
msgctxt "@info:tooltip"
msgid "Should a prefix based on the printer name be added to the print job name automatically?"
msgstr "Pitäisikö tulostustyön nimeen lisätä automaattisesti tulostimen nimeen perustuva etuliite?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:525
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:595
msgctxt "@option:check"
msgid "Add machine prefix to job name"
msgstr "Lisää laitteen etuliite työn nimeen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:535
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:605
msgctxt "@info:tooltip"
msgid "Should a summary be shown when saving a project file?"
msgstr "Näytetäänkö yhteenveto, kun projektitiedosto tallennetaan?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
msgctxt "@option:check"
msgid "Show summary dialog when saving project"
msgstr "Näytä yhteenvetoikkuna, kun projekti tallennetaan"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:619
msgctxt "@info:tooltip"
msgid "Default behavior when opening a project file"
msgstr "Projektitiedoston avaamisen oletustoimintatapa"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:557
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:627
msgctxt "@window:text"
msgid "Default behavior when opening a project file: "
msgstr "Projektitiedoston avaamisen oletustoimintatapa: "
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:571
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:641
msgctxt "@option:openProject"
msgid "Always ask me this"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:572
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:642
msgctxt "@option:openProject"
msgid "Always open as a project"
msgstr "Avaa aina projektina"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:573
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:643
msgctxt "@option:openProject"
msgid "Always import models"
msgstr "Tuo mallit aina"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:679
msgctxt "@info:tooltip"
msgid "When you have made changes to a profile and switched to a different one, a dialog will be shown asking whether you want to keep your modifications or not, or you can choose a default behaviour and never show that dialog again."
msgstr "Kun olet tehnyt muutokset profiiliin ja vaihtanut toiseen, näytetään valintaikkuna, jossa kysytään, haluatko säilyttää vai hylätä muutokset. Tässä voit myös valita oletuskäytöksen, jolloin valintaikkunaa ei näytetä uudelleen."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:618
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:688
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:52
msgctxt "@label"
msgid "Profiles"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:623
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:693
msgctxt "@window:text"
msgid "Default behavior for changed setting values when switching to a different profile: "
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:638
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:707
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:157
+msgctxt "@option:discardOrKeep"
+msgid "Always ask me this"
+msgstr "Kysy aina"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:708
msgctxt "@option:discardOrKeep"
msgid "Always discard changed settings"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:639
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:709
msgctxt "@option:discardOrKeep"
msgid "Always transfer changed settings to new profile"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:673
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:743
msgctxt "@label"
msgid "Privacy"
msgstr "Tietosuoja"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:681
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:750
msgctxt "@info:tooltip"
msgid "Should Cura check for updates when the program is started?"
msgstr "Pitäisikö Curan tarkistaa saatavilla olevat päivitykset, kun ohjelma käynnistetään?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:686
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:755
msgctxt "@option:check"
msgid "Check for updates on start"
msgstr "Tarkista päivitykset käynnistettäessä"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:697
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:765
msgctxt "@info:tooltip"
msgid "Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored."
msgstr "Pitäisikö anonyymejä tietoja tulosteesta lähettää Ultimakerille? Huomaa, että malleja, IP-osoitteita tai muita henkilökohtaisia tietoja ei lähetetä eikä tallenneta."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:702
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:770
msgctxt "@option:check"
msgid "Send (anonymous) print information"
msgstr "Lähetä (anonyymit) tulostustiedot"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:711
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:779
msgctxt "@action:button"
msgid "More information"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:729
-msgctxt "@label"
-msgid "Experimental"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:736
-msgctxt "@info:tooltip"
-msgid "Use multi build plate functionality"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:741
-msgctxt "@option:check"
-msgid "Use multi build plate functionality (restart required)"
-msgstr ""
-
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:16
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:415
msgctxt "@title:tab"
msgid "Printers"
msgstr "Tulostimet"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:63
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
msgctxt "@action:button"
msgid "Rename"
msgstr "Nimeä uudelleen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:147
-msgctxt "@label"
-msgid "Printer type:"
-msgstr "Tulostimen tyyppi:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:156
-msgctxt "@label"
-msgid "Connection:"
-msgstr "Yhteys:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:162
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
-msgctxt "@info:status"
-msgid "The printer is not connected."
-msgstr "Tulostinta ei ole yhdistetty."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:168
-msgctxt "@label"
-msgid "State:"
-msgstr "Tila:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:181
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for a printjob"
-msgstr "Odotetaan tulostustyötä"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:193
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for someone to clear the build plate"
-msgstr "Odotetaan tulostusalustan tyhjennystä"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:199
-msgctxt "@label:MonitorStatus"
-msgid "Aborting print..."
-msgstr "Keskeytetään tulostus..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:553
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:34
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:419
msgctxt "@title:tab"
msgid "Profiles"
msgstr "Profiilit"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:104
msgctxt "@label"
msgid "Create"
msgstr "Luo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:102
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:121
msgctxt "@label"
msgid "Duplicate"
msgstr "Jäljennös"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:174
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:202
msgctxt "@title:window"
msgid "Create Profile"
msgstr "Luo profiili"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:204
+msgctxt "@info"
+msgid "Please provide a name for this profile."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:260
msgctxt "@title:window"
msgid "Duplicate Profile"
msgstr "Monista profiili"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:256
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:291
msgctxt "@title:window"
msgid "Rename Profile"
msgstr "Nimeä profiili uudelleen"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:304
msgctxt "@title:window"
msgid "Import Profile"
msgstr "Profiilin tuonti"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:333
msgctxt "@title:window"
msgid "Export Profile"
msgstr "Profiilin vienti"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:350
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:396
msgctxt "@label %1 is printer name"
msgid "Printer: %1"
msgstr "Tulostin: %1"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Protected profiles"
-msgstr "Suojatut profiilit"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Custom profiles"
-msgstr "Mukautetut profiilit"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:554
msgctxt "@action:button"
msgid "Update profile with current settings/overrides"
msgstr "Päivitä nykyiset asetukset tai ohitukset profiiliin"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:487
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:561
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:257
msgctxt "@action:button"
msgid "Discard current changes"
msgstr "Hylkää tehdyt muutokset"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:504
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:580
msgctxt "@action:label"
msgid "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below."
msgstr "Tässä profiilissa käytetään tulostimen oletusarvoja, joten siinä ei ole alla olevan listan asetuksia tai ohituksia."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:511
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:588
msgctxt "@action:label"
msgid "Your current settings match the selected profile."
msgstr "Nykyiset asetukset vastaavat valittua profiilia."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:530
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:606
msgctxt "@title:tab"
msgid "Global Settings"
msgstr "Yleiset asetukset"
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:18
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:953
-msgctxt "@title:window"
-msgid "Add Printer"
-msgstr "Lisää tulostin"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:195
-msgctxt "@label"
-msgid "Printer Name:"
-msgstr "Tulostimen nimi:"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:219
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/MainWindowHeader.qml:90
msgctxt "@action:button"
-msgid "Add Printer"
-msgstr "Lisää tulostin"
+msgid "Marketplace"
+msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:84
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:27
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&File"
+msgstr "Tie&dosto"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:31
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Edit"
+msgstr "&Muokkaa"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:48
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
+msgctxt "@title:menu menubar:toplevel"
+msgid "&View"
+msgstr "&Näytä"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Settings"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:55
+msgctxt "@title:menu menubar:toplevel"
+msgid "E&xtensions"
+msgstr "Laa&jennukset"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:89
+msgctxt "@title:menu menubar:toplevel"
+msgid "P&references"
+msgstr "L&isäasetukset"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:97
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Help"
+msgstr "&Ohje"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:124
+msgctxt "@title:window"
+msgid "New project"
+msgstr "Uusi projekti"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:125
+msgctxt "@info:question"
+msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
+msgstr "Haluatko varmasti aloittaa uuden projektin? Se tyhjentää alustan ja kaikki tallentamattomat asetukset."
+
+#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:88
msgctxt "@text Print job name"
msgid "Untitled"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:15
-msgctxt "@title:window"
-msgid "About Cura"
-msgstr "Tietoja Curasta"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:55
-msgctxt "@label"
-msgid "version: %1"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:69
-msgctxt "@label"
-msgid "End-to-end solution for fused filament 3D printing."
-msgstr "Kokonaisvaltainen sulatettavan tulostuslangan 3D-tulostusratkaisu."
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:82
-msgctxt "@info:credit"
-msgid ""
-"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
-"Cura proudly uses the following open source projects:"
-msgstr ""
-"Cura-ohjelman on kehittänyt Ultimaker B.V. yhteistyössä käyttäjäyhteisön kanssa.\n"
-"Cura hyödyntää seuraavia avoimeen lähdekoodiin perustuvia projekteja:"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:132
-msgctxt "@label"
-msgid "Graphical user interface"
-msgstr "Graafinen käyttöliittymä"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:133
-msgctxt "@label"
-msgid "Application framework"
-msgstr "Sovelluskehys"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:134
-msgctxt "@label"
-msgid "G-code generator"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:135
-msgctxt "@label"
-msgid "Interprocess communication library"
-msgstr "Prosessien välinen tietoliikennekirjasto"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:137
-msgctxt "@label"
-msgid "Programming language"
-msgstr "Ohjelmointikieli"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:138
-msgctxt "@label"
-msgid "GUI framework"
-msgstr "GUI-kehys"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139
-msgctxt "@label"
-msgid "GUI framework bindings"
-msgstr "GUI-kehyksen sidonnat"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:140
-msgctxt "@label"
-msgid "C/C++ Binding library"
-msgstr "C/C++ -sidontakirjasto"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:141
-msgctxt "@label"
-msgid "Data interchange format"
-msgstr "Data Interchange Format"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:142
-msgctxt "@label"
-msgid "Support library for scientific computing"
-msgstr "Tieteellisen laskennan tukikirjasto"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:143
-msgctxt "@label"
-msgid "Support library for faster math"
-msgstr "Nopeamman laskennan tukikirjasto"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:144
-msgctxt "@label"
-msgid "Support library for handling STL files"
-msgstr "STL-tiedostojen käsittelyn tukikirjasto"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:145
-msgctxt "@label"
-msgid "Support library for handling planar objects"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:146
-msgctxt "@label"
-msgid "Support library for handling triangular meshes"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:147
-msgctxt "@label"
-msgid "Support library for analysis of complex networks"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:148
-msgctxt "@label"
-msgid "Support library for handling 3MF files"
-msgstr "Tukikirjasto 3MF-tiedostojen käsittelyyn"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:149
-msgctxt "@label"
-msgid "Support library for file metadata and streaming"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:150
-msgctxt "@label"
-msgid "Serial communication library"
-msgstr "Sarjatietoliikennekirjasto"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:151
-msgctxt "@label"
-msgid "ZeroConf discovery library"
-msgstr "ZeroConf-etsintäkirjasto"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:152
-msgctxt "@label"
-msgid "Polygon clipping library"
-msgstr "Monikulmion leikkauskirjasto"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:153
-msgctxt "@Label"
-msgid "Python HTTP library"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:155
-msgctxt "@label"
-msgid "Font"
-msgstr "Fontti"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:156
-msgctxt "@label"
-msgid "SVG icons"
-msgstr "SVG-kuvakkeet"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:157
-msgctxt "@label"
-msgid "Linux cross-distribution application deployment"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:42
-msgctxt "@label"
-msgid "Profile:"
-msgstr "Profiili:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:104
-msgctxt "@tooltip"
-msgid ""
-"Some setting/override values are different from the values stored in the profile.\n"
-"\n"
-"Click to open the profile manager."
-msgstr ""
-"Jotkut asetusten ja ohitusten arvot eroavat profiiliin tallennetuista arvoista.\n"
-"\n"
-"Avaa profiilin hallinta napsauttamalla."
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:200
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:68
msgctxt "@label:textbox"
-msgid "Search..."
-msgstr "Haku…"
+msgid "Search settings"
+msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:545
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:462
msgctxt "@action:menu"
msgid "Copy value to all extruders"
msgstr "Kopioi arvo kaikkiin suulakepuristimiin"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:554
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:471
msgctxt "@action:menu"
msgid "Copy all changed values to all extruders"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:591
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:508
msgctxt "@action:menu"
msgid "Hide this setting"
msgstr "Piilota tämä asetus"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:521
msgctxt "@action:menu"
msgid "Don't show this setting"
msgstr "Älä näytä tätä asetusta"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:613
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:525
msgctxt "@action:menu"
msgid "Keep this setting visible"
msgstr "Pidä tämä asetus näkyvissä"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:637
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:417
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:434
msgctxt "@action:menu"
msgid "Configure setting visibility..."
msgstr "Määritä asetusten näkyvyys..."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:644
-msgctxt "@action:inmenu"
-msgid "Collapse All"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:649
-msgctxt "@action:inmenu"
-msgid "Expand All"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:253
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:237
msgctxt "@label"
msgid ""
"Some hidden settings use values different from their normal calculated value.\n"
@@ -3548,27 +3513,32 @@ msgstr ""
"\n"
"Tee asetuksista näkyviä napsauttamalla."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:81
+msgctxt "@label"
+msgid "This setting is not used because all the settings that it influences are overridden."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:86
msgctxt "@label Header for list of settings."
msgid "Affects"
msgstr "Koskee seuraavia:"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:91
msgctxt "@label Header for list of settings."
msgid "Affected By"
msgstr "Riippuu seuraavista:"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:187
msgctxt "@label"
msgid "This setting is always shared between all extruders. Changing it here will change the value for all extruders."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:158
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:191
msgctxt "@label"
msgid "The value is resolved from per-extruder values "
msgstr "Arvo perustuu suulakepuristimien arvoihin "
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:189
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:230
msgctxt "@label"
msgid ""
"This setting has a value that is different from the profile.\n"
@@ -3579,7 +3549,7 @@ msgstr ""
"\n"
"Palauta profiilin arvo napsauttamalla."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:281
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:329
msgctxt "@label"
msgid ""
"This setting is normally calculated, but it currently has an absolute value set.\n"
@@ -3590,116 +3560,212 @@ msgstr ""
"\n"
"Palauta laskettu arvo napsauttamalla."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/NoIntentIcon.qml:31
+msgctxt "@label %1 is filled in with the type of a profile. %2 is filled with a list of numbers (eg '1' or '1, 2')"
+msgid "There is no %1 profile for the configuration in extruder %2. The default intent will be used instead"
+msgid_plural "There is no %1 profile for the configurations in extruders %2. The default intent will be used instead"
+msgstr[0] ""
+msgstr[1] ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:144
+msgctxt "@button"
+msgid "Recommended"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:158
+msgctxt "@button"
+msgid "Custom"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:193
+msgctxt "@label"
+msgid "Gradual infill"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:232
+msgctxt "@label"
+msgid "Gradual infill will gradually increase the amount of infill towards the top."
+msgstr "Asteittainen täyttö lisää täytön tiheyttä vähitellen yläosaa kohti."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:30
+msgctxt "@label"
+msgid "Support"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:71
+msgctxt "@label"
+msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
+msgstr "Muodosta rakenteita, jotka tukevat mallin ulokkeita sisältäviä osia. Ilman tukirakenteita kyseiset osat luhistuvat tulostuksen aikana."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:29
+msgctxt "@label"
+msgid "Adhesion"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:74
+msgctxt "@label"
+msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
+msgstr "Ota reunuksen tai pohjaristikon tulostus käyttöön. Tämä lisää kappaleen ympärille tai alle tasaisen alueen, joka on helppo leikata pois myöhemmin."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:81
+msgctxt "@tooltip"
+msgid "You have modified some profile settings. If you want to change these go to custom mode."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:13
+msgctxt "@label:Should be short"
+msgid "On"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:14
+msgctxt "@label:Should be short"
+msgid "Off"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:33
+msgctxt "@label"
+msgid "Experimental"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:47
+msgctxt "@label"
+msgid "Profile"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:172
+msgctxt "@tooltip"
+msgid ""
+"Some setting/override values are different from the values stored in the profile.\n"
+"\n"
+"Click to open the profile manager."
+msgstr ""
+"Jotkut asetusten ja ohitusten arvot eroavat profiiliin tallennetuista arvoista.\n"
+"\n"
+"Avaa profiilin hallinta napsauttamalla."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:160
+msgctxt "@label:header"
+msgid "Custom profiles"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:21
+msgctxt "@label shown when we load a Gcode file"
+msgid "Print setup disabled. G-code file can not be modified."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:52
msgctxt "@label"
msgid "Printer control"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:144
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:67
msgctxt "@label"
msgid "Jog Position"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:85
msgctxt "@label"
msgid "X/Y"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:192
msgctxt "@label"
msgid "Z"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:257
msgctxt "@label"
msgid "Jog Distance"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:443
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:301
msgctxt "@label"
msgid "Send G-code"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:506
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:365
msgctxt "@tooltip of G-code command input"
msgid "Send a custom G-code command to the connected printer. Press 'enter' to send the command."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:272
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:41
msgctxt "@label"
msgid "Extruder"
msgstr "Suulake"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:71
msgctxt "@tooltip"
msgid "The target temperature of the hotend. The hotend will heat up or cool down towards this temperature. If this is 0, the hotend heating is turned off."
msgstr "Kuuman pään kohdelämpötila. Kuuma pää lämpenee tai viilenee kohti tätä lämpötilaa. Jos asetus on 0, kuuman pään lämmitys sammutetaan."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:98
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:103
msgctxt "@tooltip"
msgid "The current temperature of this hotend."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:172
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:177
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the hotend to."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:336
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:341
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:332
msgctxt "@button Cancel pre-heating"
msgid "Cancel"
msgstr "Peruuta"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:339
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:344
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:335
msgctxt "@button"
msgid "Pre-heat"
msgstr "Esilämmitä"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:365
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:370
msgctxt "@tooltip of pre-heat"
msgid "Heat the hotend in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the hotend to heat up when you're ready to print."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:401
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:406
msgctxt "@tooltip"
msgid "The colour of the material in this extruder."
msgstr "Tämän suulakkeen materiaalin väri."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:433
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:438
msgctxt "@tooltip"
msgid "The material in this extruder."
msgstr "Tämän suulakkeen materiaali."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:465
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:470
msgctxt "@tooltip"
msgid "The nozzle inserted in this extruder."
msgstr "Tähän suulakkeeseen liitetty suutin."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:25
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:493
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
+msgctxt "@info:status"
+msgid "The printer is not connected."
+msgstr "Tulostinta ei ole yhdistetty."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:26
msgctxt "@label"
msgid "Build plate"
msgstr "Alusta"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:56
msgctxt "@tooltip"
msgid "The target temperature of the heated bed. The bed will heat up or cool down towards this temperature. If this is 0, the bed heating is turned off."
msgstr "Lämmitettävän pöydän kohdelämpötila. Pöytä lämpenee tai viilenee kohti tätä lämpötilaa. Jos asetus on 0, pöydän lämmitys sammutetaan."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:88
msgctxt "@tooltip"
msgid "The current temperature of the heated bed."
msgstr "Lämmitettävän pöydän nykyinen lämpötila."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:160
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:161
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the bed to."
msgstr "Lämmitettävän pöydän esilämmityslämpötila."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:361
msgctxt "@tooltip of pre-heat"
msgid "Heat the bed in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the bed to heat up when you're ready to print."
msgstr "Lämmitä pöytä ennen tulostusta. Voit edelleen säätää tulostinta sen lämmitessä, eikä sinun tarvitse odottaa pöydän lämpiämistä, kun olet valmis tulostamaan."
@@ -3709,12 +3775,12 @@ msgctxt "@label:category menu label"
msgid "Material"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:37
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:46
msgctxt "@label:category menu label"
msgid "Favorites"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:71
msgctxt "@label:category menu label"
msgid "Generic"
msgstr ""
@@ -3729,17 +3795,52 @@ msgctxt "@label:category menu label"
msgid "Local printers"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
-msgctxt "@title:menu menubar:toplevel"
-msgid "&View"
-msgstr "&Näytä"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:15
+msgctxt "@title:menu menubar:settings"
+msgid "&Printer"
+msgstr "&Tulostin"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:42
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:27
+msgctxt "@title:menu"
+msgid "&Material"
+msgstr "&Materiaali"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:36
+msgctxt "@action:inmenu"
+msgid "Set as Active Extruder"
+msgstr "Aseta aktiiviseksi suulakepuristimeksi"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:42
+msgctxt "@action:inmenu"
+msgid "Enable Extruder"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:49
+msgctxt "@action:inmenu"
+msgid "Disable Extruder"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:19
msgctxt "@action:inmenu menubar:view"
msgid "&Camera position"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:58
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:44
+msgctxt "@action:inmenu menubar:view"
+msgid "Camera view"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:47
+msgctxt "@action:inmenu menubar:view"
+msgid "Perspective"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:59
+msgctxt "@action:inmenu menubar:view"
+msgid "Orthographic"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:80
msgctxt "@action:inmenu menubar:view"
msgid "&Build plate"
msgstr ""
@@ -3759,6 +3860,21 @@ msgctxt "@action:inmenu"
msgid "Manage Setting Visibility..."
msgstr ""
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:33
+msgctxt "@title:menu menubar:file"
+msgid "&Save..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:54
+msgctxt "@title:menu menubar:file"
+msgid "&Export..."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:65
+msgctxt "@action:inmenu menubar:file"
+msgid "Export Selection..."
+msgstr ""
+
#: /home/ruben/Projects/Cura/resources/qml/Menus/ContextMenu.qml:27
msgctxt "@label"
msgid "Print Selected Model With:"
@@ -3778,657 +3894,507 @@ msgctxt "@label"
msgid "Number of Copies"
msgstr "Kopioiden määrä"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:33
-msgctxt "@label:header configurations"
-msgid "Available configurations"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml:18
+msgctxt "@header"
+msgid "Configurations"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml:28
-msgctxt "@label:extruder label"
-msgid "Extruder"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:112
+msgctxt "@label"
+msgid "Select configuration"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "Yes"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:223
+msgctxt "@label"
+msgid "Configurations"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "No"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:57
+msgctxt "@label"
+msgid "Loading available configurations from the printer..."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:13
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:58
+msgctxt "@label"
+msgid "The configurations are not available because the printer is disconnected."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:25
+msgctxt "@header"
+msgid "Custom"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:61
+msgctxt "@label"
+msgid "Printer"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:213
+msgctxt "@label"
+msgid "Enabled"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:251
+msgctxt "@label"
+msgid "Material"
+msgstr "Materiaali"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:378
+msgctxt "@label"
+msgid "Use glue for better adhesion with this material combination."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:128
+msgctxt "@label"
+msgid "This configuration is not available because %1 is not recognized. Please visit %2 to download the correct material profile."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:129
+msgctxt "@label"
+msgid "Marketplace"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:15
msgctxt "@title:menu menubar:file"
msgid "Open &Recent"
msgstr "Avaa &viimeisin"
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid "Print Setup"
-msgstr "Tulostuksen asennus"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid ""
-"Print Setup disabled\n"
-"G-code files cannot be modified"
-msgstr ""
-"Tulostuksen asennus ei käytössä\n"
-"G-code-tiedostoja ei voida muokata"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:340
-msgctxt "@label Hours and minutes"
-msgid "00h 00min"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:358
-msgctxt "@tooltip"
-msgid "Time specification"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:440
-msgctxt "@label"
-msgid "Cost specification"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:445
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:454
-msgctxt "@label m for meter"
-msgid "%1m"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:446
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:455
-msgctxt "@label g for grams"
-msgid "%1g"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:453
-msgctxt "@label"
-msgid "Total:"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:576
-msgctxt "@tooltip"
-msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
-msgstr "Suositeltu tulostuksen asennus
Tulosta valitun tulostimen, materiaalin ja laadun suositelluilla asetuksilla."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:581
-msgctxt "@tooltip"
-msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
-msgstr "Mukautettu tulostuksen asennus
Tulosta hallitsemalla täysin kaikkia viipalointiprosessin vaiheita."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:140
msgctxt "@label"
msgid "Active print"
msgstr "Aktiivinen tulostustyö"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:148
msgctxt "@label"
msgid "Job Name"
msgstr "Työn nimi"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:156
msgctxt "@label"
msgid "Printing Time"
msgstr "Tulostusaika"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:130
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:164
msgctxt "@label"
msgid "Estimated time left"
msgstr "Aikaa jäljellä arviolta"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:79
+#: /home/ruben/Projects/Cura/resources/qml/ViewsSelector.qml:50
+msgctxt "@label"
+msgid "View type"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ObjectSelector.qml:59
+msgctxt "@label"
+msgid "Object list"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:22
+msgctxt "@label The argument is a username."
+msgid "Hi %1"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:33
+msgctxt "@button"
+msgid "Ultimaker account"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:42
+msgctxt "@button"
+msgid "Sign out"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/AccountWidget.qml:24
+msgctxt "@action:button"
+msgid "Sign in"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:40
+msgctxt "@label"
+msgid "The next generation 3D printing workflow"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:51
+msgctxt "@text"
+msgid ""
+"- Send print jobs to Ultimaker printers outside your local network\n"
+"- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+"- Get exclusive access to print profiles from leading brands"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:78
+msgctxt "@button"
+msgid "Create account"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:59
+msgctxt "@label"
+msgid "No time estimation available"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:77
+msgctxt "@label"
+msgid "No cost estimation available"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:127
+msgctxt "@button"
+msgid "Preview"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:55
+msgctxt "@label:PrintjobStatus"
+msgid "Slicing..."
+msgstr "Viipaloidaan..."
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:67
+msgctxt "@label:PrintjobStatus"
+msgid "Unable to slice"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Processing"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Slice"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:104
+msgctxt "@label"
+msgid "Start the slicing process"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:118
+msgctxt "@button"
+msgid "Cancel"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:31
+msgctxt "@label"
+msgid "Time estimation"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:114
+msgctxt "@label"
+msgid "Material estimation"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:164
+msgctxt "@label m for meter"
+msgid "%1m"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:165
+msgctxt "@label g for grams"
+msgid "%1g"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Connected printers"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Preset printers"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:166
+msgctxt "@button"
+msgid "Add printer"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:182
+msgctxt "@button"
+msgid "Manage printers"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:81
+msgctxt "@action:inmenu"
+msgid "Show Online Troubleshooting Guide"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:88
msgctxt "@action:inmenu"
msgid "Toggle Full Screen"
msgstr "Vaihda koko näyttöön"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:86
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+msgctxt "@action:inmenu"
+msgid "Exit Full Screen"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:103
msgctxt "@action:inmenu menubar:edit"
msgid "&Undo"
msgstr "&Kumoa"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
msgctxt "@action:inmenu menubar:edit"
msgid "&Redo"
msgstr "Tee &uudelleen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:123
msgctxt "@action:inmenu menubar:file"
msgid "&Quit"
msgstr "&Lopeta"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:131
msgctxt "@action:inmenu menubar:view"
msgid "3D View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:138
msgctxt "@action:inmenu menubar:view"
msgid "Front View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:128
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:145
msgctxt "@action:inmenu menubar:view"
msgid "Top View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:135
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:152
msgctxt "@action:inmenu menubar:view"
msgid "Left Side View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:159
msgctxt "@action:inmenu menubar:view"
msgid "Right Side View"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:149
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:166
msgctxt "@action:inmenu"
msgid "Configure Cura..."
msgstr "Määritä Curan asetukset..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:156
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:173
msgctxt "@action:inmenu menubar:printer"
msgid "&Add Printer..."
msgstr "L&isää tulostin..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:179
msgctxt "@action:inmenu menubar:printer"
msgid "Manage Pr&inters..."
msgstr "Tulostinten &hallinta..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:169
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:186
msgctxt "@action:inmenu"
msgid "Manage Materials..."
msgstr "Hallitse materiaaleja..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:177
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:195
msgctxt "@action:inmenu menubar:profile"
msgid "&Update profile with current settings/overrides"
msgstr "&Päivitä nykyiset asetukset tai ohitukset profiiliin"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:185
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
msgctxt "@action:inmenu menubar:profile"
msgid "&Discard current changes"
msgstr "&Hylkää tehdyt muutokset"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:197
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:215
msgctxt "@action:inmenu menubar:profile"
msgid "&Create profile from current settings/overrides..."
msgstr "&Luo profiili nykyisten asetusten tai ohitusten perusteella..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:221
msgctxt "@action:inmenu menubar:profile"
msgid "Manage Profiles..."
msgstr "Profiilien hallinta..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:210
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:229
msgctxt "@action:inmenu menubar:help"
msgid "Show Online &Documentation"
msgstr "Näytä sähköinen &dokumentaatio"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:218
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:237
msgctxt "@action:inmenu menubar:help"
msgid "Report a &Bug"
msgstr "Ilmoita &virheestä"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:226
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:245
+msgctxt "@action:inmenu menubar:help"
+msgid "What's New"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:251
msgctxt "@action:inmenu menubar:help"
msgid "About..."
msgstr "Tietoja..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:233
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:258
msgctxt "@action:inmenu menubar:edit"
msgid "Delete Selected Model"
msgid_plural "Delete Selected Models"
msgstr[0] "Poista valittu malli"
msgstr[1] "Poista valitut mallit"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:243
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:268
msgctxt "@action:inmenu menubar:edit"
msgid "Center Selected Model"
msgid_plural "Center Selected Models"
msgstr[0] "Keskitä valittu malli"
msgstr[1] "Keskitä valitut mallit"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:277
msgctxt "@action:inmenu menubar:edit"
msgid "Multiply Selected Model"
msgid_plural "Multiply Selected Models"
msgstr[0] "Kerro valittu malli"
msgstr[1] "Kerro valitut mallit"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:261
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:286
msgctxt "@action:inmenu"
msgid "Delete Model"
msgstr "Poista malli"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:294
msgctxt "@action:inmenu"
msgid "Ce&nter Model on Platform"
msgstr "Ke&skitä malli alustalle"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:275
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:300
msgctxt "@action:inmenu menubar:edit"
msgid "&Group Models"
msgstr "&Ryhmittele mallit"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:320
msgctxt "@action:inmenu menubar:edit"
msgid "Ungroup Models"
msgstr "Poista mallien ryhmitys"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:305
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:330
msgctxt "@action:inmenu menubar:edit"
msgid "&Merge Models"
msgstr "&Yhdistä mallit"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:315
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:340
msgctxt "@action:inmenu"
msgid "&Multiply Model..."
msgstr "&Kerro malli..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:322
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:347
msgctxt "@action:inmenu menubar:edit"
msgid "Select All Models"
msgstr "Valitse kaikki mallit"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:332
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:357
msgctxt "@action:inmenu menubar:edit"
msgid "Clear Build Plate"
msgstr "Tyhjennä tulostusalusta"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:342
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:367
msgctxt "@action:inmenu menubar:file"
msgid "Reload All Models"
msgstr "Lataa kaikki mallit uudelleen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:376
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models To All Build Plates"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:358
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:383
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models"
msgstr "Järjestä kaikki mallit"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:366
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:391
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange Selection"
msgstr "Järjestä valinta"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:373
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:398
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Positions"
msgstr "Määritä kaikkien mallien positiot uudelleen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:380
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:405
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Transformations"
msgstr "Määritä kaikkien mallien muutokset uudelleen"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:387
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:412
msgctxt "@action:inmenu menubar:file"
msgid "&Open File(s)..."
msgstr "&Avaa tiedosto(t)..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:395
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:420
msgctxt "@action:inmenu menubar:file"
msgid "&New Project..."
msgstr "&Uusi projekti..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:402
-msgctxt "@action:inmenu menubar:help"
-msgid "Show Engine &Log..."
-msgstr "Näytä moottorin l&oki"
-
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:410
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:427
msgctxt "@action:inmenu menubar:help"
msgid "Show Configuration Folder"
msgstr "Näytä määrityskansio"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:424
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:441
msgctxt "@action:menu"
-msgid "Browse packages..."
+msgid "&Marketplace"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:431
-msgctxt "@action:inmenu menubar:view"
-msgid "Expand/Collapse Sidebar"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:27
-msgctxt "@label:PrintjobStatus"
-msgid "Please load a 3D model"
-msgstr "Lataa 3D-malli"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:37
-msgctxt "@label:PrintjobStatus"
-msgid "Ready to slice"
-msgstr "Valmiina viipaloimaan"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:39
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing..."
-msgstr "Viipaloidaan..."
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:41
-msgctxt "@label:PrintjobStatus %1 is target operation"
-msgid "Ready to %1"
-msgstr "Valmis: %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:43
-msgctxt "@label:PrintjobStatus"
-msgid "Unable to Slice"
-msgstr "Viipalointi ei onnistu"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:45
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing unavailable"
-msgstr "Viipalointi ei käytettävissä"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Slice current printjob"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Cancel slicing process"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Prepare"
-msgstr "Valmistele"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Cancel"
-msgstr "Peruuta"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:320
-msgctxt "@info:tooltip"
-msgid "Select the active output device"
-msgstr "Valitse aktiivinen tulostusväline"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:19
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:767
-msgctxt "@title:window"
-msgid "Open file(s)"
-msgstr "Avaa tiedosto(t)"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:64
-msgctxt "@text:window"
-msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
-msgstr "Löysimme vähintään yhden projektitiedoston valitsemiesi tiedostojen joukosta. Voit avata vain yhden projektitiedoston kerrallaan. Suosittelemme, että tuot vain malleja niistä tiedostoista. Haluatko jatkaa?"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:99
-msgctxt "@action:button"
-msgid "Import all as models"
-msgstr "Tuo kaikki malleina"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:19
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:24
msgctxt "@title:window"
msgid "Ultimaker Cura"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:103
-msgctxt "@title:menu menubar:toplevel"
-msgid "&File"
-msgstr "Tie&dosto"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:121
-msgctxt "@title:menu menubar:file"
-msgid "&Save..."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:142
-msgctxt "@title:menu menubar:file"
-msgid "&Export..."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:153
-msgctxt "@action:inmenu menubar:file"
-msgid "Export Selection..."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:174
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Edit"
-msgstr "&Muokkaa"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:191
-msgctxt "@title:menu"
-msgid "&View"
-msgstr "&Näytä"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:196
-msgctxt "@title:menu"
-msgid "&Settings"
-msgstr "&Asetukset"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:198
-msgctxt "@title:menu menubar:settings"
-msgid "&Printer"
-msgstr "&Tulostin"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:207
-msgctxt "@title:menu"
-msgid "&Material"
-msgstr "&Materiaali"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:216
-msgctxt "@action:inmenu"
-msgid "Set as Active Extruder"
-msgstr "Aseta aktiiviseksi suulakepuristimeksi"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:222
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:188
-msgctxt "@action:inmenu"
-msgid "Enable Extruder"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:229
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:194
-msgctxt "@action:inmenu"
-msgid "Disable Extruder"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:241
-msgctxt "@title:menu"
-msgid "&Build plate"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:242
-msgctxt "@title:settings"
-msgid "&Profile"
-msgstr "&Profiili"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:252
-msgctxt "@title:menu menubar:toplevel"
-msgid "E&xtensions"
-msgstr "Laa&jennukset"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:286
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Toolbox"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:294
-msgctxt "@title:menu menubar:toplevel"
-msgid "P&references"
-msgstr "L&isäasetukset"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:302
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Help"
-msgstr "&Ohje"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:232
msgctxt "@label"
msgid "This package will be installed after restarting."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:377
-msgctxt "@action:button"
-msgid "Open File"
-msgstr "Avaa tiedosto"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:547
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:413
msgctxt "@title:tab"
msgid "Settings"
msgstr "Asetukset"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:593
-msgctxt "@title:window"
-msgid "New project"
-msgstr "Uusi projekti"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:594
-msgctxt "@info:question"
-msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
-msgstr "Haluatko varmasti aloittaa uuden projektin? Se tyhjentää alustan ja kaikki tallentamattomat asetukset."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:722
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:538
msgctxt "@title:window"
msgid "Closing Cura"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:723
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:735
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
msgctxt "@label"
msgid "Are you sure you want to exit Cura?"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:868
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:589
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:19
+msgctxt "@title:window"
+msgid "Open file(s)"
+msgstr "Avaa tiedosto(t)"
+
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:695
msgctxt "@window:title"
msgid "Install Package"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:875
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:703
msgctxt "@title:window"
msgid "Open File(s)"
msgstr "Avaa tiedosto(t)"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:878
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:706
msgctxt "@text:window"
msgid "We have found one or more G-Code files within the files you have selected. You can only open one G-Code file at a time. If you want to open a G-Code file, please just select only one."
msgstr "Löysimme vähintään yhden Gcode-tiedoston valitsemiesi tiedostojen joukosta. Voit avata vain yhden Gcode-tiedoston kerrallaan. Jos haluat avata Gcode-tiedoston, valitse vain yksi."
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:14
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:809
msgctxt "@title:window"
-msgid "Save Project"
-msgstr "Tallenna projekti"
+msgid "Add Printer"
+msgstr "Lisää tulostin"
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:137
-msgctxt "@action:label"
-msgid "Build plate"
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:817
+msgctxt "@title:window"
+msgid "What's New"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:169
-msgctxt "@action:label"
-msgid "Extruder %1"
-msgstr "Suulake %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:179
-msgctxt "@action:label"
-msgid "%1 & material"
-msgstr "%1 & materiaali"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:268
-msgctxt "@action:label"
-msgid "Don't show project summary on save again"
-msgstr "Älä näytä projektin yhteenvetoa tallennettaessa"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:287
-msgctxt "@action:button"
-msgid "Save"
-msgstr "Tallenna"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:192
-msgctxt "@label"
-msgid "Layer Height"
-msgstr "Kerroksen korkeus"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:277
-msgctxt "@tooltip"
-msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:450
-msgctxt "@tooltip"
-msgid "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab"
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:467
-msgctxt "@label"
-msgid "Print Speed"
-msgstr "Tulostusnopeus"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:479
-msgctxt "@label"
-msgid "Slower"
-msgstr "Hitaammin"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:490
-msgctxt "@label"
-msgid "Faster"
-msgstr "Nopeammin"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:518
-msgctxt "@tooltip"
-msgid "You have modified some profile settings. If you want to change these go to custom mode."
-msgstr ""
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:541
-msgctxt "@label"
-msgid "Infill"
-msgstr "Täyttö"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:777
-msgctxt "@label"
-msgid "Gradual infill will gradually increase the amount of infill towards the top."
-msgstr "Asteittainen täyttö lisää täytön tiheyttä vähitellen yläosaa kohti."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:791
-msgctxt "@label"
-msgid "Enable gradual"
-msgstr "Ota asteittainen käyttöön"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:858
-msgctxt "@label"
-msgid "Generate Support"
-msgstr "Muodosta tuki"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:892
-msgctxt "@label"
-msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
-msgstr "Muodosta rakenteita, jotka tukevat mallin ulokkeita sisältäviä osia. Ilman tukirakenteita kyseiset osat luhistuvat tulostuksen aikana."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:964
-msgctxt "@label"
-msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
-msgstr "Valitse tukena käytettävä suulakepuristin. Näin mallin alle rakennetaan tukirakenteita estämään mallin painuminen tai tulostuminen ilmaan."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:987
-msgctxt "@label"
-msgid "Build Plate Adhesion"
-msgstr "Alustan tarttuvuus"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1042
-msgctxt "@label"
-msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
-msgstr "Ota reunuksen tai pohjaristikon tulostus käyttöön. Tämä lisää kappaleen ympärille tai alle tasaisen alueen, joka on helppo leikata pois myöhemmin."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1082
-msgctxt "@label"
-msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
-msgstr "Tarvitsetko apua tulosteiden parantamiseen? Lue Ultimakerin vianmääritysoppaat"
-
#: /home/ruben/Projects/Cura/resources/qml/ExtruderButton.qml:16
msgctxt "@label %1 is filled in with the name of an extruder"
msgid "Print Selected Model with %1"
@@ -4436,74 +4402,500 @@ msgid_plural "Print Selected Models with %1"
msgstr[0] "Tulosta valittu malli asetuksella %1"
msgstr[1] "Tulosta valitut mallit asetuksella %1"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:20
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:15
+msgctxt "@title:window"
+msgid "Discard or Keep changes"
+msgstr "Hylkää tai säilytä muutokset"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:57
+msgctxt "@text:window"
+msgid ""
+"You have customized some profile settings.\n"
+"Would you like to keep or discard those settings?"
+msgstr ""
+"Olet mukauttanut profiilin asetuksia.\n"
+"Haluatko säilyttää vai hylätä nämä asetukset?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:110
+msgctxt "@title:column"
+msgid "Profile settings"
+msgstr "Profiilin asetukset"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:117
+msgctxt "@title:column"
+msgid "Default"
+msgstr "Oletusarvo"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:124
+msgctxt "@title:column"
+msgid "Customized"
+msgstr "Mukautettu"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:158
+msgctxt "@option:discardOrKeep"
+msgid "Discard and never ask again"
+msgstr "Hylkää äläkä kysy uudelleen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:159
+msgctxt "@option:discardOrKeep"
+msgid "Keep and never ask again"
+msgstr "Säilytä äläkä kysy uudelleen"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:196
+msgctxt "@action:button"
+msgid "Discard"
+msgstr "Hylkää"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:209
+msgctxt "@action:button"
+msgid "Keep"
+msgstr "Säilytä"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:222
+msgctxt "@action:button"
+msgid "Create New Profile"
+msgstr "Luo uusi profiili"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:15
+msgctxt "@title:window"
+msgid "About Cura"
+msgstr "Tietoja Curasta"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:57
+msgctxt "@label"
+msgid "version: %1"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:72
+msgctxt "@label"
+msgid "End-to-end solution for fused filament 3D printing."
+msgstr "Kokonaisvaltainen sulatettavan tulostuslangan 3D-tulostusratkaisu."
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:85
+msgctxt "@info:credit"
+msgid ""
+"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
+"Cura proudly uses the following open source projects:"
+msgstr ""
+"Cura-ohjelman on kehittänyt Ultimaker B.V. yhteistyössä käyttäjäyhteisön kanssa.\n"
+"Cura hyödyntää seuraavia avoimeen lähdekoodiin perustuvia projekteja:"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:135
+msgctxt "@label"
+msgid "Graphical user interface"
+msgstr "Graafinen käyttöliittymä"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:136
+msgctxt "@label"
+msgid "Application framework"
+msgstr "Sovelluskehys"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:137
+msgctxt "@label"
+msgid "G-code generator"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:138
+msgctxt "@label"
+msgid "Interprocess communication library"
+msgstr "Prosessien välinen tietoliikennekirjasto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:140
+msgctxt "@label"
+msgid "Programming language"
+msgstr "Ohjelmointikieli"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:141
+msgctxt "@label"
+msgid "GUI framework"
+msgstr "GUI-kehys"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:142
+msgctxt "@label"
+msgid "GUI framework bindings"
+msgstr "GUI-kehyksen sidonnat"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:143
+msgctxt "@label"
+msgid "C/C++ Binding library"
+msgstr "C/C++ -sidontakirjasto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:144
+msgctxt "@label"
+msgid "Data interchange format"
+msgstr "Data Interchange Format"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:145
+msgctxt "@label"
+msgid "Support library for scientific computing"
+msgstr "Tieteellisen laskennan tukikirjasto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:146
+msgctxt "@label"
+msgid "Support library for faster math"
+msgstr "Nopeamman laskennan tukikirjasto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:147
+msgctxt "@label"
+msgid "Support library for handling STL files"
+msgstr "STL-tiedostojen käsittelyn tukikirjasto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:148
+msgctxt "@label"
+msgid "Support library for handling planar objects"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:149
+msgctxt "@label"
+msgid "Support library for handling triangular meshes"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:150
+msgctxt "@label"
+msgid "Support library for analysis of complex networks"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:151
+msgctxt "@label"
+msgid "Support library for handling 3MF files"
+msgstr "Tukikirjasto 3MF-tiedostojen käsittelyyn"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:152
+msgctxt "@label"
+msgid "Support library for file metadata and streaming"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:153
+msgctxt "@label"
+msgid "Serial communication library"
+msgstr "Sarjatietoliikennekirjasto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:154
+msgctxt "@label"
+msgid "ZeroConf discovery library"
+msgstr "ZeroConf-etsintäkirjasto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:155
+msgctxt "@label"
+msgid "Polygon clipping library"
+msgstr "Monikulmion leikkauskirjasto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:156
+msgctxt "@Label"
+msgid "Python HTTP library"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:158
+msgctxt "@label"
+msgid "Font"
+msgstr "Fontti"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:159
+msgctxt "@label"
+msgid "SVG icons"
+msgstr "SVG-kuvakkeet"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:160
+msgctxt "@label"
+msgid "Linux cross-distribution application deployment"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:64
+msgctxt "@text:window"
+msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
+msgstr "Löysimme vähintään yhden projektitiedoston valitsemiesi tiedostojen joukosta. Voit avata vain yhden projektitiedoston kerrallaan. Suosittelemme, että tuot vain malleja niistä tiedostoista. Haluatko jatkaa?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:99
+msgctxt "@action:button"
+msgid "Import all as models"
+msgstr "Tuo kaikki malleina"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:15
+msgctxt "@title:window"
+msgid "Save Project"
+msgstr "Tallenna projekti"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:177
+msgctxt "@action:label"
+msgid "Extruder %1"
+msgstr "Suulake %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:192
+msgctxt "@action:label"
+msgid "%1 & material"
+msgstr "%1 & materiaali"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:194
+msgctxt "@action:label"
+msgid "Material"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:283
+msgctxt "@action:label"
+msgid "Don't show project summary on save again"
+msgstr "Älä näytä projektin yhteenvetoa tallennettaessa"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:302
+msgctxt "@action:button"
+msgid "Save"
+msgstr "Tallenna"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:20
msgctxt "@title:window"
msgid "Open project file"
msgstr "Avaa projektitiedosto"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:93
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:93
msgctxt "@text:window"
msgid "This is a Cura project file. Would you like to open it as a project or import the models from it?"
msgstr "Tämä on Cura-projektitiedosto. Haluatko avata sen projektina vai tuoda siinä olevat mallit?"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:103
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:103
msgctxt "@text:window"
msgid "Remember my choice"
msgstr "Muista valintani"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:122
msgctxt "@action:button"
msgid "Open as project"
msgstr "Avaa projektina"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:131
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:131
msgctxt "@action:button"
msgid "Import models"
msgstr "Tuo mallit"
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15
-msgctxt "@title:window"
-msgid "Engine Log"
-msgstr "Moottorin loki"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:70
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DropDownWidget.qml:93
msgctxt "@label"
-msgid "Printer type"
+msgid "Empty"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:376
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:24
msgctxt "@label"
-msgid "Material"
-msgstr "Materiaali"
+msgid "Add a printer"
+msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:543
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:39
msgctxt "@label"
-msgid "Use glue with this material combination"
+msgid "Add a networked printer"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:575
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:81
msgctxt "@label"
-msgid "Check compatibility"
+msgid "Add a non-networked printer"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:593
-msgctxt "@tooltip"
-msgid "Click to check the material compatibility on Ultimaker.com."
-msgstr "Napsauta ja tarkista materiaalin yhteensopivuus sivustolla Ultimaker.com."
-
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:211
-msgctxt "@option:check"
-msgid "See only current build plate"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:70
+msgctxt "@label"
+msgid "Add printer by IP address"
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:227
-msgctxt "@action:button"
-msgid "Arrange to all build plates"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:133
+msgctxt "@text"
+msgid "Place enter your printer's IP address."
msgstr ""
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:247
-msgctxt "@action:button"
-msgid "Arrange current build plate"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:158
+msgctxt "@button"
+msgid "Add"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:204
+msgctxt "@label"
+msgid "Could not connect to device."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:208
+msgctxt "@label"
+msgid "The printer at this address has not responded yet."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:240
+msgctxt "@label"
+msgid "This printer cannot be added because it's an unknown printer or it's not the host of a group."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:329
+msgctxt "@button"
+msgid "Back"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:342
+msgctxt "@button"
+msgid "Connect"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/FirstStartMachineActionsContent.qml:77
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:123
+msgctxt "@button"
+msgid "Next"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:23
+msgctxt "@label"
+msgid "User Agreement"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:56
+msgctxt "@button"
+msgid "Agree"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:70
+msgctxt "@button"
+msgid "Decline and close"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:24
+msgctxt "@label"
+msgid "Help us to improve Ultimaker Cura"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:57
+msgctxt "@text"
+msgid "Ultimaker Cura collects anonymous data to improve print quality and user experience, including:"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:71
+msgctxt "@text"
+msgid "Machine types"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:77
+msgctxt "@text"
+msgid "Material usage"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:83
+msgctxt "@text"
+msgid "Number of slices"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:89
+msgctxt "@text"
+msgid "Print settings"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:102
+msgctxt "@text"
+msgid "Data collected by Ultimaker Cura will not contain any personal information."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:103
+msgctxt "@text"
+msgid "More information"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WhatsNewContent.qml:24
+msgctxt "@label"
+msgid "What's new in Ultimaker Cura"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:42
+msgctxt "@label"
+msgid "There is no printer found over your network."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:179
+msgctxt "@label"
+msgid "Refresh"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:190
+msgctxt "@label"
+msgid "Add printer by IP"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:223
+msgctxt "@label"
+msgid "Troubleshooting"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:211
+msgctxt "@label"
+msgid "Printer name"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:224
+msgctxt "@text"
+msgid "Please give your printer a name"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:36
+msgctxt "@label"
+msgid "Ultimaker Cloud"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:77
+msgctxt "@text"
+msgid "The next generation 3D printing workflow"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:94
+msgctxt "@text"
+msgid "- Send print jobs to Ultimaker printers outside your local network"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:97
+msgctxt "@text"
+msgid "- Store your Ultimaker Cura settings in the cloud for use anywhere"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:100
+msgctxt "@text"
+msgid "- Get exclusive access to print profiles from leading brands"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:119
+msgctxt "@button"
+msgid "Finish"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:128
+msgctxt "@button"
+msgid "Create an account"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:29
+msgctxt "@label"
+msgid "Welcome to Ultimaker Cura"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:47
+msgctxt "@text"
+msgid ""
+"Please follow these steps to set up\n"
+"Ultimaker Cura. This will only take a few moments."
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:58
+msgctxt "@button"
+msgid "Get started"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:27
+msgctxt "@info:tooltip"
+msgid "3D View"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:40
+msgctxt "@info:tooltip"
+msgid "Front View"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:53
+msgctxt "@info:tooltip"
+msgid "Top View"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:66
+msgctxt "@info:tooltip"
+msgid "Left View"
+msgstr ""
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:79
+msgctxt "@info:tooltip"
+msgid "Right View"
msgstr ""
#: MachineSettingsAction/plugin.json
@@ -4566,26 +4958,6 @@ msgctxt "name"
msgid "Model Checker"
msgstr ""
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "description"
-msgid "Dump the contents of all settings to a HTML file."
-msgstr "Vedosta kaikkien asetusten sisällöt HTML-tiedostoon."
-
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "name"
-msgid "God Mode"
-msgstr "Jumala-tila"
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "description"
-msgid "Shows changes since latest checked version."
-msgstr "Näyttää viimeisimmän tarkistetun version jälkeen tapahtuneet muutokset."
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "name"
-msgid "Changelog"
-msgstr "Muutosloki"
-
#: FirmwareUpdater/plugin.json
msgctxt "description"
msgid "Provides a machine actions for updating firmware."
@@ -4596,15 +4968,15 @@ msgctxt "name"
msgid "Firmware Updater"
msgstr ""
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "description"
-msgid "Create a flattend quality changes profile."
-msgstr "Luo tasoitettu laatumuutosten profiili."
+msgid "Provides support for reading AMF files."
+msgstr ""
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "name"
-msgid "Profile flatener"
-msgstr "Profiilin tasoitus"
+msgid "AMF Reader"
+msgstr ""
#: USBPrinting/plugin.json
msgctxt "description"
@@ -4616,26 +4988,6 @@ msgctxt "name"
msgid "USB printing"
msgstr "USB-tulostus"
-#: UserAgreement/plugin.json
-msgctxt "description"
-msgid "Ask the user once if he/she agrees with our license."
-msgstr ""
-
-#: UserAgreement/plugin.json
-msgctxt "name"
-msgid "UserAgreement"
-msgstr ""
-
-#: X3GWriter/plugin.json
-msgctxt "description"
-msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
-msgstr ""
-
-#: X3GWriter/plugin.json
-msgctxt "name"
-msgid "X3GWriter"
-msgstr ""
-
#: GCodeGzWriter/plugin.json
msgctxt "description"
msgid "Writes g-code to a compressed archive."
@@ -4678,13 +5030,13 @@ msgstr "Irrotettavan aseman tulostusvälineen laajennus"
#: UM3NetworkPrinting/plugin.json
msgctxt "description"
-msgid "Manages network connections to Ultimaker 3 printers."
+msgid "Manages network connections to Ultimaker networked printers."
msgstr ""
#: UM3NetworkPrinting/plugin.json
msgctxt "name"
-msgid "UM3 Network Connection"
-msgstr "UM3-verkkoyhteys"
+msgid "Ultimaker Network Connection"
+msgstr ""
#: MonitorStage/plugin.json
msgctxt "description"
@@ -4746,6 +5098,16 @@ msgctxt "name"
msgid "Support Eraser"
msgstr ""
+#: UFPReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading Ultimaker Format Packages."
+msgstr ""
+
+#: UFPReader/plugin.json
+msgctxt "name"
+msgid "UFP Reader"
+msgstr ""
+
#: SliceInfoPlugin/plugin.json
msgctxt "description"
msgid "Submits anonymous slice info. Can be disabled through preferences."
@@ -4806,6 +5168,16 @@ msgctxt "name"
msgid "Version Upgrade 3.3 to 3.4"
msgstr ""
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.3 to Cura 4.4."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.3 to 4.4"
+msgstr ""
+
#: VersionUpgrade/VersionUpgrade25to26/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.5 to Cura 2.6."
@@ -4826,6 +5198,16 @@ msgctxt "name"
msgid "Version Upgrade 2.7 to 3.0"
msgstr "Päivitys versiosta 2.7 versioon 3.0"
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 3.5 to Cura 4.0."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 3.5 to 4.0"
+msgstr ""
+
#: VersionUpgrade/VersionUpgrade34to35/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.4 to Cura 3.5."
@@ -4836,6 +5218,16 @@ msgctxt "name"
msgid "Version Upgrade 3.4 to 3.5"
msgstr ""
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.0 to Cura 4.1."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.0 to 4.1"
+msgstr ""
+
#: VersionUpgrade/VersionUpgrade30to31/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.0 to Cura 3.1."
@@ -4846,6 +5238,16 @@ msgctxt "name"
msgid "Version Upgrade 3.0 to 3.1"
msgstr ""
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.1 to Cura 4.2."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.1 to 4.2"
+msgstr ""
+
#: VersionUpgrade/VersionUpgrade26to27/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.6 to Cura 2.7."
@@ -4876,6 +5278,16 @@ msgctxt "name"
msgid "Version Upgrade 2.2 to 2.4"
msgstr "Päivitys versiosta 2.2 versioon 2.4"
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.2 to Cura 4.3."
+msgstr ""
+
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.2 to 4.3"
+msgstr ""
+
#: ImageReader/plugin.json
msgctxt "description"
msgid "Enables ability to generate printable geometry from 2D image files."
@@ -4886,6 +5298,16 @@ msgctxt "name"
msgid "Image Reader"
msgstr "Kuvanlukija"
+#: TrimeshReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading model files."
+msgstr ""
+
+#: TrimeshReader/plugin.json
+msgctxt "name"
+msgid "Trimesh Reader"
+msgstr ""
+
#: CuraEngineBackend/plugin.json
msgctxt "description"
msgid "Provides the link to the CuraEngine slicing backend."
@@ -4936,6 +5358,16 @@ msgctxt "name"
msgid "G-code Reader"
msgstr "GCode-lukija"
+#: CuraDrive/plugin.json
+msgctxt "description"
+msgid "Backup and restore your configuration."
+msgstr ""
+
+#: CuraDrive/plugin.json
+msgctxt "name"
+msgid "Cura Backups"
+msgstr ""
+
#: CuraProfileWriter/plugin.json
msgctxt "description"
msgid "Provides support for exporting Cura profiles."
@@ -4956,6 +5388,16 @@ msgctxt "name"
msgid "3MF Writer"
msgstr "3MF-kirjoitin"
+#: PreviewStage/plugin.json
+msgctxt "description"
+msgid "Provides a preview stage in Cura."
+msgstr ""
+
+#: PreviewStage/plugin.json
+msgctxt "name"
+msgid "Preview Stage"
+msgstr ""
+
#: UltimakerMachineActions/plugin.json
msgctxt "description"
msgid "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.)."
@@ -4976,6 +5418,447 @@ msgctxt "name"
msgid "Cura Profile Reader"
msgstr "Cura-profiilin lukija"
+#~ msgctxt "@item:inmenu"
+#~ msgid "Flatten active settings"
+#~ msgstr "Aktivoitujen asetusten tasoitus"
+
+#~ msgctxt "@info:status"
+#~ msgid "Profile has been flattened & activated."
+#~ msgstr "Profiili on tasoitettu ja aktivoitu."
+
+#~ msgctxt "X3G Writer File Description"
+#~ msgid "X3G File"
+#~ msgstr "X3G-tiedosto"
+
+#~ msgctxt "@action:button"
+#~ msgid "Retry"
+#~ msgstr "Yritä uudelleen"
+
+#~ msgctxt "@action:ComboBox option"
+#~ msgid "Update existing"
+#~ msgstr "Päivitä nykyinen"
+
+#~ msgctxt "@label"
+#~ msgid "Please select any upgrades made to this Ultimaker 2."
+#~ msgstr "Valitse tähän Ultimaker 2 -laitteeseen tehdyt päivitykset."
+
+#~ msgctxt "@label"
+#~ msgid "Olsson Block"
+#~ msgstr "Olsson Block -lämmitysosa"
+
+#~ msgctxt "@label"
+#~ msgid "Layer Height"
+#~ msgstr "Kerroksen korkeus"
+
+#~ msgctxt "@title:settings"
+#~ msgid "&Profile"
+#~ msgstr "&Profiili"
+
+#~ msgctxt "description"
+#~ msgid "Dump the contents of all settings to a HTML file."
+#~ msgstr "Vedosta kaikkien asetusten sisällöt HTML-tiedostoon."
+
+#~ msgctxt "name"
+#~ msgid "God Mode"
+#~ msgstr "Jumala-tila"
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network."
+#~ msgstr "Yhdistetty verkon kautta tulostimeen."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. Please approve the access request on the printer."
+#~ msgstr "Yhdistetty verkon kautta. Hyväksy tulostimen käyttöoikeuspyyntö."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. No access to control the printer."
+#~ msgstr "Yhdistetty verkon kautta tulostimeen. Ei käyttöoikeutta tulostimen hallintaan."
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer requested. Please approve the request on the printer"
+#~ msgstr "Tulostimen käyttöoikeutta pyydetty. Hyväksy tulostimen pyyntö"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Re-send the access request"
+#~ msgstr "Lähetä käyttöoikeuspyyntö uudelleen"
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer accepted"
+#~ msgstr "Tulostimen käyttöoikeus hyväksytty"
+
+#~ msgctxt "@info:status"
+#~ msgid "No access to print with this printer. Unable to send print job."
+#~ msgstr "Tällä tulostimella tulostukseen ei ole käyttöoikeutta. Tulostustyön lähetys ei onnistu."
+
+#~ msgctxt "@action:button"
+#~ msgid "Request Access"
+#~ msgstr "Pyydä käyttöoikeutta"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Send access request to the printer"
+#~ msgstr "Lähetä tulostimen käyttöoikeuspyyntö"
+
+#~ msgctxt "@window:title"
+#~ msgid "Mismatched configuration"
+#~ msgstr "Ristiriitainen määritys"
+
+#~ msgctxt "@label"
+#~ msgid "Are you sure you wish to print with the selected configuration?"
+#~ msgstr "Haluatko varmasti tulostaa valitulla määrityksellä?"
+
+#~ msgctxt "@label"
+#~ msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "Tulostimen ja Curan määrityksen tai kalibroinnin välillä on ristiriita. Parhaat tulokset saavutetaan viipaloimalla aina tulostimeen asetetuille PrintCoreille ja materiaaleille."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending new jobs (temporarily) blocked, still sending the previous print job."
+#~ msgstr "Uusien töiden lähettäminen (tilapäisesti) estetty, edellistä tulostustyötä lähetetään vielä."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending data to printer"
+#~ msgstr "Lähetetään tietoja tulostimeen"
+
+#~ msgctxt "@info:title"
+#~ msgid "Sending Data"
+#~ msgstr "Lähetetään tietoja"
+
+#~ msgctxt "@label"
+#~ msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
+#~ msgstr "Eri materiaali (Cura: {0}, tulostin: {1}) valittu suulakkeelle {2}"
+
+#~ msgctxt "@window:title"
+#~ msgid "Sync with your printer"
+#~ msgstr "Synkronoi tulostimen kanssa"
+
+#~ msgctxt "@label"
+#~ msgid "Would you like to use your current printer configuration in Cura?"
+#~ msgstr "Haluatko käyttää nykyistä tulostimen määritystä Curassa?"
+
+#~ msgctxt "@label"
+#~ msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "Tulostimen PrintCoret tai materiaalit eivät vastaa tulostettavan projektin asetuksia. Parhaat tulokset saavutetaan viipaloimalla aina tulostimeen asetetuille PrintCoreille ja materiaaleille."
+
+#~ msgctxt "@info:status"
+#~ msgid "Printer '{printer_name}' has finished printing '{job_name}'."
+#~ msgstr "{printer_name} on tulostanut työn '{job_name}'."
+
+#~ msgctxt "@info:status"
+#~ msgid "Print finished"
+#~ msgstr "Tulosta valmis"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Connect to a printer"
+#~ msgstr "Yhdistä tulostimeen"
+
+#~ msgctxt "name"
+#~ msgid "UM3 Network Connection"
+#~ msgstr "UM3-verkkoyhteys"
+
+#~ msgctxt "@label"
+#~ msgid ""
+#~ "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
+#~ "\n"
+#~ "Select your printer from the list below:"
+#~ msgstr ""
+#~ "Tulosta suoraan tulostimeen verkon kautta yhdistämällä tulostin verkkoon verkkokaapelilla tai yhdistämällä tulostin Wi-Fi-verkkoon. Jos Curaa ei yhdistetä tulostimeen, GCode-tiedostot voidaan silti siirtää tulostimeen USB-aseman avulla.\n"
+#~ "\n"
+#~ "Valitse tulostin alla olevasta luettelosta:"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Show Changelog"
+#~ msgstr "Näytä muutosloki"
+
+#~ msgctxt "@info:title"
+#~ msgid "Collecting Data"
+#~ msgstr "Kerätään tietoja"
+
+#~ msgctxt "@title"
+#~ msgid "Machine Settings"
+#~ msgstr "Laitteen asetukset"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Settings"
+#~ msgstr "Tulostimen asetukset"
+
+#~ msgctxt "@option:check"
+#~ msgid "Origin at center"
+#~ msgstr "Alkukohta keskellä"
+
+#~ msgctxt "@option:check"
+#~ msgid "Heated bed"
+#~ msgstr "Lämmitettävä pöytä"
+
+#~ msgctxt "@label"
+#~ msgid "Printhead Settings"
+#~ msgstr "Tulostuspään asetukset"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Etäisyys tulostuspään vasemmalta puolelta suuttimen keskikohtaan. Käytetään estämään aiempien tulosteiden ja tulostuspään yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Etäisyys tulostuspään etupuolelta suuttimen keskikohtaan. Käytetään estämään aiempien tulosteiden ja tulostuspään yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Etäisyys tulostuspään oikealta puolelta suuttimen keskikohtaan. Käytetään estämään aiempien tulosteiden ja tulostuspään yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Etäisyys tulostuspään takapuolelta suuttimen keskikohtaan. Käytetään estämään aiempien tulosteiden ja tulostuspään yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
+
+#~ msgctxt "@label"
+#~ msgid "Gantry height"
+#~ msgstr "Korokkeen korkeus"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
+#~ msgstr "Suuttimen kärjen ja korokejärjestelmän (X- ja Y-akselit) välinen korkeusero. Käytetään estämään aiempien tulosteiden ja korokkeen yhteentörmäyksiä, kun tulostetaan yksi kerrallaan."
+
+#~ msgctxt "@label"
+#~ msgid "Nozzle Settings"
+#~ msgstr "Suutinasetukset"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
+#~ msgstr "Tulostimen tukema tulostuslangan nimellinen halkaisija. Materiaali ja/tai profiili korvaa tarkan halkaisijan."
+
+#~ msgctxt "@label"
+#~ msgid "Changelog"
+#~ msgstr "Muutosloki"
+
+#~ msgctxt "@alabel"
+#~ msgid "Enter the IP address or hostname of your printer on the network."
+#~ msgstr "Anna verkon tulostimen IP-osoite tai isäntänimi."
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
+#~ msgstr "Oletuksena valkoiset pikselit edustavat verkossa korkeita pisteitä ja mustat pikselit edustavat verkossa matalia pisteitä. Muuta asetus, jos haluat, että mustat pikselit edustavat verkossa korkeita pisteitä ja valkoiset pikselit edustavat verkossa matalia pisteitä."
+
+#~ msgctxt "@title"
+#~ msgid "Select Printer Upgrades"
+#~ msgstr "Valitse tulostimen päivitykset"
+
+#~ msgctxt "@label"
+#~ msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
+#~ msgstr "Valitse tukena käytettävä suulakepuristin. Näin mallin alle rakennetaan tukirakenteita estämään mallin painuminen tai tulostuminen ilmaan."
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Unable to Slice"
+#~ msgstr "Viipalointi ei onnistu"
+
+#~ msgctxt "@action:button"
+#~ msgid "Add Printer"
+#~ msgstr "Lisää tulostin"
+
+#~ msgid "Modify G-Code"
+#~ msgstr "Muokkaa GCode-arvoa"
+
+#~ msgctxt "@info:status"
+#~ msgid "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."
+#~ msgstr "Ei viipaloitavaa, koska mikään malleista ei sovellu tulostustilavuuteen. Skaalaa tai pyöritä mallia, kunnes se on sopiva."
+
+#~ msgctxt "@info:status"
+#~ msgid "The selected material is incompatible with the selected machine or configuration."
+#~ msgstr "Valittu materiaali ei sovellu käytettäväksi valitun laitteen tai kokoonpanon kanssa."
+
+#~ msgctxt "@info:title"
+#~ msgid "Incompatible Material"
+#~ msgstr "Yhteensopimaton materiaali"
+
+#~ msgctxt "@info:status Don't translate the XML tags or !"
+#~ msgid "Failed to import profile from {0}: {1}"
+#~ msgstr "Profiilin tuonti epäonnistui tiedostosta {0}: {1}"
+
+#~ msgctxt "@label:status"
+#~ msgid "Preparing"
+#~ msgstr "Valmistellaan"
+
+#~ msgctxt "@label"
+#~ msgid "Printing"
+#~ msgstr "Tulostetaan"
+
+#~ msgctxt "@action:button"
+#~ msgid "Activate Configuration"
+#~ msgstr "Aktivoi määritys"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Load the configuration of the printer into Cura"
+#~ msgstr "Lataa tulostimen määritys Curaan"
+
+#~ msgctxt "@label"
+#~ msgid "Show Travels"
+#~ msgstr "Näytä siirtoliikkeet"
+
+#~ msgctxt "@label"
+#~ msgid "Show Helpers"
+#~ msgstr "Näytä avustimet"
+
+#~ msgctxt "@label"
+#~ msgid "Show Shell"
+#~ msgstr "Näytä kuori"
+
+#~ msgctxt "@label"
+#~ msgid "Show Infill"
+#~ msgstr "Näytä täyttö"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type:"
+#~ msgstr "Tulostimen tyyppi:"
+
+#~ msgctxt "@label"
+#~ msgid "Connection:"
+#~ msgstr "Yhteys:"
+
+#~ msgctxt "@label"
+#~ msgid "State:"
+#~ msgstr "Tila:"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for a printjob"
+#~ msgstr "Odotetaan tulostustyötä"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for someone to clear the build plate"
+#~ msgstr "Odotetaan tulostusalustan tyhjennystä"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Aborting print..."
+#~ msgstr "Keskeytetään tulostus..."
+
+#~ msgctxt "@label"
+#~ msgid "Protected profiles"
+#~ msgstr "Suojatut profiilit"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Name:"
+#~ msgstr "Tulostimen nimi:"
+
+#~ msgctxt "@label"
+#~ msgid "Profile:"
+#~ msgstr "Profiili:"
+
+#~ msgctxt "@label:textbox"
+#~ msgid "Search..."
+#~ msgstr "Haku..."
+
+#~ msgctxt "@label:listbox"
+#~ msgid "Print Setup"
+#~ msgstr "Tulostuksen asennus"
+
+#~ msgctxt "@label:listbox"
+#~ msgid ""
+#~ "Print Setup disabled\n"
+#~ "G-code files cannot be modified"
+#~ msgstr ""
+#~ "Tulostuksen asennus ei käytössä\n"
+#~ "G-code-tiedostoja ei voida muokata"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
+#~ msgstr "Suositeltu tulostuksen asennus
Tulosta valitun tulostimen, materiaalin ja laadun suositelluilla asetuksilla."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
+#~ msgstr "Mukautettu tulostuksen asennus
Tulosta hallitsemalla täysin kaikkia viipalointiprosessin vaiheita."
+
+#~ msgctxt "@action:inmenu menubar:help"
+#~ msgid "Show Engine &Log..."
+#~ msgstr "Näytä moottorin l&oki"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Please load a 3D model"
+#~ msgstr "Lataa 3D-malli"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Ready to slice"
+#~ msgstr "Valmiina viipaloimaan"
+
+#~ msgctxt "@label:PrintjobStatus %1 is target operation"
+#~ msgid "Ready to %1"
+#~ msgstr "Valmis: %1"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Slicing unavailable"
+#~ msgstr "Viipalointi ei käytettävissä"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Prepare"
+#~ msgstr "Valmistele"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Cancel"
+#~ msgstr "Peruuta"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Select the active output device"
+#~ msgstr "Valitse aktiivinen tulostusväline"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&View"
+#~ msgstr "&Näytä"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Settings"
+#~ msgstr "&Asetukset"
+
+#~ msgctxt "@action:button"
+#~ msgid "Open File"
+#~ msgstr "Avaa tiedosto"
+
+#~ msgctxt "@label"
+#~ msgid "Print Speed"
+#~ msgstr "Tulostusnopeus"
+
+#~ msgctxt "@label"
+#~ msgid "Slower"
+#~ msgstr "Hitaammin"
+
+#~ msgctxt "@label"
+#~ msgid "Faster"
+#~ msgstr "Nopeammin"
+
+#~ msgctxt "@label"
+#~ msgid "Enable gradual"
+#~ msgstr "Ota asteittainen käyttöön"
+
+#~ msgctxt "@label"
+#~ msgid "Generate Support"
+#~ msgstr "Muodosta tuki"
+
+#~ msgctxt "@label"
+#~ msgid "Build Plate Adhesion"
+#~ msgstr "Alustan tarttuvuus"
+
+#~ msgctxt "@label"
+#~ msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
+#~ msgstr "Tarvitsetko apua tulosteiden parantamiseen? Lue Ultimakerin vianmääritysoppaat"
+
+#~ msgctxt "@title:window"
+#~ msgid "Engine Log"
+#~ msgstr "Moottorin loki"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Click to check the material compatibility on Ultimaker.com."
+#~ msgstr "Napsauta ja tarkista materiaalin yhteensopivuus sivustolla Ultimaker.com."
+
+#~ msgctxt "description"
+#~ msgid "Shows changes since latest checked version."
+#~ msgstr "Näyttää viimeisimmän tarkistetun version jälkeen tapahtuneet muutokset."
+
+#~ msgctxt "name"
+#~ msgid "Changelog"
+#~ msgstr "Muutosloki"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattend quality changes profile."
+#~ msgstr "Luo tasoitettu laatumuutosten profiili."
+
+#~ msgctxt "name"
+#~ msgid "Profile flatener"
+#~ msgstr "Profiilin tasoitus"
+
#~ msgctxt "@action"
#~ msgid "Upgrade Firmware"
#~ msgstr "Päivitä laiteohjelmisto"
@@ -5106,7 +5989,7 @@ msgstr "Cura-profiilin lukija"
#~ msgctxt "@title:menu menubar:file"
#~ msgid "Save &As..."
-#~ msgstr "Tallenna &nimellä…"
+#~ msgstr "Tallenna &nimellä..."
#~ msgctxt "description"
#~ msgid "Accepts G-Code and sends them over WiFi to a Doodle3D WiFi-Box."
diff --git a/resources/i18n/fi_FI/fdmextruder.def.json.po b/resources/i18n/fi_FI/fdmextruder.def.json.po
index 07ccc2502e..86dd3b3474 100644
--- a/resources/i18n/fi_FI/fdmextruder.def.json.po
+++ b/resources/i18n/fi_FI/fdmextruder.def.json.po
@@ -1,13 +1,13 @@
# Cura JSON setting files
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
"PO-Revision-Date: 2017-08-11 14:31+0200\n"
"Last-Translator: Bothof \n"
"Language-Team: Finnish\n"
@@ -83,8 +83,8 @@ msgstr "Suulakkeen aloitus-GCode"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_code description"
-msgid "Start g-code to execute whenever turning the extruder on."
-msgstr "Aloitus-GCode, joka suoritetaan suulakkeen käynnistyksen yhteydessä."
+msgid "Start g-code to execute when switching to this extruder."
+msgstr ""
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_abs label"
@@ -123,8 +123,8 @@ msgstr "Suulakkeen lopetus-GCode"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_code description"
-msgid "End g-code to execute whenever turning the extruder off."
-msgstr "Lopetus-GCode, joka suoritetaan, kun suulake poistetaan käytöstä."
+msgid "End g-code to execute when switching away from this extruder."
+msgstr ""
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_abs label"
@@ -225,3 +225,11 @@ msgstr ""
msgctxt "material_diameter description"
msgid "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament."
msgstr ""
+
+#~ msgctxt "machine_extruder_start_code description"
+#~ msgid "Start g-code to execute whenever turning the extruder on."
+#~ msgstr "Aloitus-GCode, joka suoritetaan suulakkeen käynnistyksen yhteydessä."
+
+#~ msgctxt "machine_extruder_end_code description"
+#~ msgid "End g-code to execute whenever turning the extruder off."
+#~ msgstr "Lopetus-GCode, joka suoritetaan, kun suulake poistetaan käytöstä."
diff --git a/resources/i18n/fi_FI/fdmprinter.def.json.po b/resources/i18n/fi_FI/fdmprinter.def.json.po
index 6a4e7390ad..3f1b71753b 100644
--- a/resources/i18n/fi_FI/fdmprinter.def.json.po
+++ b/resources/i18n/fi_FI/fdmprinter.def.json.po
@@ -1,13 +1,13 @@
# Cura JSON setting files
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
"PO-Revision-Date: 2017-09-27 12:27+0200\n"
"Last-Translator: Bothof \n"
"Language-Team: Finnish\n"
@@ -210,6 +210,16 @@ msgctxt "machine_heated_bed description"
msgid "Whether the machine has a heated build plate present."
msgstr "Sisältääkö laite lämmitettävän alustan."
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume label"
+msgid "Has Build Volume Temperature Stabilization"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume description"
+msgid "Whether the machine is able to stabilize the build volume temperature."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "machine_center_is_zero label"
msgid "Is Center Origin"
@@ -232,7 +242,7 @@ msgstr "Suulakeryhmien määrä. Suulakeryhmä on syöttölaitteen, Bowden-putke
#: fdmprinter.def.json
msgctxt "extruders_enabled_count label"
-msgid "Number of Extruders that are enabled"
+msgid "Number of Extruders That Are Enabled"
msgstr ""
#: fdmprinter.def.json
@@ -242,8 +252,8 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter label"
-msgid "Outer nozzle diameter"
-msgstr "Suuttimen ulkoläpimitta"
+msgid "Outer Nozzle Diameter"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter description"
@@ -252,8 +262,8 @@ msgstr "Suuttimen kärjen ulkoläpimitta."
#: fdmprinter.def.json
msgctxt "machine_nozzle_head_distance label"
-msgid "Nozzle length"
-msgstr "Suuttimen pituus"
+msgid "Nozzle Length"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_head_distance description"
@@ -262,8 +272,8 @@ msgstr "Suuttimen kärjen ja tulostuspään alimman osan välinen korkeusero."
#: fdmprinter.def.json
msgctxt "machine_nozzle_expansion_angle label"
-msgid "Nozzle angle"
-msgstr "Suuttimen kulma"
+msgid "Nozzle Angle"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_expansion_angle description"
@@ -272,8 +282,8 @@ msgstr "Vaakatason ja suuttimen kärjen yllä olevan kartiomaisen osan välinen
#: fdmprinter.def.json
msgctxt "machine_heat_zone_length label"
-msgid "Heat zone length"
-msgstr "Lämpöalueen pituus"
+msgid "Heat Zone Length"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_heat_zone_length description"
@@ -302,8 +312,8 @@ msgstr "Lämpötilan hallinta Curan kautta. Kytke tämä pois, niin voit hallita
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed label"
-msgid "Heat up speed"
-msgstr "Lämpenemisnopeus"
+msgid "Heat Up Speed"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed description"
@@ -312,8 +322,8 @@ msgstr "Nopeus (°C/s), jolla suutin lämpenee, mitattuna keskiarvona normaaleis
#: fdmprinter.def.json
msgctxt "machine_nozzle_cool_down_speed label"
-msgid "Cool down speed"
-msgstr "Jäähdytysnopeus"
+msgid "Cool Down Speed"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_nozzle_cool_down_speed description"
@@ -332,7 +342,7 @@ msgstr "Minimiaika, jonka suulakkeen on oltava ei-aktiivinen, ennen kuin suutin
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor label"
-msgid "G-code flavour"
+msgid "G-code Flavor"
msgstr ""
#: fdmprinter.def.json
@@ -397,8 +407,8 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
-msgid "Disallowed areas"
-msgstr "Kielletyt alueet"
+msgid "Disallowed Areas"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas description"
@@ -417,8 +427,8 @@ msgstr "Monikulmioluettelo, jossa on alueet, joihin suutin ei saa siirtyä."
#: fdmprinter.def.json
msgctxt "machine_head_polygon label"
-msgid "Machine head polygon"
-msgstr "Laiteen pään monikulmio"
+msgid "Machine Head Polygon"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_head_polygon description"
@@ -427,8 +437,8 @@ msgstr "2D-siluetti tulostuspäästä (tuulettimen kannattimet pois lukien)"
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon label"
-msgid "Machine head & Fan polygon"
-msgstr "Laiteen pään ja tuulettimen monikulmio"
+msgid "Machine Head & Fan Polygon"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon description"
@@ -437,8 +447,8 @@ msgstr "2D-siluetti tulostuspäästä (tuulettimen päät mukaan lukien)"
#: fdmprinter.def.json
msgctxt "gantry_height label"
-msgid "Gantry height"
-msgstr "Korokkeen korkeus"
+msgid "Gantry Height"
+msgstr ""
#: fdmprinter.def.json
msgctxt "gantry_height description"
@@ -467,8 +477,8 @@ msgstr "Suuttimen sisäläpimitta. Muuta tätä asetusta, kun käytössä on muu
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords label"
-msgid "Offset With Extruder"
-msgstr "Suulakkeen siirtymä"
+msgid "Offset with Extruder"
+msgstr ""
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords description"
@@ -1015,6 +1025,16 @@ msgctxt "bottom_layers description"
msgid "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number."
msgstr "Alakerrosten lukumäärä. Kun se lasketaan alaosan paksuudesta, arvo pyöristetään kokonaislukuun."
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers label"
+msgid "Initial Bottom Layers"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers description"
+msgid "The number of initial bottom layers, from the build-plate upwards. When calculated by the bottom thickness, this value is rounded to a whole number."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "top_bottom_pattern label"
msgid "Top/Bottom Pattern"
@@ -1265,6 +1285,56 @@ msgctxt "z_seam_type option sharpest_corner"
msgid "Sharpest Corner"
msgstr "Terävin kulma"
+#: fdmprinter.def.json
+msgctxt "z_seam_position label"
+msgid "Z Seam Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position description"
+msgid "The position near where to start printing each part in a layer."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backleft"
+msgid "Back Left"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option back"
+msgid "Back"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backright"
+msgid "Back Right"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option right"
+msgid "Right"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontright"
+msgid "Front Right"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option front"
+msgid "Front"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontleft"
+msgid "Front Left"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option left"
+msgid "Left"
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "z_seam_x label"
msgid "Z Seam X"
@@ -1292,8 +1362,8 @@ msgstr "Saumakulmien asetus"
#: fdmprinter.def.json
msgctxt "z_seam_corner description"
-msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
-msgstr "Määritä, vaikuttavatko mallin ulkolinjan kulmat sauman sijaintiin. Ei mitään tarkoittaa, että kulmilla ei ole vaikutusta sauman sijaintiin. Piilota sauma -valinnalla sauman sijainti sisäkulmassa on todennäköisempää. Paljasta sauma -valinnalla sauman sijainti ulkokulmassa on todennäköisempää. Piilota tai paljasta sauma -valinnalla sauman sijainti sisä- tai ulkokulmassa on todennäköisempää."
+msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner. Smart Hiding allows both inside and outside corners, but chooses inside corners more frequently, if appropriate."
+msgstr ""
#: fdmprinter.def.json
msgctxt "z_seam_corner option z_seam_corner_none"
@@ -1315,6 +1385,11 @@ msgctxt "z_seam_corner option z_seam_corner_any"
msgid "Hide or Expose Seam"
msgstr "Piilota tai paljasta sauma"
+#: fdmprinter.def.json
+msgctxt "z_seam_corner option z_seam_corner_weighted"
+msgid "Smart Hiding"
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "z_seam_relative label"
msgid "Z Seam Relative"
@@ -1327,13 +1402,13 @@ msgstr "Kun tämä on käytössä, Z-sauman koordinaatit ovat suhteessa kunkin o
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic label"
-msgid "Ignore Small Z Gaps"
-msgstr "Ohita pienet Z-raot"
+msgid "No Skin in Z Gaps"
+msgstr ""
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic description"
-msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
-msgstr "Kun mallissa on pieniä pystyrakoja, ylä- ja alapuolen pintakalvon tekemiseen näihin kapeisiin paikkoihin voi kulua noin 5 % ylimääräistä laskenta-aikaa. Poista siinä tapauksessa tämä asetus käytöstä."
+msgid "When the model has small vertical gaps of only a few layers, there should normally be skin around those layers in the narrow space. Enable this setting to not generate skin if the vertical gap is very small. This improves printing time and slicing time, but technically leaves infill exposed to the air."
+msgstr ""
#: fdmprinter.def.json
msgctxt "skin_outline_count label"
@@ -1352,8 +1427,8 @@ msgstr "Ota silitys käyttöön"
#: fdmprinter.def.json
msgctxt "ironing_enabled description"
-msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
-msgstr "Yläpinnan läpikäynti yhden ylimääräisen kerran ilman materiaalin pursotusta. Tämän tarkoitus on sulattaa yläosan muovia enemmän, jolloin saadaan sileämpi pinta."
+msgid "Go over the top surface one additional time, but this time extruding very little material. This is meant to melt the plastic on top further, creating a smoother surface. The pressure in the nozzle chamber is kept high so that the creases in the surface are filled with material."
+msgstr ""
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer label"
@@ -1445,6 +1520,26 @@ msgctxt "jerk_ironing description"
msgid "The maximum instantaneous velocity change while performing ironing."
msgstr "Silityksen aikainen nopeuden hetkellinen maksimimuutos."
+#: fdmprinter.def.json
+msgctxt "skin_overlap label"
+msgid "Skin Overlap Percentage"
+msgstr "Pintakalvon limityksen prosentti"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines, as a percentage of the line widths of the skin lines and the innermost wall. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any percentage over 50% may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm label"
+msgid "Skin Overlap"
+msgstr "Pintakalvon limitys"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any value over half the width of the wall may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "infill label"
msgid "Infill"
@@ -1610,6 +1705,16 @@ msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location label"
+msgid "Randomize Infill Start"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location description"
+msgid "Randomize which infill line is printed first. This prevents one segment becoming the strongest, but it does so at the cost of an additional travel move."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "infill_multiplier label"
msgid "Infill Line Multiplier"
@@ -1662,26 +1767,6 @@ msgctxt "infill_overlap_mm description"
msgid "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill."
msgstr "Limityksen määrä täytön ja seinämien välillä. Pienellä limityksellä seinämät liittyvät tukevasti täyttöön."
-#: fdmprinter.def.json
-msgctxt "skin_overlap label"
-msgid "Skin Overlap Percentage"
-msgstr "Pintakalvon limityksen prosentti"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap description"
-msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm label"
-msgid "Skin Overlap"
-msgstr "Pintakalvon limitys"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm description"
-msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
-msgstr "Limityksen määrä pintakalvon ja seinämien välillä. Pienellä limityksellä seinämät liittyvät tukevasti pintakalvoon."
-
#: fdmprinter.def.json
msgctxt "infill_wipe_dist label"
msgid "Infill Wipe Distance"
@@ -1862,6 +1947,16 @@ msgctxt "default_material_print_temperature description"
msgid "The default temperature used for printing. This should be the \"base\" temperature of a material. All other print temperatures should use offsets based on this value"
msgstr "Tulostuksessa käytettävä oletuslämpötila. Tämän tulee olla materiaalin ”pohjalämpötila”. Kaikkien muiden tulostuslämpötilojen tulee käyttää tähän arvoon perustuvia siirtymiä."
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature label"
+msgid "Build Volume Temperature"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature description"
+msgid "The temperature of the environment to print in. If this is 0, the build volume temperature will not be adjusted."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "material_print_temperature label"
msgid "Printing Temperature"
@@ -1972,6 +2067,86 @@ msgctxt "material_shrinkage_percentage description"
msgid "Shrinkage ratio in percentage."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "material_crystallinity label"
+msgid "Crystalline Material"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_crystallinity description"
+msgid "Is this material the type that breaks off cleanly when heated (crystalline), or is it the type that produces long intertwined polymer chains (non-crystalline)?"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position label"
+msgid "Anti-ooze Retracted Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position description"
+msgid "How far the material needs to be retracted before it stops oozing."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed label"
+msgid "Anti-ooze Retraction Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed description"
+msgid "How fast the material needs to be retracted during a filament switch to prevent oozing."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position label"
+msgid "Break Preparation Retracted Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position description"
+msgid "How far the filament can be stretched before it breaks, while heated."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed label"
+msgid "Break Preparation Retraction Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed description"
+msgid "How fast the filament needs to be retracted just before breaking it off in a retraction."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position label"
+msgid "Break Retracted Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position description"
+msgid "How far to retract the filament in order to break it cleanly."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed label"
+msgid "Break Retraction Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed description"
+msgid "The speed at which to retract the filament in order to break it cleanly."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature label"
+msgid "Break Temperature"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature description"
+msgid "The temperature at which the filament is broken for a clean break."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "material_flow label"
msgid "Flow"
@@ -1982,6 +2157,126 @@ msgctxt "material_flow description"
msgid "Flow compensation: the amount of material extruded is multiplied by this value."
msgstr "Virtauksen kompensointi: pursotetun materiaalin määrä kerrotaan tällä arvolla."
+#: fdmprinter.def.json
+msgctxt "wall_material_flow label"
+msgid "Wall Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_material_flow description"
+msgid "Flow compensation on wall lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow label"
+msgid "Outer Wall Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow description"
+msgid "Flow compensation on the outermost wall line."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow label"
+msgid "Inner Wall(s) Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow description"
+msgid "Flow compensation on wall lines for all wall lines except the outermost one."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow label"
+msgid "Top/Bottom Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow description"
+msgid "Flow compensation on top/bottom lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow label"
+msgid "Top Surface Skin Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow description"
+msgid "Flow compensation on lines of the areas at the top of the print."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow label"
+msgid "Infill Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow description"
+msgid "Flow compensation on infill lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow label"
+msgid "Skirt/Brim Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow description"
+msgid "Flow compensation on skirt or brim lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow label"
+msgid "Support Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow description"
+msgid "Flow compensation on support structure lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow label"
+msgid "Support Interface Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow description"
+msgid "Flow compensation on lines of support roof or floor."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow label"
+msgid "Support Roof Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow description"
+msgid "Flow compensation on support roof lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow label"
+msgid "Support Floor Flow"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow description"
+msgid "Flow compensation on support floor lines."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow label"
+msgid "Prime Tower Flow"
+msgstr "Esitäyttötornin virtaus"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow description"
+msgid "Flow compensation on prime tower lines."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "material_flow_layer_0 label"
msgid "Initial Layer Flow"
@@ -2099,7 +2394,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "limit_support_retractions description"
-msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
+msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excessive stringing within the support structure."
msgstr ""
#: fdmprinter.def.json
@@ -2119,8 +2414,8 @@ msgstr "Suuttimen vaihdon takaisinvetoetäisyys"
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_amount description"
-msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
-msgstr "Takaisinvedon määrä: 0 tarkoittaa, että takaisinvetoa ei ole lainkaan. Tämän on yleensä oltava sama kuin lämpöalueen pituus."
+msgid "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+msgstr ""
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_speeds label"
@@ -2152,6 +2447,16 @@ msgctxt "switch_extruder_prime_speed description"
msgid "The speed at which the filament is pushed back after a nozzle switch retraction."
msgstr "Nopeus, jolla tulostuslanka työnnetään takaisin suuttimen vaihdon takaisinvedon jälkeen."
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount label"
+msgid "Nozzle Switch Extra Prime Amount"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount description"
+msgid "Extra material to prime after nozzle switching."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "speed label"
msgid "Speed"
@@ -2343,14 +2648,14 @@ msgid "The speed at which the skirt and brim are printed. Normally this is done
msgstr "Nopeus, jolla helma ja reunus tulostetaan. Yleensä se tehdään alkukerroksen nopeudella. Joskus helma tai reunus halutaan kuitenkin tulostaa eri nopeudella."
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override label"
-msgid "Maximum Z Speed"
-msgstr "Z:n maksiminopeus"
+msgctxt "speed_z_hop label"
+msgid "Z Hop Speed"
+msgstr ""
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override description"
-msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
-msgstr "Maksiminopeus, jolla alustaa liikutetaan. Jos tämä määritetään nollaan, tulostuksessa käytetään laiteohjelmiston oletusasetuksia Z:n maksiminopeudelle."
+msgctxt "speed_z_hop description"
+msgid "The speed at which the vertical Z movement is made for Z Hops. This is typically lower than the print speed since the build plate or machine's gantry is harder to move."
+msgstr ""
#: fdmprinter.def.json
msgctxt "speed_slowdown_layers label"
@@ -2779,7 +3084,7 @@ msgstr "Pyyhkäisytila"
#: fdmprinter.def.json
msgctxt "retraction_combing description"
-msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
+msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas or to only comb within the infill."
msgstr ""
#: fdmprinter.def.json
@@ -2852,16 +3157,6 @@ msgctxt "travel_avoid_distance description"
msgid "The distance between the nozzle and already printed parts when avoiding during travel moves."
msgstr "Suuttimen ja aiemmin tulostetun osan välinen etäisyys siirtoliikkeiden yhteydessä."
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position label"
-msgid "Start Layers with the Same Part"
-msgstr "Aloita kerrokset samalla osalla"
-
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position description"
-msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
-msgstr "Aloita tulostus jokaisessa kerroksessa tulostamalla kappale, joka on lähellä samaa pistettä, jotta uutta kerrosta ei aloiteta tulostamalla kappaletta, johon edellinen kerros päättyi. Näin saadaan aikaan paremmat ulokkeet ja pienet osat, mutta tulostus kestää kauemmin."
-
#: fdmprinter.def.json
msgctxt "layer_start_x label"
msgid "Layer Start X"
@@ -2922,6 +3217,16 @@ msgctxt "retraction_hop_after_extruder_switch description"
msgid "After the machine switched from one extruder to the other, the build plate is lowered to create clearance between the nozzle and the print. This prevents the nozzle from leaving oozed material on the outside of a print."
msgstr "Alustaa lasketaan koneen vaihdettua yhdestä suulakkeesta toiseen, jotta suuttimen ja tulosteen väliin jää tilaa. Tämä estää suutinta jättämästä tihkunutta ainetta tulosteen ulkopuolelle."
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height label"
+msgid "Z Hop After Extruder Switch Height"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height description"
+msgid "The height difference when performing a Z Hop after extruder switch."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "cooling label"
msgid "Cooling"
@@ -3192,6 +3497,11 @@ msgctxt "support_pattern option cross"
msgid "Cross"
msgstr "Risti"
+#: fdmprinter.def.json
+msgctxt "support_pattern option gyroid"
+msgid "Gyroid"
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "support_wall_count label"
msgid "Support Wall Line Count"
@@ -3253,13 +3563,13 @@ msgid "Distance between the printed initial layer support structure lines. This
msgstr ""
#: fdmprinter.def.json
-msgctxt "support_infill_angle label"
-msgid "Support Infill Line Direction"
+msgctxt "support_infill_angles label"
+msgid "Support Infill Line Directions"
msgstr ""
#: fdmprinter.def.json
-msgctxt "support_infill_angle description"
-msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
+msgctxt "support_infill_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angle 0 degrees."
msgstr ""
#: fdmprinter.def.json
@@ -3389,8 +3699,8 @@ msgstr "Tuen liitosetäisyys"
#: fdmprinter.def.json
msgctxt "support_join_distance description"
-msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
-msgstr "Tukirakenteiden maksimietäisyys toisistaan X-/Y-suunnissa. Kun erilliset rakenteet ovat tätä arvoa lähempänä toisiaan, rakenteet sulautuvat toisiinsa."
+msgid "The maximum distance between support structures in the X/Y directions. When separate structures are closer together than this value, the structures merge into one."
+msgstr ""
#: fdmprinter.def.json
msgctxt "support_offset label"
@@ -3432,6 +3742,16 @@ msgctxt "gradual_support_infill_step_height description"
msgid "The height of support infill of a given density before switching to half the density."
msgstr "Tietyn tiheysarvon tuen täytön korkeus ennen puoleen tiheyteen vaihtamista."
+#: fdmprinter.def.json
+msgctxt "minimum_support_area label"
+msgid "Minimum Support Area"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_support_area description"
+msgid "Minimum area size for support polygons. Polygons which have an area smaller than this value will not be generated."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "support_interface_enable label"
msgid "Enable Support Interface"
@@ -3657,6 +3977,96 @@ msgctxt "support_bottom_pattern option zigzag"
msgid "Zig Zag"
msgstr "Siksak"
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area label"
+msgid "Minimum Support Interface Area"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area description"
+msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area label"
+msgid "Minimum Support Roof Area"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area description"
+msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area label"
+msgid "Minimum Support Floor Area"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area description"
+msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset label"
+msgid "Support Interface Horizontal Expansion"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset description"
+msgid "Amount of offset applied to the support interface polygons."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset label"
+msgid "Support Roof Horizontal Expansion"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset description"
+msgid "Amount of offset applied to the roofs of the support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset label"
+msgid "Support Floor Horizontal Expansion"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset description"
+msgid "Amount of offset applied to the floors of the support."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles label"
+msgid "Support Interface Line Directions"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles label"
+msgid "Support Roof Line Directions"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles label"
+msgid "Support Floor Line Directions"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "support_fan_enable label"
msgid "Fan Speed Override"
@@ -3698,14 +4108,14 @@ msgid "The diameter of a special tower."
msgstr "Erityistornin läpimitta."
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter label"
-msgid "Minimum Diameter"
-msgstr "Minimiläpimitta"
+msgctxt "support_tower_maximum_supported_diameter label"
+msgid "Maximum Tower-Supported Diameter"
+msgstr ""
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter description"
-msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
-msgstr "Erityisellä tukitornilla tuettavan pienen alueen minimiläpimitta X- ja Y-suunnissa."
+msgctxt "support_tower_maximum_supported_diameter description"
+msgid "Maximum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+msgstr ""
#: fdmprinter.def.json
msgctxt "support_tower_roof_angle label"
@@ -4199,16 +4609,6 @@ msgctxt "prime_tower_enable description"
msgid "Print a tower next to the print which serves to prime the material after each nozzle switch."
msgstr "Tulosta tulosteen viereen torni, jolla materiaali esitäytetään aina suuttimen vaihdon jälkeen."
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular label"
-msgid "Circular Prime Tower"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular description"
-msgid "Make the prime tower as a circular shape."
-msgstr ""
-
#: fdmprinter.def.json
msgctxt "prime_tower_size label"
msgid "Prime Tower Size"
@@ -4249,16 +4649,6 @@ msgctxt "prime_tower_position_y description"
msgid "The y coordinate of the position of the prime tower."
msgstr "Esitäyttötornin sijainnin Y-koordinaatti."
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow label"
-msgid "Prime Tower Flow"
-msgstr "Esitäyttötornin virtaus"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow description"
-msgid "Flow compensation: the amount of material extruded is multiplied by this value."
-msgstr "Virtauksen kompensointi: pursotetun materiaalin määrä kerrotaan tällä arvolla."
-
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled label"
msgid "Wipe Inactive Nozzle on Prime Tower"
@@ -4269,6 +4659,16 @@ msgctxt "prime_tower_wipe_enabled description"
msgid "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower."
msgstr "Kun esitäyttötorni on tulostettu yhdellä suuttimella, pyyhi toisesta suuttimesta tihkunut materiaali pois esitäyttötornissa."
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable label"
+msgid "Prime Tower Brim"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable description"
+msgid "Prime-towers might need the extra adhesion afforded by a brim even if the model doesn't. Presently can't be used with the 'Raft' adhesion-type."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "ooze_shield_enabled label"
msgid "Enable Ooze Shield"
@@ -4389,6 +4789,36 @@ msgctxt "remove_empty_first_layers description"
msgid "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution label"
+msgid "Maximum Resolution"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution description"
+msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution label"
+msgid "Maximum Travel Resolution"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution description"
+msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation label"
+msgid "Maximum Deviation"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation description"
+msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution, so if the two conflict the Maximum Deviation will always be held true."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "blackmagic label"
msgid "Special Modes"
@@ -4551,8 +4981,8 @@ msgstr "Kierukoitujen ääriviivojen tasoittaminen"
#: fdmprinter.def.json
msgctxt "smooth_spiralized_contours description"
-msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
-msgstr "Vähennä Z-sauman näkyvyyttä tasoittamalla kierukoidut ääriviivat (Z-sauman pitäisi olla lähes näkymätön tulosteessa, mutta kerrosnäkymässä sen voi edelleen havaita). Ota huomioon, että tasoittaminen usein sumentaa pinnan pieniä yksityiskohtia."
+msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+msgstr ""
#: fdmprinter.def.json
msgctxt "relative_extrusion label"
@@ -4764,26 +5194,6 @@ msgctxt "minimum_polygon_circumference description"
msgid "Polygons in sliced layers that have a circumference smaller than this amount will be filtered out. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details."
msgstr ""
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution label"
-msgid "Maximum Resolution"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution description"
-msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution label"
-msgid "Maximum Travel Resolution"
-msgstr ""
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution description"
-msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
-msgstr ""
-
#: fdmprinter.def.json
msgctxt "support_skip_some_zags label"
msgid "Break Up Support In Chunks"
@@ -4924,16 +5334,6 @@ msgctxt "coasting_speed description"
msgid "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops."
msgstr "Nopeus, jolla siirrytään vapaaliu'un aikana, suhteessa pursotusreitin nopeuteen. Arvoksi suositellaan hieman alle 100 %, sillä vapaaliukusiirron aikana paine Bowden-putkessa laskee."
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation label"
-msgid "Alternate Skin Rotation"
-msgstr "Vuorottele pintakalvon pyöritystä"
-
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation description"
-msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
-msgstr "Muuttaa ylä-/alakerrosten tulostussuuntaa. Normaalisti ne tulostetaan vain vinottain. Tämä asetus lisää vain X- ja vain Y -suunnat."
-
#: fdmprinter.def.json
msgctxt "cross_infill_pocket_size label"
msgid "Cross 3D Pocket Size"
@@ -5041,8 +5441,8 @@ msgstr "Ota kartiomainen tuki käyttöön"
#: fdmprinter.def.json
msgctxt "support_conical_enabled description"
-msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
-msgstr "Kokeellinen ominaisuus: tekee tukialueet pienemmiksi alaosassa verrattuna ulokkeeseen."
+msgid "Make support areas smaller at the bottom than at the overhang."
+msgstr ""
#: fdmprinter.def.json
msgctxt "support_conical_angle label"
@@ -5106,22 +5506,22 @@ msgstr "Keskimääräinen etäisyys kunkin linjasegmentin satunnaisten pisteiden
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset label"
-msgid "Flow rate compensation max extrusion offset"
+msgid "Flow Rate Compensation Max Extrusion Offset"
msgstr ""
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset description"
-msgid "The maximum distance in mm to compensate."
+msgid "The maximum distance in mm to move the filament to compensate for changes in flow rate."
msgstr ""
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor label"
-msgid "Flow rate compensation factor"
+msgid "Flow Rate Compensation Factor"
msgstr ""
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor description"
-msgid "The multiplication factor for the flow rate -> distance translation."
+msgid "How far to move the filament in order to compensate for changes in flow rate, as a percentage of how far the filament would move in one second of extrusion."
msgstr ""
#: fdmprinter.def.json
@@ -5385,7 +5785,7 @@ msgstr "Suuttimen ja vaakasuoraan laskevien linjojen välinen etäisyys. Suuremp
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
-msgid "Use adaptive layers"
+msgid "Use Adaptive Layers"
msgstr ""
#: fdmprinter.def.json
@@ -5395,7 +5795,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
-msgid "Adaptive layers maximum variation"
+msgid "Adaptive Layers Maximum Variation"
msgstr ""
#: fdmprinter.def.json
@@ -5405,7 +5805,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
-msgid "Adaptive layers variation step size"
+msgid "Adaptive Layers Variation Step Size"
msgstr ""
#: fdmprinter.def.json
@@ -5415,12 +5815,12 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
-msgid "Adaptive layers threshold"
+msgid "Adaptive Layers Topography Size"
msgstr ""
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
-msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
+msgid "Target horizontal distance between two adjacent layers. Reducing this setting causes thinner layers to be used to bring the edges of the layers closer together."
msgstr ""
#: fdmprinter.def.json
@@ -5430,7 +5830,7 @@ msgstr ""
#: fdmprinter.def.json
msgctxt "wall_overhang_angle description"
-msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
+msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging. Overhang that gets supported by support will not be treated as overhang either."
msgstr ""
#: fdmprinter.def.json
@@ -5633,6 +6033,196 @@ msgctxt "bridge_fan_speed_3 description"
msgid "Percentage fan speed to use when printing the third bridge skin layer."
msgstr ""
+#: fdmprinter.def.json
+msgctxt "clean_between_layers label"
+msgid "Wipe Nozzle Between Layers"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "clean_between_layers description"
+msgid "Whether to include nozzle wipe G-Code between layers. Enabling this setting could influence behavior of retract at layer change. Please use Wipe Retraction settings to control retraction at layers where the wipe script will be working."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe label"
+msgid "Material Volume Between Wipes"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe description"
+msgid "Maximum material, that can be extruded before another nozzle wipe is initiated."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable label"
+msgid "Wipe Retraction Enable"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable description"
+msgid "Retract the filament when the nozzle is moving over a non-printed area."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount label"
+msgid "Wipe Retraction Distance"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount description"
+msgid "Amount to retract the filament so it does not ooze during the wipe sequence."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount label"
+msgid "Wipe Retraction Extra Prime Amount"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount description"
+msgid "Some material can ooze away during a wipe travel moves, which can be compensated for here."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed label"
+msgid "Wipe Retraction Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed description"
+msgid "The speed at which the filament is retracted and primed during a wipe retraction move."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed label"
+msgid "Wipe Retraction Retract Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed description"
+msgid "The speed at which the filament is retracted during a wipe retraction move."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed label"
+msgid "Retraction Prime Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed description"
+msgid "The speed at which the filament is primed during a wipe retraction move."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause label"
+msgid "Wipe Pause"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause description"
+msgid "Pause after the unretract."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable label"
+msgid "Wipe Z Hop When Retracted"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable description"
+msgid "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount label"
+msgid "Wipe Z Hop Height"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount description"
+msgid "The height difference when performing a Z Hop."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed label"
+msgid "Wipe Hop Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed description"
+msgid "Speed to move the z-axis during the hop."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x label"
+msgid "Wipe Brush X Position"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x description"
+msgid "X location where wipe script will start."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count label"
+msgid "Wipe Repeat Count"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count description"
+msgid "Number of times to move the nozzle across the brush."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance label"
+msgid "Wipe Move Distance"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance description"
+msgid "The distance to move the head back and forth across the brush."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size label"
+msgid "Small Hole Max Size"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size description"
+msgid "Holes and part outlines with a diameter smaller than this will be printed using Small Feature Speed."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length label"
+msgid "Small Feature Max Length"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length description"
+msgid "Feature outlines that are shorter than this length will be printed using Small Feature Speed."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor label"
+msgid "Small Feature Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor description"
+msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 label"
+msgid "Small Feature Initial Layer Speed"
+msgstr ""
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 description"
+msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr ""
+
#: fdmprinter.def.json
msgctxt "command_line_settings label"
msgid "Command Line Settings"
@@ -5693,6 +6283,122 @@ msgctxt "mesh_rotation_matrix description"
msgid "Transformation matrix to be applied to the model when loading it from file."
msgstr "Mallissa käytettävä muunnosmatriisi, kun malli ladataan tiedostosta."
+#~ msgctxt "skin_alternate_rotation label"
+#~ msgid "Alternate Skin Rotation"
+#~ msgstr "Vuorottele pintakalvon pyöritystä"
+
+#~ msgctxt "skin_alternate_rotation description"
+#~ msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
+#~ msgstr "Muuttaa ylä-/alakerrosten tulostussuuntaa. Normaalisti ne tulostetaan vain vinottain. Tämä asetus lisää vain X- ja vain Y -suunnat."
+
+#~ msgctxt "ironing_enabled description"
+#~ msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
+#~ msgstr "Yläpinnan läpikäynti yhden ylimääräisen kerran ilman materiaalin pursotusta. Tämän tarkoitus on sulattaa yläosan muovia enemmän, jolloin saadaan sileämpi pinta."
+
+#~ msgctxt "start_layers_at_same_position label"
+#~ msgid "Start Layers with the Same Part"
+#~ msgstr "Aloita kerrokset samalla osalla"
+
+#~ msgctxt "start_layers_at_same_position description"
+#~ msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
+#~ msgstr "Aloita tulostus jokaisessa kerroksessa tulostamalla kappale, joka on lähellä samaa pistettä, jotta uutta kerrosta ei aloiteta tulostamalla kappaletta, johon edellinen kerros päättyi. Näin saadaan aikaan paremmat ulokkeet ja pienet osat, mutta tulostus kestää kauemmin."
+
+#~ msgctxt "z_seam_corner description"
+#~ msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
+#~ msgstr "Määritä, vaikuttavatko mallin ulkolinjan kulmat sauman sijaintiin. Ei mitään tarkoittaa, että kulmilla ei ole vaikutusta sauman sijaintiin. Piilota sauma -valinnalla sauman sijainti sisäkulmassa on todennäköisempää. Paljasta sauma -valinnalla sauman sijainti ulkokulmassa on todennäköisempää. Piilota tai paljasta sauma -valinnalla sauman sijainti sisä- tai ulkokulmassa on todennäköisempää."
+
+#~ msgctxt "skin_no_small_gaps_heuristic label"
+#~ msgid "Ignore Small Z Gaps"
+#~ msgstr "Ohita pienet Z-raot"
+
+#~ msgctxt "skin_no_small_gaps_heuristic description"
+#~ msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
+#~ msgstr "Kun mallissa on pieniä pystyrakoja, ylä- ja alapuolen pintakalvon tekemiseen näihin kapeisiin paikkoihin voi kulua noin 5 % ylimääräistä laskenta-aikaa. Poista siinä tapauksessa tämä asetus käytöstä."
+
+#~ msgctxt "max_feedrate_z_override label"
+#~ msgid "Maximum Z Speed"
+#~ msgstr "Z:n maksiminopeus"
+
+#~ msgctxt "max_feedrate_z_override description"
+#~ msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
+#~ msgstr "Maksiminopeus, jolla alustaa liikutetaan. Jos tämä määritetään nollaan, tulostuksessa käytetään laiteohjelmiston oletusasetuksia Z:n maksiminopeudelle."
+
+#~ msgctxt "support_join_distance description"
+#~ msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
+#~ msgstr "Tukirakenteiden maksimietäisyys toisistaan X-/Y-suunnissa. Kun erilliset rakenteet ovat tätä arvoa lähempänä toisiaan, rakenteet sulautuvat toisiinsa."
+
+#~ msgctxt "support_minimal_diameter label"
+#~ msgid "Minimum Diameter"
+#~ msgstr "Minimiläpimitta"
+
+#~ msgctxt "support_minimal_diameter description"
+#~ msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+#~ msgstr "Erityisellä tukitornilla tuettavan pienen alueen minimiläpimitta X- ja Y-suunnissa."
+
+#~ msgctxt "prime_tower_flow description"
+#~ msgid "Flow compensation: the amount of material extruded is multiplied by this value."
+#~ msgstr "Virtauksen kompensointi: pursotetun materiaalin määrä kerrotaan tällä arvolla."
+
+#~ msgctxt "smooth_spiralized_contours description"
+#~ msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+#~ msgstr "Vähennä Z-sauman näkyvyyttä tasoittamalla kierukoidut ääriviivat (Z-sauman pitäisi olla lähes näkymätön tulosteessa, mutta kerrosnäkymässä sen voi edelleen havaita). Ota huomioon, että tasoittaminen usein sumentaa pinnan pieniä yksityiskohtia."
+
+#~ msgctxt "support_conical_enabled description"
+#~ msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
+#~ msgstr "Kokeellinen ominaisuus: tekee tukialueet pienemmiksi alaosassa verrattuna ulokkeeseen."
+
+#~ msgctxt "machine_nozzle_tip_outer_diameter label"
+#~ msgid "Outer nozzle diameter"
+#~ msgstr "Suuttimen ulkoläpimitta"
+
+#~ msgctxt "machine_nozzle_head_distance label"
+#~ msgid "Nozzle length"
+#~ msgstr "Suuttimen pituus"
+
+#~ msgctxt "machine_nozzle_expansion_angle label"
+#~ msgid "Nozzle angle"
+#~ msgstr "Suuttimen kulma"
+
+#~ msgctxt "machine_heat_zone_length label"
+#~ msgid "Heat zone length"
+#~ msgstr "Lämpöalueen pituus"
+
+#~ msgctxt "machine_nozzle_heat_up_speed label"
+#~ msgid "Heat up speed"
+#~ msgstr "Lämpenemisnopeus"
+
+#~ msgctxt "machine_nozzle_cool_down_speed label"
+#~ msgid "Cool down speed"
+#~ msgstr "Jäähdytysnopeus"
+
+#~ msgctxt "machine_disallowed_areas label"
+#~ msgid "Disallowed areas"
+#~ msgstr "Kielletyt alueet"
+
+#~ msgctxt "machine_head_polygon label"
+#~ msgid "Machine head polygon"
+#~ msgstr "Laiteen pään monikulmio"
+
+#~ msgctxt "machine_head_with_fans_polygon label"
+#~ msgid "Machine head & Fan polygon"
+#~ msgstr "Laiteen pään ja tuulettimen monikulmio"
+
+#~ msgctxt "gantry_height label"
+#~ msgid "Gantry height"
+#~ msgstr "Korokkeen korkeus"
+
+#~ msgctxt "machine_use_extruder_offset_to_offset_coords label"
+#~ msgid "Offset With Extruder"
+#~ msgstr "Suulakkeen siirtymä"
+
+#~ msgctxt "skin_overlap_mm description"
+#~ msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
+#~ msgstr "Limityksen määrä pintakalvon ja seinämien välillä. Pienellä limityksellä seinämät liittyvät tukevasti pintakalvoon."
+
+#~ msgctxt "switch_extruder_retraction_amount description"
+#~ msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+#~ msgstr "Takaisinvedon määrä: 0 tarkoittaa, että takaisinvetoa ei ole lainkaan. Tämän on yleensä oltava sama kuin lämpöalueen pituus."
+
#~ msgctxt "infill_pattern option concentric_3d"
#~ msgid "Concentric 3D"
#~ msgstr "Samankeskinen 3D"
diff --git a/resources/i18n/fr_FR/cura.po b/resources/i18n/fr_FR/cura.po
index 9b1fff4124..3633753794 100644
--- a/resources/i18n/fr_FR/cura.po
+++ b/resources/i18n/fr_FR/cura.po
@@ -1,24 +1,24 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0100\n"
-"PO-Revision-Date: 2018-09-28 14:59+0200\n"
-"Last-Translator: Bothof \n"
-"Language-Team: French\n"
+"POT-Creation-Date: 2019-11-05 13:13+0100\n"
+"PO-Revision-Date: 2019-07-29 15:51+0200\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: French , French \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.2.3\n"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:22
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:30
msgctxt "@action"
msgid "Machine Settings"
msgstr "Paramètres de la machine"
@@ -40,23 +40,23 @@ msgctxt "@item:inlistbox"
msgid "G-code File"
msgstr "Fichier GCode"
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:67
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:66
msgctxt "@error:not supported"
msgid "GCodeWriter does not support non-text mode."
msgstr "GCodeWriter ne prend pas en charge le mode non-texte."
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:73
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:89
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:72
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:88
msgctxt "@warning:status"
msgid "Please prepare G-code before exporting."
msgstr "Veuillez préparer le G-Code avant d'exporter."
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:30
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:31
msgctxt "@info:title"
msgid "3D Model Assistant"
msgstr "Assistant de modèle 3D"
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:80
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:92
#, python-brace-format
msgctxt "@info:status"
msgid ""
@@ -64,68 +64,56 @@ msgid ""
"
{model_names}
\n"
"
Find out how to ensure the best possible print quality and reliability.
"
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py:25
msgctxt "@action"
msgid "Update Firmware"
msgstr "Mettre à jour le firmware"
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:23
-msgctxt "@item:inmenu"
-msgid "Flatten active settings"
-msgstr "Aplatir les paramètres actifs"
+#: /home/ruben/Projects/Cura/plugins/AMFReader/__init__.py:15
+msgctxt "@item:inlistbox"
+msgid "AMF File"
+msgstr "Fichier AMF"
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:35
-msgctxt "@info:status"
-msgid "Profile has been flattened & activated."
-msgstr "Le profil a été aplati et activé."
-
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:32
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:42
msgctxt "@item:inmenu"
msgid "USB printing"
msgstr "Impression par USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:33
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:43
msgctxt "@action:button Preceded by 'Ready to'."
msgid "Print via USB"
msgstr "Imprimer via USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:34
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:44
msgctxt "@info:tooltip"
msgid "Print via USB"
msgstr "Imprimer via USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:69
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:80
msgctxt "@info:status"
msgid "Connected via USB"
msgstr "Connecté via USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:92
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:105
msgctxt "@label"
msgid "A USB print is in progress, closing Cura will stop this print. Are you sure?"
msgstr "Une impression USB est en cours, la fermeture de Cura arrêtera cette impression. Êtes-vous sûr ?"
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/install/X3GWriter/__init__.py:15
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/__init__.py:15
-msgctxt "X3G Writer File Description"
-msgid "X3G File"
-msgstr "Fichier X3G"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid "A print is still in progress. Cura cannot start another print via USB until the previous print has completed."
+msgstr "Une impression est encore en cours. Cura ne peut pas démarrer une autre impression via USB tant que l'impression précédente n'est pas terminée."
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:16
-msgctxt "X3g Writer Plugin Description"
-msgid "Writes X3g to files"
-msgstr "Écrit X3G dans des fichiers"
-
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:21
-msgctxt "X3g Writer File Description"
-msgid "X3g File"
-msgstr "Fichier X3G"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid "Print in Progress"
+msgstr "Impression en cours"
#: /home/ruben/Projects/Cura/plugins/GCodeGzWriter/__init__.py:17
#: /home/ruben/Projects/Cura/plugins/GCodeGzReader/__init__.py:17
@@ -139,6 +127,7 @@ msgid "GCodeGzWriter does not support text mode."
msgstr "GCodeGzWriter ne prend pas en charge le mode texte."
#: /home/ruben/Projects/Cura/plugins/UFPWriter/__init__.py:28
+#: /home/ruben/Projects/Cura/plugins/UFPReader/__init__.py:22
msgctxt "@item:inlistbox"
msgid "Ultimaker Format Package"
msgstr "Ultimaker Format Package"
@@ -160,7 +149,7 @@ msgid "Save to Removable Drive {0}"
msgstr "Enregistrer sur un lecteur amovible {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:64
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:133
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py:107
msgctxt "@info:status"
msgid "There are no file formats available to write with!"
msgstr "Aucun format de fichier n'est disponible pour écriture !"
@@ -197,9 +186,9 @@ msgid "Could not save to removable drive {0}: {1}"
msgstr "Impossible d'enregistrer sur le lecteur {0}: {1}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:137
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:133
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:140
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1607
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:139
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:146
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1668
msgctxt "@info:title"
msgid "Error"
msgstr "Erreur"
@@ -228,8 +217,9 @@ msgstr "Ejecter le lecteur amovible {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:151
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:163
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1597
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1695
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1658
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1758
msgctxt "@info:title"
msgid "Warning"
msgstr "Avertissement"
@@ -256,232 +246,164 @@ msgctxt "@item:intext"
msgid "Removable Drive"
msgstr "Lecteur amovible"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:73
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:88
-msgctxt "@action:button Preceded by 'Ready to'."
-msgid "Print over network"
-msgstr "Imprimer sur le réseau"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:74
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:89
-msgctxt "@properties:tooltip"
-msgid "Print over network"
-msgstr "Imprimer sur le réseau"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:87
-msgctxt "@info:status"
-msgid "Connected over the network."
-msgstr "Connecté sur le réseau."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:90
-msgctxt "@info:status"
-msgid "Connected over the network. Please approve the access request on the printer."
-msgstr "Connecté sur le réseau. Veuillez approuver la demande d'accès sur l'imprimante."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:92
-msgctxt "@info:status"
-msgid "Connected over the network. No access to control the printer."
-msgstr "Connecté sur le réseau. Pas d'accès pour commander l'imprimante."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:97
-msgctxt "@info:status"
-msgid "Access to the printer requested. Please approve the request on the printer"
-msgstr "Accès à l'imprimante demandé. Veuillez approuver la demande sur l'imprimante"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:100
-msgctxt "@info:title"
-msgid "Authentication status"
-msgstr "Statut d'authentification"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:102
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:108
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:112
-msgctxt "@info:title"
-msgid "Authentication Status"
-msgstr "Statut d'authentification"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:103
-msgctxt "@action:button"
-msgid "Retry"
-msgstr "Réessayer"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:104
-msgctxt "@info:tooltip"
-msgid "Re-send the access request"
-msgstr "Renvoyer la demande d'accès"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:107
-msgctxt "@info:status"
-msgid "Access to the printer accepted"
-msgstr "Accès à l'imprimante accepté"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:111
-msgctxt "@info:status"
-msgid "No access to print with this printer. Unable to send print job."
-msgstr "Aucun accès pour imprimer avec cette imprimante. Impossible d'envoyer la tâche d'impression."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:113
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:33
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:70
-msgctxt "@action:button"
-msgid "Request Access"
-msgstr "Demande d'accès"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:115
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:34
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:71
-msgctxt "@info:tooltip"
-msgid "Send access request to the printer"
-msgstr "Envoyer la demande d'accès à l'imprimante"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:200
-msgctxt "@label"
-msgid "Unable to start a new print job."
-msgstr "Impossible de démarrer une nouvelle tâche d'impression."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:202
-msgctxt "@label"
-msgid "There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. Please resolve this issues before continuing."
-msgstr "Un problème avec la configuration de votre Ultimaker empêche le démarrage de l'impression. Veuillez résoudre ce problème avant de continuer."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:208
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:230
-msgctxt "@window:title"
-msgid "Mismatched configuration"
-msgstr "Configuration différente"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:222
-msgctxt "@label"
-msgid "Are you sure you wish to print with the selected configuration?"
-msgstr "Êtes-vous sûr(e) de vouloir imprimer avec la configuration sélectionnée ?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:224
-msgctxt "@label"
-msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "Problème de compatibilité entre la configuration ou l'étalonnage de l'imprimante et Cura. Pour un résultat optimal, découpez toujours pour les PrintCores et matériaux insérés dans votre imprimante."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:251
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:199
-msgctxt "@info:status"
-msgid "Sending new jobs (temporarily) blocked, still sending the previous print job."
-msgstr "Envoi de nouvelles tâches (temporairement) bloqué, envoi de la tâche d'impression précédente en cours."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:258
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:218
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:234
-msgctxt "@info:status"
-msgid "Sending data to printer"
-msgstr "Envoi des données à l'imprimante"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:259
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:219
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:235
-msgctxt "@info:title"
-msgid "Sending Data"
-msgstr "Envoi des données"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:260
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:236
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:80
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:381
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:20
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:143
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:391
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:87
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:279
-msgctxt "@action:button"
-msgid "Cancel"
-msgstr "Annuler"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:323
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No Printcore loaded in slot {slot_number}"
-msgstr "Pas de PrintCore inséré dans la fente {slot_number}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:329
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No material loaded in slot {slot_number}"
-msgstr "Aucun matériau inséré dans la fente {slot_number}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:352
-#, python-brace-format
-msgctxt "@label"
-msgid "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}"
-msgstr "PrintCore différent (Cura : {cura_printcore_name}, Imprimante : {remote_printcore_name}) sélectionné pour l'extrudeuse {extruder_id}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:361
-#, python-brace-format
-msgctxt "@label"
-msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
-msgstr "Matériau différent (Cura : {0}, Imprimante : {1}) sélectionné pour l'extrudeuse {2}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:547
-msgctxt "@window:title"
-msgid "Sync with your printer"
-msgstr "Synchroniser avec votre imprimante"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:549
-msgctxt "@label"
-msgid "Would you like to use your current printer configuration in Cura?"
-msgstr "Voulez-vous utiliser votre configuration d'imprimante actuelle dans Cura ?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:551
-msgctxt "@label"
-msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "Les PrintCores et / ou matériaux sur votre imprimante diffèrent de ceux de votre projet actuel. Pour un résultat optimal, découpez toujours pour les PrintCores et matériaux insérés dans votre imprimante."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:91
-msgctxt "@info:status"
-msgid "Connected over the network"
-msgstr "Connecté sur le réseau"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:303
-msgctxt "@info:status"
-msgid "Print job was successfully sent to the printer."
-msgstr "L'envoi de la tâche d'impression à l'imprimante a réussi."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:305
-msgctxt "@info:title"
-msgid "Data Sent"
-msgstr "Données envoyées"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:306
-msgctxt "@action:button"
-msgid "View in Monitor"
-msgstr "Afficher sur le moniteur"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:422
-#, python-brace-format
-msgctxt "@info:status"
-msgid "Printer '{printer_name}' has finished printing '{job_name}'."
-msgstr "{printer_name} a terminé d'imprimer '{job_name}'."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:424
-#, python-brace-format
-msgctxt "@info:status"
-msgid "The print job '{job_name}' was finished."
-msgstr "La tâche d'impression '{job_name}' est terminée."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:425
-msgctxt "@info:status"
-msgid "Print finished"
-msgstr "Impression terminée"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py:26
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py:26
msgctxt "@action"
msgid "Connect via Network"
msgstr "Connecter via le réseau"
-#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:13
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:57
+msgctxt "@action:button Preceded by 'Ready to'."
+msgid "Print over network"
+msgstr "Imprimer sur le réseau"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:58
+msgctxt "@properties:tooltip"
+msgid "Print over network"
+msgstr "Imprimer sur le réseau"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:59
+msgctxt "@info:status"
+msgid "Connected over the network"
+msgstr "Connecté sur le réseau"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:15
+msgctxt "@info:status"
+msgid "Please wait until the current job has been sent."
+msgstr "Veuillez patienter jusqu'à ce que la tâche en cours ait été envoyée."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:16
+msgctxt "@info:title"
+msgid "Print error"
+msgstr "Erreur d'impression"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:21
+msgctxt "@info:title"
+msgid "New cloud printers found"
+msgstr "Nouvelles imprimantes cloud trouvées"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:22
+msgctxt "@info:message"
+msgid "New printers have been found connected to your account, you can find them in your list of discovered printers."
+msgstr "De nouvelles imprimantes ont été trouvées connectées à votre compte. Vous pouvez les trouver dans votre liste d'imprimantes découvertes."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:27
+msgctxt "@info:option_text"
+msgid "Do not show this message again"
+msgstr "Ne plus afficher ce message"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:27
+#, python-brace-format
+msgctxt "@info:status"
+msgid "You are attempting to connect to {0} but it is not the host of a group. You can visit the web page to configure it as a group host."
+msgstr "Vous tentez de vous connecter à {0} mais ce n'est pas l'hôte de groupe. Vous pouvez visiter la page Web pour la configurer en tant qu'hôte de groupe."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:30
+msgctxt "@info:title"
+msgid "Not a group host"
+msgstr "Pas un hôte de groupe"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:35
+msgctxt "@action"
+msgid "Configure group"
+msgstr "Configurer le groupe"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:27
+msgctxt "@info:status"
+msgid "Send and monitor print jobs from anywhere using your Ultimaker account."
+msgstr "Lancez et surveillez des impressions où que vous soyez avec votre compte Ultimaker."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:33
+msgctxt "@info:status Ultimaker Cloud should not be translated."
+msgid "Connect to Ultimaker Cloud"
+msgstr "Se connecter à Ultimaker Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:36
+msgctxt "@action"
+msgid "Get started"
+msgstr "Prise en main"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:14
+msgctxt "@info:status"
+msgid "Sending Print Job"
+msgstr "Lancement d'une tâche d'impression"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:15
+msgctxt "@info:status"
+msgid "Uploading print job to printer."
+msgstr "Téléchargement de la tâche d'impression sur l'imprimante."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:15
+msgctxt "@info:status"
+msgid "Print job was successfully sent to the printer."
+msgstr "L'envoi de la tâche d'impression à l'imprimante a réussi."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:16
+msgctxt "@info:title"
+msgid "Data Sent"
+msgstr "Données envoyées"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:18
+msgctxt "@info:status"
+msgid "You are attempting to connect to a printer that is not running Ultimaker Connect. Please update the printer to the latest firmware."
+msgstr "Vous tentez de vous connecter à une imprimante qui n'exécute pas Ultimaker Connect. Veuillez mettre à jour l'imprimante avec le dernier micrologiciel."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:21
+msgctxt "@info:title"
+msgid "Update your printer"
+msgstr "Mettre à jour votre imprimante"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:24
+#, python-brace-format
+msgctxt "@info:status"
+msgid "Cura has detected material profiles that were not yet installed on the host printer of group {0}."
+msgstr "Cura a détecté des profils de matériau qui ne sont pas encore installés sur l'imprimante hôte du groupe {0}."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:26
+msgctxt "@info:title"
+msgid "Sending materials to printer"
+msgstr "Envoi de matériaux à l'imprimante"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:15
+msgctxt "@info:text"
+msgid "Could not upload the data to the printer."
+msgstr "Impossible de transférer les données à l'imprimante."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:16
+msgctxt "@info:title"
+msgid "Network error"
+msgstr "Erreur de réseau"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:27
+msgctxt "@info:status"
+msgid "tomorrow"
+msgstr "demain"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:30
+msgctxt "@info:status"
+msgid "today"
+msgstr "aujourd'hui"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:138
+msgctxt "@action:button"
+msgid "Print via Cloud"
+msgstr "Imprimer via le cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:139
+msgctxt "@properties:tooltip"
+msgid "Print via Cloud"
+msgstr "Imprimer via le cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:140
+msgctxt "@info:status"
+msgid "Connected via Cloud"
+msgstr "Connecté via le cloud"
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:14
msgctxt "@item:inmenu"
msgid "Monitor"
msgstr "Surveiller"
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:119
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:125
msgctxt "@info"
msgid "Could not access update information."
msgstr "Impossible d'accéder aux informations de mise à jour."
@@ -503,22 +425,28 @@ msgctxt "@action:button"
msgid "How to update"
msgstr "Comment effectuer la mise à jour"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:14
+#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:15
msgctxt "@item:inlistbox"
msgid "Layer view"
msgstr "Vue en couches"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:113
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:117
msgctxt "@info:status"
msgid "Cura does not accurately display layers when Wire Printing is enabled"
msgstr "Cura n'affiche pas les couches avec précision lorsque l'impression filaire est activée"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:114
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:118
msgctxt "@info:title"
msgid "Simulation View"
msgstr "Vue simulation"
#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:35
+msgctxt "@item:inmenu"
+msgid "Post Processing"
+msgstr "Post-traitement"
+
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:36
+msgctxt "@item:inmenu"
msgid "Modify G-Code"
msgstr "Modifier le G-Code"
@@ -532,36 +460,6 @@ msgctxt "@info:tooltip"
msgid "Create a volume in which supports are not printed."
msgstr "Créer un volume dans lequel les supports ne sont pas imprimés."
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:52
-msgctxt "@info"
-msgid "Cura collects anonymized usage statistics."
-msgstr "Cura recueille des statistiques d'utilisation anonymes."
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:55
-msgctxt "@info:title"
-msgid "Collecting Data"
-msgstr "Collecte des données"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:57
-msgctxt "@action:button"
-msgid "More info"
-msgstr "Plus d'informations"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:58
-msgctxt "@action:tooltip"
-msgid "See more information on what data Cura sends."
-msgstr "Voir plus d'informations sur les données envoyées par Cura."
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:60
-msgctxt "@action:button"
-msgid "Allow"
-msgstr "Autoriser"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:61
-msgctxt "@action:tooltip"
-msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
-msgstr "Autoriser Cura à envoyer des statistiques d'utilisation anonymes pour mieux prioriser les améliorations futures apportées à Cura. Certaines de vos préférences et paramètres sont envoyés, ainsi que la version du logiciel Cura et un hachage des modèles que vous découpez."
-
#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
msgid "Cura 15.04 profiles"
@@ -592,56 +490,86 @@ msgctxt "@item:inlistbox"
msgid "GIF Image"
msgstr "Image GIF"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:15
+msgctxt "@item:inlistbox 'Open' is part of the name of this file format."
+msgid "Open Compressed Triangle Mesh"
+msgstr "Ouvrir le maillage triangulaire compressé"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:19
+msgctxt "@item:inlistbox"
+msgid "COLLADA Digital Asset Exchange"
+msgstr "COLLADA Digital Asset Exchange"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:23
+msgctxt "@item:inlistbox"
+msgid "glTF Binary"
+msgstr "glTF binaire"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:27
+msgctxt "@item:inlistbox"
+msgid "glTF Embedded JSON"
+msgstr "JSON incorporé glTF"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:36
+msgctxt "@item:inlistbox"
+msgid "Stanford Triangle Format"
+msgstr "Format Triangle de Stanford"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:40
+msgctxt "@item:inlistbox"
+msgid "Compressed COLLADA Digital Asset Exchange"
+msgstr "COLLADA Digital Asset Exchange compressé"
+
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
msgctxt "@info:status"
msgid "Unable to slice with the current material as it is incompatible with the selected machine or configuration."
msgstr "Impossible de découper le matériau actuel, car celui-ci est incompatible avec la machine ou la configuration sélectionnée."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:363
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:387
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:396
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:405
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:414
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
msgctxt "@info:title"
msgid "Unable to slice"
msgstr "Impossible de découper"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:361
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice with the current settings. The following settings have errors: {0}"
msgstr "Impossible de couper avec les paramètres actuels. Les paramètres suivants contiennent des erreurs : {0}"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:385
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice due to some per-model settings. The following settings have errors on one or more models: {error_labels}"
msgstr "Impossible de couper en raison de certains paramètres par modèle. Les paramètres suivants contiennent des erreurs sur un ou plusieurs modèles : {error_labels}"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:394
msgctxt "@info:status"
msgid "Unable to slice because the prime tower or prime position(s) are invalid."
msgstr "Impossible de couper car la tour primaire ou la (les) position(s) d'amorçage ne sont pas valides."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:403
#, python-format
msgctxt "@info:status"
msgid "Unable to slice because there are objects associated with disabled Extruder %s."
msgstr "Impossible de couper car il existe des objets associés à l'extrudeuse désactivée %s."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:412
msgctxt "@info:status"
-msgid "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."
-msgstr "Rien à couper car aucun des modèles ne convient au volume d'impression. Mettez à l'échelle ou faites pivoter les modèles pour les faire correspondre."
+msgid "Nothing to slice because none of the models fit the build volume or are assigned to a disabled extruder. Please scale or rotate models to fit, or enable an extruder."
+msgstr "Rien à découper car les modèles ne conviennent pas au volume d'impression ou sont assignés à une extrudeuse désactivée. Mettez les modèles à l'échelle ou faites-les pivoter pour les faire correspondre, ou activez une extrudeuse."
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:50
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:status"
msgid "Processing Layers"
msgstr "Traitement des couches"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:title"
msgid "Information"
msgstr "Informations"
@@ -656,14 +584,12 @@ msgctxt "@info:tooltip"
msgid "Configure Per Model Settings"
msgstr "Configurer les paramètres par modèle"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:175
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:575
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:186
msgctxt "@title:tab"
msgid "Recommended"
msgstr "Recommandé"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:177
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:580
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:188
msgctxt "@title:tab"
msgid "Custom"
msgstr "Personnalisé"
@@ -674,19 +600,19 @@ msgctxt "@item:inlistbox"
msgid "3MF File"
msgstr "Fichier 3MF"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:190
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:714
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:198
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:651
msgctxt "@label"
msgid "Nozzle"
msgstr "Buse"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:468
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:496
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Project file {0} contains an unknown machine type {1}. Cannot import the machine. Models will be imported instead."
msgstr "Le fichier projet {0} contient un type de machine inconnu {1}. Impossible d'importer la machine. Les modèles seront importés à la place."
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:471
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:499
msgctxt "@info:title"
msgid "Open Project File"
msgstr "Ouvrir un fichier de projet"
@@ -701,22 +627,65 @@ msgctxt "@item:inlistbox"
msgid "G File"
msgstr "Fichier G"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:324
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:335
msgctxt "@info:status"
msgid "Parsing G-code"
msgstr "Analyse du G-Code"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:326
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:474
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:337
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:491
msgctxt "@info:title"
msgid "G-code Details"
msgstr "Détails G-Code"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:472
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:489
msgctxt "@info:generic"
msgid "Make sure the g-code is suitable for your printer and printer configuration before sending the file to it. The g-code representation may not be accurate."
msgstr "Assurez-vous que le g-code est adapté à votre imprimante et à la configuration de l'imprimante avant d'y envoyer le fichier. La représentation du g-code peut ne pas être exacte."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:64
+msgctxt "@item:inmenu"
+msgid "Manage backups"
+msgstr "Gérer les sauvegardes"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:107
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:113
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:104
+msgctxt "@info:title"
+msgid "Backup"
+msgstr "Sauvegarde"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+msgctxt "@info:backup_status"
+msgid "There was an error listing your backups."
+msgstr "Une erreur s’est produite lors du listage de vos sauvegardes."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:132
+msgctxt "@info:backup_status"
+msgid "There was an error trying to restore your backup."
+msgstr "Une erreur s’est produite lors de la tentative de restauration de votre sauvegarde."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:15
+msgctxt "@info:title"
+msgid "Backups"
+msgstr "Sauvegardes"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:27
+msgctxt "@info:backup_status"
+msgid "Uploading your backup..."
+msgstr "Téléchargement de votre sauvegarde..."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:36
+msgctxt "@info:backup_status"
+msgid "There was an error while uploading your backup."
+msgstr "Une erreur s’est produite lors du téléchargement de votre sauvegarde."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:39
+msgctxt "@info:backup_status"
+msgid "Your backup has finished uploading."
+msgstr "Le téléchargement de votre sauvegarde est terminé."
+
#: /home/ruben/Projects/Cura/plugins/CuraProfileWriter/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
@@ -738,330 +707,452 @@ msgctxt "@error:zip"
msgid "Error writing 3mf file."
msgstr "Erreur d'écriture du fichier 3MF."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelection.py:17
+#: /home/ruben/Projects/Cura/plugins/PreviewStage/__init__.py:13
+msgctxt "@item:inmenu"
+msgid "Preview"
+msgstr "Aperçu"
+
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelection.py:18
msgctxt "@action"
msgid "Select upgrades"
msgstr "Sélectionner les mises à niveau"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py:14
-msgctxt "@action"
-msgid "Checkup"
-msgstr "Check-up"
-
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.py:21
msgctxt "@action"
msgid "Level build plate"
msgstr "Nivellement du plateau"
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:82
-msgctxt "@tooltip"
-msgid "Outer Wall"
-msgstr "Paroi externe"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:83
-msgctxt "@tooltip"
-msgid "Inner Walls"
-msgstr "Parois internes"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:84
-msgctxt "@tooltip"
-msgid "Skin"
-msgstr "Couche extérieure"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:85
-msgctxt "@tooltip"
-msgid "Infill"
-msgstr "Remplissage"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:86
-msgctxt "@tooltip"
-msgid "Support Infill"
-msgstr "Remplissage du support"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:87
-msgctxt "@tooltip"
-msgid "Support Interface"
-msgstr "Interface du support"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:88
-msgctxt "@tooltip"
-msgid "Support"
-msgstr "Support"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:89
-msgctxt "@tooltip"
-msgid "Skirt"
-msgstr "Jupe"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:90
-msgctxt "@tooltip"
-msgid "Travel"
-msgstr "Déplacement"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:91
-msgctxt "@tooltip"
-msgid "Retractions"
-msgstr "Rétractions"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:92
-msgctxt "@tooltip"
-msgid "Other"
-msgstr "Autre"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:310
-#, python-brace-format
-msgctxt "@label"
-msgid "Pre-sliced file {0}"
-msgstr "Fichier {0} prédécoupé"
-
-#: /home/ruben/Projects/Cura/cura/API/Account.py:71
+#: /home/ruben/Projects/Cura/cura/API/Account.py:82
msgctxt "@info:title"
msgid "Login failed"
msgstr "La connexion a échoué"
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:201
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:121
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:36
+msgctxt "@info:not supported profile"
+msgid "Not supported"
+msgstr "Non pris en charge"
+
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:55
+msgctxt "@info:No intent profile selected"
+msgid "Default"
+msgstr "Default"
+
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:196
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:125
msgctxt "@title:window"
msgid "File Already Exists"
msgstr "Le fichier existe déjà"
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:202
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:122
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:197
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:126
#, python-brace-format
msgctxt "@label Don't translate the XML tag !"
msgid "The file {0} already exists. Are you sure you want to overwrite it?"
msgstr "Le fichier {0} existe déjà. Êtes-vous sûr de vouloir le remplacer ?"
-#: /home/ruben/Projects/Cura/cura/Settings/ExtrudersModel.py:212
-msgctxt "@menuitem"
-msgid "Not overridden"
-msgstr "Pas écrasé"
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:117
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:430
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:433
msgctxt "@info:status"
-msgid "The selected material is incompatible with the selected machine or configuration."
-msgstr "Le matériau sélectionné est incompatible avec la machine ou la configuration sélectionnée."
+msgid "Invalid file URL:"
+msgstr "URL de fichier invalide :"
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:118
-msgctxt "@info:title"
-msgid "Incompatible Material"
-msgstr "Matériau incompatible"
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:780
+msgctxt "@info:message Followed by a list of settings."
+msgid "Settings have been changed to match the current availability of extruders:"
+msgstr "Les paramètres ont été modifiés pour correspondre aux extrudeuses actuellement disponibles :"
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:866
-#, python-format
-msgctxt "@info:generic"
-msgid "Settings have been changed to match the current availability of extruders: [%s]"
-msgstr "Les paramètres ont été modifiés pour correspondre aux extrudeuses actuellement disponibles : [%s]"
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:868
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:782
msgctxt "@info:title"
msgid "Settings updated"
msgstr "Paramètres mis à jour"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:131
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1334
+msgctxt "@info:title"
+msgid "Extruder(s) Disabled"
+msgstr "Extrudeuse(s) désactivée(s)"
+
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1457
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:99
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:86
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:182
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:223
+msgctxt "@label"
+msgid "Unknown"
+msgstr "Inconnu"
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:137
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Failed to export profile to {0}: {1}"
msgstr "Échec de l'exportation du profil vers {0} : {1}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:138
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid "Failed to export profile to {0}: Writer plugin reported failure."
msgstr "Échec de l'exportation du profil vers {0} : le plug-in du générateur a rapporté une erreur."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:143
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:149
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid "Exported profile to {0}"
msgstr "Profil exporté vers {0}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:150
msgctxt "@info:title"
msgid "Export succeeded"
msgstr "L'exportation a réussi"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:170
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:177
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
-msgid "Failed to import profile from {0}: {1}"
-msgstr "Échec de l'importation du profil depuis le fichier {0} : {1}"
+msgctxt "@info:status Don't translate the XML tags !"
+msgid "Failed to import profile from {0}: {1}"
+msgstr "Impossible d'importer le profil depuis {0} : {1}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:190
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:181
+#, python-brace-format
+msgctxt "@info:status Don't translate the XML tags !"
+msgid "Can't import profile from {0} before a printer is added."
+msgstr "Impossible d'importer le profil depuis {0} avant l'ajout d'une imprimante."
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:198
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "No custom profile to import in file {0}"
msgstr "Aucun profil personnalisé à importer dans le fichier {0}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:194
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:202
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "Failed to import profile from {0}:"
msgstr "Échec de l'importation du profil depuis le fichier {0} :"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:218
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:228
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:226
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:236
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "This profile {0} contains incorrect data, could not import it."
msgstr "Le profil {0} contient des données incorrectes ; échec de l'importation."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:241
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:325
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags !"
-msgid "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it."
-msgstr "La machine définie dans le profil {0} ({1}) ne correspond pas à votre machine actuelle ({2}) ; échec de l'importation."
-
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:312
-#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
+msgctxt "@info:status Don't translate the XML tag !"
msgid "Failed to import profile from {0}:"
msgstr "Échec de l'importation du profil depuis le fichier {0} :"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:315
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:328
#, python-brace-format
msgctxt "@info:status"
msgid "Successfully imported profile {0}"
msgstr "Importation du profil {0} réussie"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:318
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:331
#, python-brace-format
msgctxt "@info:status"
msgid "File {0} does not contain any valid profile."
msgstr "Le fichier {0} ne contient pas de profil valide."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:321
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:334
#, python-brace-format
msgctxt "@info:status"
msgid "Profile {0} has an unknown file type or is corrupted."
msgstr "Le profil {0} est un type de fichier inconnu ou est corrompu."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:339
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
msgctxt "@label"
msgid "Custom profile"
msgstr "Personnaliser le profil"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:355
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:385
msgctxt "@info:status"
msgid "Profile is missing a quality type."
msgstr "Il manque un type de qualité au profil."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:399
#, python-brace-format
msgctxt "@info:status"
msgid "Could not find a quality type {0} for the current configuration."
msgstr "Impossible de trouver un type de qualité {0} pour la configuration actuelle."
-#: /home/ruben/Projects/Cura/cura/ObjectsModel.py:63
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:76
+msgctxt "@tooltip"
+msgid "Outer Wall"
+msgstr "Paroi externe"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:77
+msgctxt "@tooltip"
+msgid "Inner Walls"
+msgstr "Parois internes"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:78
+msgctxt "@tooltip"
+msgid "Skin"
+msgstr "Couche extérieure"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:79
+msgctxt "@tooltip"
+msgid "Infill"
+msgstr "Remplissage"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:80
+msgctxt "@tooltip"
+msgid "Support Infill"
+msgstr "Remplissage du support"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:81
+msgctxt "@tooltip"
+msgid "Support Interface"
+msgstr "Interface du support"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:82
+msgctxt "@tooltip"
+msgid "Support"
+msgstr "Support"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:83
+msgctxt "@tooltip"
+msgid "Skirt"
+msgstr "Jupe"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:84
+msgctxt "@tooltip"
+msgid "Prime Tower"
+msgstr "Tour primaire"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:85
+msgctxt "@tooltip"
+msgid "Travel"
+msgstr "Déplacement"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:86
+msgctxt "@tooltip"
+msgid "Retractions"
+msgstr "Rétractions"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:87
+msgctxt "@tooltip"
+msgid "Other"
+msgstr "Autre"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:302
+#, python-brace-format
+msgctxt "@label"
+msgid "Pre-sliced file {0}"
+msgstr "Fichier {0} prédécoupé"
+
+#: /home/ruben/Projects/Cura/cura/UI/WelcomePagesModel.py:56
+msgctxt "@action:button"
+msgid "Next"
+msgstr "Suivant"
+
+#: /home/ruben/Projects/Cura/cura/UI/ObjectsModel.py:62
#, python-brace-format
msgctxt "@label"
msgid "Group #{group_nr}"
msgstr "Groupe nº {group_nr}"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:65
-msgctxt "@info:title"
-msgid "Network enabled printers"
-msgstr "Imprimantes réseau"
+#: /home/ruben/Projects/Cura/cura/UI/WhatsNewPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:482
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:124
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:169
+msgctxt "@action:button"
+msgid "Close"
+msgstr "Fermer"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:80
-msgctxt "@info:title"
-msgid "Local printers"
-msgstr "Imprimantes locales"
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
+msgctxt "@action:button"
+msgid "Add"
+msgstr "Ajouter"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:109
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:18
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:81
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:352
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:58
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:149
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:406
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:294
+msgctxt "@action:button"
+msgid "Cancel"
+msgstr "Annuler"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:36
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:320
+msgctxt "@label"
+msgid "Default"
+msgstr "Default"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:39
+msgctxt "@label"
+msgid "Visual"
+msgstr "Visuel"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:40
+msgctxt "@text"
+msgid "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality."
+msgstr "Le profil visuel est conçu pour imprimer des prototypes et des modèles visuels dans le but d'obtenir une qualité visuelle et de surface élevée."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:43
+msgctxt "@label"
+msgid "Engineering"
+msgstr "Engineering"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:44
+msgctxt "@text"
+msgid "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances."
+msgstr "Le profil d'ingénierie est conçu pour imprimer des prototypes fonctionnels et des pièces finales dans le but d'obtenir une meilleure précision et des tolérances"
+" plus étroites."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:47
+msgctxt "@label"
+msgid "Draft"
+msgstr "Ébauche"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:48
+msgctxt "@text"
+msgid "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction."
+msgstr "L'ébauche du profil est conçue pour imprimer les prototypes initiaux et la validation du concept dans le but de réduire considérablement le temps d'impression."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/ExtrudersModel.py:208
+msgctxt "@menuitem"
+msgid "Not overridden"
+msgstr "Pas écrasé"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:357
+msgctxt "@label"
+msgid "Custom profiles"
+msgstr "Personnaliser les profils"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:391
#, python-brace-format
msgctxt "@item:inlistbox"
msgid "All Supported Types ({0})"
msgstr "Tous les types supportés ({0})"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:110
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:392
msgctxt "@item:inlistbox"
msgid "All Files (*)"
msgstr "Tous les fichiers (*)"
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:636
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:213
msgctxt "@label"
msgid "Custom Material"
msgstr "Matériau personnalisé"
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:637
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:214
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:205
msgctxt "@label"
msgid "Custom"
msgstr "Personnalisé"
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:81
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:116
+msgctxt "@label"
+msgid "The printer(s) below cannot be connected because they are part of a group"
+msgstr "Les imprimantes ci-dessous ne peuvent pas être connectées car elles font partie d'un groupe"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:118
+msgctxt "@label"
+msgid "Available networked printers"
+msgstr "Imprimantes en réseau disponibles"
+
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:90
msgctxt "@info:status"
msgid "The build volume height has been reduced due to the value of the \"Print Sequence\" setting to prevent the gantry from colliding with printed models."
msgstr "La hauteur du volume d'impression a été réduite en raison de la valeur du paramètre « Séquence d'impression » afin d'éviter que le portique ne heurte les modèles imprimés."
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:83
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:92
msgctxt "@info:title"
msgid "Build Volume"
msgstr "Volume d'impression"
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:98
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:99
msgctxt "@info:backup_failed"
msgid "Could not create archive from user data directory: {}"
msgstr "Impossible de créer une archive à partir du répertoire de données de l'utilisateur : {}"
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:103
-msgctxt "@info:title"
-msgid "Backup"
-msgstr "Sauvegarde"
-
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:113
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:114
msgctxt "@info:backup_failed"
msgid "Tried to restore a Cura backup without having proper data or meta data."
msgstr "A essayé de restaurer une sauvegarde Cura sans disposer de données ou de métadonnées appropriées."
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:123
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:125
msgctxt "@info:backup_failed"
-msgid "Tried to restore a Cura backup that does not match your current version."
-msgstr "A essayé de restaurer une sauvegarde Cura qui ne correspond pas à votre version actuelle."
+msgid "Tried to restore a Cura backup that is higher than the current version."
+msgstr "A essayé de restaurer une sauvegarde Cura supérieure à la version actuelle."
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:27
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationHelpers.py:79
+msgctxt "@message"
+msgid "Could not read response."
+msgstr "Impossible de lire la réponse."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+msgctxt "@info"
+msgid "Unable to reach the Ultimaker account server."
+msgstr "Impossible d’atteindre le serveur du compte Ultimaker."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:70
+msgctxt "@message"
+msgid "Please give the required permissions when authorizing this application."
+msgstr "Veuillez donner les permissions requises lors de l'autorisation de cette application."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:77
+msgctxt "@message"
+msgid "Something unexpected happened when trying to log in, please try again."
+msgstr "Une erreur s'est produite lors de la connexion, veuillez réessayer."
+
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:29
msgctxt "@info:status"
msgid "Multiplying and placing objects"
msgstr "Multiplication et placement d'objets"
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:28
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:30
msgctxt "@info:title"
-msgid "Placing Object"
-msgstr "Placement de l'objet"
+msgid "Placing Objects"
+msgstr "Placement des objets"
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:96
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:103
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:149
msgctxt "@info:status"
msgid "Unable to find a location within the build volume for all objects"
msgstr "Impossible de trouver un emplacement dans le volume d'impression pour tous les objets"
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+msgctxt "@info:title"
+msgid "Placing Object"
+msgstr "Placement de l'objet"
+
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:30
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:67
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:66
msgctxt "@info:status"
msgid "Finding new location for objects"
msgstr "Recherche d'un nouvel emplacement pour les objets"
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:34
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:71
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:70
msgctxt "@info:title"
msgid "Finding Location"
msgstr "Recherche d'emplacement"
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:97
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:151
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:104
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
msgctxt "@info:title"
msgid "Can't Find Location"
msgstr "Impossible de trouver un emplacement"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:87
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:83
msgctxt "@title:window"
msgid "Cura can't start"
msgstr "Échec du démarrage de Cura"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:93
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:89
msgctxt "@label crash message"
msgid ""
"
Oops, Ultimaker Cura has encountered something that doesn't seem right.
\n"
@@ -1069,356 +1160,328 @@ msgid ""
"
Backups can be found in the configuration folder.
\n"
"
Please send us this Crash Report to fix the problem.
\n"
" "
-msgstr "
Oups, un problème est survenu dans Ultimaker Cura.
\n
Une erreur irrécupérable est survenue lors du démarrage. Elle peut avoir été causée par des fichiers de configuration incorrects. Nous vous suggérons de sauvegarder et de réinitialiser votre configuration.
\n
Les sauvegardes se trouvent dans le dossier de configuration.
\n
Veuillez nous envoyer ce rapport d'incident pour que nous puissions résoudre le problème.
\n "
+msgstr ""
+"
Oups, un problème est survenu dans Ultimaker Cura.
\n"
+"
Une erreur irrécupérable est survenue lors du démarrage. Elle peut avoir été causée par des fichiers de configuration incorrects. Nous vous suggérons de sauvegarder et de réinitialiser votre configuration.
\n"
+"
Les sauvegardes se trouvent dans le dossier de configuration.
\n"
+"
Veuillez nous envoyer ce rapport d'incident pour que nous puissions résoudre le problème.
\n"
+" "
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:102
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:98
msgctxt "@action:button"
msgid "Send crash report to Ultimaker"
msgstr "Envoyer le rapport de d'incident à Ultimaker"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:105
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:101
msgctxt "@action:button"
msgid "Show detailed crash report"
msgstr "Afficher le rapport d'incident détaillé"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:109
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:105
msgctxt "@action:button"
msgid "Show configuration folder"
msgstr "Afficher le dossier de configuration"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:120
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:116
msgctxt "@action:button"
msgid "Backup and Reset Configuration"
msgstr "Sauvegarder et réinitialiser la configuration"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:149
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:145
msgctxt "@title:window"
msgid "Crash Report"
msgstr "Rapport d'incident"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:169
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:165
msgctxt "@label crash message"
msgid ""
"
A fatal error has occurred in Cura. Please send us this Crash Report to fix the problem
\n"
"
Please use the \"Send report\" button to post a bug report automatically to our servers
\n"
" "
-msgstr "
Une erreur fatale est survenue dans Cura. Veuillez nous envoyer ce rapport d'incident pour résoudre le problème
\n
Veuillez utiliser le bouton « Envoyer rapport » pour publier automatiquement un rapport d'erreur sur nos serveurs
\n "
+msgstr ""
+"
Une erreur fatale est survenue dans Cura. Veuillez nous envoyer ce rapport d'incident pour résoudre le problème
\n"
+"
Veuillez utiliser le bouton « Envoyer rapport » pour publier automatiquement un rapport d'erreur sur nos serveurs
"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:222
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:218
msgctxt "@title:groupbox"
msgid "Error traceback"
msgstr "Retraçage de l'erreur"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:303
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:299
msgctxt "@title:groupbox"
msgid "Logs"
msgstr "Journaux"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:326
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:322
msgctxt "@title:groupbox"
-msgid "User description"
-msgstr "Description de l'utilisateur"
+msgid "User description (Note: Developers may not speak your language, please use English if possible)"
+msgstr "Description de l'utilisateur (Remarque : les développeurs peuvent ne pas partler votre langue. Veuillez utiliser l'anglais si possible)"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:345
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:342
msgctxt "@action:button"
msgid "Send report"
msgstr "Envoyer rapport"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:473
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:513
msgctxt "@info:progress"
msgid "Loading machines..."
msgstr "Chargement des machines..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:775
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:520
+msgctxt "@info:progress"
+msgid "Setting up preferences..."
+msgstr "Configuration des préférences..."
+
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:824
msgctxt "@info:progress"
msgid "Setting up scene..."
msgstr "Préparation de la scène..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:811
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:859
msgctxt "@info:progress"
msgid "Loading interface..."
msgstr "Chargement de l'interface..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1037
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1150
#, python-format
msgctxt "@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm."
msgid "%(width).1f x %(depth).1f x %(height).1f mm"
msgstr "%(width).1f x %(depth).1f x %(height).1f mm"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1596
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1657
#, python-brace-format
msgctxt "@info:status"
msgid "Only one G-code file can be loaded at a time. Skipped importing {0}"
msgstr "Un seul fichier G-Code peut être chargé à la fois. Importation de {0} sautée"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1606
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1667
#, python-brace-format
msgctxt "@info:status"
msgid "Can't open any other file if G-code is loading. Skipped importing {0}"
msgstr "Impossible d'ouvrir un autre fichier si le G-Code est en cours de chargement. Importation de {0} sautée"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1694
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1757
msgctxt "@info:status"
msgid "The selected model was too small to load."
msgstr "Le modèle sélectionné était trop petit pour être chargé."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:61
-msgctxt "@title"
-msgid "Machine Settings"
-msgstr "Paramètres de la machine"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:80
-msgctxt "@title:tab"
-msgid "Printer"
-msgstr "Imprimante"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:99
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:56
+msgctxt "@title:label"
msgid "Printer Settings"
msgstr "Paramètres de l'imprimante"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:110
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:70
msgctxt "@label"
msgid "X (Width)"
msgstr "X (Largeur)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:111
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:121
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:131
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:237
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:386
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:402
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:428
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:440
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:896
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:74
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:88
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:102
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:243
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:265
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:285
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:79
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:93
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:109
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:124
msgctxt "@label"
msgid "mm"
msgstr "mm"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:120
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:84
msgctxt "@label"
msgid "Y (Depth)"
msgstr "Y (Profondeur)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:130
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:98
msgctxt "@label"
msgid "Z (Height)"
msgstr "Z (Hauteur)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:142
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:112
msgctxt "@label"
msgid "Build plate shape"
msgstr "Forme du plateau"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:151
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:125
+msgctxt "@label"
msgid "Origin at center"
msgstr "Origine au centre"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:159
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:137
+msgctxt "@label"
msgid "Heated bed"
msgstr "Plateau chauffant"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:170
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:149
+msgctxt "@label"
+msgid "Heated build volume"
+msgstr "Volume de fabrication chauffant"
+
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:161
msgctxt "@label"
msgid "G-code flavor"
msgstr "Parfum G-Code"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:183
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:185
+msgctxt "@title:label"
msgid "Printhead Settings"
msgstr "Paramètres de la tête d'impression"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:193
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:199
msgctxt "@label"
msgid "X min"
msgstr "X min"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:194
-msgctxt "@tooltip"
-msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distance entre la gauche de la tête d'impression et le centre de la buse. Permet d'empêcher les collisions entre les impressions précédentes et la tête d'impression lors d'une impression « Un à la fois »."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:219
msgctxt "@label"
msgid "Y min"
msgstr "Y min"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:204
-msgctxt "@tooltip"
-msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distance entre le devant de la tête d'impression et le centre de la buse. Permet d'empêcher les collisions entre les impressions précédentes et la tête d'impression lors d'une impression « Un à la fois »."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:213
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:239
msgctxt "@label"
msgid "X max"
msgstr "X max"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:214
-msgctxt "@tooltip"
-msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distance entre la droite de la tête d'impression et le centre de la buse. Permet d'empêcher les collisions entre les impressions précédentes et la tête d'impression lors d'une impression « Un à la fois »."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:261
msgctxt "@label"
msgid "Y max"
msgstr "Y max"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:224
-msgctxt "@tooltip"
-msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distance entre le dos de la tête d'impression et le centre de la buse. Permet d'empêcher les collisions entre les impressions précédentes et la tête d'impression lors d'une impression « Un à la fois »."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:236
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:281
msgctxt "@label"
-msgid "Gantry height"
+msgid "Gantry Height"
msgstr "Hauteur du portique"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:238
-msgctxt "@tooltip"
-msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
-msgstr "La différence de hauteur entre la pointe de la buse et le système de portique (axes X et Y). Permet d'empêcher les collisions entre les impressions précédentes et le portique lors d'une impression « Un à la fois »."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:257
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:295
msgctxt "@label"
msgid "Number of Extruders"
msgstr "Nombre d'extrudeuses"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:313
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:355
+msgctxt "@title:label"
msgid "Start G-code"
msgstr "G-Code de démarrage"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:323
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very start."
-msgstr "Commandes G-Code à exécuter au tout début."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:332
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:366
+msgctxt "@title:label"
msgid "End G-code"
msgstr "G-Code de fin"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:342
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very end."
-msgstr "Commandes G-Code à exécuter tout à la fin."
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:42
+msgctxt "@title:tab"
+msgid "Printer"
+msgstr "Imprimante"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:373
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:63
+msgctxt "@title:label"
msgid "Nozzle Settings"
msgstr "Paramètres de la buse"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:385
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:75
msgctxt "@label"
msgid "Nozzle size"
msgstr "Taille de la buse"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:401
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:89
msgctxt "@label"
msgid "Compatible material diameter"
msgstr "Diamètre du matériau compatible"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:403
-msgctxt "@tooltip"
-msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
-msgstr "Le diamètre nominal de filament pris en charge par l'imprimante. Le diamètre exact sera remplacé par le matériau et / ou le profil."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:427
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:105
msgctxt "@label"
msgid "Nozzle offset X"
msgstr "Décalage buse X"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:439
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:120
msgctxt "@label"
msgid "Nozzle offset Y"
msgstr "Décalage buse Y"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:451
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:135
msgctxt "@label"
msgid "Cooling Fan Number"
msgstr "Numéro du ventilateur de refroidissement"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:452
-msgctxt "@label"
-msgid ""
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:472
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:162
+msgctxt "@title:label"
msgid "Extruder Start G-code"
msgstr "Extrudeuse G-Code de démarrage"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:490
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:176
+msgctxt "@title:label"
msgid "Extruder End G-code"
msgstr "Extrudeuse G-Code de fin"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
msgctxt "@action:button"
msgid "Install"
msgstr "Installer"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:20
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
msgctxt "@action:button"
msgid "Installed"
msgstr "Installé"
@@ -1428,69 +1491,82 @@ msgctxt "@info"
msgid "Could not connect to the Cura Package database. Please check your connection."
msgstr "Impossible de se connecter à la base de données Cura Package. Veuillez vérifier votre connexion."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:38
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:28
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/SmallRatingWidget.qml:27
+msgctxt "@label"
+msgid "ratings"
+msgstr "évaluations"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:30
msgctxt "@title:tab"
msgid "Plugins"
msgstr "Plug-ins"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:75
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:42
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:66
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:77
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:44
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:89
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:417
msgctxt "@title:tab"
msgid "Materials"
msgstr "Matériaux"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:79
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+msgctxt "@label"
+msgid "Your rating"
+msgstr "Votre évaluation"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:99
msgctxt "@label"
msgid "Version"
msgstr "Version"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:85
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:106
msgctxt "@label"
msgid "Last updated"
msgstr "Dernière mise à jour"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:113
msgctxt "@label"
msgid "Author"
msgstr "Auteur"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:120
msgctxt "@label"
msgid "Downloads"
msgstr "Téléchargements"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:116
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:158
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:258
-msgctxt "@label"
-msgid "Unknown"
-msgstr "Inconnu"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:56
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to install or update"
+msgstr "Connexion nécessaire pour l'installation ou la mise à jour"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:44
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:30
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:80
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Buy material spools"
+msgstr "Acheter des bobines de matériau"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:96
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:34
msgctxt "@action:button"
msgid "Update"
msgstr "Mise à jour"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:45
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:35
msgctxt "@action:button"
msgid "Updating"
msgstr "Mise à jour"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:98
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:36
msgctxt "@action:button"
msgid "Updated"
msgstr "Mis à jour"
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/Toolbox.qml:13
msgctxt "@title"
-msgid "Toolbox"
-msgstr "Boîte à outils"
+msgid "Marketplace"
+msgstr "Marché en ligne"
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml:25
msgctxt "@action:button"
@@ -1517,52 +1593,67 @@ msgctxt "@text:window"
msgid "Profiles"
msgstr "Profils"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:89
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:90
msgctxt "@action:button"
msgid "Confirm"
msgstr "Confirmer"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to login first before you can rate"
+msgstr "Vous devez être connecté avant de pouvoir effectuer une évaluation"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to install the package before you can rate"
+msgstr "Vous devez installer le paquet avant de pouvoir effectuer une évaluation"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:19
msgctxt "@info"
msgid "You will need to restart Cura before changes in packages have effect."
msgstr "Vous devez redémarrer Cura pour que les changements apportés aux paquets ne prennent effet."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:45
msgctxt "@info:button"
msgid "Quit Cura"
msgstr "Quitter Cura"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Contributions"
msgstr "Contributions de la communauté"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Plugins"
msgstr "Plug-ins de la communauté"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:43
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:40
msgctxt "@label"
msgid "Generic Materials"
msgstr "Matériaux génériques"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:56
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:59
msgctxt "@title:tab"
msgid "Installed"
msgstr "Installé"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:22
msgctxt "@label"
msgid "Will install upon restarting"
msgstr "S'installera au redémarrage"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:53
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to update"
+msgstr "Connexion nécessaire pour effectuer la mise à jour"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Downgrade"
msgstr "Revenir à une version précédente"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Uninstall"
msgstr "Désinstaller"
@@ -1578,14 +1669,17 @@ msgid ""
"This plugin contains a license.\n"
"You need to accept this license to install this plugin.\n"
"Do you agree with the terms below?"
-msgstr "Ce plug-in contient une licence.\nVous devez approuver cette licence pour installer ce plug-in.\nAcceptez-vous les clauses ci-dessous ?"
+msgstr ""
+"Ce plug-in contient une licence.\n"
+"Vous devez approuver cette licence pour installer ce plug-in.\n"
+"Acceptez-vous les clauses ci-dessous ?"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:54
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:55
msgctxt "@action:button"
msgid "Accept"
msgstr "Accepter"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:65
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:66
msgctxt "@action:button"
msgid "Decline"
msgstr "Refuser"
@@ -1595,22 +1689,62 @@ msgctxt "@label"
msgid "Featured"
msgstr "Fonctionnalités"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:34
msgctxt "@label"
msgid "Compatibility"
msgstr "Compatibilité"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:124
+msgctxt "@label:table_header"
+msgid "Machine"
+msgstr "Machine"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:137
+msgctxt "@label:table_header"
+msgid "Build Plate"
+msgstr "Plateau"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:143
+msgctxt "@label:table_header"
+msgid "Support"
+msgstr "Support"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:149
+msgctxt "@label:table_header"
+msgid "Quality"
+msgstr "Qualité"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:170
+msgctxt "@action:label"
+msgid "Technical Data Sheet"
+msgstr "Fiche technique"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:179
+msgctxt "@action:label"
+msgid "Safety Data Sheet"
+msgstr "Fiche de sécurité"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:188
+msgctxt "@action:label"
+msgid "Printing Guidelines"
+msgstr "Directives d'impression"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:197
+msgctxt "@action:label"
+msgid "Website"
+msgstr "Site Internet"
+
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml:16
msgctxt "@info"
msgid "Fetching packages..."
msgstr "Récupération des paquets..."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:88
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:91
msgctxt "@label"
msgid "Website"
msgstr "Site Internet"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:94
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:98
msgctxt "@label"
msgid "Email"
msgstr "E-mail"
@@ -1620,23 +1754,6 @@ msgctxt "@info:tooltip"
msgid "Some things could be problematic in this print. Click to see tips for adjustment."
msgstr "Certains éléments pourraient causer des problèmes à cette impression. Cliquez pour voir les conseils d'ajustement."
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18
-msgctxt "@label"
-msgid "Changelog"
-msgstr "Récapitulatif des changements"
-
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:37
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:53
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:467
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:514
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:121
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:166
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:38
-msgctxt "@action:button"
-msgid "Close"
-msgstr "Fermer"
-
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:31
msgctxt "@title"
msgid "Update Firmware"
@@ -1712,423 +1829,504 @@ msgctxt "@label"
msgid "Firmware update failed due to missing firmware."
msgstr "Échec de la mise à jour du firmware en raison du firmware manquant."
-#: /home/ruben/Projects/Cura/plugins/UserAgreement/UserAgreement.qml:16
-msgctxt "@title:window"
-msgid "User Agreement"
-msgstr "Accord utilisateur"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:155
+msgctxt "@label link to Connect and Cloud interfaces"
+msgid "Manage printer"
+msgstr "Gérer l'imprimante"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:46
-msgctxt "@window:title"
-msgid "Existing Connection"
-msgstr "Connexion existante"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:192
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:183
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:153
+msgctxt "@label"
+msgid "Glass"
+msgstr "Verre"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:48
-msgctxt "@message:text"
-msgid "This printer/group is already added to Cura. Please select another printer/group."
-msgstr "Ce groupe / cette imprimante a déjà été ajouté à Cura. Veuillez sélectionner un autre groupe / imprimante."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:256
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:514
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:248
+msgctxt "@info"
+msgid "Please update your printer's firmware to manage the queue remotely."
+msgstr "Veuillez mettre à jour le Firmware de votre imprimante pour gérer la file d'attente à distance."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:65
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:289
+msgctxt "@info"
+msgid "The webcam is not available because you are monitoring a cloud printer."
+msgstr "La webcam n'est pas disponible car vous surveillez une imprimante cloud."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:348
+msgctxt "@label:status"
+msgid "Loading..."
+msgstr "Chargement..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:352
+msgctxt "@label:status"
+msgid "Unavailable"
+msgstr "Indisponible"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:356
+msgctxt "@label:status"
+msgid "Unreachable"
+msgstr "Injoignable"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:360
+msgctxt "@label:status"
+msgid "Idle"
+msgstr "Inactif"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:401
+msgctxt "@label"
+msgid "Untitled"
+msgstr "Sans titre"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:422
+msgctxt "@label"
+msgid "Anonymous"
+msgstr "Anonyme"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:449
+msgctxt "@label:status"
+msgid "Requires configuration changes"
+msgstr "Nécessite des modifications de configuration"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:487
+msgctxt "@action:button"
+msgid "Details"
+msgstr "Détails"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:132
+msgctxt "@label"
+msgid "Unavailable printer"
+msgstr "Imprimante indisponible"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:134
+msgctxt "@label"
+msgid "First available"
+msgstr "Premier disponible"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:31
+msgctxt "@label"
+msgid "Queued"
+msgstr "Mis en file d'attente"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:67
+msgctxt "@label link to connect manager"
+msgid "Manage in browser"
+msgstr "Gérer dans le navigateur"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:100
+msgctxt "@label"
+msgid "There are no print jobs in the queue. Slice and send a job to add one."
+msgstr "Il n'y a pas de travaux d'impression dans la file d'attente. Découpez et envoyez une tache pour en ajouter une."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:115
+msgctxt "@label"
+msgid "Print jobs"
+msgstr "Tâches d'impression"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:131
+msgctxt "@label"
+msgid "Total print time"
+msgstr "Temps total d'impression"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:147
+msgctxt "@label"
+msgid "Waiting for"
+msgstr "Attente de"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:45
msgctxt "@title:window"
msgid "Connect to Networked Printer"
msgstr "Connecter à l'imprimante en réseau"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:75
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
msgctxt "@label"
-msgid ""
-"To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
-"\n"
-"Select your printer from the list below:"
-msgstr "Pour imprimer directement sur votre imprimante sur le réseau, assurez-vous que votre imprimante est connectée au réseau via un câble réseau ou en connectant votre imprimante à votre réseau Wi-Fi. Si vous ne connectez pas Cura avec votre imprimante, vous pouvez utiliser une clé USB pour transférer les fichiers g-code sur votre imprimante.\n\nSélectionnez votre imprimante dans la liste ci-dessous :"
+msgid "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer."
+msgstr "Pour imprimer directement sur votre imprimante via le réseau, assurez-vous que votre imprimante est connectée au réseau via un câble Ethernet ou en connectant votre imprimante à votre réseau Wi-Fi. Si vous ne connectez pas Cura avec votre imprimante, vous pouvez utiliser une clé USB pour transférer les fichiers g-code sur votre imprimante."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:85
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:42
-msgctxt "@action:button"
-msgid "Add"
-msgstr "Ajouter"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
+msgctxt "@label"
+msgid "Select your printer from the list below:"
+msgstr "Sélectionnez votre imprimante dans la liste ci-dessous :"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:95
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:77
msgctxt "@action:button"
msgid "Edit"
msgstr "Modifier"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:106
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:128
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:117
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:88
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:138
msgctxt "@action:button"
msgid "Remove"
msgstr "Supprimer"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:114
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:96
msgctxt "@action:button"
msgid "Refresh"
msgstr "Rafraîchir"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:207
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:176
msgctxt "@label"
msgid "If your printer is not listed, read the network printing troubleshooting guide"
msgstr "Si votre imprimante n'apparaît pas dans la liste, lisez le guide de dépannage de l'impression en réseau"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:234
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:205
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:258
msgctxt "@label"
msgid "Type"
msgstr "Type"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:271
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:274
msgctxt "@label"
msgid "Firmware version"
msgstr "Version du firmware"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:290
msgctxt "@label"
msgid "Address"
msgstr "Adresse"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:305
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:263
msgctxt "@label"
msgid "This printer is not set up to host a group of printers."
msgstr "Cette imprimante n'est pas configurée pour héberger un groupe d'imprimantes."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:309
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:267
msgctxt "@label"
msgid "This printer is the host for a group of %1 printers."
msgstr "Cette imprimante est l'hôte d'un groupe d'imprimantes %1."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:319
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:278
msgctxt "@label"
msgid "The printer at this address has not yet responded."
msgstr "L'imprimante à cette adresse n'a pas encore répondu."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:324
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
msgctxt "@action:button"
msgid "Connect"
msgstr "Connecter"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:338
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:296
+msgctxt "@title:window"
+msgid "Invalid IP address"
+msgstr "Adresse IP non valide"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:146
+msgctxt "@text"
+msgid "Please enter a valid IP address."
+msgstr "Veuillez saisir une adresse IP valide."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:308
msgctxt "@title:window"
msgid "Printer Address"
msgstr "Adresse de l'imprimante"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
-msgctxt "@alabel"
-msgid "Enter the IP address or hostname of your printer on the network."
-msgstr "Saisissez l'adresse IP ou le nom d'hôte de votre imprimante sur le réseau."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:102
+msgctxt "@label"
+msgid "Enter the IP address of your printer on the network."
+msgstr "Saisissez l'adresse IP de votre imprimante sur le réseau."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:390
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:132
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:138
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:181
msgctxt "@action:button"
msgid "OK"
msgstr "OK"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:44
-msgctxt "@action:button"
-msgid "Print"
-msgstr "Imprimer"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:47
-msgctxt "@title:window"
-msgid "Print over network"
-msgstr "Imprimer sur le réseau"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:79
-msgctxt "@label"
-msgid "Printer selection"
-msgstr "Sélection d'imprimantes"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:173
-msgctxt "@label"
-msgid "Not available"
-msgstr "Non disponible"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:175
-msgctxt "@label"
-msgid "Unreachable"
-msgstr "Injoignable"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:180
-msgctxt "@label"
-msgid "Available"
-msgstr "Disponible"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:37
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:44
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:46
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:78
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:90
msgctxt "@label:status"
msgid "Aborted"
msgstr "Abandonné"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:39
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:80
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:82
msgctxt "@label:status"
msgid "Finished"
msgstr "Terminé"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:84
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:86
msgctxt "@label:status"
-msgid "Preparing"
-msgstr "Préparation"
+msgid "Preparing..."
+msgstr "Préparation..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:48
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:88
msgctxt "@label:status"
-msgid "Pausing"
-msgstr "Mise en pause"
+msgid "Aborting..."
+msgstr "Abandon..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:52
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:92
msgctxt "@label:status"
-msgid "Resuming"
-msgstr "Reprise"
+msgid "Pausing..."
+msgstr "Mise en pause..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:54
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:94
+msgctxt "@label:status"
+msgid "Paused"
+msgstr "En pause"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:96
+msgctxt "@label:status"
+msgid "Resuming..."
+msgstr "Reprise..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:98
msgctxt "@label:status"
msgid "Action required"
msgstr "Action requise"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:213
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:100
+msgctxt "@label:status"
+msgid "Finishes %1 at %2"
+msgstr "Finit %1 à %2"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:11
+msgctxt "@title:window"
+msgid "Print over network"
+msgstr "Imprimer sur le réseau"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:52
+msgctxt "@action:button"
+msgid "Print"
+msgstr "Imprimer"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:80
msgctxt "@label"
-msgid "Waiting for: Unavailable printer"
-msgstr "En attente : imprimante non disponible"
+msgid "Printer selection"
+msgstr "Sélection d'imprimantes"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:215
-msgctxt "@label"
-msgid "Waiting for: First available"
-msgstr "En attente : première imprimante disponible"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:217
-msgctxt "@label"
-msgid "Waiting for: "
-msgstr "En attente : "
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:299
-msgctxt "@label"
-msgid "Configuration change"
-msgstr "Modification des configurations"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:365
-msgctxt "@label"
-msgid "The assigned printer, %1, requires the following configuration change(s):"
-msgstr "L'imprimante assignée, %1, nécessite d'apporter la ou les modifications suivantes à la configuration :"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:367
-msgctxt "@label"
-msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
-msgstr "L'imprimante %1 est assignée, mais le projet contient une configuration matérielle inconnue."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:375
-msgctxt "@label"
-msgid "Change material %1 from %2 to %3."
-msgstr "Changer le matériau %1 de %2 à %3."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:378
-msgctxt "@label"
-msgid "Load %3 as material %1 (This cannot be overridden)."
-msgstr "Charger %3 comme matériau %1 (Ceci ne peut pas être remplacé)."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:381
-msgctxt "@label"
-msgid "Change print core %1 from %2 to %3."
-msgstr "Changer le print core %1 de %2 à %3."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:384
-msgctxt "@label"
-msgid "Change build plate to %1 (This cannot be overridden)."
-msgstr "Changer le plateau en %1 (Ceci ne peut pas être remplacé)."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:404
-msgctxt "@label"
-msgid "Override"
-msgstr "Remplacer"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:432
-msgctxt "@label"
-msgid "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?"
-msgstr "Le fait de démarrer un travail d'impression avec une configuration incompatible peut endommager votre imprimante 3D. Êtes-vous sûr de vouloir remplacer la configuration et imprimer %1 ?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:435
-msgctxt "@window:title"
-msgid "Override configuration configuration and start print"
-msgstr "Remplacer la configuration et lancer l'impression"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:466
-msgctxt "@label"
-msgid "Glass"
-msgstr "Verre"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:469
-msgctxt "@label"
-msgid "Aluminum"
-msgstr "Aluminium"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:39
-msgctxt "@label link to connect manager"
-msgid "Manage queue"
-msgstr "Gérer la file d'attente"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:60
-msgctxt "@label"
-msgid "Queued"
-msgstr "Mis en file d'attente"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:36
-msgctxt "@label"
-msgid "Printing"
-msgstr "Impression"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:49
-msgctxt "@label link to connect manager"
-msgid "Manage printers"
-msgstr "Gérer les imprimantes"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:115
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:54
msgctxt "@label"
msgid "Move to top"
msgstr "Déplacer l'impression en haut"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:124
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:70
msgctxt "@label"
msgid "Delete"
msgstr "Effacer"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:100
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:289
msgctxt "@label"
msgid "Resume"
msgstr "Reprendre"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:102
+msgctxt "@label"
+msgid "Pausing..."
+msgstr "Mise en pause..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:104
+msgctxt "@label"
+msgid "Resuming..."
+msgstr "Reprise..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:106
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:284
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:293
msgctxt "@label"
msgid "Pause"
msgstr "Pause"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:146
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
+msgctxt "@label"
+msgid "Aborting..."
+msgstr "Abandon..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
msgctxt "@label"
msgid "Abort"
msgstr "Abandonner"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:178
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:143
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to move %1 to the top of the queue?"
msgstr "Êtes-vous sûr de vouloir déplacer %1 en haut de la file d'attente ?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:179
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:144
msgctxt "@window:title"
msgid "Move print job to top"
msgstr "Déplacer l'impression en haut de la file d'attente"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:188
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:153
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to delete %1?"
msgstr "Êtes-vous sûr de vouloir supprimer %1 ?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:189
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:154
msgctxt "@window:title"
msgid "Delete print job"
msgstr "Supprimer l'impression"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:198
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:163
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to abort %1?"
msgstr "Êtes-vous sûr de vouloir annuler %1 ?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:199
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:164
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:335
msgctxt "@window:title"
msgid "Abort print"
msgstr "Abandonner l'impression"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:43
-msgctxt "@info:tooltip"
-msgid "Connect to a printer"
-msgstr "Connecter à une imprimante"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:20
+msgctxt "@title:window"
+msgid "Configuration Changes"
+msgstr "Modifications de configuration"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:121
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:27
msgctxt "@action:button"
-msgid "Activate Configuration"
-msgstr "Activer la configuration"
+msgid "Override"
+msgstr "Remplacer"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:122
-msgctxt "@info:tooltip"
-msgid "Load the configuration of the printer into Cura"
-msgstr "Charger la configuration de l'imprimante dans Cura"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:85
+msgctxt "@label"
+msgid "The assigned printer, %1, requires the following configuration change:"
+msgid_plural "The assigned printer, %1, requires the following configuration changes:"
+msgstr[0] "L'imprimante assignée, %1, nécessite la modification de configuration suivante :"
+msgstr[1] "L'imprimante assignée, %1, nécessite les modifications de configuration suivantes :"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:130
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:89
+msgctxt "@label"
+msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
+msgstr "L'imprimante %1 est assignée, mais le projet contient une configuration matérielle inconnue."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:99
+msgctxt "@label"
+msgid "Change material %1 from %2 to %3."
+msgstr "Changer le matériau %1 de %2 à %3."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:102
+msgctxt "@label"
+msgid "Load %3 as material %1 (This cannot be overridden)."
+msgstr "Charger %3 comme matériau %1 (Ceci ne peut pas être remplacé)."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:105
+msgctxt "@label"
+msgid "Change print core %1 from %2 to %3."
+msgstr "Changer le print core %1 de %2 à %3."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:108
+msgctxt "@label"
+msgid "Change build plate to %1 (This cannot be overridden)."
+msgstr "Changer le plateau en %1 (Ceci ne peut pas être remplacé)."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:115
+msgctxt "@label"
+msgid "Override will use the specified settings with the existing printer configuration. This may result in a failed print."
+msgstr "Si vous sélectionnez « Remplacer », les paramètres de la configuration actuelle de l'imprimante seront utilisés. Cela peut entraîner l'échec de l'impression."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:156
+msgctxt "@label"
+msgid "Aluminum"
+msgstr "Aluminium"
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:100
+msgctxt "@info"
+msgid ""
+"Please make sure your printer has a connection:\n"
+"- Check if the printer is turned on.\n"
+"- Check if the printer is connected to the network.\n"
+"- Check if you are signed in to discover cloud-connected printers."
+msgstr ""
+"Assurez-vous que votre imprimante est connectée :\n"
+"- Vérifiez si l'imprimante est sous tension.\n"
+"- Vérifiez si l'imprimante est connectée au réseau.- Vérifiez si vous êtes connecté pour découvrir les imprimantes connectées au cloud."
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:117
+msgctxt "@info"
+msgid "Please connect your printer to the network."
+msgstr "Veuillez connecter votre imprimante au réseau."
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:156
+msgctxt "@label link to technical assistance"
+msgid "View user manuals online"
+msgstr "Voir les manuels d'utilisation en ligne"
+
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:20
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:49
msgctxt "@label"
msgid "Color scheme"
msgstr "Modèle de couleurs"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:145
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:107
msgctxt "@label:listbox"
msgid "Material Color"
msgstr "Couleur du matériau"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:149
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:111
msgctxt "@label:listbox"
msgid "Line Type"
msgstr "Type de ligne"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:153
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:115
msgctxt "@label:listbox"
msgid "Feedrate"
msgstr "Taux d'alimentation"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:157
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:119
msgctxt "@label:listbox"
msgid "Layer thickness"
msgstr "Épaisseur de la couche"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:198
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:156
msgctxt "@label"
msgid "Compatibility Mode"
msgstr "Mode de compatibilité"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:284
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:230
msgctxt "@label"
-msgid "Show Travels"
-msgstr "Afficher les déplacements"
+msgid "Travels"
+msgstr "Déplacements"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:290
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:236
msgctxt "@label"
-msgid "Show Helpers"
-msgstr "Afficher les aides"
+msgid "Helpers"
+msgstr "Aides"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:296
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:242
msgctxt "@label"
-msgid "Show Shell"
-msgstr "Afficher la coque"
+msgid "Shell"
+msgstr "Coque"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:302
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:248
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:65
msgctxt "@label"
-msgid "Show Infill"
-msgstr "Afficher le remplissage"
+msgid "Infill"
+msgstr "Remplissage"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:355
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:298
msgctxt "@label"
msgid "Only Show Top Layers"
msgstr "Afficher uniquement les couches supérieures"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:366
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:308
msgctxt "@label"
msgid "Show 5 Detailed Layers On Top"
msgstr "Afficher 5 niveaux détaillés en haut"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:379
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:322
msgctxt "@label"
msgid "Top / Bottom"
msgstr "Haut / bas"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:383
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:326
msgctxt "@label"
msgid "Inner Wall"
msgstr "Paroi interne"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:448
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:384
msgctxt "@label"
msgid "min"
msgstr "min."
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:500
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:433
msgctxt "@label"
msgid "max"
msgstr "max."
@@ -2143,40 +2341,40 @@ msgctxt "@label"
msgid "Post Processing Scripts"
msgstr "Scripts de post-traitement"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:227
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:233
msgctxt "@action"
msgid "Add a script"
msgstr "Ajouter un script"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:273
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:279
msgctxt "@label"
msgid "Settings"
msgstr "Paramètres"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:477
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:493
msgctxt "@info:tooltip"
msgid "Change active post-processing scripts"
msgstr "Modifier les scripts de post-traitement actifs"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:16
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:17
msgctxt "@title:window"
msgid "More information on anonymous data collection"
msgstr "Plus d'informations sur la collecte de données anonymes"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:66
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:74
msgctxt "@text:window"
-msgid "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent."
-msgstr "Cura envoie des données anonymes à Ultimaker afin d'améliorer la qualité d'impression et l'expérience utilisateur. Voici un exemple de toutes les données envoyées."
+msgid "Ultimaker Cura collects anonymous data in order to improve the print quality and user experience. Below is an example of all the data that is shared:"
+msgstr "Ultimaker Cura recueille des données anonymes afin d'améliorer la qualité d'impression et l'expérience utilisateur. Voici un exemple de toutes les données partagées :"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:101
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:109
msgctxt "@text:window"
-msgid "I don't want to send these data"
-msgstr "Je ne veux pas envoyer ces données"
+msgid "I don't want to send anonymous data"
+msgstr "Je ne veux pas envoyer de données anonymes"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:111
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:118
msgctxt "@text:window"
-msgid "Allow sending these data to Ultimaker and help us improve Cura"
-msgstr "Permettre l'envoi de ces données à Ultimaker et nous aider à améliorer Cura"
+msgid "Allow sending anonymous data"
+msgstr "Autoriser l'envoi de données anonymes"
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:19
msgctxt "@title:window"
@@ -2225,19 +2423,19 @@ msgstr "Profondeur (mm)"
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:126
msgctxt "@info:tooltip"
-msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
-msgstr "Par défaut, les pixels blancs représentent les points hauts sur la maille tandis que les pixels noirs représentent les points bas sur la maille. Modifiez cette option pour inverser le comportement de manière à ce que les pixels noirs représentent les points hauts sur la maille et les pixels blancs les points bas."
-
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
-msgctxt "@item:inlistbox"
-msgid "Lighter is higher"
-msgstr "Le plus clair est plus haut"
+msgid "For lithophanes dark pixels should correspond to thicker locations in order to block more light coming through. For height maps lighter pixels signify higher terrain, so lighter pixels should correspond to thicker locations in the generated 3D model."
+msgstr "Pour les lithophanies, les pixels foncés doivent correspondre à des emplacements plus épais afin d'empêcher la lumière de passer. Pour des cartes de hauteur, les pixels clairs signifient un terrain plus élevé, de sorte que les pixels clairs doivent correspondre à des emplacements plus épais dans le modèle 3D généré."
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
msgctxt "@item:inlistbox"
msgid "Darker is higher"
msgstr "Le plus foncé est plus haut"
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
+msgctxt "@item:inlistbox"
+msgid "Lighter is higher"
+msgstr "Le plus clair est plus haut"
+
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:149
msgctxt "@info:tooltip"
msgid "The amount of smoothing to apply to the image."
@@ -2248,81 +2446,80 @@ msgctxt "@action:label"
msgid "Smoothing"
msgstr "Lissage"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:37
-msgctxt "@label"
-msgid "Mesh Type"
-msgstr "Type de maille"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:68
-msgctxt "@label"
-msgid "Normal model"
-msgstr "Modèle normal"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:75
-msgctxt "@label"
-msgid "Print as support"
-msgstr "Imprimer comme support"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:83
-msgctxt "@label"
-msgid "Don't support overlap with other models"
-msgstr "Ne pas prendre en charge le chevauchement avec d'autres modèles"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:91
-msgctxt "@label"
-msgid "Modify settings for overlap with other models"
-msgstr "Modifier les paramètres de chevauchement avec d'autres modèles"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:99
-msgctxt "@label"
-msgid "Modify settings for infill of other models"
-msgstr "Modifier les paramètres de remplissage d'autres modèles"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:347
-msgctxt "@action:button"
-msgid "Select settings"
-msgstr "Sélectionner les paramètres"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:389
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:13
msgctxt "@title:window"
msgid "Select Settings to Customize for this model"
msgstr "Sélectionner les paramètres pour personnaliser ce modèle"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:437
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:98
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:56
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:94
msgctxt "@label:textbox"
msgid "Filter..."
msgstr "Filtrer..."
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:451
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:70
msgctxt "@label:checkbox"
msgid "Show all"
msgstr "Afficher tout"
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:44
+msgctxt "@label"
+msgid "Mesh Type"
+msgstr "Type de maille"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:85
+msgctxt "@label"
+msgid "Normal model"
+msgstr "Modèle normal"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:97
+msgctxt "@label"
+msgid "Print as support"
+msgstr "Imprimer comme support"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:109
+msgctxt "@label"
+msgid "Modify settings for overlaps"
+msgstr "Modifier les paramètres de chevauchement"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:121
+msgctxt "@label"
+msgid "Don't support overlaps"
+msgstr "Ne prend pas en charge le chevauchement"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:145
+msgctxt "@action:checkbox"
+msgid "Infill only"
+msgstr "Remplissage uniquement"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:368
+msgctxt "@action:button"
+msgid "Select settings"
+msgstr "Sélectionner les paramètres"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:14
msgctxt "@title:window"
msgid "Open Project"
msgstr "Ouvrir un projet"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:58
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Update/override existing profile"
msgid "Update existing"
msgstr "Mettre à jour l'existant"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:59
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Save settings in a new profile"
msgid "Create new"
msgstr "Créer"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:70
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:73
msgctxt "@action:title"
msgid "Summary - Cura Project"
msgstr "Résumé - Projet Cura"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:92
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:97
msgctxt "@action:label"
msgid "Printer settings"
msgstr "Paramètres de l'imprimante"
@@ -2338,20 +2535,25 @@ msgctxt "@action:ComboBox option"
msgid "Update"
msgstr "Mise à jour"
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
+msgctxt "@action:ComboBox option"
+msgid "Create new"
+msgstr "Créer"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:143
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:105
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:106
msgctxt "@action:label"
msgid "Type"
msgstr "Type"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:159
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
msgctxt "@action:label"
msgid "Printer Group"
msgstr "Groupe d'imprimantes"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:180
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:196
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:220
msgctxt "@action:label"
msgid "Profile settings"
msgstr "Paramètres de profil"
@@ -2362,226 +2564,222 @@ msgid "How should the conflict in the profile be resolved?"
msgstr "Comment le conflit du profil doit-il être résolu ?"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:216
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:220
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:323
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:244
msgctxt "@action:label"
msgid "Name"
msgstr "Nom"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:231
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:204
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:261
+msgctxt "@action:label"
+msgid "Intent"
+msgstr "Intent"
+
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:246
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:228
msgctxt "@action:label"
msgid "Not in profile"
msgstr "Absent du profil"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:236
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:209
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:251
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:233
msgctxt "@action:label"
msgid "%1 override"
msgid_plural "%1 overrides"
msgstr[0] "%1 écrasent"
msgstr[1] "%1 écrase"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:247
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:262
msgctxt "@action:label"
msgid "Derivative from"
msgstr "Dérivé de"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:252
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:267
msgctxt "@action:label"
msgid "%1, %2 override"
msgid_plural "%1, %2 overrides"
msgstr[0] "%1, %2 écrasent"
msgstr[1] "%1, %2 écrase"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:268
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:283
msgctxt "@action:label"
msgid "Material settings"
msgstr "Paramètres du matériau"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:284
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:299
msgctxt "@info:tooltip"
msgid "How should the conflict in the material be resolved?"
msgstr "Comment le conflit du matériau doit-il être résolu ?"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:327
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:237
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:342
msgctxt "@action:label"
msgid "Setting visibility"
msgstr "Visibilité des paramètres"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:336
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:351
msgctxt "@action:label"
msgid "Mode"
msgstr "Mode"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:352
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:246
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:367
msgctxt "@action:label"
msgid "Visible settings:"
msgstr "Paramètres visibles :"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:357
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:251
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:372
msgctxt "@action:label"
msgid "%1 out of %2"
msgstr "%1 sur %2"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:383
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:398
msgctxt "@action:warning"
msgid "Loading a project will clear all models on the build plate."
msgstr "Le chargement d'un projet effacera tous les modèles sur le plateau."
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:401
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:416
msgctxt "@action:button"
msgid "Open"
msgstr "Ouvrir"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:26
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:25
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:28
msgctxt "@title"
-msgid "Select Printer Upgrades"
-msgstr "Sélectionner les mises à niveau de l'imprimante"
+msgid "My Backups"
+msgstr "Mes sauvegardes"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:38
-msgctxt "@label"
-msgid "Please select any upgrades made to this Ultimaker 2."
-msgstr "Sélectionnez les mises à niveau disponibles pour cet Ultimaker 2."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:38
+msgctxt "@empty_state"
+msgid "You don't have any backups currently. Use the 'Backup Now' button to create one."
+msgstr "Vous n'avez actuellement aucune sauvegarde. Utilisez le bouton « Sauvegarder maintenant » pour en créer une."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:47
-msgctxt "@label"
-msgid "Olsson Block"
-msgstr "Blocage Olsson"
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:60
+msgctxt "@backup_limit_info"
+msgid "During the preview phase, you'll be limited to 5 visible backups. Remove a backup to see older ones."
+msgstr "Pendant la phase de prévisualisation, vous ne pourrez voir qu'un maximum de 5 sauvegardes. Supprimez une sauvegarde pour voir les plus anciennes."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:27
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:34
+msgctxt "@description"
+msgid "Backup and synchronize your Cura settings."
+msgstr "Sauvegardez et synchronisez vos paramètres Cura."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:51
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:68
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:138
+msgctxt "@button"
+msgid "Sign in"
+msgstr "Se connecter"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/main.qml:24
+msgctxt "@title:window"
+msgid "Cura Backups"
+msgstr "Sauvegardes Cura"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:21
+msgctxt "@backuplist:label"
+msgid "Cura Version"
+msgstr "Version Cura"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:29
+msgctxt "@backuplist:label"
+msgid "Machines"
+msgstr "Machines"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:37
+msgctxt "@backuplist:label"
+msgid "Materials"
+msgstr "Matériaux"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:45
+msgctxt "@backuplist:label"
+msgid "Profiles"
+msgstr "Profils"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:53
+msgctxt "@backuplist:label"
+msgid "Plugins"
+msgstr "Plug-ins"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:71
+msgctxt "@button"
+msgid "Restore"
+msgstr "Restaurer"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:99
+msgctxt "@dialog:title"
+msgid "Delete Backup"
+msgstr "Supprimer la sauvegarde"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:100
+msgctxt "@dialog:info"
+msgid "Are you sure you want to delete this backup? This cannot be undone."
+msgstr "Êtes-vous sûr de vouloir supprimer cette sauvegarde ? Il est impossible d'annuler cette action."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:108
+msgctxt "@dialog:title"
+msgid "Restore Backup"
+msgstr "Restaurer la sauvegarde"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:109
+msgctxt "@dialog:info"
+msgid "You will need to restart Cura before your backup is restored. Do you want to close Cura now?"
+msgstr "Vous devez redémarrer Cura avant que votre sauvegarde ne soit restaurée. Voulez-vous fermer Cura maintenant ?"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:22
+msgctxt "@button"
+msgid "Want more?"
+msgstr "Vous en voulez plus ?"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:31
+msgctxt "@button"
+msgid "Backup Now"
+msgstr "Sauvegarder maintenant"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:43
+msgctxt "@checkbox:description"
+msgid "Auto Backup"
+msgstr "Sauvegarde automatique"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:44
+msgctxt "@checkbox:description"
+msgid "Automatically create a backup each day that Cura is started."
+msgstr "Créez automatiquement une sauvegarde chaque jour où Cura est démarré."
+
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:30
msgctxt "@title"
msgid "Build Plate Leveling"
msgstr "Nivellement du plateau"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:38
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:44
msgctxt "@label"
msgid "To make sure your prints will come out great, you can now adjust your buildplate. When you click 'Move to Next Position' the nozzle will move to the different positions that can be adjusted."
msgstr "Pour obtenir des résultats d'impression optimaux, vous pouvez maintenant régler votre plateau. Quand vous cliquez sur 'Aller à la position suivante', la buse se déplacera vers les différentes positions pouvant être réglées."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:47
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:57
msgctxt "@label"
msgid "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle."
msgstr "Pour chacune des positions ; glissez un bout de papier sous la buse et ajustez la hauteur du plateau. La hauteur du plateau est juste lorsque la pointe de la buse gratte légèrement le papier."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:62
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:75
msgctxt "@action:button"
msgid "Start Build Plate Leveling"
msgstr "Démarrer le nivellement du plateau"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:74
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:87
msgctxt "@action:button"
msgid "Move to Next Position"
msgstr "Aller à la position suivante"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:37
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:30
msgctxt "@label"
msgid "Please select any upgrades made to this Ultimaker Original"
msgstr "Sélectionnez les mises à niveau disponibles pour cet Ultimaker Original"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:45
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:41
msgctxt "@label"
msgid "Heated Build Plate (official kit or self-built)"
msgstr "Plateau chauffant (kit officiel ou fabriqué soi-même)"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:27
-msgctxt "@title"
-msgid "Check Printer"
-msgstr "Tester l'imprimante"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:39
-msgctxt "@label"
-msgid "It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional"
-msgstr "Il est préférable de procéder à quelques tests de fonctionnement sur votre Ultimaker. Vous pouvez passer cette étape si vous savez que votre machine est fonctionnelle"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:53
-msgctxt "@action:button"
-msgid "Start Printer Check"
-msgstr "Démarrer le test de l'imprimante"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:80
-msgctxt "@label"
-msgid "Connection: "
-msgstr "Connexion : "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Connected"
-msgstr "Connecté"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Not connected"
-msgstr "Non connecté"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:99
-msgctxt "@label"
-msgid "Min endstop X: "
-msgstr "Fin de course X : "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-msgctxt "@info:status"
-msgid "Works"
-msgstr "Fonctionne"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:173
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Not checked"
-msgstr "Non testé"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:120
-msgctxt "@label"
-msgid "Min endstop Y: "
-msgstr "Fin de course Y : "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:141
-msgctxt "@label"
-msgid "Min endstop Z: "
-msgstr "Fin de course Z : "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:163
-msgctxt "@label"
-msgid "Nozzle temperature check: "
-msgstr "Test de la température de la buse : "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Stop Heating"
-msgstr "Arrêter le chauffage"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Start Heating"
-msgstr "Démarrer le chauffage"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:223
-msgctxt "@label"
-msgid "Build plate temperature check:"
-msgstr "Contrôle de la température du plateau :"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Checked"
-msgstr "Contrôlée"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:284
-msgctxt "@label"
-msgid "Everything is in order! You're done with your CheckUp."
-msgstr "Tout est en ordre ! Vous avez terminé votre check-up."
-
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:119
msgctxt "@label:MonitorStatus"
msgid "Not connected to a printer"
@@ -2593,7 +2791,6 @@ msgid "Printer does not accept commands"
msgstr "L'imprimante n'accepte pas les commandes"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:133
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:197
msgctxt "@label:MonitorStatus"
msgid "In maintenance. Please check the printer"
msgstr "En maintenance. Vérifiez l'imprimante"
@@ -2604,19 +2801,16 @@ msgid "Lost connection with the printer"
msgstr "Connexion avec l'imprimante perdue"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:146
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:187
msgctxt "@label:MonitorStatus"
msgid "Printing..."
msgstr "Impression..."
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:149
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:189
msgctxt "@label:MonitorStatus"
msgid "Paused"
msgstr "En pause"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:152
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:191
msgctxt "@label:MonitorStatus"
msgid "Preparing..."
msgstr "Préparation..."
@@ -2636,233 +2830,176 @@ msgctxt "@label"
msgid "Are you sure you want to abort the print?"
msgstr "Êtes-vous sûr(e) de vouloir abandonner l'impression ?"
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:15
-msgctxt "@title:window"
-msgid "Discard or Keep changes"
-msgstr "Annuler ou conserver les modifications"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:57
-msgctxt "@text:window"
-msgid ""
-"You have customized some profile settings.\n"
-"Would you like to keep or discard those settings?"
-msgstr "Vous avez personnalisé certains paramètres du profil.\nSouhaitez-vous conserver ces changements, ou les annuler ?"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:110
-msgctxt "@title:column"
-msgid "Profile settings"
-msgstr "Paramètres du profil"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:117
-msgctxt "@title:column"
-msgid "Default"
-msgstr "Par défaut"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:124
-msgctxt "@title:column"
-msgid "Customized"
-msgstr "Personnalisé"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:157
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:637
-msgctxt "@option:discardOrKeep"
-msgid "Always ask me this"
-msgstr "Toujours me demander"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:158
-msgctxt "@option:discardOrKeep"
-msgid "Discard and never ask again"
-msgstr "Annuler et ne plus me demander"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:159
-msgctxt "@option:discardOrKeep"
-msgid "Keep and never ask again"
-msgstr "Conserver et ne plus me demander"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:196
-msgctxt "@action:button"
-msgid "Discard"
-msgstr "Annuler"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:209
-msgctxt "@action:button"
-msgid "Keep"
-msgstr "Conserver"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:222
-msgctxt "@action:button"
-msgid "Create New Profile"
-msgstr "Créer un nouveau profil"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:71
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:72
msgctxt "@title"
msgid "Information"
msgstr "Informations"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:100
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
msgctxt "@title:window"
msgid "Confirm Diameter Change"
msgstr "Confirmer le changement de diamètre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:102
msgctxt "@label (%1 is a number)"
msgid "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?"
msgstr "Le nouveau diamètre de filament est réglé sur %1 mm, ce qui n'est pas compatible avec l'extrudeuse actuelle. Souhaitez-vous poursuivre ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:128
msgctxt "@label"
msgid "Display Name"
msgstr "Afficher le nom"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:143
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:138
msgctxt "@label"
msgid "Brand"
msgstr "Marque"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:148
msgctxt "@label"
msgid "Material Type"
msgstr "Type de matériau"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:158
msgctxt "@label"
msgid "Color"
msgstr "Couleur"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:212
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:208
msgctxt "@label"
msgid "Properties"
msgstr "Propriétés"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:214
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:210
msgctxt "@label"
msgid "Density"
msgstr "Densité"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:229
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:225
msgctxt "@label"
msgid "Diameter"
msgstr "Diamètre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:263
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:259
msgctxt "@label"
msgid "Filament Cost"
msgstr "Coût du filament"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:280
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:276
msgctxt "@label"
msgid "Filament weight"
msgstr "Poids du filament"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:298
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:294
msgctxt "@label"
msgid "Filament length"
msgstr "Longueur du filament"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:307
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:303
msgctxt "@label"
msgid "Cost per Meter"
msgstr "Coût au mètre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:321
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:317
msgctxt "@label"
msgid "This material is linked to %1 and shares some of its properties."
msgstr "Ce matériau est lié à %1 et partage certaines de ses propriétés."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:328
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:324
msgctxt "@label"
msgid "Unlink Material"
msgstr "Délier le matériau"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:335
msgctxt "@label"
msgid "Description"
msgstr "Description"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:352
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:348
msgctxt "@label"
msgid "Adhesion Information"
msgstr "Informations d'adhérence"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:378
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:19
msgctxt "@label"
msgid "Print settings"
msgstr "Paramètres d'impression"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:84
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:35
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:108
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:40
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:84
msgctxt "@action:button"
msgid "Activate"
msgstr "Activer"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:126
msgctxt "@action:button"
msgid "Create"
msgstr "Créer"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:140
msgctxt "@action:button"
msgid "Duplicate"
msgstr "Dupliquer"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:141
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:170
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:167
msgctxt "@action:button"
msgid "Import"
msgstr "Importer"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:154
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:184
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:179
msgctxt "@action:button"
msgid "Export"
msgstr "Exporter"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:233
msgctxt "@action:label"
msgid "Printer"
msgstr "Imprimante"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:262
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:274
msgctxt "@title:window"
msgid "Confirm Remove"
msgstr "Confirmer la suppression"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:263
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:240
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:300
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:275
msgctxt "@label (%1 is object name)"
msgid "Are you sure you wish to remove %1? This cannot be undone!"
msgstr "Êtes-vous sûr de vouloir supprimer l'objet %1 ? Vous ne pourrez pas revenir en arrière !"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:277
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:285
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:314
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:322
msgctxt "@title:window"
msgid "Import Material"
msgstr "Importer un matériau"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:286
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:323
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Could not import material %1: %2"
msgstr "Impossible d'importer le matériau %1 : %2"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:290
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:327
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully imported material %1"
msgstr "Matériau %1 importé avec succès"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:316
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:345
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:353
msgctxt "@title:window"
msgid "Export Material"
msgstr "Exporter un matériau"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:320
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:357
msgctxt "@info:status Don't translate the XML tags and !"
msgid "Failed to export material to %1: %2"
msgstr "Échec de l'exportation de matériau vers %1 : %2"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:326
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:363
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully exported material to %1"
msgstr "Matériau exporté avec succès vers %1"
@@ -2872,817 +3009,784 @@ msgctxt "@title:tab"
msgid "Setting Visibility"
msgstr "Visibilité des paramètres"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:46
msgctxt "@label:textbox"
msgid "Check all"
msgstr "Vérifier tout"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:47
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:61
msgctxt "@info:status"
msgid "Calculated"
msgstr "Calculer"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:60
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:75
msgctxt "@title:column"
msgid "Setting"
msgstr "Paramètre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
msgctxt "@title:column"
msgid "Profile"
msgstr "Profil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:74
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:89
msgctxt "@title:column"
msgid "Current"
msgstr "Actuel"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:97
msgctxt "@title:column"
msgid "Unit"
msgstr "Unité"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:15
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:410
msgctxt "@title:tab"
msgid "General"
msgstr "Général"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:132
msgctxt "@label"
msgid "Interface"
msgstr "Interface"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:143
msgctxt "@label"
msgid "Language:"
msgstr "Langue :"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:221
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:210
msgctxt "@label"
msgid "Currency:"
msgstr "Devise :"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:235
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:223
msgctxt "@label"
msgid "Theme:"
msgstr "Thème :"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:292
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:279
msgctxt "@label"
msgid "You will need to restart the application for these changes to have effect."
msgstr "Vous devez redémarrer l'application pour que ces changements prennent effet."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:309
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:296
msgctxt "@info:tooltip"
msgid "Slice automatically when changing settings."
msgstr "Découper automatiquement si les paramètres sont modifiés."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:317
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:304
msgctxt "@option:check"
msgid "Slice automatically"
msgstr "Découper automatiquement"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:318
msgctxt "@label"
msgid "Viewport behavior"
msgstr "Comportement Viewport"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:326
msgctxt "@info:tooltip"
msgid "Highlight unsupported areas of the model in red. Without support these areas will not print properly."
msgstr "Surligne les parties non supportées du modèle en rouge. Sans ajouter de support, ces zones ne s'imprimeront pas correctement."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:335
msgctxt "@option:check"
msgid "Display overhang"
msgstr "Mettre en surbrillance les porte-à-faux"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:355
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:343
msgctxt "@info:tooltip"
msgid "Moves the camera so the model is in the center of the view when a model is selected"
msgstr "Déplace la caméra afin que le modèle sélectionné se trouve au centre de la vue"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
msgctxt "@action:button"
msgid "Center camera when item is selected"
msgstr "Centrer la caméra lorsqu'un élément est sélectionné"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:369
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:358
msgctxt "@info:tooltip"
msgid "Should the default zoom behavior of cura be inverted?"
msgstr "Le comportement de zoom par défaut de Cura doit-il être inversé ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:363
msgctxt "@action:button"
msgid "Invert the direction of camera zoom."
msgstr "Inverser la direction du zoom de la caméra."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
msgctxt "@info:tooltip"
msgid "Should zooming move in the direction of the mouse?"
msgstr "Le zoom doit-il se faire dans la direction de la souris ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:389
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
+msgctxt "@info:tooltip"
+msgid "Zooming towards the mouse is not supported in the orthographic perspective."
+msgstr "Le zoom vers la souris n'est pas pris en charge dans la perspective orthographique."
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
msgctxt "@action:button"
msgid "Zoom toward mouse direction"
msgstr "Zoomer vers la direction de la souris"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:399
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:410
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved so that they no longer intersect?"
msgstr "Les modèles dans la zone d'impression doivent-ils être déplacés afin de ne plus se croiser ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:404
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:415
msgctxt "@option:check"
msgid "Ensure models are kept apart"
msgstr "Veillez à ce que les modèles restent séparés"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:413
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:424
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved down to touch the build plate?"
msgstr "Les modèles dans la zone d'impression doivent-ils être abaissés afin de toucher le plateau ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:418
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:429
msgctxt "@option:check"
msgid "Automatically drop models to the build plate"
msgstr "Abaisser automatiquement les modèles sur le plateau"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:430
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:441
msgctxt "@info:tooltip"
msgid "Show caution message in g-code reader."
msgstr "Afficher le message d'avertissement dans le lecteur G-Code."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:439
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:450
msgctxt "@option:check"
msgid "Caution message in g-code reader"
msgstr "Message d'avertissement dans le lecteur G-Code"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:447
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:458
msgctxt "@info:tooltip"
msgid "Should layer be forced into compatibility mode?"
msgstr "La couche doit-elle être forcée en mode de compatibilité ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:452
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:463
msgctxt "@option:check"
msgid "Force layer view compatibility mode (restart required)"
msgstr "Forcer l'affichage de la couche en mode de compatibilité (redémarrage requis)"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:468
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:473
+msgctxt "@info:tooltip"
+msgid "Should Cura open at the location it was closed?"
+msgstr "Est-ce que Cura devrait ouvrir à l'endroit où il a été fermé ?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:478
+msgctxt "@option:check"
+msgid "Restore window position on start"
+msgstr "Restaurer la position de la fenêtre au démarrage"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:488
+msgctxt "@info:tooltip"
+msgid "What type of camera rendering should be used?"
+msgstr "Quel type de rendu de la caméra doit-il être utilisé?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+msgctxt "@window:text"
+msgid "Camera rendering:"
+msgstr "Rendu caméra :"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:506
+msgid "Perspective"
+msgstr "Perspective"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:507
+msgid "Orthographic"
+msgstr "Orthographique"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:538
msgctxt "@label"
msgid "Opening and saving files"
msgstr "Ouvrir et enregistrer des fichiers"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:475
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:545
msgctxt "@info:tooltip"
msgid "Should models be scaled to the build volume if they are too large?"
msgstr "Les modèles doivent-ils être mis à l'échelle du volume d'impression s'ils sont trop grands ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:550
msgctxt "@option:check"
msgid "Scale large models"
msgstr "Réduire la taille des modèles trop grands"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:490
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:560
msgctxt "@info:tooltip"
msgid "An model may appear extremely small if its unit is for example in meters rather than millimeters. Should these models be scaled up?"
msgstr "Un modèle peut apparaître en tout petit si son unité est par exemple en mètres plutôt qu'en millimètres. Ces modèles doivent-ils être agrandis ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:565
msgctxt "@option:check"
msgid "Scale extremely small models"
msgstr "Mettre à l'échelle les modèles extrêmement petits"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:505
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:575
msgctxt "@info:tooltip"
msgid "Should models be selected after they are loaded?"
msgstr "Les modèles doivent-ils être sélectionnés après leur chargement ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:510
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:580
msgctxt "@option:check"
msgid "Select models when loaded"
msgstr "Sélectionner les modèles lorsqu'ils sont chargés"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:520
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:590
msgctxt "@info:tooltip"
msgid "Should a prefix based on the printer name be added to the print job name automatically?"
msgstr "Un préfixe basé sur le nom de l'imprimante doit-il être automatiquement ajouté au nom de la tâche d'impression ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:525
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:595
msgctxt "@option:check"
msgid "Add machine prefix to job name"
msgstr "Ajouter le préfixe de la machine au nom de la tâche"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:535
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:605
msgctxt "@info:tooltip"
msgid "Should a summary be shown when saving a project file?"
msgstr "Un résumé doit-il être affiché lors de l'enregistrement d'un fichier de projet ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
msgctxt "@option:check"
msgid "Show summary dialog when saving project"
msgstr "Afficher la boîte de dialogue du résumé lors de l'enregistrement du projet"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:619
msgctxt "@info:tooltip"
msgid "Default behavior when opening a project file"
msgstr "Comportement par défaut lors de l'ouverture d'un fichier de projet"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:557
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:627
msgctxt "@window:text"
msgid "Default behavior when opening a project file: "
msgstr "Comportement par défaut lors de l'ouverture d'un fichier de projet : "
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:571
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:641
msgctxt "@option:openProject"
msgid "Always ask me this"
msgstr "Toujours me demander"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:572
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:642
msgctxt "@option:openProject"
msgid "Always open as a project"
msgstr "Toujours ouvrir comme projet"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:573
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:643
msgctxt "@option:openProject"
msgid "Always import models"
msgstr "Toujours importer les modèles"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:679
msgctxt "@info:tooltip"
msgid "When you have made changes to a profile and switched to a different one, a dialog will be shown asking whether you want to keep your modifications or not, or you can choose a default behaviour and never show that dialog again."
msgstr "Lorsque vous apportez des modifications à un profil puis passez à un autre profil, une boîte de dialogue apparaît, vous demandant si vous souhaitez conserver les modifications. Vous pouvez aussi choisir une option par défaut, et le dialogue ne s'affichera plus."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:618
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:688
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:52
msgctxt "@label"
msgid "Profiles"
msgstr "Profils"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:623
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:693
msgctxt "@window:text"
msgid "Default behavior for changed setting values when switching to a different profile: "
msgstr "Comportement par défaut pour les valeurs de paramètres modifiées lors du passage à un profil différent : "
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:638
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:707
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:157
+msgctxt "@option:discardOrKeep"
+msgid "Always ask me this"
+msgstr "Toujours me demander"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:708
msgctxt "@option:discardOrKeep"
msgid "Always discard changed settings"
msgstr "Toujours rejeter les paramètres modifiés"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:639
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:709
msgctxt "@option:discardOrKeep"
msgid "Always transfer changed settings to new profile"
msgstr "Toujours transférer les paramètres modifiés dans le nouveau profil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:673
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:743
msgctxt "@label"
msgid "Privacy"
msgstr "Confidentialité"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:681
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:750
msgctxt "@info:tooltip"
msgid "Should Cura check for updates when the program is started?"
msgstr "Cura doit-il vérifier les mises à jour au démarrage du programme ?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:686
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:755
msgctxt "@option:check"
msgid "Check for updates on start"
msgstr "Vérifier les mises à jour au démarrage"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:697
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:765
msgctxt "@info:tooltip"
msgid "Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored."
msgstr "Les données anonymes de votre impression doivent-elles être envoyées à Ultimaker ? Notez qu'aucun modèle, aucune adresse IP ni aucune autre information permettant de vous identifier personnellement ne seront envoyés ou stockés."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:702
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:770
msgctxt "@option:check"
msgid "Send (anonymous) print information"
msgstr "Envoyer des informations (anonymes) sur l'impression"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:711
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:779
msgctxt "@action:button"
msgid "More information"
msgstr "Plus d'informations"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:729
-msgctxt "@label"
-msgid "Experimental"
-msgstr "Expérimental"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:736
-msgctxt "@info:tooltip"
-msgid "Use multi build plate functionality"
-msgstr "Utiliser la fonctionnalité multi-plateau"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:741
-msgctxt "@option:check"
-msgid "Use multi build plate functionality (restart required)"
-msgstr "Utiliser la fonctionnalité multi-plateau (redémarrage requis)"
-
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:16
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:415
msgctxt "@title:tab"
msgid "Printers"
msgstr "Imprimantes"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:63
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
msgctxt "@action:button"
msgid "Rename"
msgstr "Renommer"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:147
-msgctxt "@label"
-msgid "Printer type:"
-msgstr "Type d'imprimante :"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:156
-msgctxt "@label"
-msgid "Connection:"
-msgstr "Connexion :"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:162
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
-msgctxt "@info:status"
-msgid "The printer is not connected."
-msgstr "L'imprimante n'est pas connectée."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:168
-msgctxt "@label"
-msgid "State:"
-msgstr "État :"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:181
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for a printjob"
-msgstr "En attente d'une tâche d'impression"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:193
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for someone to clear the build plate"
-msgstr "En attente du dégagement du plateau"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:199
-msgctxt "@label:MonitorStatus"
-msgid "Aborting print..."
-msgstr "Abandon de l'impression..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:553
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:34
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:419
msgctxt "@title:tab"
msgid "Profiles"
msgstr "Profils"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:104
msgctxt "@label"
msgid "Create"
msgstr "Créer"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:102
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:121
msgctxt "@label"
msgid "Duplicate"
msgstr "Dupliquer"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:174
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:202
msgctxt "@title:window"
msgid "Create Profile"
msgstr "Créer un profil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:204
+msgctxt "@info"
+msgid "Please provide a name for this profile."
+msgstr "Veuillez fournir un nom pour ce profil."
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:260
msgctxt "@title:window"
msgid "Duplicate Profile"
msgstr "Dupliquer un profil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:256
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:291
msgctxt "@title:window"
msgid "Rename Profile"
msgstr "Renommer le profil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:304
msgctxt "@title:window"
msgid "Import Profile"
msgstr "Importer un profil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:333
msgctxt "@title:window"
msgid "Export Profile"
msgstr "Exporter un profil"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:350
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:396
msgctxt "@label %1 is printer name"
msgid "Printer: %1"
msgstr "Imprimante : %1"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Protected profiles"
-msgstr "Profils protégés"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Custom profiles"
-msgstr "Personnaliser les profils"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:554
msgctxt "@action:button"
msgid "Update profile with current settings/overrides"
msgstr "Mettre à jour le profil à l'aide des paramètres / forçages actuels"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:487
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:561
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:257
msgctxt "@action:button"
msgid "Discard current changes"
msgstr "Ignorer les modifications actuelles"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:504
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:580
msgctxt "@action:label"
msgid "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below."
msgstr "Ce profil utilise les paramètres par défaut spécifiés par l'imprimante, de sorte qu'aucun paramètre / forçage n'apparaît dans la liste ci-dessous."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:511
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:588
msgctxt "@action:label"
msgid "Your current settings match the selected profile."
msgstr "Vos paramètres actuels correspondent au profil sélectionné."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:530
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:606
msgctxt "@title:tab"
msgid "Global Settings"
msgstr "Paramètres généraux"
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:18
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:953
-msgctxt "@title:window"
-msgid "Add Printer"
-msgstr "Ajouter une imprimante"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:195
-msgctxt "@label"
-msgid "Printer Name:"
-msgstr "Nom de l'imprimante :"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:219
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/MainWindowHeader.qml:90
msgctxt "@action:button"
-msgid "Add Printer"
-msgstr "Ajouter une imprimante"
+msgid "Marketplace"
+msgstr "Marché en ligne"
-#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:84
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:27
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&File"
+msgstr "&Fichier"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:31
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Edit"
+msgstr "&Modifier"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:48
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
+msgctxt "@title:menu menubar:toplevel"
+msgid "&View"
+msgstr "&Visualisation"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Settings"
+msgstr "&Paramètres"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:55
+msgctxt "@title:menu menubar:toplevel"
+msgid "E&xtensions"
+msgstr "E&xtensions"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:89
+msgctxt "@title:menu menubar:toplevel"
+msgid "P&references"
+msgstr "P&références"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:97
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Help"
+msgstr "&Aide"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:124
+msgctxt "@title:window"
+msgid "New project"
+msgstr "Nouveau projet"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:125
+msgctxt "@info:question"
+msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
+msgstr "Êtes-vous sûr(e) de souhaiter lancer un nouveau projet ? Cela supprimera les objets du plateau ainsi que tous paramètres non enregistrés."
+
+#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:88
msgctxt "@text Print job name"
msgid "Untitled"
msgstr "Sans titre"
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:15
-msgctxt "@title:window"
-msgid "About Cura"
-msgstr "À propos de Cura"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:55
-msgctxt "@label"
-msgid "version: %1"
-msgstr "version : %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:69
-msgctxt "@label"
-msgid "End-to-end solution for fused filament 3D printing."
-msgstr "Solution complète pour l'impression 3D par dépôt de filament fondu."
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:82
-msgctxt "@info:credit"
-msgid ""
-"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
-"Cura proudly uses the following open source projects:"
-msgstr "Cura a été développé par Ultimaker B.V. en coopération avec la communauté Ultimaker.\nCura est fier d'utiliser les projets open source suivants :"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:132
-msgctxt "@label"
-msgid "Graphical user interface"
-msgstr "Interface utilisateur graphique"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:133
-msgctxt "@label"
-msgid "Application framework"
-msgstr "Cadre d'application"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:134
-msgctxt "@label"
-msgid "G-code generator"
-msgstr "Générateur G-Code"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:135
-msgctxt "@label"
-msgid "Interprocess communication library"
-msgstr "Bibliothèque de communication interprocess"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:137
-msgctxt "@label"
-msgid "Programming language"
-msgstr "Langage de programmation"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:138
-msgctxt "@label"
-msgid "GUI framework"
-msgstr "Cadre IUG"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139
-msgctxt "@label"
-msgid "GUI framework bindings"
-msgstr "Liens cadre IUG"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:140
-msgctxt "@label"
-msgid "C/C++ Binding library"
-msgstr "Bibliothèque C/C++ Binding"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:141
-msgctxt "@label"
-msgid "Data interchange format"
-msgstr "Format d'échange de données"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:142
-msgctxt "@label"
-msgid "Support library for scientific computing"
-msgstr "Prise en charge de la bibliothèque pour le calcul scientifique"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:143
-msgctxt "@label"
-msgid "Support library for faster math"
-msgstr "Prise en charge de la bibliothèque pour des maths plus rapides"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:144
-msgctxt "@label"
-msgid "Support library for handling STL files"
-msgstr "Prise en charge de la bibliothèque pour le traitement des fichiers STL"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:145
-msgctxt "@label"
-msgid "Support library for handling planar objects"
-msgstr "Prise en charge de la bibliothèque pour le traitement des objets planaires"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:146
-msgctxt "@label"
-msgid "Support library for handling triangular meshes"
-msgstr "Prise en charge de la bibliothèque pour le traitement des mailles triangulaires"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:147
-msgctxt "@label"
-msgid "Support library for analysis of complex networks"
-msgstr "Prise en charge de la bibliothèque pour l'analyse de réseaux complexes"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:148
-msgctxt "@label"
-msgid "Support library for handling 3MF files"
-msgstr "Prise en charge de la bibliothèque pour le traitement des fichiers 3MF"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:149
-msgctxt "@label"
-msgid "Support library for file metadata and streaming"
-msgstr "Prise en charge de la bibliothèque pour les métadonnées et le streaming de fichiers"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:150
-msgctxt "@label"
-msgid "Serial communication library"
-msgstr "Bibliothèque de communication série"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:151
-msgctxt "@label"
-msgid "ZeroConf discovery library"
-msgstr "Bibliothèque de découverte ZeroConf"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:152
-msgctxt "@label"
-msgid "Polygon clipping library"
-msgstr "Bibliothèque de découpe polygone"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:153
-msgctxt "@Label"
-msgid "Python HTTP library"
-msgstr "Bibliothèque Python HTTP"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:155
-msgctxt "@label"
-msgid "Font"
-msgstr "Police"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:156
-msgctxt "@label"
-msgid "SVG icons"
-msgstr "Icônes SVG"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:157
-msgctxt "@label"
-msgid "Linux cross-distribution application deployment"
-msgstr "Déploiement d'applications sur multiples distributions Linux"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:42
-msgctxt "@label"
-msgid "Profile:"
-msgstr "Profil :"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:104
-msgctxt "@tooltip"
-msgid ""
-"Some setting/override values are different from the values stored in the profile.\n"
-"\n"
-"Click to open the profile manager."
-msgstr "Certaines valeurs de paramètre / forçage sont différentes des valeurs enregistrées dans le profil. \n\nCliquez pour ouvrir le gestionnaire de profils."
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:200
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:68
msgctxt "@label:textbox"
-msgid "Search..."
-msgstr "Rechercher..."
+msgid "Search settings"
+msgstr "Paramètres de recherche"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:545
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:462
msgctxt "@action:menu"
msgid "Copy value to all extruders"
msgstr "Copier la valeur vers tous les extrudeurs"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:554
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:471
msgctxt "@action:menu"
msgid "Copy all changed values to all extruders"
msgstr "Copier toutes les valeurs modifiées vers toutes les extrudeuses"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:591
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:508
msgctxt "@action:menu"
msgid "Hide this setting"
msgstr "Masquer ce paramètre"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:521
msgctxt "@action:menu"
msgid "Don't show this setting"
msgstr "Masquer ce paramètre"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:613
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:525
msgctxt "@action:menu"
msgid "Keep this setting visible"
msgstr "Afficher ce paramètre"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:637
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:417
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:434
msgctxt "@action:menu"
msgid "Configure setting visibility..."
msgstr "Configurer la visibilité des paramètres..."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:644
-msgctxt "@action:inmenu"
-msgid "Collapse All"
-msgstr "Réduire tout"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:649
-msgctxt "@action:inmenu"
-msgid "Expand All"
-msgstr "Développer tout"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:253
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:237
msgctxt "@label"
msgid ""
"Some hidden settings use values different from their normal calculated value.\n"
"\n"
"Click to make these settings visible."
-msgstr "Certains paramètres masqués utilisent des valeurs différentes de leur valeur normalement calculée.\n\nCliquez pour rendre ces paramètres visibles."
+msgstr ""
+"Certains paramètres masqués utilisent des valeurs différentes de leur valeur normalement calculée.\n"
+"\n"
+"Cliquez pour rendre ces paramètres visibles."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:81
+msgctxt "@label"
+msgid "This setting is not used because all the settings that it influences are overridden."
+msgstr "Ce paramètre n'est pas utilisé car tous les paramètres qu'il influence sont remplacés."
+
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:86
msgctxt "@label Header for list of settings."
msgid "Affects"
msgstr "Touche"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:91
msgctxt "@label Header for list of settings."
msgid "Affected By"
msgstr "Touché par"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:187
msgctxt "@label"
msgid "This setting is always shared between all extruders. Changing it here will change the value for all extruders."
msgstr "Ce paramètre est toujours partagé par toutes les extrudeuses. Le modifier ici entraînera la modification de la valeur pour toutes les extrudeuses."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:158
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:191
msgctxt "@label"
msgid "The value is resolved from per-extruder values "
msgstr "La valeur est résolue à partir des valeurs par extrudeur "
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:189
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:230
msgctxt "@label"
msgid ""
"This setting has a value that is different from the profile.\n"
"\n"
"Click to restore the value of the profile."
-msgstr "Ce paramètre possède une valeur qui est différente du profil.\n\nCliquez pour restaurer la valeur du profil."
+msgstr ""
+"Ce paramètre possède une valeur qui est différente du profil.\n"
+"\n"
+"Cliquez pour restaurer la valeur du profil."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:281
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:329
msgctxt "@label"
msgid ""
"This setting is normally calculated, but it currently has an absolute value set.\n"
"\n"
"Click to restore the calculated value."
-msgstr "Ce paramètre est normalement calculé mais il possède actuellement une valeur absolue définie.\n\nCliquez pour restaurer la valeur calculée."
+msgstr ""
+"Ce paramètre est normalement calculé mais il possède actuellement une valeur absolue définie.\n"
+"\n"
+"Cliquez pour restaurer la valeur calculée."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/NoIntentIcon.qml:31
+msgctxt "@label %1 is filled in with the type of a profile. %2 is filled with a list of numbers (eg '1' or '1, 2')"
+msgid "There is no %1 profile for the configuration in extruder %2. The default intent will be used instead"
+msgid_plural "There is no %1 profile for the configurations in extruders %2. The default intent will be used instead"
+msgstr[0] ""
+msgstr[1] ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:144
+msgctxt "@button"
+msgid "Recommended"
+msgstr "Recommandé"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:158
+msgctxt "@button"
+msgid "Custom"
+msgstr "Personnalisé"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:193
+msgctxt "@label"
+msgid "Gradual infill"
+msgstr "Remplissage graduel"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:232
+msgctxt "@label"
+msgid "Gradual infill will gradually increase the amount of infill towards the top."
+msgstr "Un remplissage graduel augmentera la quantité de remplissage vers le haut."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:30
+msgctxt "@label"
+msgid "Support"
+msgstr "Support"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:71
+msgctxt "@label"
+msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
+msgstr "Générer des structures pour soutenir les parties du modèle qui possèdent des porte-à-faux. Sans ces structures, ces parties s'effondreront durant l'impression."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:29
+msgctxt "@label"
+msgid "Adhesion"
+msgstr "Adhérence"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:74
+msgctxt "@label"
+msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
+msgstr "Activez l'impression d'une bordure ou plaquette (Brim/Raft). Cela ajoutera une zone plate autour de ou sous votre objet qui est facile à découper par la suite."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:81
+msgctxt "@tooltip"
+msgid "You have modified some profile settings. If you want to change these go to custom mode."
+msgstr "Vous avez modifié certains paramètres du profil. Si vous souhaitez les modifier, allez dans le mode Personnaliser."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:13
+msgctxt "@label:Should be short"
+msgid "On"
+msgstr "On"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:14
+msgctxt "@label:Should be short"
+msgid "Off"
+msgstr "Off"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:33
+msgctxt "@label"
+msgid "Experimental"
+msgstr "Expérimental"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:47
+msgctxt "@label"
+msgid "Profile"
+msgstr "Profil"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:172
+msgctxt "@tooltip"
+msgid ""
+"Some setting/override values are different from the values stored in the profile.\n"
+"\n"
+"Click to open the profile manager."
+msgstr ""
+"Certaines valeurs de paramètre / forçage sont différentes des valeurs enregistrées dans le profil. \n"
+"\n"
+"Cliquez pour ouvrir le gestionnaire de profils."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:160
+msgctxt "@label:header"
+msgid "Custom profiles"
+msgstr "Personnaliser les profils"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:21
+msgctxt "@label shown when we load a Gcode file"
+msgid "Print setup disabled. G-code file can not be modified."
+msgstr "Configuration d'impression désactivée. Le fichier G-Code ne peut pas être modifié."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:52
msgctxt "@label"
msgid "Printer control"
msgstr "Contrôle de l'imprimante"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:144
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:67
msgctxt "@label"
msgid "Jog Position"
msgstr "Position de coupe"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:85
msgctxt "@label"
msgid "X/Y"
msgstr "X/Y"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:192
msgctxt "@label"
msgid "Z"
msgstr "Z"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:257
msgctxt "@label"
msgid "Jog Distance"
msgstr "Distance de coupe"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:443
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:301
msgctxt "@label"
msgid "Send G-code"
msgstr "Envoyer G-Code"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:506
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:365
msgctxt "@tooltip of G-code command input"
msgid "Send a custom G-code command to the connected printer. Press 'enter' to send the command."
msgstr "Envoyer une commande G-Code personnalisée à l'imprimante connectée. Appuyez sur « Entrée » pour envoyer la commande."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:272
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:41
msgctxt "@label"
msgid "Extruder"
msgstr "Extrudeuse"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:71
msgctxt "@tooltip"
msgid "The target temperature of the hotend. The hotend will heat up or cool down towards this temperature. If this is 0, the hotend heating is turned off."
msgstr "Température cible de l'extrémité chauffante. L'extrémité chauffante sera chauffée ou refroidie pour tendre vers cette température. Si la valeur est 0, le chauffage de l'extrémité chauffante sera coupé."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:98
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:103
msgctxt "@tooltip"
msgid "The current temperature of this hotend."
msgstr "Température actuelle de cette extrémité chauffante."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:172
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:177
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the hotend to."
msgstr "Température jusqu'à laquelle préchauffer l'extrémité chauffante."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:336
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:341
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:332
msgctxt "@button Cancel pre-heating"
msgid "Cancel"
msgstr "Annuler"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:339
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:344
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:335
msgctxt "@button"
msgid "Pre-heat"
msgstr "Préchauffer"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:365
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:370
msgctxt "@tooltip of pre-heat"
msgid "Heat the hotend in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the hotend to heat up when you're ready to print."
msgstr "Préchauffez l'extrémité chauffante avant l'impression. Vous pouvez continuer l'ajustement de votre impression pendant qu'elle chauffe, ce qui vous évitera un temps d'attente lorsque vous serez prêt à lancer l'impression."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:401
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:406
msgctxt "@tooltip"
msgid "The colour of the material in this extruder."
msgstr "Couleur du matériau dans cet extrudeur."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:433
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:438
msgctxt "@tooltip"
msgid "The material in this extruder."
msgstr "Matériau dans cet extrudeur."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:465
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:470
msgctxt "@tooltip"
msgid "The nozzle inserted in this extruder."
msgstr "Buse insérée dans cet extrudeur."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:25
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:493
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
+msgctxt "@info:status"
+msgid "The printer is not connected."
+msgstr "L'imprimante n'est pas connectée."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:26
msgctxt "@label"
msgid "Build plate"
msgstr "Plateau"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:56
msgctxt "@tooltip"
msgid "The target temperature of the heated bed. The bed will heat up or cool down towards this temperature. If this is 0, the bed heating is turned off."
msgstr "Température cible du plateau chauffant. Le plateau sera chauffé ou refroidi pour tendre vers cette température. Si la valeur est 0, le chauffage du plateau sera éteint."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:88
msgctxt "@tooltip"
msgid "The current temperature of the heated bed."
msgstr "Température actuelle du plateau chauffant."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:160
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:161
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the bed to."
msgstr "Température jusqu'à laquelle préchauffer le plateau."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:361
msgctxt "@tooltip of pre-heat"
msgid "Heat the bed in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the bed to heat up when you're ready to print."
msgstr "Préchauffez le plateau avant l'impression. Vous pouvez continuer à ajuster votre impression pendant qu'il chauffe, et vous n'aurez pas à attendre que le plateau chauffe lorsque vous serez prêt à lancer l'impression."
@@ -3692,12 +3796,12 @@ msgctxt "@label:category menu label"
msgid "Material"
msgstr "Matériau"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:37
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:46
msgctxt "@label:category menu label"
msgid "Favorites"
msgstr "Favoris"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:71
msgctxt "@label:category menu label"
msgid "Generic"
msgstr "Générique"
@@ -3712,17 +3816,52 @@ msgctxt "@label:category menu label"
msgid "Local printers"
msgstr "Imprimantes locales"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
-msgctxt "@title:menu menubar:toplevel"
-msgid "&View"
-msgstr "&Visualisation"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:15
+msgctxt "@title:menu menubar:settings"
+msgid "&Printer"
+msgstr "Im&primante"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:42
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:27
+msgctxt "@title:menu"
+msgid "&Material"
+msgstr "&Matériau"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:36
+msgctxt "@action:inmenu"
+msgid "Set as Active Extruder"
+msgstr "Définir comme extrudeur actif"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:42
+msgctxt "@action:inmenu"
+msgid "Enable Extruder"
+msgstr "Activer l'extrudeuse"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:49
+msgctxt "@action:inmenu"
+msgid "Disable Extruder"
+msgstr "Désactiver l'extrudeuse"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:19
msgctxt "@action:inmenu menubar:view"
msgid "&Camera position"
msgstr "Position de la &caméra"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:58
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:44
+msgctxt "@action:inmenu menubar:view"
+msgid "Camera view"
+msgstr "Vue de la caméra"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:47
+msgctxt "@action:inmenu menubar:view"
+msgid "Perspective"
+msgstr "Perspective"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:59
+msgctxt "@action:inmenu menubar:view"
+msgid "Orthographic"
+msgstr "Orthographique"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:80
msgctxt "@action:inmenu menubar:view"
msgid "&Build plate"
msgstr "&Plateau"
@@ -3742,6 +3881,21 @@ msgctxt "@action:inmenu"
msgid "Manage Setting Visibility..."
msgstr "Gérer la visibilité des paramètres..."
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:33
+msgctxt "@title:menu menubar:file"
+msgid "&Save..."
+msgstr "Enregi&strer..."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:54
+msgctxt "@title:menu menubar:file"
+msgid "&Export..."
+msgstr "&Exporter..."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:65
+msgctxt "@action:inmenu menubar:file"
+msgid "Export Selection..."
+msgstr "Exporter la sélection..."
+
#: /home/ruben/Projects/Cura/resources/qml/Menus/ContextMenu.qml:27
msgctxt "@label"
msgid "Print Selected Model With:"
@@ -3761,654 +3915,509 @@ msgctxt "@label"
msgid "Number of Copies"
msgstr "Nombre de copies"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:33
-msgctxt "@label:header configurations"
-msgid "Available configurations"
-msgstr "Configurations disponibles"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml:18
+msgctxt "@header"
+msgid "Configurations"
+msgstr "Configurations"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml:28
-msgctxt "@label:extruder label"
-msgid "Extruder"
-msgstr "Extrudeuse"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:112
+msgctxt "@label"
+msgid "Select configuration"
+msgstr "Sélectionner la configuration"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "Yes"
-msgstr "Oui"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:223
+msgctxt "@label"
+msgid "Configurations"
+msgstr "Configurations"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "No"
-msgstr "Non"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:57
+msgctxt "@label"
+msgid "Loading available configurations from the printer..."
+msgstr "Chargement des configurations disponibles à partir de l'imprimante..."
-#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:13
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:58
+msgctxt "@label"
+msgid "The configurations are not available because the printer is disconnected."
+msgstr "Les configurations ne sont pas disponibles car l'imprimante est déconnectée."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:25
+msgctxt "@header"
+msgid "Custom"
+msgstr "Personnalisé"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:61
+msgctxt "@label"
+msgid "Printer"
+msgstr "Imprimante"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:213
+msgctxt "@label"
+msgid "Enabled"
+msgstr "Activé"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:251
+msgctxt "@label"
+msgid "Material"
+msgstr "Matériau"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:378
+msgctxt "@label"
+msgid "Use glue for better adhesion with this material combination."
+msgstr "Utiliser de la colle pour une meilleure adhérence avec cette combinaison de matériaux."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:128
+msgctxt "@label"
+msgid "This configuration is not available because %1 is not recognized. Please visit %2 to download the correct material profile."
+msgstr "Cette configuration n'est pas disponible car %1 n'est pas reconnu. Veuillez visiter %2 pour télécharger le profil matériel correct."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:129
+msgctxt "@label"
+msgid "Marketplace"
+msgstr "Marché en ligne"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:15
msgctxt "@title:menu menubar:file"
msgid "Open &Recent"
msgstr "Ouvrir un fichier &récent"
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid "Print Setup"
-msgstr "Configuration de l'impression"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid ""
-"Print Setup disabled\n"
-"G-code files cannot be modified"
-msgstr "Configuration de l'impression désactivée\nLes fichiers G-Code ne peuvent pas être modifiés"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:340
-msgctxt "@label Hours and minutes"
-msgid "00h 00min"
-msgstr "00h 00min"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:358
-msgctxt "@tooltip"
-msgid "Time specification"
-msgstr "Spécification de temps"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:440
-msgctxt "@label"
-msgid "Cost specification"
-msgstr "Spécification de coût"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:445
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:454
-msgctxt "@label m for meter"
-msgid "%1m"
-msgstr "%1m"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:446
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:455
-msgctxt "@label g for grams"
-msgid "%1g"
-msgstr "%1g"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:453
-msgctxt "@label"
-msgid "Total:"
-msgstr "Total :"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:576
-msgctxt "@tooltip"
-msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
-msgstr "Configuration de l'impression recommandée
Imprimer avec les paramètres recommandés pour l'imprimante, le matériau et la qualité sélectionnés."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:581
-msgctxt "@tooltip"
-msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
-msgstr "Configuration de l'impression personnalisée
Imprimer avec un contrôle fin de chaque élément du processus de découpe."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:140
msgctxt "@label"
msgid "Active print"
msgstr "Activer l'impression"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:148
msgctxt "@label"
msgid "Job Name"
msgstr "Nom de la tâche"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:156
msgctxt "@label"
msgid "Printing Time"
msgstr "Durée d'impression"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:130
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:164
msgctxt "@label"
msgid "Estimated time left"
msgstr "Durée restante estimée"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:79
+#: /home/ruben/Projects/Cura/resources/qml/ViewsSelector.qml:50
+msgctxt "@label"
+msgid "View type"
+msgstr "Type d'affichage"
+
+#: /home/ruben/Projects/Cura/resources/qml/ObjectSelector.qml:59
+msgctxt "@label"
+msgid "Object list"
+msgstr "Liste d'objets"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:22
+msgctxt "@label The argument is a username."
+msgid "Hi %1"
+msgstr "Bonjour %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:33
+msgctxt "@button"
+msgid "Ultimaker account"
+msgstr "Compte Ultimaker"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:42
+msgctxt "@button"
+msgid "Sign out"
+msgstr "Déconnexion"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/AccountWidget.qml:24
+msgctxt "@action:button"
+msgid "Sign in"
+msgstr "Se connecter"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:40
+msgctxt "@label"
+msgid "The next generation 3D printing workflow"
+msgstr "Le flux d'impression 3D de nouvelle génération"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:51
+msgctxt "@text"
+msgid ""
+"- Send print jobs to Ultimaker printers outside your local network\n"
+"- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+"- Get exclusive access to print profiles from leading brands"
+msgstr ""
+"- Envoyez des tâches d'impression à des imprimantes Ultimaker hors de votre réseau local\n"
+"- Stockez vos paramètres Ultimaker Cura dans le cloud pour les utiliser où que vous soyez\n"
+"- Obtenez un accès exclusif aux profils d'impression des principales marques"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:78
+msgctxt "@button"
+msgid "Create account"
+msgstr "Créer un compte"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:59
+msgctxt "@label"
+msgid "No time estimation available"
+msgstr "Aucune estimation de la durée n'est disponible"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:77
+msgctxt "@label"
+msgid "No cost estimation available"
+msgstr "Aucune estimation des coûts n'est disponible"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:127
+msgctxt "@button"
+msgid "Preview"
+msgstr "Aperçu"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:55
+msgctxt "@label:PrintjobStatus"
+msgid "Slicing..."
+msgstr "Découpe en cours..."
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:67
+msgctxt "@label:PrintjobStatus"
+msgid "Unable to slice"
+msgstr "Impossible de découper"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Processing"
+msgstr "Traitement"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Slice"
+msgstr "Découper"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:104
+msgctxt "@label"
+msgid "Start the slicing process"
+msgstr "Démarrer le processus de découpe"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:118
+msgctxt "@button"
+msgid "Cancel"
+msgstr "Annuler"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:31
+msgctxt "@label"
+msgid "Time estimation"
+msgstr "Estimation de durée"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:114
+msgctxt "@label"
+msgid "Material estimation"
+msgstr "Estimation du matériau"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:164
+msgctxt "@label m for meter"
+msgid "%1m"
+msgstr "%1m"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:165
+msgctxt "@label g for grams"
+msgid "%1g"
+msgstr "%1g"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Connected printers"
+msgstr "Imprimantes connectées"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Preset printers"
+msgstr "Imprimantes préréglées"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:166
+msgctxt "@button"
+msgid "Add printer"
+msgstr "Ajouter une imprimante"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:182
+msgctxt "@button"
+msgid "Manage printers"
+msgstr "Gérer les imprimantes"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:81
+msgctxt "@action:inmenu"
+msgid "Show Online Troubleshooting Guide"
+msgstr "Afficher le guide de dépannage en ligne"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:88
msgctxt "@action:inmenu"
msgid "Toggle Full Screen"
msgstr "Passer en Plein écran"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:86
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+msgctxt "@action:inmenu"
+msgid "Exit Full Screen"
+msgstr "Quitter le mode plein écran"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:103
msgctxt "@action:inmenu menubar:edit"
msgid "&Undo"
msgstr "&Annuler"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
msgctxt "@action:inmenu menubar:edit"
msgid "&Redo"
msgstr "&Rétablir"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:123
msgctxt "@action:inmenu menubar:file"
msgid "&Quit"
msgstr "&Quitter"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:131
msgctxt "@action:inmenu menubar:view"
msgid "3D View"
msgstr "Vue 3D"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:138
msgctxt "@action:inmenu menubar:view"
msgid "Front View"
msgstr "Vue de face"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:128
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:145
msgctxt "@action:inmenu menubar:view"
msgid "Top View"
msgstr "Vue du dessus"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:135
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:152
msgctxt "@action:inmenu menubar:view"
msgid "Left Side View"
msgstr "Vue latérale gauche"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:159
msgctxt "@action:inmenu menubar:view"
msgid "Right Side View"
msgstr "Vue latérale droite"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:149
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:166
msgctxt "@action:inmenu"
msgid "Configure Cura..."
msgstr "Configurer Cura..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:156
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:173
msgctxt "@action:inmenu menubar:printer"
msgid "&Add Printer..."
msgstr "&Ajouter une imprimante..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:179
msgctxt "@action:inmenu menubar:printer"
msgid "Manage Pr&inters..."
msgstr "Gérer les &imprimantes..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:169
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:186
msgctxt "@action:inmenu"
msgid "Manage Materials..."
msgstr "Gérer les matériaux..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:177
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:195
msgctxt "@action:inmenu menubar:profile"
msgid "&Update profile with current settings/overrides"
msgstr "&Mettre à jour le profil à l'aide des paramètres / forçages actuels"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:185
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
msgctxt "@action:inmenu menubar:profile"
msgid "&Discard current changes"
msgstr "&Ignorer les modifications actuelles"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:197
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:215
msgctxt "@action:inmenu menubar:profile"
msgid "&Create profile from current settings/overrides..."
msgstr "&Créer un profil à partir des paramètres / forçages actuels..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:221
msgctxt "@action:inmenu menubar:profile"
msgid "Manage Profiles..."
msgstr "Gérer les profils..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:210
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:229
msgctxt "@action:inmenu menubar:help"
msgid "Show Online &Documentation"
msgstr "Afficher la &documentation en ligne"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:218
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:237
msgctxt "@action:inmenu menubar:help"
msgid "Report a &Bug"
msgstr "Notifier un &bug"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:226
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:245
+msgctxt "@action:inmenu menubar:help"
+msgid "What's New"
+msgstr "Quoi de neuf"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:251
msgctxt "@action:inmenu menubar:help"
msgid "About..."
msgstr "À propos de..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:233
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:258
msgctxt "@action:inmenu menubar:edit"
msgid "Delete Selected Model"
msgid_plural "Delete Selected Models"
msgstr[0] "Supprimer le modèle sélectionné"
msgstr[1] "Supprimer les modèles sélectionnés"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:243
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:268
msgctxt "@action:inmenu menubar:edit"
msgid "Center Selected Model"
msgid_plural "Center Selected Models"
msgstr[0] "Centrer le modèle sélectionné"
msgstr[1] "Centrer les modèles sélectionnés"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:277
msgctxt "@action:inmenu menubar:edit"
msgid "Multiply Selected Model"
msgid_plural "Multiply Selected Models"
msgstr[0] "Multiplier le modèle sélectionné"
msgstr[1] "Multiplier les modèles sélectionnés"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:261
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:286
msgctxt "@action:inmenu"
msgid "Delete Model"
msgstr "Supprimer le modèle"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:294
msgctxt "@action:inmenu"
msgid "Ce&nter Model on Platform"
msgstr "Ce&ntrer le modèle sur le plateau"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:275
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:300
msgctxt "@action:inmenu menubar:edit"
msgid "&Group Models"
msgstr "&Grouper les modèles"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:320
msgctxt "@action:inmenu menubar:edit"
msgid "Ungroup Models"
msgstr "Dégrouper les modèles"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:305
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:330
msgctxt "@action:inmenu menubar:edit"
msgid "&Merge Models"
msgstr "&Fusionner les modèles"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:315
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:340
msgctxt "@action:inmenu"
msgid "&Multiply Model..."
msgstr "&Multiplier le modèle..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:322
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:347
msgctxt "@action:inmenu menubar:edit"
msgid "Select All Models"
msgstr "Sélectionner tous les modèles"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:332
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:357
msgctxt "@action:inmenu menubar:edit"
msgid "Clear Build Plate"
msgstr "Supprimer les objets du plateau"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:342
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:367
msgctxt "@action:inmenu menubar:file"
msgid "Reload All Models"
msgstr "Recharger tous les modèles"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:376
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models To All Build Plates"
msgstr "Réorganiser tous les modèles sur tous les plateaux"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:358
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:383
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models"
msgstr "Réorganiser tous les modèles"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:366
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:391
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange Selection"
msgstr "Réorganiser la sélection"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:373
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:398
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Positions"
msgstr "Réinitialiser toutes les positions des modèles"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:380
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:405
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Transformations"
msgstr "Réinitialiser tous les modèles et transformations"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:387
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:412
msgctxt "@action:inmenu menubar:file"
msgid "&Open File(s)..."
msgstr "&Ouvrir le(s) fichier(s)..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:395
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:420
msgctxt "@action:inmenu menubar:file"
msgid "&New Project..."
msgstr "&Nouveau projet..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:402
-msgctxt "@action:inmenu menubar:help"
-msgid "Show Engine &Log..."
-msgstr "Afficher le &journal du moteur..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:410
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:427
msgctxt "@action:inmenu menubar:help"
msgid "Show Configuration Folder"
msgstr "Afficher le dossier de configuration"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:424
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:441
msgctxt "@action:menu"
-msgid "Browse packages..."
-msgstr "Parcourir les paquets..."
+msgid "&Marketplace"
+msgstr "&Marché en ligne"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:431
-msgctxt "@action:inmenu menubar:view"
-msgid "Expand/Collapse Sidebar"
-msgstr "Déplier / replier la barre latérale"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:27
-msgctxt "@label:PrintjobStatus"
-msgid "Please load a 3D model"
-msgstr "Veuillez charger un modèle 3D"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:37
-msgctxt "@label:PrintjobStatus"
-msgid "Ready to slice"
-msgstr "Prêt à découper"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:39
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing..."
-msgstr "Découpe en cours..."
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:41
-msgctxt "@label:PrintjobStatus %1 is target operation"
-msgid "Ready to %1"
-msgstr "Prêt à %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:43
-msgctxt "@label:PrintjobStatus"
-msgid "Unable to Slice"
-msgstr "Impossible de découper"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:45
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing unavailable"
-msgstr "Découpe indisponible"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Slice current printjob"
-msgstr "Découper la tâche d'impression en cours"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Cancel slicing process"
-msgstr "Annuler le processus de découpe"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Prepare"
-msgstr "Préparer"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Cancel"
-msgstr "Annuler"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:320
-msgctxt "@info:tooltip"
-msgid "Select the active output device"
-msgstr "Sélectionner le périphérique de sortie actif"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:19
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:767
-msgctxt "@title:window"
-msgid "Open file(s)"
-msgstr "Ouvrir le(s) fichier(s)"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:64
-msgctxt "@text:window"
-msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
-msgstr "Nous avons trouvé au moins un fichier de projet parmi les fichiers que vous avez sélectionnés. Vous ne pouvez ouvrir qu'un seul fichier de projet à la fois. Nous vous conseillons de n'importer que les modèles de ces fichiers. Souhaitez-vous continuer ?"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:99
-msgctxt "@action:button"
-msgid "Import all as models"
-msgstr "Importer tout comme modèles"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:19
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:24
msgctxt "@title:window"
msgid "Ultimaker Cura"
msgstr "Ultimaker Cura"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:103
-msgctxt "@title:menu menubar:toplevel"
-msgid "&File"
-msgstr "&Fichier"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:121
-msgctxt "@title:menu menubar:file"
-msgid "&Save..."
-msgstr "Enregi&strer..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:142
-msgctxt "@title:menu menubar:file"
-msgid "&Export..."
-msgstr "&Exporter..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:153
-msgctxt "@action:inmenu menubar:file"
-msgid "Export Selection..."
-msgstr "Exporter la sélection..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:174
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Edit"
-msgstr "&Modifier"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:191
-msgctxt "@title:menu"
-msgid "&View"
-msgstr "&Visualisation"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:196
-msgctxt "@title:menu"
-msgid "&Settings"
-msgstr "&Paramètres"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:198
-msgctxt "@title:menu menubar:settings"
-msgid "&Printer"
-msgstr "Im&primante"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:207
-msgctxt "@title:menu"
-msgid "&Material"
-msgstr "&Matériau"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:216
-msgctxt "@action:inmenu"
-msgid "Set as Active Extruder"
-msgstr "Définir comme extrudeur actif"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:222
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:188
-msgctxt "@action:inmenu"
-msgid "Enable Extruder"
-msgstr "Activer l'extrudeuse"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:229
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:194
-msgctxt "@action:inmenu"
-msgid "Disable Extruder"
-msgstr "Désactiver l'extrudeuse"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:241
-msgctxt "@title:menu"
-msgid "&Build plate"
-msgstr "Plateau"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:242
-msgctxt "@title:settings"
-msgid "&Profile"
-msgstr "&Profil"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:252
-msgctxt "@title:menu menubar:toplevel"
-msgid "E&xtensions"
-msgstr "E&xtensions"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:286
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Toolbox"
-msgstr "&Boîte à outils"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:294
-msgctxt "@title:menu menubar:toplevel"
-msgid "P&references"
-msgstr "P&références"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:302
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Help"
-msgstr "&Aide"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:232
msgctxt "@label"
msgid "This package will be installed after restarting."
msgstr "Ce paquet sera installé après le redémarrage."
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:377
-msgctxt "@action:button"
-msgid "Open File"
-msgstr "Ouvrir un fichier"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:547
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:413
msgctxt "@title:tab"
msgid "Settings"
msgstr "Paramètres"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:593
-msgctxt "@title:window"
-msgid "New project"
-msgstr "Nouveau projet"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:594
-msgctxt "@info:question"
-msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
-msgstr "Êtes-vous sûr(e) de souhaiter lancer un nouveau projet ? Cela supprimera les objets du plateau ainsi que tous paramètres non enregistrés."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:722
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:538
msgctxt "@title:window"
msgid "Closing Cura"
msgstr "Fermeture de Cura"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:723
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:735
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
msgctxt "@label"
msgid "Are you sure you want to exit Cura?"
msgstr "Êtes-vous sûr de vouloir quitter Cura ?"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:868
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:589
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:19
+msgctxt "@title:window"
+msgid "Open file(s)"
+msgstr "Ouvrir le(s) fichier(s)"
+
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:695
msgctxt "@window:title"
msgid "Install Package"
msgstr "Installer le paquet"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:875
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:703
msgctxt "@title:window"
msgid "Open File(s)"
msgstr "Ouvrir le(s) fichier(s)"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:878
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:706
msgctxt "@text:window"
msgid "We have found one or more G-Code files within the files you have selected. You can only open one G-Code file at a time. If you want to open a G-Code file, please just select only one."
msgstr "Nous avons trouvé au moins un fichier G-Code parmi les fichiers que vous avez sélectionné. Vous ne pouvez ouvrir qu'un seul fichier G-Code à la fois. Si vous souhaitez ouvrir un fichier G-Code, veuillez ne sélectionner qu'un seul fichier de ce type."
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:14
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:809
msgctxt "@title:window"
-msgid "Save Project"
-msgstr "Enregistrer le projet"
+msgid "Add Printer"
+msgstr "Ajouter une imprimante"
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:137
-msgctxt "@action:label"
-msgid "Build plate"
-msgstr "Plateau"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:169
-msgctxt "@action:label"
-msgid "Extruder %1"
-msgstr "Extrudeuse %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:179
-msgctxt "@action:label"
-msgid "%1 & material"
-msgstr "%1 & matériau"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:268
-msgctxt "@action:label"
-msgid "Don't show project summary on save again"
-msgstr "Ne pas afficher à nouveau le résumé du projet lors de l'enregistrement"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:287
-msgctxt "@action:button"
-msgid "Save"
-msgstr "Enregistrer"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:192
-msgctxt "@label"
-msgid "Layer Height"
-msgstr "Hauteur de la couche"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:277
-msgctxt "@tooltip"
-msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
-msgstr "Ce profil de qualité n'est pas disponible pour votre matériau et configuration des buses actuels. Veuillez modifier ces derniers pour activer ce profil de qualité"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:450
-msgctxt "@tooltip"
-msgid "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab"
-msgstr "Un profil personnalisé est actuellement actif. Pour activer le curseur de qualité, choisissez un profil de qualité par défaut dans l'onglet Personnaliser"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:467
-msgctxt "@label"
-msgid "Print Speed"
-msgstr "Vitesse d’impression"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:479
-msgctxt "@label"
-msgid "Slower"
-msgstr "Ralentir"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:490
-msgctxt "@label"
-msgid "Faster"
-msgstr "Accélérer"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:518
-msgctxt "@tooltip"
-msgid "You have modified some profile settings. If you want to change these go to custom mode."
-msgstr "Vous avez modifié certains paramètres du profil. Si vous souhaitez les modifier, allez dans le mode Personnaliser."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:541
-msgctxt "@label"
-msgid "Infill"
-msgstr "Remplissage"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:777
-msgctxt "@label"
-msgid "Gradual infill will gradually increase the amount of infill towards the top."
-msgstr "Un remplissage graduel augmentera la quantité de remplissage vers le haut."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:791
-msgctxt "@label"
-msgid "Enable gradual"
-msgstr "Permettre le remplissage graduel"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:858
-msgctxt "@label"
-msgid "Generate Support"
-msgstr "Générer les supports"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:892
-msgctxt "@label"
-msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
-msgstr "Générer des structures pour soutenir les parties du modèle qui possèdent des porte-à-faux. Sans ces structures, ces parties s'effondreront durant l'impression."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:964
-msgctxt "@label"
-msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
-msgstr "Sélectionnez l'extrudeur à utiliser comme support. Cela créera des structures de support sous le modèle afin de l'empêcher de s'affaisser ou de s'imprimer dans les airs."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:987
-msgctxt "@label"
-msgid "Build Plate Adhesion"
-msgstr "Adhérence au plateau"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1042
-msgctxt "@label"
-msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
-msgstr "Activez l'impression d'une bordure ou plaquette (Brim/Raft). Cela ajoutera une zone plate autour de ou sous votre objet qui est facile à découper par la suite."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1082
-msgctxt "@label"
-msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
-msgstr "Besoin d'aide pour améliorer vos impressions ? Lisez les Guides de dépannage Ultimaker"
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:817
+msgctxt "@title:window"
+msgid "What's New"
+msgstr "Quoi de neuf"
#: /home/ruben/Projects/Cura/resources/qml/ExtruderButton.qml:16
msgctxt "@label %1 is filled in with the name of an extruder"
@@ -4417,75 +4426,503 @@ msgid_plural "Print Selected Models with %1"
msgstr[0] "Imprimer le modèle sélectionné avec %1"
msgstr[1] "Imprimer les modèles sélectionnés avec %1"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:20
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:15
+msgctxt "@title:window"
+msgid "Discard or Keep changes"
+msgstr "Annuler ou conserver les modifications"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:57
+msgctxt "@text:window"
+msgid ""
+"You have customized some profile settings.\n"
+"Would you like to keep or discard those settings?"
+msgstr ""
+"Vous avez personnalisé certains paramètres du profil.\n"
+"Souhaitez-vous conserver ces changements, ou les annuler ?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:110
+msgctxt "@title:column"
+msgid "Profile settings"
+msgstr "Paramètres du profil"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:117
+msgctxt "@title:column"
+msgid "Default"
+msgstr "Par défaut"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:124
+msgctxt "@title:column"
+msgid "Customized"
+msgstr "Personnalisé"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:158
+msgctxt "@option:discardOrKeep"
+msgid "Discard and never ask again"
+msgstr "Annuler et ne plus me demander"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:159
+msgctxt "@option:discardOrKeep"
+msgid "Keep and never ask again"
+msgstr "Conserver et ne plus me demander"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:196
+msgctxt "@action:button"
+msgid "Discard"
+msgstr "Annuler"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:209
+msgctxt "@action:button"
+msgid "Keep"
+msgstr "Conserver"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:222
+msgctxt "@action:button"
+msgid "Create New Profile"
+msgstr "Créer un nouveau profil"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:15
+msgctxt "@title:window"
+msgid "About Cura"
+msgstr "À propos de Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:57
+msgctxt "@label"
+msgid "version: %1"
+msgstr "version : %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:72
+msgctxt "@label"
+msgid "End-to-end solution for fused filament 3D printing."
+msgstr "Solution complète pour l'impression 3D par dépôt de filament fondu."
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:85
+msgctxt "@info:credit"
+msgid ""
+"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
+"Cura proudly uses the following open source projects:"
+msgstr ""
+"Cura a été développé par Ultimaker B.V. en coopération avec la communauté Ultimaker.\n"
+"Cura est fier d'utiliser les projets open source suivants :"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:135
+msgctxt "@label"
+msgid "Graphical user interface"
+msgstr "Interface utilisateur graphique"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:136
+msgctxt "@label"
+msgid "Application framework"
+msgstr "Cadre d'application"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:137
+msgctxt "@label"
+msgid "G-code generator"
+msgstr "Générateur G-Code"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:138
+msgctxt "@label"
+msgid "Interprocess communication library"
+msgstr "Bibliothèque de communication interprocess"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:140
+msgctxt "@label"
+msgid "Programming language"
+msgstr "Langage de programmation"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:141
+msgctxt "@label"
+msgid "GUI framework"
+msgstr "Cadre IUG"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:142
+msgctxt "@label"
+msgid "GUI framework bindings"
+msgstr "Liens cadre IUG"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:143
+msgctxt "@label"
+msgid "C/C++ Binding library"
+msgstr "Bibliothèque C/C++ Binding"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:144
+msgctxt "@label"
+msgid "Data interchange format"
+msgstr "Format d'échange de données"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:145
+msgctxt "@label"
+msgid "Support library for scientific computing"
+msgstr "Prise en charge de la bibliothèque pour le calcul scientifique"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:146
+msgctxt "@label"
+msgid "Support library for faster math"
+msgstr "Prise en charge de la bibliothèque pour des maths plus rapides"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:147
+msgctxt "@label"
+msgid "Support library for handling STL files"
+msgstr "Prise en charge de la bibliothèque pour le traitement des fichiers STL"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:148
+msgctxt "@label"
+msgid "Support library for handling planar objects"
+msgstr "Prise en charge de la bibliothèque pour le traitement des objets planaires"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:149
+msgctxt "@label"
+msgid "Support library for handling triangular meshes"
+msgstr "Prise en charge de la bibliothèque pour le traitement des mailles triangulaires"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:150
+msgctxt "@label"
+msgid "Support library for analysis of complex networks"
+msgstr "Prise en charge de la bibliothèque pour l'analyse de réseaux complexes"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:151
+msgctxt "@label"
+msgid "Support library for handling 3MF files"
+msgstr "Prise en charge de la bibliothèque pour le traitement des fichiers 3MF"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:152
+msgctxt "@label"
+msgid "Support library for file metadata and streaming"
+msgstr "Prise en charge de la bibliothèque pour les métadonnées et le streaming de fichiers"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:153
+msgctxt "@label"
+msgid "Serial communication library"
+msgstr "Bibliothèque de communication série"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:154
+msgctxt "@label"
+msgid "ZeroConf discovery library"
+msgstr "Bibliothèque de découverte ZeroConf"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:155
+msgctxt "@label"
+msgid "Polygon clipping library"
+msgstr "Bibliothèque de découpe polygone"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:156
+msgctxt "@Label"
+msgid "Python HTTP library"
+msgstr "Bibliothèque Python HTTP"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:158
+msgctxt "@label"
+msgid "Font"
+msgstr "Police"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:159
+msgctxt "@label"
+msgid "SVG icons"
+msgstr "Icônes SVG"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:160
+msgctxt "@label"
+msgid "Linux cross-distribution application deployment"
+msgstr "Déploiement d'applications sur multiples distributions Linux"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:64
+msgctxt "@text:window"
+msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
+msgstr "Nous avons trouvé au moins un fichier de projet parmi les fichiers que vous avez sélectionnés. Vous ne pouvez ouvrir qu'un seul fichier de projet à la fois. Nous vous conseillons de n'importer que les modèles de ces fichiers. Souhaitez-vous continuer ?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:99
+msgctxt "@action:button"
+msgid "Import all as models"
+msgstr "Importer tout comme modèles"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:15
+msgctxt "@title:window"
+msgid "Save Project"
+msgstr "Enregistrer le projet"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:177
+msgctxt "@action:label"
+msgid "Extruder %1"
+msgstr "Extrudeuse %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:192
+msgctxt "@action:label"
+msgid "%1 & material"
+msgstr "%1 & matériau"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:194
+msgctxt "@action:label"
+msgid "Material"
+msgstr "Matériau"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:283
+msgctxt "@action:label"
+msgid "Don't show project summary on save again"
+msgstr "Ne pas afficher à nouveau le résumé du projet lors de l'enregistrement"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:302
+msgctxt "@action:button"
+msgid "Save"
+msgstr "Enregistrer"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:20
msgctxt "@title:window"
msgid "Open project file"
msgstr "Ouvrir un fichier de projet"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:93
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:93
msgctxt "@text:window"
msgid "This is a Cura project file. Would you like to open it as a project or import the models from it?"
msgstr "Ceci est un fichier de projet Cura. Souhaitez-vous l'ouvrir comme projet ou en importer les modèles ?"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:103
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:103
msgctxt "@text:window"
msgid "Remember my choice"
msgstr "Se souvenir de mon choix"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:122
msgctxt "@action:button"
msgid "Open as project"
msgstr "Ouvrir comme projet"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:131
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:131
msgctxt "@action:button"
msgid "Import models"
msgstr "Importer les modèles"
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15
-msgctxt "@title:window"
-msgid "Engine Log"
-msgstr "Journal du moteur"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:70
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DropDownWidget.qml:93
msgctxt "@label"
-msgid "Printer type"
-msgstr "Type d'imprimante"
+msgid "Empty"
+msgstr "Vide"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:376
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:24
msgctxt "@label"
-msgid "Material"
-msgstr "Matériau"
+msgid "Add a printer"
+msgstr "Ajouter une imprimante"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:543
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:39
msgctxt "@label"
-msgid "Use glue with this material combination"
-msgstr "Utiliser de la colle avec cette combinaison de matériaux"
+msgid "Add a networked printer"
+msgstr "Ajouter une imprimante en réseau"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:575
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:81
msgctxt "@label"
-msgid "Check compatibility"
-msgstr "Vérifier la compatibilité"
+msgid "Add a non-networked printer"
+msgstr "Ajouter une imprimante hors réseau"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:593
-msgctxt "@tooltip"
-msgid "Click to check the material compatibility on Ultimaker.com."
-msgstr "Cliquez ici pour vérifier la compatibilité des matériaux sur Ultimaker.com."
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:70
+msgctxt "@label"
+msgid "Add printer by IP address"
+msgstr "Ajouter une imprimante par adresse IP"
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:211
-msgctxt "@option:check"
-msgid "See only current build plate"
-msgstr "Afficher uniquement le plateau actuel"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:133
+msgctxt "@text"
+msgid "Place enter your printer's IP address."
+msgstr "Saisissez l'adresse IP de votre imprimante."
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:227
-msgctxt "@action:button"
-msgid "Arrange to all build plates"
-msgstr "Réorganiser sur tous les plateaux"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:158
+msgctxt "@button"
+msgid "Add"
+msgstr "Ajouter"
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:247
-msgctxt "@action:button"
-msgid "Arrange current build plate"
-msgstr "Réorganiser le plateau actuel"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:204
+msgctxt "@label"
+msgid "Could not connect to device."
+msgstr "Impossible de se connecter à l'appareil."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:208
+msgctxt "@label"
+msgid "The printer at this address has not responded yet."
+msgstr "L'imprimante à cette adresse n'a pas encore répondu."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:240
+msgctxt "@label"
+msgid "This printer cannot be added because it's an unknown printer or it's not the host of a group."
+msgstr "Cette imprimante ne peut pas être ajoutée parce qu'il s'agit d'une imprimante inconnue ou de l'hôte d'un groupe."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:329
+msgctxt "@button"
+msgid "Back"
+msgstr "Précédent"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:342
+msgctxt "@button"
+msgid "Connect"
+msgstr "Se connecter"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/FirstStartMachineActionsContent.qml:77
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:123
+msgctxt "@button"
+msgid "Next"
+msgstr "Suivant"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:23
+msgctxt "@label"
+msgid "User Agreement"
+msgstr "Accord utilisateur"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:56
+msgctxt "@button"
+msgid "Agree"
+msgstr "Accepter"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:70
+msgctxt "@button"
+msgid "Decline and close"
+msgstr "Décliner et fermer"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:24
+msgctxt "@label"
+msgid "Help us to improve Ultimaker Cura"
+msgstr "Aidez-nous à améliorer Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:57
+msgctxt "@text"
+msgid "Ultimaker Cura collects anonymous data to improve print quality and user experience, including:"
+msgstr "Ultimaker Cura recueille des données anonymes pour améliorer la qualité d'impression et l'expérience utilisateur, notamment :"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:71
+msgctxt "@text"
+msgid "Machine types"
+msgstr "Types de machines"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:77
+msgctxt "@text"
+msgid "Material usage"
+msgstr "Utilisation du matériau"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:83
+msgctxt "@text"
+msgid "Number of slices"
+msgstr "Nombre de découpes"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:89
+msgctxt "@text"
+msgid "Print settings"
+msgstr "Paramètres d'impression"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:102
+msgctxt "@text"
+msgid "Data collected by Ultimaker Cura will not contain any personal information."
+msgstr "Les données recueillies par Ultimaker Cura ne contiendront aucun renseignement personnel."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:103
+msgctxt "@text"
+msgid "More information"
+msgstr "Plus d'informations"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WhatsNewContent.qml:24
+msgctxt "@label"
+msgid "What's new in Ultimaker Cura"
+msgstr "Quoi de neuf dans Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:42
+msgctxt "@label"
+msgid "There is no printer found over your network."
+msgstr "Aucune imprimante n'a été trouvée sur votre réseau."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:179
+msgctxt "@label"
+msgid "Refresh"
+msgstr "Rafraîchir"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:190
+msgctxt "@label"
+msgid "Add printer by IP"
+msgstr "Ajouter une imprimante par IP"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:223
+msgctxt "@label"
+msgid "Troubleshooting"
+msgstr "Dépannage"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:211
+msgctxt "@label"
+msgid "Printer name"
+msgstr "Nom de l'imprimante"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:224
+msgctxt "@text"
+msgid "Please give your printer a name"
+msgstr "Veuillez donner un nom à votre imprimante"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:36
+msgctxt "@label"
+msgid "Ultimaker Cloud"
+msgstr "Ultimaker Cloud"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:77
+msgctxt "@text"
+msgid "The next generation 3D printing workflow"
+msgstr "Le flux d'impression 3D de nouvelle génération"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:94
+msgctxt "@text"
+msgid "- Send print jobs to Ultimaker printers outside your local network"
+msgstr "- Envoyez des tâches d'impression à des imprimantes Ultimaker hors de votre réseau local"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:97
+msgctxt "@text"
+msgid "- Store your Ultimaker Cura settings in the cloud for use anywhere"
+msgstr "- Stockez vos paramètres Ultimaker Cura dans le cloud pour les utiliser où que vous soyez"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:100
+msgctxt "@text"
+msgid "- Get exclusive access to print profiles from leading brands"
+msgstr "- Accédez en exclusivité aux profils d'impression des plus grandes marques"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:119
+msgctxt "@button"
+msgid "Finish"
+msgstr "Fin"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:128
+msgctxt "@button"
+msgid "Create an account"
+msgstr "Créer un compte"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:29
+msgctxt "@label"
+msgid "Welcome to Ultimaker Cura"
+msgstr "Bienvenue dans Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:47
+msgctxt "@text"
+msgid ""
+"Please follow these steps to set up\n"
+"Ultimaker Cura. This will only take a few moments."
+msgstr ""
+"Veuillez suivre ces étapes pour configurer\n"
+"Ultimaker Cura. Cela ne prendra que quelques instants."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:58
+msgctxt "@button"
+msgid "Get started"
+msgstr "Prise en main"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:27
+msgctxt "@info:tooltip"
+msgid "3D View"
+msgstr "Vue 3D"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:40
+msgctxt "@info:tooltip"
+msgid "Front View"
+msgstr "Vue de face"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:53
+msgctxt "@info:tooltip"
+msgid "Top View"
+msgstr "Vue du dessus"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:66
+msgctxt "@info:tooltip"
+msgid "Left View"
+msgstr "Vue gauche"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:79
+msgctxt "@info:tooltip"
+msgid "Right View"
+msgstr "Vue droite"
#: MachineSettingsAction/plugin.json
msgctxt "description"
@@ -4547,26 +4984,6 @@ msgctxt "name"
msgid "Model Checker"
msgstr "Contrôleur de modèle"
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "description"
-msgid "Dump the contents of all settings to a HTML file."
-msgstr "Exporter les contenus de tous les paramètres vers un fichier HTML."
-
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "name"
-msgid "God Mode"
-msgstr "Mode God"
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "description"
-msgid "Shows changes since latest checked version."
-msgstr "Affiche les changements depuis la dernière version."
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "name"
-msgid "Changelog"
-msgstr "Récapitulatif des changements"
-
#: FirmwareUpdater/plugin.json
msgctxt "description"
msgid "Provides a machine actions for updating firmware."
@@ -4577,15 +4994,15 @@ msgctxt "name"
msgid "Firmware Updater"
msgstr "Programme de mise à jour du firmware"
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "description"
-msgid "Create a flattend quality changes profile."
-msgstr "Créer un profil de changements de qualité aplati."
+msgid "Provides support for reading AMF files."
+msgstr "Fournit la prise en charge de la lecture de fichiers AMF."
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "name"
-msgid "Profile flatener"
-msgstr "Aplatisseur de profil"
+msgid "AMF Reader"
+msgstr "Lecteur AMF"
#: USBPrinting/plugin.json
msgctxt "description"
@@ -4597,26 +5014,6 @@ msgctxt "name"
msgid "USB printing"
msgstr "Impression par USB"
-#: UserAgreement/plugin.json
-msgctxt "description"
-msgid "Ask the user once if he/she agrees with our license."
-msgstr "Demander à l'utilisateur une fois s'il appose son accord à notre licence."
-
-#: UserAgreement/plugin.json
-msgctxt "name"
-msgid "UserAgreement"
-msgstr "UserAgreement"
-
-#: X3GWriter/plugin.json
-msgctxt "description"
-msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
-msgstr "Permet de sauvegarder la tranche résultante sous forme de fichier X3G, pour prendre en charge les imprimantes qui lisent ce format (Malyan, Makerbot et autres imprimantes basées sur Sailfish)."
-
-#: X3GWriter/plugin.json
-msgctxt "name"
-msgid "X3GWriter"
-msgstr "X3GWriter"
-
#: GCodeGzWriter/plugin.json
msgctxt "description"
msgid "Writes g-code to a compressed archive."
@@ -4659,13 +5056,13 @@ msgstr "Plugin de périphérique de sortie sur disque amovible"
#: UM3NetworkPrinting/plugin.json
msgctxt "description"
-msgid "Manages network connections to Ultimaker 3 printers."
-msgstr "Gère les connexions réseau vers les imprimantes Ultimaker 3."
+msgid "Manages network connections to Ultimaker networked printers."
+msgstr "Gère les connexions réseau vers les imprimantes Ultimaker en réseau."
#: UM3NetworkPrinting/plugin.json
msgctxt "name"
-msgid "UM3 Network Connection"
-msgstr "Connexion au réseau UM3"
+msgid "Ultimaker Network Connection"
+msgstr "Connexion réseau Ultimaker"
#: MonitorStage/plugin.json
msgctxt "description"
@@ -4727,6 +5124,16 @@ msgctxt "name"
msgid "Support Eraser"
msgstr "Effaceur de support"
+#: UFPReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading Ultimaker Format Packages."
+msgstr "Fournit un support pour la lecture des paquets de format Ultimaker."
+
+#: UFPReader/plugin.json
+msgctxt "name"
+msgid "UFP Reader"
+msgstr "Lecteur UFP"
+
#: SliceInfoPlugin/plugin.json
msgctxt "description"
msgid "Submits anonymous slice info. Can be disabled through preferences."
@@ -4787,6 +5194,16 @@ msgctxt "name"
msgid "Version Upgrade 3.3 to 3.4"
msgstr "Mise à niveau de 3.3 vers 3.4"
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.3 to Cura 4.4."
+msgstr "Configurations des mises à niveau de Cura 4.3 vers Cura 4.4."
+
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.3 to 4.4"
+msgstr "Mise à niveau de 4.3 vers 4.4"
+
#: VersionUpgrade/VersionUpgrade25to26/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.5 to Cura 2.6."
@@ -4807,6 +5224,16 @@ msgctxt "name"
msgid "Version Upgrade 2.7 to 3.0"
msgstr "Mise à niveau de version, de 2.7 vers 3.0"
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 3.5 to Cura 4.0."
+msgstr "Configurations des mises à niveau de Cura 3.5 vers Cura 4.0."
+
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 3.5 to 4.0"
+msgstr "Mise à niveau de 3.5 vers 4.0"
+
#: VersionUpgrade/VersionUpgrade34to35/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.4 to Cura 3.5."
@@ -4817,6 +5244,16 @@ msgctxt "name"
msgid "Version Upgrade 3.4 to 3.5"
msgstr "Mise à niveau de 3.4 vers 3.5"
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.0 to Cura 4.1."
+msgstr "Configurations des mises à niveau de Cura 4.0 vers Cura 4.1."
+
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.0 to 4.1"
+msgstr "Mise à niveau de 4.0 vers 4.1"
+
#: VersionUpgrade/VersionUpgrade30to31/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.0 to Cura 3.1."
@@ -4827,6 +5264,16 @@ msgctxt "name"
msgid "Version Upgrade 3.0 to 3.1"
msgstr "Mise à niveau de version, de 3.0 vers 3.1"
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.1 to Cura 4.2."
+msgstr "Configurations des mises à jour de Cura 4.1 vers Cura 4.2."
+
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.1 to 4.2"
+msgstr "Mise à jour de 4.1 vers 4.2"
+
#: VersionUpgrade/VersionUpgrade26to27/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.6 to Cura 2.7."
@@ -4857,6 +5304,16 @@ msgctxt "name"
msgid "Version Upgrade 2.2 to 2.4"
msgstr "Mise à niveau de 2.2 vers 2.4"
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.2 to Cura 4.3."
+msgstr "Configurations des mises à jour de Cura 4.2 vers Cura 4.3."
+
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.2 to 4.3"
+msgstr "Mise à jour de 4.2 vers 4.3"
+
#: ImageReader/plugin.json
msgctxt "description"
msgid "Enables ability to generate printable geometry from 2D image files."
@@ -4867,6 +5324,16 @@ msgctxt "name"
msgid "Image Reader"
msgstr "Lecteur d'images"
+#: TrimeshReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading model files."
+msgstr "Fournit la prise en charge de la lecture de fichiers modèle 3D."
+
+#: TrimeshReader/plugin.json
+msgctxt "name"
+msgid "Trimesh Reader"
+msgstr "Lecteur de Trimesh"
+
#: CuraEngineBackend/plugin.json
msgctxt "description"
msgid "Provides the link to the CuraEngine slicing backend."
@@ -4917,6 +5384,16 @@ msgctxt "name"
msgid "G-code Reader"
msgstr "Lecteur G-Code"
+#: CuraDrive/plugin.json
+msgctxt "description"
+msgid "Backup and restore your configuration."
+msgstr "Sauvegardez et restaurez votre configuration."
+
+#: CuraDrive/plugin.json
+msgctxt "name"
+msgid "Cura Backups"
+msgstr "Sauvegardes Cura"
+
#: CuraProfileWriter/plugin.json
msgctxt "description"
msgid "Provides support for exporting Cura profiles."
@@ -4937,6 +5414,16 @@ msgctxt "name"
msgid "3MF Writer"
msgstr "Générateur 3MF"
+#: PreviewStage/plugin.json
+msgctxt "description"
+msgid "Provides a preview stage in Cura."
+msgstr "Fournit une étape de prévisualisation dans Cura."
+
+#: PreviewStage/plugin.json
+msgctxt "name"
+msgid "Preview Stage"
+msgstr "Étape de prévisualisation"
+
#: UltimakerMachineActions/plugin.json
msgctxt "description"
msgid "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.)."
@@ -4957,9 +5444,29 @@ msgctxt "name"
msgid "Cura Profile Reader"
msgstr "Lecteur de profil Cura"
-#~ msgctxt "@warning:status"
-#~ msgid "Please generate G-code before saving."
-#~ msgstr "Veuillez générer le G-Code avant d'enregistrer."
+#~ msgctxt "@item:inmenu"
+#~ msgid "Flatten active settings"
+#~ msgstr "Aplatir les paramètres actifs"
+
+#~ msgctxt "@info:status"
+#~ msgid "Profile has been flattened & activated."
+#~ msgstr "Le profil a été aplati et activé."
+
+#~ msgctxt "X3g Writer Plugin Description"
+#~ msgid "Writes X3g to files"
+#~ msgstr "Écrit X3G dans des fichiers"
+
+#~ msgctxt "X3g Writer File Description"
+#~ msgid "X3g File"
+#~ msgstr "Fichier X3G"
+
+#~ msgctxt "X3G Writer File Description"
+#~ msgid "X3G File"
+#~ msgstr "Fichier X3G"
+
+#~ msgctxt "@item:inlistbox"
+#~ msgid "Open Compressed Triangle Mesh"
+#~ msgstr "Ouvrir le maillage triangulaire compressé"
#~ msgctxt "@item:inmenu"
#~ msgid "Profile Assistant"
@@ -4969,6 +5476,1032 @@ msgstr "Lecteur de profil Cura"
#~ msgid "Profile Assistant"
#~ msgstr "Assistant de profil"
+#~ msgctxt "@action:button"
+#~ msgid "Retry"
+#~ msgstr "Réessayer"
+
+#~ msgctxt "@label:table_header"
+#~ msgid "Print Core"
+#~ msgstr "Print Core"
+
+#~ msgctxt "@label"
+#~ msgid "Don't support overlap with other models"
+#~ msgstr "Ne pas prendre en charge le chevauchement avec d'autres modèles"
+
+#~ msgctxt "@label"
+#~ msgid "Modify settings for overlap with other models"
+#~ msgstr "Modifier les paramètres de chevauchement avec d'autres modèles"
+
+#~ msgctxt "@label"
+#~ msgid "Modify settings for infill of other models"
+#~ msgstr "Modifier les paramètres de remplissage d'autres modèles"
+
+#~ msgctxt "@action:ComboBox option"
+#~ msgid "Update existing"
+#~ msgstr "Mettre à jour l'existant"
+
+#~ msgctxt "@label"
+#~ msgid "Not supported"
+#~ msgstr "Non pris en charge"
+
+#~ msgctxt "@action:button"
+#~ msgid "Previous"
+#~ msgstr "Précédent"
+
+#~ msgctxt "@label"
+#~ msgid "Tip"
+#~ msgstr "Astuce"
+
+#~ msgctxt "@label"
+#~ msgid "Print experiment"
+#~ msgstr "Test d'impression"
+
+#~ msgctxt "@label"
+#~ msgid "Checklist"
+#~ msgstr "Liste de contrôle"
+
+#~ msgctxt "@label"
+#~ msgid "Please select any upgrades made to this Ultimaker 2."
+#~ msgstr "Sélectionnez les mises à niveau disponibles pour cet Ultimaker 2."
+
+#~ msgctxt "@label"
+#~ msgid "Olsson Block"
+#~ msgstr "Blocage Olsson"
+
+#~ msgctxt "@window:text"
+#~ msgid "Camera rendering: "
+#~ msgstr "Rendu caméra : "
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Use multi build plate functionality"
+#~ msgstr "Utiliser la fonctionnalité multi-plateau"
+
+#~ msgctxt "@option:check"
+#~ msgid "Use multi build plate functionality (restart required)"
+#~ msgstr "Utiliser la fonctionnalité multi-plateau (redémarrage requis)"
+
+#~ msgctxt "@label"
+#~ msgid "Default profiles"
+#~ msgstr "Profils par défaut"
+
+#~ msgctxt "@label:textbox"
+#~ msgid "search settings"
+#~ msgstr "paramètres de recherche"
+
+#~ msgctxt "@label"
+#~ msgid "Layer Height"
+#~ msgstr "Hauteur de la couche"
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile."
+#~ msgstr "Ce profil de qualité n'est pas disponible pour votre matériau et configuration des buses actuels. Veuillez modifier ces derniers pour activer ce profil de qualité."
+
+#~ msgctxt "@tooltip"
+#~ msgid "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab"
+#~ msgstr "Un profil personnalisé est actuellement actif. Pour activer le curseur de qualité, choisissez un profil de qualité par défaut dans l'onglet Personnaliser"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Build plate"
+#~ msgstr "Plateau"
+
+#~ msgctxt "@title:settings"
+#~ msgid "&Profile"
+#~ msgstr "&Profil"
+
+#~ msgctxt "@action:label"
+#~ msgid "Build plate"
+#~ msgstr "Plateau"
+
+#~ msgctxt "description"
+#~ msgid "Dump the contents of all settings to a HTML file."
+#~ msgstr "Exporter les contenus de tous les paramètres vers un fichier HTML."
+
+#~ msgctxt "name"
+#~ msgid "God Mode"
+#~ msgstr "Mode God"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattened quality changes profile."
+#~ msgstr "Créer un profil de changements de qualité aplati."
+
+#~ msgctxt "name"
+#~ msgid "Profile Flattener"
+#~ msgstr "Aplatisseur de profil"
+
+#~ msgctxt "description"
+#~ msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
+#~ msgstr "Permet aux fabricants de matériaux de créer de nouveaux matériaux et profils de qualité à l'aide d'une interface utilisateur ad hoc."
+
+#~ msgctxt "name"
+#~ msgid "Print Profile Assistant"
+#~ msgstr "Assistant de profil d'impression"
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network."
+#~ msgstr "Connecté sur le réseau."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. Please approve the access request on the printer."
+#~ msgstr "Connecté sur le réseau. Veuillez approuver la demande d'accès sur l'imprimante."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. No access to control the printer."
+#~ msgstr "Connecté sur le réseau. Pas d'accès pour commander l'imprimante."
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer requested. Please approve the request on the printer"
+#~ msgstr "Accès à l'imprimante demandé. Veuillez approuver la demande sur l'imprimante"
+
+#~ msgctxt "@info:title"
+#~ msgid "Authentication status"
+#~ msgstr "Statut d'authentification"
+
+#~ msgctxt "@info:title"
+#~ msgid "Authentication Status"
+#~ msgstr "Statut d'authentification"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Re-send the access request"
+#~ msgstr "Renvoyer la demande d'accès"
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer accepted"
+#~ msgstr "Accès à l'imprimante accepté"
+
+#~ msgctxt "@info:status"
+#~ msgid "No access to print with this printer. Unable to send print job."
+#~ msgstr "Aucun accès pour imprimer avec cette imprimante. Impossible d'envoyer la tâche d'impression."
+
+#~ msgctxt "@action:button"
+#~ msgid "Request Access"
+#~ msgstr "Demande d'accès"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Send access request to the printer"
+#~ msgstr "Envoyer la demande d'accès à l'imprimante"
+
+#~ msgctxt "@label"
+#~ msgid "Unable to start a new print job."
+#~ msgstr "Impossible de démarrer une nouvelle tâche d'impression."
+
+#~ msgctxt "@label"
+#~ msgid "There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. Please resolve this issues before continuing."
+#~ msgstr "Un problème avec la configuration de votre Ultimaker empêche le démarrage de l'impression. Veuillez résoudre ce problème avant de continuer."
+
+#~ msgctxt "@window:title"
+#~ msgid "Mismatched configuration"
+#~ msgstr "Configuration différente"
+
+#~ msgctxt "@label"
+#~ msgid "Are you sure you wish to print with the selected configuration?"
+#~ msgstr "Êtes-vous sûr(e) de vouloir imprimer avec la configuration sélectionnée ?"
+
+#~ msgctxt "@label"
+#~ msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "Problème de compatibilité entre la configuration ou l'étalonnage de l'imprimante et Cura. Pour un résultat optimal, découpez toujours pour les PrintCores et matériaux insérés dans votre imprimante."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending new jobs (temporarily) blocked, still sending the previous print job."
+#~ msgstr "Envoi de nouvelles tâches (temporairement) bloqué, envoi de la tâche d'impression précédente en cours."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending data to printer"
+#~ msgstr "Envoi des données à l'imprimante"
+
+#~ msgctxt "@info:title"
+#~ msgid "Sending Data"
+#~ msgstr "Envoi des données"
+
+#~ msgctxt "@info:status"
+#~ msgid "No Printcore loaded in slot {slot_number}"
+#~ msgstr "Pas de PrintCore inséré dans la fente {slot_number}"
+
+#~ msgctxt "@info:status"
+#~ msgid "No material loaded in slot {slot_number}"
+#~ msgstr "Aucun matériau inséré dans la fente {slot_number}"
+
+#~ msgctxt "@label"
+#~ msgid "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}"
+#~ msgstr "PrintCore différent (Cura : {cura_printcore_name}, Imprimante : {remote_printcore_name}) sélectionné pour l'extrudeuse {extruder_id}"
+
+#~ msgctxt "@label"
+#~ msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
+#~ msgstr "Matériau différent (Cura : {0}, Imprimante : {1}) sélectionné pour l'extrudeuse {2}"
+
+#~ msgctxt "@window:title"
+#~ msgid "Sync with your printer"
+#~ msgstr "Synchroniser avec votre imprimante"
+
+#~ msgctxt "@label"
+#~ msgid "Would you like to use your current printer configuration in Cura?"
+#~ msgstr "Voulez-vous utiliser votre configuration d'imprimante actuelle dans Cura ?"
+
+#~ msgctxt "@label"
+#~ msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "Les PrintCores et / ou matériaux sur votre imprimante diffèrent de ceux de votre projet actuel. Pour un résultat optimal, découpez toujours pour les PrintCores et matériaux insérés dans votre imprimante."
+
+#~ msgctxt "@action:button"
+#~ msgid "View in Monitor"
+#~ msgstr "Afficher sur le moniteur"
+
+#~ msgctxt "@info:status"
+#~ msgid "Printer '{printer_name}' has finished printing '{job_name}'."
+#~ msgstr "{printer_name} a terminé d'imprimer '{job_name}'."
+
+#~ msgctxt "@info:status"
+#~ msgid "The print job '{job_name}' was finished."
+#~ msgstr "La tâche d'impression '{job_name}' est terminée."
+
+#~ msgctxt "@info:status"
+#~ msgid "Print finished"
+#~ msgstr "Impression terminée"
+
+#~ msgctxt "@label:material"
+#~ msgid "Empty"
+#~ msgstr "Vide"
+
+#~ msgctxt "@label:material"
+#~ msgid "Unknown"
+#~ msgstr "Inconnu"
+
+#~ msgctxt "@info:title"
+#~ msgid "Cloud error"
+#~ msgstr "Erreur de cloud"
+
+#~ msgctxt "@info:status"
+#~ msgid "Could not export print job."
+#~ msgstr "Impossible d'exporter la tâche d'impression."
+
+#~ msgctxt "@info:description"
+#~ msgid "There was an error connecting to the cloud."
+#~ msgstr "Une erreur s'est produite lors de la connexion au cloud."
+
+#~ msgctxt "@info:status"
+#~ msgid "Uploading via Ultimaker Cloud"
+#~ msgstr "Téléchargement via Ultimaker Cloud"
+
+#~ msgctxt "@info:status Ultimaker Cloud is a brand name and shouldn't be translated."
+#~ msgid "Connect to Ultimaker Cloud"
+#~ msgstr "Se connecter à Ultimaker Cloud"
+
+#~ msgctxt "@action"
+#~ msgid "Don't ask me again for this printer."
+#~ msgstr "Ne plus me demander pour cette imprimante."
+
+#~ msgctxt "@info:status"
+#~ msgid "You can now send and monitor print jobs from anywhere using your Ultimaker account."
+#~ msgstr "Vous pouvez maintenant lancer et surveiller des impressions où que vous soyez avec votre compte Ultimaker."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected!"
+#~ msgstr "Connecté !"
+
+#~ msgctxt "@action"
+#~ msgid "Review your connection"
+#~ msgstr "Consulter votre connexion"
+
+#~ msgctxt "@info:status Don't translate the XML tags !"
+#~ msgid "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it."
+#~ msgstr "La machine définie dans le profil {0} ({1}) ne correspond pas à votre machine actuelle ({2}) ; échec de l'importation."
+
+#~ msgctxt "@info:status Don't translate the XML tags or !"
+#~ msgid "Failed to import profile from {0}:"
+#~ msgstr "Échec de l'importation du profil depuis le fichier {0} :"
+
+#~ msgctxt "@window:title"
+#~ msgid "Existing Connection"
+#~ msgstr "Connexion existante"
+
+#~ msgctxt "@message:text"
+#~ msgid "This printer/group is already added to Cura. Please select another printer/group."
+#~ msgstr "Ce groupe / cette imprimante a déjà été ajouté à Cura. Veuillez sélectionner un autre groupe / imprimante."
+
+#~ msgctxt "@label"
+#~ msgid "Enter the IP address or hostname of your printer on the network."
+#~ msgstr "Saisissez l'adresse IP ou le nom d'hôte de votre imprimante sur le réseau."
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Connect to a printer"
+#~ msgstr "Connecter à une imprimante"
+
+#~ msgctxt "@title"
+#~ msgid "Cura Settings Guide"
+#~ msgstr "Guide des paramètres de Cura"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Zooming towards the mouse is not supported in the orthogonal perspective."
+#~ msgstr "Zoom vers la souris n'est pas pris en charge dans la perspective orthogonale."
+
+#~ msgid "Orthogonal"
+#~ msgstr "Orthogonale"
+
+#~ msgctxt "description"
+#~ msgid "Manages network connections to Ultimaker 3 printers."
+#~ msgstr "Gère les connexions réseau vers les imprimantes Ultimaker 3."
+
+#~ msgctxt "name"
+#~ msgid "UM3 Network Connection"
+#~ msgstr "Connexion au réseau UM3"
+
+#~ msgctxt "description"
+#~ msgid "Provides extra information and explanations about settings in Cura, with images and animations."
+#~ msgstr "Fournit des informations et explications supplémentaires sur les paramètres de Cura, avec des images et des animations."
+
+#~ msgctxt "name"
+#~ msgid "Settings Guide"
+#~ msgstr "Guide des paramètres"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Cura Settings Guide"
+#~ msgstr "Guide des paramètres de Cura"
+
+#~ msgctxt "@info:generic"
+#~ msgid "Settings have been changed to match the current availability of extruders: [%s]"
+#~ msgstr "Les paramètres ont été modifiés pour correspondre aux extrudeuses actuellement disponibles : [%s]"
+
+#~ msgctxt "@title:groupbox"
+#~ msgid "User description"
+#~ msgstr "Description de l'utilisateur"
+
+#~ msgctxt "@info"
+#~ msgid "These options are not available because you are monitoring a cloud printer."
+#~ msgstr "Ces options ne sont pas disponibles car vous surveillez une imprimante cloud."
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Go to Cura Connect"
+#~ msgstr "Aller à Cura Connect"
+
+#~ msgctxt "@info"
+#~ msgid "All jobs are printed."
+#~ msgstr "Toutes les tâches ont été imprimées."
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "View print history"
+#~ msgstr "Voir l'historique d'impression"
+
+#~ msgctxt "@label"
+#~ msgid ""
+#~ "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
+#~ "\n"
+#~ "Select your printer from the list below:"
+#~ msgstr ""
+#~ "Pour imprimer directement sur votre imprimante sur le réseau, assurez-vous que votre imprimante est connectée au réseau via un câble réseau ou en connectant votre imprimante à votre réseau Wi-Fi. Si vous ne connectez pas Cura avec votre imprimante, vous pouvez utiliser une clé USB pour transférer les fichiers g-code sur votre imprimante.\n"
+#~ "\n"
+#~ "Sélectionnez votre imprimante dans la liste ci-dessous :"
+
+#~ msgctxt "@info"
+#~ msgid ""
+#~ "Please make sure your printer has a connection:\n"
+#~ "- Check if the printer is turned on.\n"
+#~ "- Check if the printer is connected to the network."
+#~ msgstr ""
+#~ "Assurez-vous que votre imprimante est connectée :\n"
+#~ "- Vérifiez si l'imprimante est sous tension.\n"
+#~ "- Vérifiez si l'imprimante est connectée au réseau."
+
+#~ msgctxt "@option:check"
+#~ msgid "See only current build plate"
+#~ msgstr "Afficher uniquement le plateau actuel"
+
+#~ msgctxt "@action:button"
+#~ msgid "Arrange to all build plates"
+#~ msgstr "Réorganiser sur tous les plateaux"
+
+#~ msgctxt "@action:button"
+#~ msgid "Arrange current build plate"
+#~ msgstr "Réorganiser le plateau actuel"
+
+#~ msgctxt "description"
+#~ msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
+#~ msgstr "Permet de sauvegarder la tranche résultante sous forme de fichier X3G, pour prendre en charge les imprimantes qui lisent ce format (Malyan, Makerbot et autres imprimantes basées sur Sailfish)."
+
+#~ msgctxt "name"
+#~ msgid "X3GWriter"
+#~ msgstr "X3GWriter"
+
+#~ msgctxt "description"
+#~ msgid "Reads SVG files as toolpaths, for debugging printer movements."
+#~ msgstr "Lit les fichiers SVG comme des Toolpaths, pour déboguer les mouvements de l'imprimante."
+
+#~ msgctxt "name"
+#~ msgid "SVG Toolpath Reader"
+#~ msgstr "Lecteur de Toolpaths SVG"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Changelog"
+#~ msgstr "Récapitulatif des changements"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Show Changelog"
+#~ msgstr "Afficher le récapitulatif des changements"
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending data to remote cluster"
+#~ msgstr "Envoi de données à un cluster distant"
+
+#~ msgctxt "@info:status"
+#~ msgid "Connect to Ultimaker Cloud"
+#~ msgstr "Se connecter à Ultimaker Cloud"
+
+#~ msgctxt "@info"
+#~ msgid "Cura collects anonymized usage statistics."
+#~ msgstr "Cura recueille des statistiques d'utilisation anonymes."
+
+#~ msgctxt "@info:title"
+#~ msgid "Collecting Data"
+#~ msgstr "Collecte des données"
+
+#~ msgctxt "@action:button"
+#~ msgid "More info"
+#~ msgstr "Plus d'informations"
+
+#~ msgctxt "@action:tooltip"
+#~ msgid "See more information on what data Cura sends."
+#~ msgstr "Voir plus d'informations sur les données envoyées par Cura."
+
+#~ msgctxt "@action:button"
+#~ msgid "Allow"
+#~ msgstr "Autoriser"
+
+#~ msgctxt "@action:tooltip"
+#~ msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
+#~ msgstr "Autoriser Cura à envoyer des statistiques d'utilisation anonymes pour mieux prioriser les améliorations futures apportées à Cura. Certaines de vos préférences et paramètres sont envoyés, ainsi que la version du logiciel Cura et un hachage des modèles que vous découpez."
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Evaluation"
+#~ msgstr "Évaluation"
+
+#~ msgctxt "@info:title"
+#~ msgid "Network enabled printers"
+#~ msgstr "Imprimantes réseau"
+
+#~ msgctxt "@info:title"
+#~ msgid "Local printers"
+#~ msgstr "Imprimantes locales"
+
+#~ msgctxt "@info:backup_failed"
+#~ msgid "Tried to restore a Cura backup that does not match your current version."
+#~ msgstr "A essayé de restaurer une sauvegarde Cura qui ne correspond pas à votre version actuelle."
+
+#~ msgctxt "@title"
+#~ msgid "Machine Settings"
+#~ msgstr "Paramètres de la machine"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Settings"
+#~ msgstr "Paramètres de l'imprimante"
+
+#~ msgctxt "@option:check"
+#~ msgid "Origin at center"
+#~ msgstr "Origine au centre"
+
+#~ msgctxt "@option:check"
+#~ msgid "Heated bed"
+#~ msgstr "Plateau chauffant"
+
+#~ msgctxt "@label"
+#~ msgid "Printhead Settings"
+#~ msgstr "Paramètres de la tête d'impression"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distance entre la gauche de la tête d'impression et le centre de la buse. Permet d'empêcher les collisions entre les impressions précédentes et la tête d'impression lors d'une impression « Un à la fois »."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distance entre le devant de la tête d'impression et le centre de la buse. Permet d'empêcher les collisions entre les impressions précédentes et la tête d'impression lors d'une impression « Un à la fois »."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distance entre la droite de la tête d'impression et le centre de la buse. Permet d'empêcher les collisions entre les impressions précédentes et la tête d'impression lors d'une impression « Un à la fois »."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distance entre le dos de la tête d'impression et le centre de la buse. Permet d'empêcher les collisions entre les impressions précédentes et la tête d'impression lors d'une impression « Un à la fois »."
+
+#~ msgctxt "@label"
+#~ msgid "Gantry height"
+#~ msgstr "Hauteur du portique"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
+#~ msgstr "La différence de hauteur entre la pointe de la buse et le système de portique (axes X et Y). Permet d'empêcher les collisions entre les impressions précédentes et le portique lors d'une impression « Un à la fois »."
+
+#~ msgctxt "@label"
+#~ msgid "Start G-code"
+#~ msgstr "G-Code de démarrage"
+
+#~ msgctxt "@tooltip"
+#~ msgid "G-code commands to be executed at the very start."
+#~ msgstr "Commandes G-Code à exécuter au tout début."
+
+#~ msgctxt "@label"
+#~ msgid "End G-code"
+#~ msgstr "G-Code de fin"
+
+#~ msgctxt "@tooltip"
+#~ msgid "G-code commands to be executed at the very end."
+#~ msgstr "Commandes G-Code à exécuter tout à la fin."
+
+#~ msgctxt "@label"
+#~ msgid "Nozzle Settings"
+#~ msgstr "Paramètres de la buse"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
+#~ msgstr "Le diamètre nominal de filament pris en charge par l'imprimante. Le diamètre exact sera remplacé par le matériau et / ou le profil."
+
+#~ msgctxt "@label"
+#~ msgid "Extruder Start G-code"
+#~ msgstr "Extrudeuse G-Code de démarrage"
+
+#~ msgctxt "@label"
+#~ msgid "Extruder End G-code"
+#~ msgstr "Extrudeuse G-Code de fin"
+
+#~ msgctxt "@label"
+#~ msgid "Changelog"
+#~ msgstr "Récapitulatif des changements"
+
+#~ msgctxt "@title:window"
+#~ msgid "User Agreement"
+#~ msgstr "Accord utilisateur"
+
+#~ msgctxt "@alabel"
+#~ msgid "Enter the IP address or hostname of your printer on the network."
+#~ msgstr "Saisissez l'adresse IP ou le nom d'hôte de votre imprimante sur le réseau."
+
+#~ msgctxt "@info"
+#~ msgid "Please select a network connected printer to monitor."
+#~ msgstr "Veuillez sélectionner une imprimante à surveiller qui est connectée au réseau."
+
+#~ msgctxt "@info"
+#~ msgid "Please connect your Ultimaker printer to your local network."
+#~ msgstr "Veuillez connecter votre imprimante Ultimaker à votre réseau local."
+
+#~ msgctxt "@text:window"
+#~ msgid "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent."
+#~ msgstr "Cura envoie des données anonymes à Ultimaker afin d'améliorer la qualité d'impression et l'expérience utilisateur. Voici un exemple de toutes les données envoyées."
+
+#~ msgctxt "@text:window"
+#~ msgid "I don't want to send this data"
+#~ msgstr "Je ne veux pas envoyer ces données"
+
+#~ msgctxt "@text:window"
+#~ msgid "Allow sending this data to Ultimaker and help us improve Cura"
+#~ msgstr "Permettre l'envoi de ces données à Ultimaker et nous aider à améliorer Cura"
+
+#~ msgctxt "@label"
+#~ msgid "No print selected"
+#~ msgstr "Aucune impression sélectionnée"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
+#~ msgstr "Par défaut, les pixels blancs représentent les points hauts sur la maille tandis que les pixels noirs représentent les points bas sur la maille. Modifiez cette option pour inverser le comportement de manière à ce que les pixels noirs représentent les points hauts sur la maille et les pixels blancs les points bas."
+
+#~ msgctxt "@title"
+#~ msgid "Select Printer Upgrades"
+#~ msgstr "Sélectionner les mises à niveau de l'imprimante"
+
+#~ msgctxt "@label"
+#~ msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
+#~ msgstr "Sélectionnez l'extrudeur à utiliser comme support. Cela créera des structures de support sous le modèle afin de l'empêcher de s'affaisser ou de s'imprimer dans les airs."
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile"
+#~ msgstr "Ce profil de qualité n'est pas disponible pour votre matériau et configuration des buses actuels. Veuillez modifier ces derniers pour activer ce profil de qualité."
+
+#~ msgctxt "@label shown when we load a Gcode file"
+#~ msgid "Print setup disabled. G code file can not be modified."
+#~ msgstr "Configuration d'impression désactivée. Le fichier G-Code ne peut pas être modifié."
+
+#~ msgctxt "@label"
+#~ msgid "See the material compatibility chart"
+#~ msgstr "Voir le tableau de compatibilité des matériaux"
+
+#~ msgctxt "@label"
+#~ msgid "View types"
+#~ msgstr "Types d'affichages"
+
+#~ msgctxt "@label"
+#~ msgid "Hi "
+#~ msgstr "Bonjour "
+
+#~ msgctxt "@text"
+#~ msgid ""
+#~ "- Send print jobs to Ultimaker printers outside your local network\n"
+#~ "- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+#~ "- Get exclusive access to material profiles from leading brands"
+#~ msgstr ""
+#~ "- Envoyez des tâches d'impression à des imprimantes Ultimaker hors de votre réseau local\n"
+#~ "- Stockez vos paramètres Ultimaker Cura dans le cloud pour les utiliser où que vous soyez\n"
+#~ "- Obtenez un accès exclusif aux profils de matériaux des principales marques"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Unable to Slice"
+#~ msgstr "Impossible de découper"
+
+#~ msgctxt "@label"
+#~ msgid "Time specification"
+#~ msgstr "Spécification de durée"
+
+#~ msgctxt "@label"
+#~ msgid "Material specification"
+#~ msgstr "Spécification des matériaux"
+
+#~ msgctxt "@title:tab"
+#~ msgid "Add a printer to Cura"
+#~ msgstr "Ajouter une imprimante à Cura"
+
+#~ msgctxt "@title:tab"
+#~ msgid ""
+#~ "Select the printer you want to use from the list below.\n"
+#~ "\n"
+#~ "If your printer is not in the list, use the \"Custom FFF Printer\" from the \"Custom\" category and adjust the settings to match your printer in the next dialog."
+#~ msgstr ""
+#~ "Sélectionnez l'imprimante que vous voulez utiliser dans la liste ci-dessous.\n"
+#~ "\n"
+#~ "Si votre imprimante n'est pas dans la liste, utilisez l'imprimante « Imprimante FFF personnalisée » de la catégorie « Personnalisé » et ajustez les paramètres pour qu'ils correspondent à votre imprimante dans le dialogue suivant."
+
+#~ msgctxt "@label"
+#~ msgid "Manufacturer"
+#~ msgstr "Fabricant"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Name"
+#~ msgstr "Nom de l'imprimante"
+
+#~ msgctxt "@action:button"
+#~ msgid "Add Printer"
+#~ msgstr "Ajouter une imprimante"
+
+#~ msgid "Modify G-Code"
+#~ msgstr "Modifier le G-Code"
+
+#~ msgctxt "@info:status"
+#~ msgid "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."
+#~ msgstr "Rien à couper car aucun des modèles ne convient au volume d'impression. Mettez à l'échelle ou faites pivoter les modèles pour les faire correspondre."
+
+#~ msgctxt "@info:status"
+#~ msgid "The selected material is incompatible with the selected machine or configuration."
+#~ msgstr "Le matériau sélectionné est incompatible avec la machine ou la configuration sélectionnée."
+
+#~ msgctxt "@info:title"
+#~ msgid "Incompatible Material"
+#~ msgstr "Matériau incompatible"
+
+#~ msgctxt "@info:status Don't translate the XML tags or !"
+#~ msgid "Failed to import profile from {0}: {1}"
+#~ msgstr "Échec de l'importation du profil depuis le fichier {0} : {1}"
+
+#~ msgctxt "@title"
+#~ msgid "Toolbox"
+#~ msgstr "Boîte à outils"
+
+#~ msgctxt "@label"
+#~ msgid "Not available"
+#~ msgstr "Non disponible"
+
+#~ msgctxt "@label"
+#~ msgid "Unreachable"
+#~ msgstr "Injoignable"
+
+#~ msgctxt "@label"
+#~ msgid "Available"
+#~ msgstr "Disponible"
+
+#~ msgctxt "@label:status"
+#~ msgid "Preparing"
+#~ msgstr "Préparation"
+
+#~ msgctxt "@label:status"
+#~ msgid "Pausing"
+#~ msgstr "Mise en pause"
+
+#~ msgctxt "@label:status"
+#~ msgid "Resuming"
+#~ msgstr "Reprise"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: Unavailable printer"
+#~ msgstr "En attente : imprimante non disponible"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: First available"
+#~ msgstr "En attente : première imprimante disponible"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: "
+#~ msgstr "En attente : "
+
+#~ msgctxt "@label"
+#~ msgid "Configuration change"
+#~ msgstr "Modification des configurations"
+
+#~ msgctxt "@label"
+#~ msgid "The assigned printer, %1, requires the following configuration change(s):"
+#~ msgstr "L'imprimante assignée, %1, nécessite d'apporter la ou les modifications suivantes à la configuration :"
+
+#~ msgctxt "@label"
+#~ msgid "Override"
+#~ msgstr "Remplacer"
+
+#~ msgctxt "@label"
+#~ msgid "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?"
+#~ msgstr "Le fait de démarrer un travail d'impression avec une configuration incompatible peut endommager votre imprimante 3D. Êtes-vous sûr de vouloir remplacer la configuration et imprimer %1 ?"
+
+#~ msgctxt "@window:title"
+#~ msgid "Override configuration configuration and start print"
+#~ msgstr "Remplacer la configuration et lancer l'impression"
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Manage queue"
+#~ msgstr "Gérer la file d'attente"
+
+#~ msgctxt "@label"
+#~ msgid "Printing"
+#~ msgstr "Impression"
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Manage printers"
+#~ msgstr "Gérer les imprimantes"
+
+#~ msgctxt "@action:button"
+#~ msgid "Activate Configuration"
+#~ msgstr "Activer la configuration"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Load the configuration of the printer into Cura"
+#~ msgstr "Charger la configuration de l'imprimante dans Cura"
+
+#~ msgctxt "@label"
+#~ msgid "Show Travels"
+#~ msgstr "Afficher les déplacements"
+
+#~ msgctxt "@label"
+#~ msgid "Show Helpers"
+#~ msgstr "Afficher les aides"
+
+#~ msgctxt "@label"
+#~ msgid "Show Shell"
+#~ msgstr "Afficher la coque"
+
+#~ msgctxt "@label"
+#~ msgid "Show Infill"
+#~ msgstr "Afficher le remplissage"
+
+#~ msgctxt "@text:window"
+#~ msgid "I don't want to send these data"
+#~ msgstr "Je ne veux pas envoyer ces données"
+
+#~ msgctxt "@text:window"
+#~ msgid "Allow sending these data to Ultimaker and help us improve Cura"
+#~ msgstr "Permettre l'envoi de ces données à Ultimaker et nous aider à améliorer Cura"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type:"
+#~ msgstr "Type d'imprimante :"
+
+#~ msgctxt "@label"
+#~ msgid "Connection:"
+#~ msgstr "Connexion :"
+
+#~ msgctxt "@label"
+#~ msgid "State:"
+#~ msgstr "État :"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for a printjob"
+#~ msgstr "En attente d'une tâche d'impression"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for someone to clear the build plate"
+#~ msgstr "En attente du dégagement du plateau"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Aborting print..."
+#~ msgstr "Abandon de l'impression..."
+
+#~ msgctxt "@label"
+#~ msgid "Protected profiles"
+#~ msgstr "Profils protégés"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Name:"
+#~ msgstr "Nom de l'imprimante :"
+
+#~ msgctxt "@label"
+#~ msgid "Profile:"
+#~ msgstr "Profil :"
+
+#~ msgctxt "@label:textbox"
+#~ msgid "Search..."
+#~ msgstr "Rechercher..."
+
+#~ msgctxt "@action:inmenu"
+#~ msgid "Collapse All"
+#~ msgstr "Réduire tout"
+
+#~ msgctxt "@action:inmenu"
+#~ msgid "Expand All"
+#~ msgstr "Développer tout"
+
+#~ msgctxt "@label:header configurations"
+#~ msgid "Available configurations"
+#~ msgstr "Configurations disponibles"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "Extruder"
+#~ msgstr "Extrudeuse"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "Yes"
+#~ msgstr "Oui"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "No"
+#~ msgstr "Non"
+
+#~ msgctxt "@label:listbox"
+#~ msgid "Print Setup"
+#~ msgstr "Configuration de l'impression"
+
+#~ msgctxt "@label:listbox"
+#~ msgid ""
+#~ "Print Setup disabled\n"
+#~ "G-code files cannot be modified"
+#~ msgstr ""
+#~ "Configuration de l'impression désactivée\n"
+#~ "Les fichiers G-Code ne peuvent pas être modifiés"
+
+#~ msgctxt "@label Hours and minutes"
+#~ msgid "00h 00min"
+#~ msgstr "00h 00min"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Time specification"
+#~ msgstr "Spécification de temps"
+
+#~ msgctxt "@label"
+#~ msgid "Cost specification"
+#~ msgstr "Spécification de coût"
+
+#~ msgctxt "@label"
+#~ msgid "Total:"
+#~ msgstr "Total :"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
+#~ msgstr "Configuration de l'impression recommandée
Imprimer avec les paramètres recommandés pour l'imprimante, le matériau et la qualité sélectionnés."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
+#~ msgstr "Configuration de l'impression personnalisée
Imprimer avec un contrôle fin de chaque élément du processus de découpe."
+
+#~ msgctxt "@action:inmenu menubar:help"
+#~ msgid "Show Engine &Log..."
+#~ msgstr "Afficher le &journal du moteur..."
+
+#~ msgctxt "@action:menu"
+#~ msgid "Browse packages..."
+#~ msgstr "Parcourir les paquets..."
+
+#~ msgctxt "@action:inmenu menubar:view"
+#~ msgid "Expand/Collapse Sidebar"
+#~ msgstr "Déplier / replier la barre latérale"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Please load a 3D model"
+#~ msgstr "Veuillez charger un modèle 3D"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Ready to slice"
+#~ msgstr "Prêt à découper"
+
+#~ msgctxt "@label:PrintjobStatus %1 is target operation"
+#~ msgid "Ready to %1"
+#~ msgstr "Prêt à %1"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Slicing unavailable"
+#~ msgstr "Découpe indisponible"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Slice current printjob"
+#~ msgstr "Découper la tâche d'impression en cours"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Cancel slicing process"
+#~ msgstr "Annuler le processus de découpe"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Prepare"
+#~ msgstr "Préparer"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Cancel"
+#~ msgstr "Annuler"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Select the active output device"
+#~ msgstr "Sélectionner le périphérique de sortie actif"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&View"
+#~ msgstr "&Visualisation"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Settings"
+#~ msgstr "&Paramètres"
+
+#~ msgctxt "@title:menu menubar:toplevel"
+#~ msgid "&Toolbox"
+#~ msgstr "&Boîte à outils"
+
+#~ msgctxt "@action:button"
+#~ msgid "Open File"
+#~ msgstr "Ouvrir un fichier"
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
+#~ msgstr "Ce profil de qualité n'est pas disponible pour votre matériau et configuration des buses actuels. Veuillez modifier ces derniers pour activer ce profil de qualité"
+
+#~ msgctxt "@label"
+#~ msgid "Print Speed"
+#~ msgstr "Vitesse d’impression"
+
+#~ msgctxt "@label"
+#~ msgid "Slower"
+#~ msgstr "Ralentir"
+
+#~ msgctxt "@label"
+#~ msgid "Faster"
+#~ msgstr "Accélérer"
+
+#~ msgctxt "@label"
+#~ msgid "Enable gradual"
+#~ msgstr "Permettre le remplissage graduel"
+
+#~ msgctxt "@label"
+#~ msgid "Generate Support"
+#~ msgstr "Générer les supports"
+
+#~ msgctxt "@label"
+#~ msgid "Build Plate Adhesion"
+#~ msgstr "Adhérence au plateau"
+
+#~ msgctxt "@label"
+#~ msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
+#~ msgstr "Besoin d'aide pour améliorer vos impressions ? Lisez les Guides de dépannage Ultimaker"
+
+#~ msgctxt "@title:window"
+#~ msgid "Engine Log"
+#~ msgstr "Journal du moteur"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type"
+#~ msgstr "Type d'imprimante"
+
+#~ msgctxt "@label"
+#~ msgid "Use glue with this material combination"
+#~ msgstr "Utiliser de la colle avec cette combinaison de matériaux"
+
+#~ msgctxt "@label"
+#~ msgid "Check compatibility"
+#~ msgstr "Vérifier la compatibilité"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Click to check the material compatibility on Ultimaker.com."
+#~ msgstr "Cliquez ici pour vérifier la compatibilité des matériaux sur Ultimaker.com."
+
+#~ msgctxt "description"
+#~ msgid "Shows changes since latest checked version."
+#~ msgstr "Affiche les changements depuis la dernière version."
+
+#~ msgctxt "name"
+#~ msgid "Changelog"
+#~ msgstr "Récapitulatif des changements"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattend quality changes profile."
+#~ msgstr "Créer un profil de changements de qualité aplati."
+
+#~ msgctxt "name"
+#~ msgid "Profile flatener"
+#~ msgstr "Aplatisseur de profil"
+
+#~ msgctxt "description"
+#~ msgid "Ask the user once if he/she agrees with our license."
+#~ msgstr "Demander à l'utilisateur une fois s'il appose son accord à notre licence."
+
+#~ msgctxt "name"
+#~ msgid "UserAgreement"
+#~ msgstr "UserAgreement"
+
+#~ msgctxt "@warning:status"
+#~ msgid "Please generate G-code before saving."
+#~ msgstr "Veuillez générer le G-Code avant d'enregistrer."
+
#~ msgctxt "@action"
#~ msgid "Upgrade Firmware"
#~ msgstr "Mise à niveau du firmware"
@@ -4993,22 +6526,6 @@ msgstr "Lecteur de profil Cura"
#~ msgid "Confirm uninstall "
#~ msgstr "Confirmer la désinstallation "
-#~ msgctxt "@label:status"
-#~ msgid "Paused"
-#~ msgstr "En pause"
-
-#~ msgctxt "@action:button"
-#~ msgid "Previous"
-#~ msgstr "Précédent"
-
-#~ msgctxt "@action:button"
-#~ msgid "Next"
-#~ msgstr "Suivant"
-
-#~ msgctxt "@label"
-#~ msgid "Tip"
-#~ msgstr "Astuce"
-
#~ msgctxt "@label Print estimates: m for meters, g for grams, %4 is currency and %3 is print cost"
#~ msgid "%1m / ~ %2g / ~ %4 %3"
#~ msgstr "%1m / ~ %2g / ~ %4 %3"
@@ -5017,26 +6534,10 @@ msgstr "Lecteur de profil Cura"
#~ msgid "%1m / ~ %2g"
#~ msgstr "%1m / ~ %2g"
-#~ msgctxt "@label"
-#~ msgid "Print experiment"
-#~ msgstr "Test d'impression"
-
-#~ msgctxt "@label"
-#~ msgid "Checklist"
-#~ msgstr "Liste de contrôle"
-
#~ msgctxt "@title"
#~ msgid "Upgrade Firmware"
#~ msgstr "Mise à niveau du firmware"
-#~ msgctxt "description"
-#~ msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
-#~ msgstr "Permet aux fabricants de matériaux de créer de nouveaux matériaux et profils de qualité à l'aide d'une interface utilisateur ad hoc."
-
-#~ msgctxt "name"
-#~ msgid "Print Profile Assistant"
-#~ msgstr "Assistant de profil d'impression"
-
#~ msgctxt "@action:button"
#~ msgid "Print with Doodle3D WiFi-Box"
#~ msgstr "Imprimer avec Doodle3D WiFi-Box"
@@ -5129,10 +6630,6 @@ msgstr "Lecteur de profil Cura"
#~ msgid "Lost connection with the printer"
#~ msgstr "Connexion avec l'imprimante perdue"
-#~ msgctxt "@label:status"
-#~ msgid "Unavailable"
-#~ msgstr "Indisponible"
-
#~ msgctxt "@label:status"
#~ msgid "Unknown"
#~ msgstr "Inconnu"
diff --git a/resources/i18n/fr_FR/fdmextruder.def.json.po b/resources/i18n/fr_FR/fdmextruder.def.json.po
index 52969f511f..59ade887b6 100644
--- a/resources/i18n/fr_FR/fdmextruder.def.json.po
+++ b/resources/i18n/fr_FR/fdmextruder.def.json.po
@@ -1,14 +1,14 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 14:25+0100\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-03-13 14:00+0200\n"
"Last-Translator: Bothof \n"
"Language-Team: French\n"
"Language: fr_FR\n"
@@ -83,8 +83,8 @@ msgstr "Extrudeuse G-Code de démarrage"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_code description"
-msgid "Start g-code to execute whenever turning the extruder on."
-msgstr "G-Code de démarrage à exécuter à chaque mise en marche de l'extrudeuse."
+msgid "Start g-code to execute when switching to this extruder."
+msgstr "Démarrer le G-Code à exécuter lors du passage à cette extrudeuse."
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_abs label"
@@ -123,8 +123,8 @@ msgstr "Extrudeuse G-Code de fin"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_code description"
-msgid "End g-code to execute whenever turning the extruder off."
-msgstr "G-Code de fin à exécuter à chaque arrêt de l'extrudeuse."
+msgid "End g-code to execute when switching away from this extruder."
+msgstr "Fin du G-Code à exécuter lors de l'abandon de l'extrudeuse."
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_abs label"
@@ -225,3 +225,11 @@ msgstr "Diamètre"
msgctxt "material_diameter description"
msgid "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament."
msgstr "Ajuste le diamètre du filament utilisé. Faites correspondre cette valeur au diamètre du filament utilisé."
+
+#~ msgctxt "machine_extruder_start_code description"
+#~ msgid "Start g-code to execute whenever turning the extruder on."
+#~ msgstr "G-Code de démarrage à exécuter à chaque mise en marche de l'extrudeuse."
+
+#~ msgctxt "machine_extruder_end_code description"
+#~ msgid "End g-code to execute whenever turning the extruder off."
+#~ msgstr "G-Code de fin à exécuter à chaque arrêt de l'extrudeuse."
diff --git a/resources/i18n/fr_FR/fdmprinter.def.json.po b/resources/i18n/fr_FR/fdmprinter.def.json.po
index 87aa9d5a27..9779482577 100644
--- a/resources/i18n/fr_FR/fdmprinter.def.json.po
+++ b/resources/i18n/fr_FR/fdmprinter.def.json.po
@@ -1,16 +1,16 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 15:00+0200\n"
-"Last-Translator: Bothof \n"
-"Language-Team: French\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-07-29 15:51+0200\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: French , French \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -57,7 +57,9 @@ msgctxt "machine_start_gcode description"
msgid ""
"G-code commands to be executed at the very start - separated by \n"
"."
-msgstr "Commandes G-Code à exécuter au tout début, séparées par \n."
+msgstr ""
+"Commandes G-Code à exécuter au tout début, séparées par \n"
+"."
#: fdmprinter.def.json
msgctxt "machine_end_gcode label"
@@ -69,7 +71,9 @@ msgctxt "machine_end_gcode description"
msgid ""
"G-code commands to be executed at the very end - separated by \n"
"."
-msgstr "Commandes G-Code à exécuter tout à la fin, séparées par \n."
+msgstr ""
+"Commandes G-Code à exécuter tout à la fin, séparées par \n"
+"."
#: fdmprinter.def.json
msgctxt "material_guid label"
@@ -211,6 +215,16 @@ msgctxt "machine_heated_bed description"
msgid "Whether the machine has a heated build plate present."
msgstr "Si la machine a un plateau chauffé présent."
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume label"
+msgid "Has Build Volume Temperature Stabilization"
+msgstr "Est dotée de la stabilisation de la température du volume d'impression"
+
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume description"
+msgid "Whether the machine is able to stabilize the build volume temperature."
+msgstr "Si la machine est capable de stabiliser la température du volume d'impression."
+
#: fdmprinter.def.json
msgctxt "machine_center_is_zero label"
msgid "Is Center Origin"
@@ -233,7 +247,7 @@ msgstr "Nombre de trains d'extrudeuse. Un train d'extrudeuse est la combinaison
#: fdmprinter.def.json
msgctxt "extruders_enabled_count label"
-msgid "Number of Extruders that are enabled"
+msgid "Number of Extruders That Are Enabled"
msgstr "Nombre d'extrudeuses activées"
#: fdmprinter.def.json
@@ -243,7 +257,7 @@ msgstr "Nombre de trains d'extrusion activés ; automatiquement défini dans le
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter label"
-msgid "Outer nozzle diameter"
+msgid "Outer Nozzle Diameter"
msgstr "Diamètre extérieur de la buse"
#: fdmprinter.def.json
@@ -253,7 +267,7 @@ msgstr "Le diamètre extérieur de la pointe de la buse."
#: fdmprinter.def.json
msgctxt "machine_nozzle_head_distance label"
-msgid "Nozzle length"
+msgid "Nozzle Length"
msgstr "Longueur de la buse"
#: fdmprinter.def.json
@@ -263,7 +277,7 @@ msgstr "La différence de hauteur entre la pointe de la buse et la partie la plu
#: fdmprinter.def.json
msgctxt "machine_nozzle_expansion_angle label"
-msgid "Nozzle angle"
+msgid "Nozzle Angle"
msgstr "Angle de la buse"
#: fdmprinter.def.json
@@ -273,7 +287,7 @@ msgstr "L'angle entre le plan horizontal et la partie conique juste au-dessus de
#: fdmprinter.def.json
msgctxt "machine_heat_zone_length label"
-msgid "Heat zone length"
+msgid "Heat Zone Length"
msgstr "Longueur de la zone chauffée"
#: fdmprinter.def.json
@@ -303,7 +317,7 @@ msgstr "Contrôler ou non la température depuis Cura. Désactivez cette option
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed label"
-msgid "Heat up speed"
+msgid "Heat Up Speed"
msgstr "Vitesse de chauffage"
#: fdmprinter.def.json
@@ -313,7 +327,7 @@ msgstr "La vitesse (°C/s) à laquelle la buse chauffe, sur une moyenne de la pl
#: fdmprinter.def.json
msgctxt "machine_nozzle_cool_down_speed label"
-msgid "Cool down speed"
+msgid "Cool Down Speed"
msgstr "Vitesse de refroidissement"
#: fdmprinter.def.json
@@ -333,7 +347,7 @@ msgstr "La durée minimale pendant laquelle une extrudeuse doit être inactive a
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor label"
-msgid "G-code flavour"
+msgid "G-code Flavor"
msgstr "Parfum G-Code"
#: fdmprinter.def.json
@@ -398,7 +412,7 @@ msgstr "S'il faut utiliser les commandes de rétraction du firmware (G10 / G11
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
-msgid "Disallowed areas"
+msgid "Disallowed Areas"
msgstr "Zones interdites"
#: fdmprinter.def.json
@@ -418,7 +432,7 @@ msgstr "Une liste de polygones comportant les zones dans lesquelles le bec n'a p
#: fdmprinter.def.json
msgctxt "machine_head_polygon label"
-msgid "Machine head polygon"
+msgid "Machine Head Polygon"
msgstr "Polygone de la tête de machine"
#: fdmprinter.def.json
@@ -428,8 +442,8 @@ msgstr "Une silhouette 2D de la tête d'impression (sans les capuchons du ventil
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon label"
-msgid "Machine head & Fan polygon"
-msgstr "Tête de la machine et polygone du ventilateur"
+msgid "Machine Head & Fan Polygon"
+msgstr "Polygone de la tête de la machine et du ventilateur"
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon description"
@@ -438,7 +452,7 @@ msgstr "Une silhouette 2D de la tête d'impression (avec les capuchons du ventil
#: fdmprinter.def.json
msgctxt "gantry_height label"
-msgid "Gantry height"
+msgid "Gantry Height"
msgstr "Hauteur du portique"
#: fdmprinter.def.json
@@ -468,7 +482,7 @@ msgstr "Le diamètre intérieur de la buse. Modifiez ce paramètre si vous utili
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords label"
-msgid "Offset With Extruder"
+msgid "Offset with Extruder"
msgstr "Décalage avec extrudeuse"
#: fdmprinter.def.json
@@ -1016,6 +1030,17 @@ msgctxt "bottom_layers description"
msgid "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number."
msgstr "Le nombre de couches inférieures. Lorsqu'elle est calculée par l'épaisseur du dessous, cette valeur est arrondie à un nombre entier."
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers label"
+msgid "Initial Bottom Layers"
+msgstr "Couches inférieures initiales"
+
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers description"
+msgid "The number of initial bottom layers, from the build-plate upwards. When calculated by the bottom thickness, this value is rounded to a whole number."
+msgstr "Le nombre de couches inférieures initiales à partir du haut du plateau. Lorsqu'elle est calculée par l'épaisseur du dessous, cette valeur est arrondie"
+" à un nombre entier."
+
#: fdmprinter.def.json
msgctxt "top_bottom_pattern label"
msgid "Top/Bottom Pattern"
@@ -1219,7 +1244,7 @@ msgstr "Imprimer les parties du modèle qui sont horizontalement plus fines que
#: fdmprinter.def.json
msgctxt "xy_offset label"
msgid "Horizontal Expansion"
-msgstr "Vitesse d’impression horizontale"
+msgstr "Expansion horizontale"
#: fdmprinter.def.json
msgctxt "xy_offset description"
@@ -1266,6 +1291,56 @@ msgctxt "z_seam_type option sharpest_corner"
msgid "Sharpest Corner"
msgstr "Angle le plus aigu"
+#: fdmprinter.def.json
+msgctxt "z_seam_position label"
+msgid "Z Seam Position"
+msgstr "Position de la jointure en Z"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position description"
+msgid "The position near where to start printing each part in a layer."
+msgstr "La position près de laquelle démarre l'impression de chaque partie dans une couche."
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backleft"
+msgid "Back Left"
+msgstr "Arrière gauche"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option back"
+msgid "Back"
+msgstr "Précédent"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backright"
+msgid "Back Right"
+msgstr "Arrière droit"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option right"
+msgid "Right"
+msgstr "Droite"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontright"
+msgid "Front Right"
+msgstr "Avant droit"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option front"
+msgid "Front"
+msgstr "Avant"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontleft"
+msgid "Front Left"
+msgstr "Avant gauche"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option left"
+msgid "Left"
+msgstr "Gauche"
+
#: fdmprinter.def.json
msgctxt "z_seam_x label"
msgid "Z Seam X"
@@ -1293,8 +1368,8 @@ msgstr "Préférence de jointure d'angle"
#: fdmprinter.def.json
msgctxt "z_seam_corner description"
-msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
-msgstr "Vérifie si les angles du contour du modèle influencent l'emplacement de la jointure. « Aucune » signifie que les angles n'ont aucune influence sur l'emplacement de la jointure. « Masquer jointure » génère généralement le positionnement de la jointure sur un angle intérieur. « Exposer jointure » génère généralement le positionnement de la jointure sur un angle extérieur. « Masquer ou exposer jointure » génère généralement le positionnement de la jointure sur un angle intérieur ou extérieur."
+msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner. Smart Hiding allows both inside and outside corners, but chooses inside corners more frequently, if appropriate."
+msgstr "Vérifie si les angles du contour du modèle influencent l'emplacement de la jointure. « Aucune » signifie que les angles n'ont aucune influence sur l'emplacement de la jointure. « Masquer la jointure » génère le positionnement de la jointure sur un angle intérieur. « Exposer la jointure » génère le positionnement de la jointure sur un angle extérieur. « Masquer ou exposer la jointure » génère le positionnement de la jointure sur un angle intérieur ou extérieur. « Jointure intelligente » autorise les angles intérieurs et extérieurs, mais choisit plus fréquemment les angles intérieurs, le cas échéant."
#: fdmprinter.def.json
msgctxt "z_seam_corner option z_seam_corner_none"
@@ -1316,6 +1391,11 @@ msgctxt "z_seam_corner option z_seam_corner_any"
msgid "Hide or Expose Seam"
msgstr "Masquer ou exposer jointure"
+#: fdmprinter.def.json
+msgctxt "z_seam_corner option z_seam_corner_weighted"
+msgid "Smart Hiding"
+msgstr "Masquage intelligent"
+
#: fdmprinter.def.json
msgctxt "z_seam_relative label"
msgid "Z Seam Relative"
@@ -1328,13 +1408,13 @@ msgstr "Si cette option est activée, les coordonnées de la jointure z sont rel
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic label"
-msgid "Ignore Small Z Gaps"
-msgstr "Ignorer les petits trous en Z"
+msgid "No Skin in Z Gaps"
+msgstr "Aucune couche dans les trous en Z"
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic description"
-msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
-msgstr "Quand le modèle présente de petits trous verticaux, environ 5 % de temps de calcul supplémentaire peut être alloué à la génération de couches du dessus et du dessous dans ces espaces étroits. Dans ce cas, désactivez ce paramètre."
+msgid "When the model has small vertical gaps of only a few layers, there should normally be skin around those layers in the narrow space. Enable this setting to not generate skin if the vertical gap is very small. This improves printing time and slicing time, but technically leaves infill exposed to the air."
+msgstr "Lorsque le modèle comporte de petits trous verticaux de quelques couches seulement, il doit normalement y avoir une couche autour de celles-ci dans l'espace étroit. Activez ce paramètre pour ne pas générer de couche si le trou vertical est très petit. Cela améliore le temps d'impression et le temps de découpage, mais laisse techniquement le remplissage exposé à l'air."
#: fdmprinter.def.json
msgctxt "skin_outline_count label"
@@ -1353,8 +1433,8 @@ msgstr "Activer l'étirage"
#: fdmprinter.def.json
msgctxt "ironing_enabled description"
-msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
-msgstr "Aller au-dessus de la surface supérieure une fois supplémentaire, mais sans extruder de matériau. Cela signifie de faire fondre le plastique en haut un peu plus, pour créer une surface lisse."
+msgid "Go over the top surface one additional time, but this time extruding very little material. This is meant to melt the plastic on top further, creating a smoother surface. The pressure in the nozzle chamber is kept high so that the creases in the surface are filled with material."
+msgstr "Allez au-dessus de la surface une fois supplémentaire, mais en extrudant très peu de matériau. Cela signifie de faire fondre le plastique en haut un peu plus, pour créer une surface lisse. La pression dans la chambre de la buse est maintenue élevée afin que les plis de la surface soient remplis de matériau."
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer label"
@@ -1446,6 +1526,26 @@ msgctxt "jerk_ironing description"
msgid "The maximum instantaneous velocity change while performing ironing."
msgstr "Le changement instantané maximal de vitesse lors de l'étirage."
+#: fdmprinter.def.json
+msgctxt "skin_overlap label"
+msgid "Skin Overlap Percentage"
+msgstr "Pourcentage de chevauchement de la couche extérieure"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines, as a percentage of the line widths of the skin lines and the innermost wall. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any percentage over 50% may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "Ajuster le degré de chevauchement entre les parois et les (extrémités des) lignes centrales de la couche extérieure, en pourcentage de la largeur des lignes de la couche extérieure et de la paroi intérieure. Un chevauchement léger permet de relier fermement les parois à la couche extérieure. Notez que, si la largeur de la couche extérieure est égale à celle de la ligne de la paroi, un pourcentage supérieur à 50 % peut déjà faire dépasser la couche extérieure de la paroi, car dans ce cas la position de la buse de l'extrudeuse peut déjà atteindre le milieu de la paroi."
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm label"
+msgid "Skin Overlap"
+msgstr "Chevauchement de la couche extérieure"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any value over half the width of the wall may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "Ajuster le degré de chevauchement entre les parois et les (extrémités des) lignes centrales de la couche extérieure. Un chevauchement léger permet de relier fermement les parois à la couche extérieure. Notez que, si la largeur de la couche extérieure est égale à celle de la ligne de la paroi, une valeur supérieure à la moitié de la largeur de la paroi peut déjà faire dépasser la couche extérieure de la paroi, car dans ce cas la position de la buse de l'extrudeuse peut déjà atteindre le milieu de la paroi."
+
#: fdmprinter.def.json
msgctxt "infill label"
msgid "Infill"
@@ -1611,6 +1711,16 @@ msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
msgstr "Le motif de remplissage est décalé de cette distance sur l'axe Y."
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location label"
+msgid "Randomize Infill Start"
+msgstr "Randomiser le démarrage du remplissage"
+
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location description"
+msgid "Randomize which infill line is printed first. This prevents one segment becoming the strongest, but it does so at the cost of an additional travel move."
+msgstr "Randomisez la ligne de remplissage qui est imprimée en premier. Cela empêche un segment de devenir plus fort, mais cela se fait au prix d'un déplacement supplémentaire."
+
#: fdmprinter.def.json
msgctxt "infill_multiplier label"
msgid "Infill Line Multiplier"
@@ -1631,7 +1741,9 @@ msgctxt "infill_wall_line_count description"
msgid ""
"Add extra walls around the infill area. Such walls can make top/bottom skin lines sag down less which means you need less top/bottom skin layers for the same quality at the cost of some extra material.\n"
"This feature can combine with the Connect Infill Polygons to connect all the infill into a single extrusion path without the need for travels or retractions if configured right."
-msgstr "Ajoutez des parois supplémentaires autour de la zone de remplissage. De telles parois peuvent réduire l'affaissement des lignes de couche extérieure supérieure / inférieure, réduisant le nombre de couches extérieures supérieures / inférieures nécessaires pour obtenir la même qualité, au prix d'un peu de matériau supplémentaire.\nConfigurée correctement, cette fonctionnalité peut être combinée avec « Relier les polygones de remplissage » pour relier tous les remplissages en un seul mouvement d'extrusion sans avoir besoin de déplacements ou de rétractions."
+msgstr ""
+"Ajoutez des parois supplémentaires autour de la zone de remplissage. De telles parois peuvent réduire l'affaissement des lignes de couche extérieure supérieure / inférieure, réduisant le nombre de couches extérieures supérieures / inférieures nécessaires pour obtenir la même qualité, au prix d'un peu de matériau supplémentaire.\n"
+"Configurée correctement, cette fonctionnalité peut être combinée avec « Relier les polygones de remplissage » pour relier tous les remplissages en un seul mouvement d'extrusion sans avoir besoin de déplacements ou de rétractions."
#: fdmprinter.def.json
msgctxt "sub_div_rad_add label"
@@ -1663,26 +1775,6 @@ msgctxt "infill_overlap_mm description"
msgid "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill."
msgstr "Le degré de chevauchement entre le remplissage et les parois. Un léger chevauchement permet de lier fermement les parois au remplissage."
-#: fdmprinter.def.json
-msgctxt "skin_overlap label"
-msgid "Skin Overlap Percentage"
-msgstr "Pourcentage de chevauchement de la couche extérieure"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap description"
-msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
-msgstr "Le montant de chevauchement entre la couche extérieure et les parois en pourcentage de la largeur de ligne de couche extérieure. Un chevauchement faible permet aux parois de se connecter fermement à la couche extérieure. Ce montant est un pourcentage des largeurs moyennes des lignes de la couche extérieure et de la paroi la plus intérieure."
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm label"
-msgid "Skin Overlap"
-msgstr "Chevauchement de la couche extérieure"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm description"
-msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
-msgstr "Le degré de chevauchement entre la couche extérieure et les parois. Un léger chevauchement permet de lier fermement les parois à la couche externe."
-
#: fdmprinter.def.json
msgctxt "infill_wipe_dist label"
msgid "Infill Wipe Distance"
@@ -1863,6 +1955,16 @@ msgctxt "default_material_print_temperature description"
msgid "The default temperature used for printing. This should be the \"base\" temperature of a material. All other print temperatures should use offsets based on this value"
msgstr "La température par défaut utilisée pour l'impression. Il doit s'agir de la température de « base » d'un matériau. Toutes les autres températures d'impression doivent utiliser des décalages basés sur cette valeur"
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature label"
+msgid "Build Volume Temperature"
+msgstr "Température du volume d'impression"
+
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature description"
+msgid "The temperature of the environment to print in. If this is 0, the build volume temperature will not be adjusted."
+msgstr "La température de l'environnement d'impression. Si cette valeur est 0, la température du volume d'impression ne sera pas ajustée."
+
#: fdmprinter.def.json
msgctxt "material_print_temperature label"
msgid "Printing Temperature"
@@ -1973,6 +2075,86 @@ msgctxt "material_shrinkage_percentage description"
msgid "Shrinkage ratio in percentage."
msgstr "Taux de contraction en pourcentage."
+#: fdmprinter.def.json
+msgctxt "material_crystallinity label"
+msgid "Crystalline Material"
+msgstr "Matériau cristallin"
+
+#: fdmprinter.def.json
+msgctxt "material_crystallinity description"
+msgid "Is this material the type that breaks off cleanly when heated (crystalline), or is it the type that produces long intertwined polymer chains (non-crystalline)?"
+msgstr "Ce matériau se casse-t-il proprement lorsqu'il est chauffé (cristallin) ou est-ce le type qui produit de longues chaînes polymères entrelacées (non cristallines) ?"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position label"
+msgid "Anti-ooze Retracted Position"
+msgstr "Position anti-suintage rétractée"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position description"
+msgid "How far the material needs to be retracted before it stops oozing."
+msgstr "Jusqu'où le matériau doit être rétracté avant qu'il cesse de suinter."
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed label"
+msgid "Anti-ooze Retraction Speed"
+msgstr "Vitesse de rétraction de l'anti-suintage"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed description"
+msgid "How fast the material needs to be retracted during a filament switch to prevent oozing."
+msgstr "À quelle vitesse le matériau doit-il être rétracté lors d'un changement de filament pour empêcher le suintage."
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position label"
+msgid "Break Preparation Retracted Position"
+msgstr "Préparation de rupture Position rétractée"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position description"
+msgid "How far the filament can be stretched before it breaks, while heated."
+msgstr "Jusqu'où le filament peut être étiré avant qu'il ne se casse, pendant qu'il est chauffé."
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed label"
+msgid "Break Preparation Retraction Speed"
+msgstr "Vitesse de rétraction de préparation de rupture"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed description"
+msgid "How fast the filament needs to be retracted just before breaking it off in a retraction."
+msgstr "La vitesse à laquelle le filament doit être rétracté juste avant de le briser dans une rétraction."
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position label"
+msgid "Break Retracted Position"
+msgstr "Position rétractée de rupture"
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position description"
+msgid "How far to retract the filament in order to break it cleanly."
+msgstr "Jusqu'où rétracter le filament afin de le casser proprement."
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed label"
+msgid "Break Retraction Speed"
+msgstr "Vitesse de rétraction de rupture"
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed description"
+msgid "The speed at which to retract the filament in order to break it cleanly."
+msgstr "La vitesse à laquelle rétracter le filament afin de le rompre proprement."
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature label"
+msgid "Break Temperature"
+msgstr "Température de rupture"
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature description"
+msgid "The temperature at which the filament is broken for a clean break."
+msgstr "La température à laquelle le filament est cassé pour une rupture propre."
+
#: fdmprinter.def.json
msgctxt "material_flow label"
msgid "Flow"
@@ -1983,6 +2165,126 @@ msgctxt "material_flow description"
msgid "Flow compensation: the amount of material extruded is multiplied by this value."
msgstr "Compensation du débit : la quantité de matériau extrudée est multipliée par cette valeur."
+#: fdmprinter.def.json
+msgctxt "wall_material_flow label"
+msgid "Wall Flow"
+msgstr "Débit de paroi"
+
+#: fdmprinter.def.json
+msgctxt "wall_material_flow description"
+msgid "Flow compensation on wall lines."
+msgstr "Compensation de débit sur les lignes de la paroi."
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow label"
+msgid "Outer Wall Flow"
+msgstr "Débit de paroi externe"
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow description"
+msgid "Flow compensation on the outermost wall line."
+msgstr "Compensation de débit sur la ligne de la paroi la plus à l'extérieur."
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow label"
+msgid "Inner Wall(s) Flow"
+msgstr "Débit de paroi(s) interne(s)"
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow description"
+msgid "Flow compensation on wall lines for all wall lines except the outermost one."
+msgstr "Compensation de débit sur les lignes de la paroi pour toutes les lignes de paroi, à l'exception de la ligne la plus externe."
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow label"
+msgid "Top/Bottom Flow"
+msgstr "Débit du dessus/dessous"
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow description"
+msgid "Flow compensation on top/bottom lines."
+msgstr "Compensation de débit sur les lignes du dessus/dessous."
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow label"
+msgid "Top Surface Skin Flow"
+msgstr "Débit de la surface du dessus"
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow description"
+msgid "Flow compensation on lines of the areas at the top of the print."
+msgstr "Compensation de débit sur les lignes des zones en haut de l'impression."
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow label"
+msgid "Infill Flow"
+msgstr "Débit de remplissage"
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow description"
+msgid "Flow compensation on infill lines."
+msgstr "Compensation de débit sur les lignes de remplissage."
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow label"
+msgid "Skirt/Brim Flow"
+msgstr "Débit de la jupe/bordure"
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow description"
+msgid "Flow compensation on skirt or brim lines."
+msgstr "Compensation de débit sur les lignes de jupe ou bordure."
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow label"
+msgid "Support Flow"
+msgstr "Débit du support"
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow description"
+msgid "Flow compensation on support structure lines."
+msgstr "Compensation de débit sur les lignes de support."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow label"
+msgid "Support Interface Flow"
+msgstr "Débit de l'interface de support"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow description"
+msgid "Flow compensation on lines of support roof or floor."
+msgstr "Compensation de débit sur les lignes de plafond ou de bas de support."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow label"
+msgid "Support Roof Flow"
+msgstr "Débit du plafond de support"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow description"
+msgid "Flow compensation on support roof lines."
+msgstr "Compensation de débit sur les lignes du plafond de support."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow label"
+msgid "Support Floor Flow"
+msgstr "Débit du bas de support"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow description"
+msgid "Flow compensation on support floor lines."
+msgstr "Compensation de débit sur les lignes de bas de support."
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow label"
+msgid "Prime Tower Flow"
+msgstr "Débit de la tour primaire"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow description"
+msgid "Flow compensation on prime tower lines."
+msgstr "Compensation de débit sur les lignes de la tour primaire."
+
#: fdmprinter.def.json
msgctxt "material_flow_layer_0 label"
msgid "Initial Layer Flow"
@@ -2100,8 +2402,8 @@ msgstr "Limiter les rétractations du support"
#: fdmprinter.def.json
msgctxt "limit_support_retractions description"
-msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
-msgstr "Omettre la rétraction lors du passage entre supports en ligne droite. L'activation de ce paramètre permet de gagner du temps lors de l'impression, mais peut conduire à un cordage excessif à l'intérieur de la structure de support."
+msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excessive stringing within the support structure."
+msgstr "Omettre la rétraction lors du passage entre supports en ligne droite. L'activation de ce paramètre permet de gagner du temps lors de l'impression, mais peut conduire à un stringing excessif à l'intérieur de la structure de support."
#: fdmprinter.def.json
msgctxt "material_standby_temperature label"
@@ -2120,8 +2422,8 @@ msgstr "Distance de rétraction de changement de buse"
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_amount description"
-msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
-msgstr "La quantité de rétraction : définir à 0 pour aucune rétraction. Cette valeur doit généralement être égale à la longueur de la zone chauffée."
+msgid "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+msgstr "Degré de rétraction lors de la commutation d'extrudeuses. Une valeur de 0 signifie qu'il n'y aura aucune rétraction. En général, cette valeur doit être équivalente à la longueur de la zone de chauffe."
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_speeds label"
@@ -2153,6 +2455,16 @@ msgctxt "switch_extruder_prime_speed description"
msgid "The speed at which the filament is pushed back after a nozzle switch retraction."
msgstr "La vitesse à laquelle le filament est poussé vers l'arrière après une rétraction de changement de buse."
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount label"
+msgid "Nozzle Switch Extra Prime Amount"
+msgstr "Montant de l'amorce supplémentaire lors d'un changement de buse"
+
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount description"
+msgid "Extra material to prime after nozzle switching."
+msgstr "Matériel supplémentaire à amorcer après le changement de buse."
+
#: fdmprinter.def.json
msgctxt "speed label"
msgid "Speed"
@@ -2344,14 +2656,14 @@ msgid "The speed at which the skirt and brim are printed. Normally this is done
msgstr "La vitesse à laquelle la jupe et la bordure sont imprimées. Normalement, cette vitesse est celle de la couche initiale, mais il est parfois nécessaire d’imprimer la jupe ou la bordure à une vitesse différente."
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override label"
-msgid "Maximum Z Speed"
-msgstr "Vitesse Z maximale"
+msgctxt "speed_z_hop label"
+msgid "Z Hop Speed"
+msgstr "Vitesse du décalage en Z"
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override description"
-msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
-msgstr "La vitesse maximale à laquelle le plateau se déplace. Définir cette valeur sur zéro impose à l'impression d'utiliser les valeurs par défaut du firmware pour la vitesse z maximale."
+msgctxt "speed_z_hop description"
+msgid "The speed at which the vertical Z movement is made for Z Hops. This is typically lower than the print speed since the build plate or machine's gantry is harder to move."
+msgstr "La vitesse à laquelle le mouvement vertical en Z est effectué pour des décalages en Z. Cette vitesse est généralement inférieure à la vitesse d'impression car le plateau ou le portique de la machine est plus difficile à déplacer."
#: fdmprinter.def.json
msgctxt "speed_slowdown_layers label"
@@ -2780,8 +3092,8 @@ msgstr "Mode de détours"
#: fdmprinter.def.json
msgctxt "retraction_combing description"
-msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
-msgstr "Les détours maintiennent la buse dans les zones déjà imprimées lors des déplacements. Cela résulte en des déplacements légèrement plus longs mais réduit le recours aux rétractions. Si les détours sont désactivés, le matériau se rétractera et la buse se déplacera en ligne droite jusqu'au point suivant. Il est également possible d'éviter les détours sur les zones de la couche extérieure supérieure / inférieure et aussi de n'effectuer les détours que dans le remplissage. Notez que l'option « À l'intérieur du remplissage » se comporte exactement comme l'option « Pas dans la couche extérieure » dans les versions précédentes de Cura."
+msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas or to only comb within the infill."
+msgstr "Les détours maintiennent la buse dans les zones déjà imprimées lors des déplacements. Cela résulte en des déplacements légèrement plus longs mais réduit le recours aux rétractions. Si les détours sont désactivés, le matériau se rétractera et la buse se déplacera en ligne droite jusqu'au point suivant. Il est également possible d'éviter les détours sur les zones de la couche du dessus / dessous ou d'effectuer les détours uniquement dans le remplissage."
#: fdmprinter.def.json
msgctxt "retraction_combing option off"
@@ -2853,16 +3165,6 @@ msgctxt "travel_avoid_distance description"
msgid "The distance between the nozzle and already printed parts when avoiding during travel moves."
msgstr "La distance entre la buse et les pièces déjà imprimées lors du contournement pendant les déplacements."
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position label"
-msgid "Start Layers with the Same Part"
-msgstr "Démarrer les couches avec la même partie"
-
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position description"
-msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
-msgstr "Dans chaque couche, démarre l'impression de l'objet à proximité du même point, de manière à ce que nous ne commencions pas une nouvelle couche en imprimant la pièce avec laquelle la couche précédente s'est terminée. Cela renforce les porte-à-faux et les petites pièces, mais augmente le temps d'impression."
-
#: fdmprinter.def.json
msgctxt "layer_start_x label"
msgid "Layer Start X"
@@ -2923,6 +3225,16 @@ msgctxt "retraction_hop_after_extruder_switch description"
msgid "After the machine switched from one extruder to the other, the build plate is lowered to create clearance between the nozzle and the print. This prevents the nozzle from leaving oozed material on the outside of a print."
msgstr "Une fois que la machine est passée d'une extrudeuse à l'autre, le plateau s'abaisse pour créer un dégagement entre la buse et l'impression. Cela évite que la buse ne ressorte avec du matériau suintant sur l'extérieur d'une impression."
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height label"
+msgid "Z Hop After Extruder Switch Height"
+msgstr "Décalage en Z après changement de hauteur d'extrudeuse"
+
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height description"
+msgid "The height difference when performing a Z Hop after extruder switch."
+msgstr "La différence de hauteur lors de la réalisation d'un décalage en Z après changement d'extrudeuse."
+
#: fdmprinter.def.json
msgctxt "cooling label"
msgid "Cooling"
@@ -3193,6 +3505,11 @@ msgctxt "support_pattern option cross"
msgid "Cross"
msgstr "Entrecroisé"
+#: fdmprinter.def.json
+msgctxt "support_pattern option gyroid"
+msgid "Gyroid"
+msgstr "Gyroïde"
+
#: fdmprinter.def.json
msgctxt "support_wall_count label"
msgid "Support Wall Line Count"
@@ -3254,14 +3571,14 @@ msgid "Distance between the printed initial layer support structure lines. This
msgstr "Distance entre les lignes de la structure de support de la couche initiale imprimée. Ce paramètre est calculé en fonction de la densité du support."
#: fdmprinter.def.json
-msgctxt "support_infill_angle label"
-msgid "Support Infill Line Direction"
+msgctxt "support_infill_angles label"
+msgid "Support Infill Line Directions"
msgstr "Direction de ligne de remplissage du support"
#: fdmprinter.def.json
-msgctxt "support_infill_angle description"
-msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
-msgstr "Orientation du motif de remplissage pour les supports. Le motif de remplissage du support pivote dans le plan horizontal."
+msgctxt "support_infill_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angle 0 degrees."
+msgstr "Une liste de sens de ligne (exprimés en nombres entiers) à utiliser. Les éléments de la liste sont utilisés de manière séquentielle à mesure de l'avancement des couches. La liste reprend depuis le début lorsque la fin est atteinte. Les éléments de la liste sont séparés par des virgules et la liste entière est encadrée entre crochets. La valeur par défaut est une liste vide, ce qui signifie que l'angle par défaut est utilisé (0 degré)."
#: fdmprinter.def.json
msgctxt "support_brim_enable label"
@@ -3390,8 +3707,8 @@ msgstr "Distance de jointement des supports"
#: fdmprinter.def.json
msgctxt "support_join_distance description"
-msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
-msgstr "La distance maximale entre les supports dans les directions X/Y. Lorsque des supports séparés sont plus rapprochés que cette valeur, ils fusionnent."
+msgid "The maximum distance between support structures in the X/Y directions. When separate structures are closer together than this value, the structures merge into one."
+msgstr "La distance maximale entre les supports dans les directions X/Y. Lorsque des modèle séparés sont plus rapprochés que cette valeur, ils fusionnent."
#: fdmprinter.def.json
msgctxt "support_offset label"
@@ -3433,6 +3750,16 @@ msgctxt "gradual_support_infill_step_height description"
msgid "The height of support infill of a given density before switching to half the density."
msgstr "La hauteur de remplissage de support d'une densité donnée avant de passer à la moitié de la densité."
+#: fdmprinter.def.json
+msgctxt "minimum_support_area label"
+msgid "Minimum Support Area"
+msgstr "Surface minimale de support"
+
+#: fdmprinter.def.json
+msgctxt "minimum_support_area description"
+msgid "Minimum area size for support polygons. Polygons which have an area smaller than this value will not be generated."
+msgstr "Taille minimale de la surface des polygones de support : les polygones dont la surface est inférieure à cette valeur ne seront pas générés."
+
#: fdmprinter.def.json
msgctxt "support_interface_enable label"
msgid "Enable Support Interface"
@@ -3658,6 +3985,98 @@ msgctxt "support_bottom_pattern option zigzag"
msgid "Zig Zag"
msgstr "Zig Zag"
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area label"
+msgid "Minimum Support Interface Area"
+msgstr "Surface minimale de l'interface de support"
+
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area description"
+msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Taille minimale de la surface des polygones d'interface de support. Les polygones dont la surface est inférieure à cette valeur ne seront pas imprimés"
+" comme support normal."
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area label"
+msgid "Minimum Support Roof Area"
+msgstr "Surface minimale du plafond de support"
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area description"
+msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Taille minimale de la surface des plafonds du support. Les polygones dont la surface est inférieure à cette valeur ne seront pas imprimés comme support"
+" normal."
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area label"
+msgid "Minimum Support Floor Area"
+msgstr "Surface minimale du bas de support"
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area description"
+msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Taille minimale de la surface des bas du support. Les polygones dont la surface est inférieure à cette valeur ne seront pas imprimés comme support normal."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset label"
+msgid "Support Interface Horizontal Expansion"
+msgstr "Expansion horizontale de l'interface de support"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset description"
+msgid "Amount of offset applied to the support interface polygons."
+msgstr "Quantité de décalage appliquée aux polygones de l'interface de support."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset label"
+msgid "Support Roof Horizontal Expansion"
+msgstr "Expansion horizontale du plafond de support"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset description"
+msgid "Amount of offset applied to the roofs of the support."
+msgstr "Quantité de décalage appliqué aux plafonds du support."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset label"
+msgid "Support Floor Horizontal Expansion"
+msgstr "Expansion horizontale du bas de support"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset description"
+msgid "Amount of offset applied to the floors of the support."
+msgstr "Quantité de décalage appliqué aux bas du support."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles label"
+msgid "Support Interface Line Directions"
+msgstr "Direction de ligne d'interface du support"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Une liste de sens de ligne (exprimés en nombres entiers) à utiliser. Les éléments de la liste sont utilisés de manière séquentielle à mesure de l'avancement des couches. La liste reprend depuis le début lorsque la fin est atteinte. Les éléments de la liste sont séparés par des virgules et la liste entière est encadrée entre crochets. La valeur par défaut est une liste vide, ce qui signifie que les angles par défaut sont utilisés (alternative entre 45 et 135 degrés si les interfaces sont assez épaisses ou 90 degrés)."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles label"
+msgid "Support Roof Line Directions"
+msgstr "Direction de la ligne de plafond de support"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Une liste de sens de ligne (exprimés en nombres entiers) à utiliser. Les éléments de la liste sont utilisés de manière séquentielle à mesure de l'avancement des couches. La liste reprend depuis le début lorsque la fin est atteinte. Les éléments de la liste sont séparés par des virgules et la liste entière est encadrée entre crochets. La valeur par défaut est une liste vide, ce qui signifie que les angles par défaut sont utilisés (alternative entre 45 et 135 degrés si les interfaces sont assez épaisses ou 90 degrés)."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles label"
+msgid "Support Floor Line Directions"
+msgstr "Direction de la ligne de bas de support"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Une liste de sens de ligne (exprimés en nombres entiers) à utiliser. Les éléments de la liste sont utilisés de manière séquentielle à mesure de l'avancement des couches. La liste reprend depuis le début lorsque la fin est atteinte. Les éléments de la liste sont séparés par des virgules et la liste entière est encadrée entre crochets. La valeur par défaut est une liste vide, ce qui signifie que les angles par défaut sont utilisés (alternative entre 45 et 135 degrés si les interfaces sont assez épaisses ou 90 degrés)."
+
#: fdmprinter.def.json
msgctxt "support_fan_enable label"
msgid "Fan Speed Override"
@@ -3699,14 +4118,14 @@ msgid "The diameter of a special tower."
msgstr "Le diamètre d’une tour spéciale."
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter label"
-msgid "Minimum Diameter"
-msgstr "Diamètre minimal"
+msgctxt "support_tower_maximum_supported_diameter label"
+msgid "Maximum Tower-Supported Diameter"
+msgstr "Diamètre maximal supporté par la tour"
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter description"
-msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
-msgstr "Le diamètre minimal sur les axes X/Y d’une petite zone qui doit être soutenue par une tour de soutien spéciale."
+msgctxt "support_tower_maximum_supported_diameter description"
+msgid "Maximum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+msgstr "Le diamètre maximal sur les axes X/Y d’une petite zone qui doit être soutenue par une tour de soutien spéciale."
#: fdmprinter.def.json
msgctxt "support_tower_roof_angle label"
@@ -3828,7 +4247,9 @@ msgctxt "skirt_gap description"
msgid ""
"The horizontal distance between the skirt and the first layer of the print.\n"
"This is the minimum distance. Multiple skirt lines will extend outwards from this distance."
-msgstr "La distance horizontale entre la jupe et la première couche de l’impression.\nIl s’agit de la distance minimale séparant la jupe de l’objet. Si la jupe a d’autres lignes, celles-ci s’étendront vers l’extérieur."
+msgstr ""
+"La distance horizontale entre la jupe et la première couche de l’impression.\n"
+"Il s’agit de la distance minimale séparant la jupe de l’objet. Si la jupe a d’autres lignes, celles-ci s’étendront vers l’extérieur."
#: fdmprinter.def.json
msgctxt "skirt_brim_minimal_length label"
@@ -4200,16 +4621,6 @@ msgctxt "prime_tower_enable description"
msgid "Print a tower next to the print which serves to prime the material after each nozzle switch."
msgstr "Imprimer une tour à côté de l'impression qui sert à amorcer le matériau après chaque changement de buse."
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular label"
-msgid "Circular Prime Tower"
-msgstr "Tour primaire circulaire"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular description"
-msgid "Make the prime tower as a circular shape."
-msgstr "Réaliser la tour primaire en forme circulaire."
-
#: fdmprinter.def.json
msgctxt "prime_tower_size label"
msgid "Prime Tower Size"
@@ -4250,16 +4661,6 @@ msgctxt "prime_tower_position_y description"
msgid "The y coordinate of the position of the prime tower."
msgstr "Les coordonnées Y de la position de la tour primaire."
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow label"
-msgid "Prime Tower Flow"
-msgstr "Débit de la tour primaire"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow description"
-msgid "Flow compensation: the amount of material extruded is multiplied by this value."
-msgstr "Compensation du débit : la quantité de matériau extrudée est multipliée par cette valeur."
-
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled label"
msgid "Wipe Inactive Nozzle on Prime Tower"
@@ -4270,6 +4671,16 @@ msgctxt "prime_tower_wipe_enabled description"
msgid "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower."
msgstr "Après l'impression de la tour primaire à l'aide d'une buse, nettoyer le matériau qui suinte de l'autre buse sur la tour primaire."
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable label"
+msgid "Prime Tower Brim"
+msgstr "Bordure de la tour primaire"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable description"
+msgid "Prime-towers might need the extra adhesion afforded by a brim even if the model doesn't. Presently can't be used with the 'Raft' adhesion-type."
+msgstr "Les tours primaires peuvent avoir besoin de l'adhérence supplémentaire d'une bordure, même si le modèle n'en a pas besoin. Ne peut actuellement pas être utilisé avec le type d'adhérence « Raft » (radeau)."
+
#: fdmprinter.def.json
msgctxt "ooze_shield_enabled label"
msgid "Enable Ooze Shield"
@@ -4390,6 +4801,36 @@ msgctxt "remove_empty_first_layers description"
msgid "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle."
msgstr "Supprimer les couches vides sous la première couche imprimée si elles sont présentes. Le fait de désactiver ce paramètre peut entraîner l'apparition de premières couches vides si le paramètre Tolérance à la découpe est défini sur Exclusif ou Milieu."
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution label"
+msgid "Maximum Resolution"
+msgstr "Résolution maximum"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution description"
+msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
+msgstr "Taille minimum d'un segment de ligne après découpage. Si vous augmentez cette valeur, la maille aura une résolution plus faible. Cela peut permettre à l'imprimante de suivre la vitesse à laquelle elle doit traiter le G-Code et augmentera la vitesse de découpe en enlevant des détails de la maille que l'imprimante ne peut pas traiter de toute manière."
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution label"
+msgid "Maximum Travel Resolution"
+msgstr "Résolution de déplacement maximum"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution description"
+msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
+msgstr "Taille minimale d'un segment de ligne de déplacement après la découpe. Si vous augmentez cette valeur, les mouvements de déplacement auront des coins moins lisses. Cela peut permettre à l'imprimante de suivre la vitesse à laquelle elle doit traiter le G-Code, mais cela peut réduire la précision de l'évitement du modèle."
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation label"
+msgid "Maximum Deviation"
+msgstr "Écart maximum"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation description"
+msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution, so if the two conflict the Maximum Deviation will always be held true."
+msgstr "L'écart maximum autorisé lors de la réduction de la résolution pour le paramètre Résolution maximum. Si vous augmentez cette valeur, l'impression sera moins précise, mais le G-Code sera plus petit. L'écart maximum est une limite pour la résolution maximum. Donc si les deux entrent en conflit, l'Écart maximum restera valable."
+
#: fdmprinter.def.json
msgctxt "blackmagic label"
msgid "Special Modes"
@@ -4552,8 +4993,8 @@ msgstr "Lisser les contours spiralisés"
#: fdmprinter.def.json
msgctxt "smooth_spiralized_contours description"
-msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
-msgstr "Lisser les contours spiralisés pour réduire la visibilité de la jointure en Z (la jointure en Z doit être à peine visible sur l'impression mais sera toujours visible dans la vue en couches). Veuillez remarquer que le lissage aura tendance à estomper les détails fins de la surface."
+msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+msgstr "Lisser les contours spiralisés pour réduire la visibilité de la jointure en Z (la jointure en Z doit être à peine visible sur l'impression mais sera toujours visible dans la vue en couches). Veuillez remarquer que le lissage aura tendance à estomper les détails très fins de la surface."
#: fdmprinter.def.json
msgctxt "relative_extrusion label"
@@ -4765,26 +5206,6 @@ msgctxt "minimum_polygon_circumference description"
msgid "Polygons in sliced layers that have a circumference smaller than this amount will be filtered out. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details."
msgstr "Les polygones en couches tranchées dont la circonférence est inférieure à cette valeur seront filtrés. Des valeurs élevées permettent d'obtenir un maillage de meilleure résolution mais augmentent le temps de découpe. Cette option est principalement destinée aux imprimantes SLA haute résolution et aux modèles 3D de très petite taille avec beaucoup de détails."
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution label"
-msgid "Maximum Resolution"
-msgstr "Résolution maximum"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution description"
-msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
-msgstr "Taille minimum d'un segment de ligne après découpage. Si vous augmentez cette valeur, la maille aura une résolution plus faible. Cela peut permettre à l'imprimante de suivre la vitesse à laquelle elle doit traiter le G-Code et augmentera la vitesse de découpe en enlevant des détails de la maille que l'imprimante ne peut pas traiter de toute manière."
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution label"
-msgid "Maximum Travel Resolution"
-msgstr "Résolution de déplacement maximum"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution description"
-msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
-msgstr "Taille minimale d'un segment de ligne de déplacement après la découpe. Si vous augmentez cette valeur, les mouvements de déplacement auront des coins moins lisses. Cela peut permettre à l'imprimante de suivre la vitesse à laquelle elle doit traiter le G-Code, mais cela peut réduire la précision de l'évitement du modèle."
-
#: fdmprinter.def.json
msgctxt "support_skip_some_zags label"
msgid "Break Up Support In Chunks"
@@ -4925,16 +5346,6 @@ msgctxt "coasting_speed description"
msgid "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops."
msgstr "Vitesse de déplacement pendant une roue libre, par rapport à la vitesse de déplacement pendant l'extrusion. Une valeur légèrement inférieure à 100 % est conseillée car, lors du mouvement en roue libre, la pression dans le tube bowden chute."
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation label"
-msgid "Alternate Skin Rotation"
-msgstr "Alterner la rotation dans les couches extérieures"
-
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation description"
-msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
-msgstr "Alterne le sens d'impression des couches du dessus/dessous. Elles sont généralement imprimées uniquement en diagonale. Ce paramètre ajoute les sens X uniquement et Y uniquement."
-
#: fdmprinter.def.json
msgctxt "cross_infill_pocket_size label"
msgid "Cross 3D Pocket Size"
@@ -5042,8 +5453,8 @@ msgstr "Activer les supports coniques"
#: fdmprinter.def.json
msgctxt "support_conical_enabled description"
-msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
-msgstr "Fonctionnalité expérimentale : rendre les aires de support plus petites en bas qu'au niveau du porte-à-faux à supporter."
+msgid "Make support areas smaller at the bottom than at the overhang."
+msgstr "Rendre les aires de support plus petites en bas qu'au niveau du porte-à-faux à supporter."
#: fdmprinter.def.json
msgctxt "support_conical_angle label"
@@ -5107,23 +5518,24 @@ msgstr "Distance moyenne entre les points ajoutés aléatoirement sur chaque seg
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset label"
-msgid "Flow rate compensation max extrusion offset"
+msgid "Flow Rate Compensation Max Extrusion Offset"
msgstr "Décalage d'extrusion max. pour compensation du débit"
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset description"
-msgid "The maximum distance in mm to compensate."
-msgstr "Distance de compensation maximum en mm."
+msgid "The maximum distance in mm to move the filament to compensate for changes in flow rate."
+msgstr "La distance maximale en mm pour déplacer le filament afin de compenser les variations du débit."
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor label"
-msgid "Flow rate compensation factor"
+msgid "Flow Rate Compensation Factor"
msgstr "Facteur de compensation du débit"
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor description"
-msgid "The multiplication factor for the flow rate -> distance translation."
-msgstr "Facteur de multiplication pour le débit -> translation de la distance."
+msgid "How far to move the filament in order to compensate for changes in flow rate, as a percentage of how far the filament would move in one second of extrusion."
+msgstr "La distance de déplacement du filament pour compenser les variations du débit, en pourcentage de la distance de déplacement du filament en une seconde"
+" d'extrusion."
#: fdmprinter.def.json
msgctxt "wireframe_enabled label"
@@ -5275,7 +5687,9 @@ msgctxt "wireframe_up_half_speed description"
msgid ""
"Distance of an upward move which is extruded with half speed.\n"
"This can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing."
-msgstr "Distance d’un déplacement ascendant qui est extrudé à mi-vitesse.\nCela peut permettre une meilleure adhérence aux couches précédentes sans surchauffer le matériau dans ces couches. Uniquement applicable à l'impression filaire."
+msgstr ""
+"Distance d’un déplacement ascendant qui est extrudé à mi-vitesse.\n"
+"Cela peut permettre une meilleure adhérence aux couches précédentes sans surchauffer le matériau dans ces couches. Uniquement applicable à l'impression filaire."
#: fdmprinter.def.json
msgctxt "wireframe_top_jump label"
@@ -5384,7 +5798,7 @@ msgstr "Distance entre la buse et les lignes descendantes horizontalement. Un es
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
-msgid "Use adaptive layers"
+msgid "Use Adaptive Layers"
msgstr "Utiliser des couches adaptatives"
#: fdmprinter.def.json
@@ -5394,7 +5808,7 @@ msgstr "Cette option calcule la hauteur des couches en fonction de la forme du m
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
-msgid "Adaptive layers maximum variation"
+msgid "Adaptive Layers Maximum Variation"
msgstr "Variation maximale des couches adaptatives"
#: fdmprinter.def.json
@@ -5404,7 +5818,7 @@ msgstr "Hauteur maximale autorisée par rapport à la couche de base."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
-msgid "Adaptive layers variation step size"
+msgid "Adaptive Layers Variation Step Size"
msgstr "Taille des étapes de variation des couches adaptatives"
#: fdmprinter.def.json
@@ -5414,13 +5828,14 @@ msgstr "Différence de hauteur de la couche suivante par rapport à la précéde
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
-msgid "Adaptive layers threshold"
-msgstr "Limite des couches adaptatives"
+msgid "Adaptive Layers Topography Size"
+msgstr "Taille de la topographie des couches adaptatives"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
-msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
-msgstr "Limite indiquant d'utiliser ou non une couche plus petite. Ce nombre est comparé à la tangente de la pente la plus raide d'une couche."
+msgid "Target horizontal distance between two adjacent layers. Reducing this setting causes thinner layers to be used to bring the edges of the layers closer together."
+msgstr "Distance horizontale cible entre deux couches adjacentes. La réduction de ce paramètre entraîne l'utilisation de couches plus fines pour rapprocher les"
+" bords des couches."
#: fdmprinter.def.json
msgctxt "wall_overhang_angle label"
@@ -5429,8 +5844,9 @@ msgstr "Angle de parois en porte-à-faux"
#: fdmprinter.def.json
msgctxt "wall_overhang_angle description"
-msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
-msgstr "Les parois ayant un angle supérieur à cette valeur seront imprimées en utilisant les paramètres de parois en porte-à-faux. Si la valeur est 90, aucune paroi ne sera considérée comme étant en porte-à-faux."
+msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging. Overhang that gets supported by support will not be treated as overhang either."
+msgstr "Les parois ayant un angle supérieur à cette valeur seront imprimées en utilisant les paramètres de parois en porte-à-faux. Si la valeur est 90, aucune"
+" paroi ne sera considérée comme étant en porte-à-faux. La saillie soutenue par le support ne sera pas non plus considérée comme étant en porte-à-faux."
#: fdmprinter.def.json
msgctxt "wall_overhang_speed_factor label"
@@ -5632,6 +6048,198 @@ msgctxt "bridge_fan_speed_3 description"
msgid "Percentage fan speed to use when printing the third bridge skin layer."
msgstr "Vitesse du ventilateur en pourcentage à utiliser pour l'impression de la troisième couche extérieure du pont."
+#: fdmprinter.def.json
+msgctxt "clean_between_layers label"
+msgid "Wipe Nozzle Between Layers"
+msgstr "Essuyer la buse entre les couches"
+
+#: fdmprinter.def.json
+msgctxt "clean_between_layers description"
+msgid "Whether to include nozzle wipe G-Code between layers. Enabling this setting could influence behavior of retract at layer change. Please use Wipe Retraction settings to control retraction at layers where the wipe script will be working."
+msgstr "Inclure ou non le G-Code d'essuyage de la buse entre les couches. L'activation de ce paramètre peut influencer le comportement de la rétraction lors du changement de couche. Veuillez utiliser les paramètres de rétraction d'essuyage pour contrôler la rétraction aux couches où le script d'essuyage sera exécuté."
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe label"
+msgid "Material Volume Between Wipes"
+msgstr "Volume de matériau entre les essuyages"
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe description"
+msgid "Maximum material, that can be extruded before another nozzle wipe is initiated."
+msgstr "Le volume maximum de matériau qui peut être extrudé avant qu'un autre essuyage de buse ne soit lancé."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable label"
+msgid "Wipe Retraction Enable"
+msgstr "Activation de la rétraction d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable description"
+msgid "Retract the filament when the nozzle is moving over a non-printed area."
+msgstr "Rétracte le filament quand la buse se déplace vers une zone non imprimée."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount label"
+msgid "Wipe Retraction Distance"
+msgstr "Distance de rétraction d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount description"
+msgid "Amount to retract the filament so it does not ooze during the wipe sequence."
+msgstr "La distance de rétraction du filament afin qu'il ne suinte pas pendant la séquence d'essuyage."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount label"
+msgid "Wipe Retraction Extra Prime Amount"
+msgstr "Degré supplémentaire de rétraction d'essuyage primaire"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount description"
+msgid "Some material can ooze away during a wipe travel moves, which can be compensated for here."
+msgstr "Du matériau peut suinter pendant un déplacement d'essuyage, ce qui peut être compensé ici."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed label"
+msgid "Wipe Retraction Speed"
+msgstr "Vitesse de rétraction d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed description"
+msgid "The speed at which the filament is retracted and primed during a wipe retraction move."
+msgstr "La vitesse à laquelle le filament est rétracté et préparé pendant un déplacement de rétraction d'essuyage."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed label"
+msgid "Wipe Retraction Retract Speed"
+msgstr "Vitesse de rétraction d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed description"
+msgid "The speed at which the filament is retracted during a wipe retraction move."
+msgstr "La vitesse à laquelle le filament est rétracté pendant un déplacement de rétraction d'essuyage."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed label"
+msgid "Retraction Prime Speed"
+msgstr "Vitesse de rétraction primaire"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed description"
+msgid "The speed at which the filament is primed during a wipe retraction move."
+msgstr "La vitesse à laquelle le filament est préparé pendant un déplacement de rétraction d'essuyage."
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause label"
+msgid "Wipe Pause"
+msgstr "Pause d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause description"
+msgid "Pause after the unretract."
+msgstr "Pause après l'irrétraction."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable label"
+msgid "Wipe Z Hop When Retracted"
+msgstr "Décalage en Z d'essuyage lors d’une rétraction"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable description"
+msgid "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate."
+msgstr "À chaque rétraction, le plateau est abaissé pour créer un espace entre la buse et l'impression. Cela évite que la buse ne touche l'impression pendant les déplacements, réduisant ainsi le risque de heurter l'impression à partir du plateau."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount label"
+msgid "Wipe Z Hop Height"
+msgstr "Hauteur du décalage en Z d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount description"
+msgid "The height difference when performing a Z Hop."
+msgstr "La différence de hauteur lors de la réalisation d'un décalage en Z."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed label"
+msgid "Wipe Hop Speed"
+msgstr "Vitesse du décalage d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed description"
+msgid "Speed to move the z-axis during the hop."
+msgstr "Vitesse de déplacement de l'axe Z pendant le décalage."
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x label"
+msgid "Wipe Brush X Position"
+msgstr "Position X de la brosse d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x description"
+msgid "X location where wipe script will start."
+msgstr "Emplacement X où le script d'essuyage démarrera."
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count label"
+msgid "Wipe Repeat Count"
+msgstr "Nombre de répétitions d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count description"
+msgid "Number of times to move the nozzle across the brush."
+msgstr "Le nombre de déplacements de la buse à travers la brosse."
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance label"
+msgid "Wipe Move Distance"
+msgstr "Distance de déplacement d'essuyage"
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance description"
+msgid "The distance to move the head back and forth across the brush."
+msgstr "La distance de déplacement de la tête d'avant en arrière à travers la brosse."
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size label"
+msgid "Small Hole Max Size"
+msgstr "Taille maximale des petits trous"
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size description"
+msgid "Holes and part outlines with a diameter smaller than this will be printed using Small Feature Speed."
+msgstr "Les trous et les contours des pièces dont le diamètre est inférieur à celui-ci seront imprimés en utilisant l'option Vitesse de petite structure."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length label"
+msgid "Small Feature Max Length"
+msgstr "Longueur max de petite structure"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length description"
+msgid "Feature outlines that are shorter than this length will be printed using Small Feature Speed."
+msgstr "Les contours des structures dont le diamètre est inférieur à cette longueur seront imprimés en utilisant l'option Vitesse de petite structure."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor label"
+msgid "Small Feature Speed"
+msgstr "Vitesse de petite structure"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor description"
+msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "Les petites structures seront imprimées à ce pourcentage de la vitesse d'impression normale. Une impression plus lente peut aider à l'adhésion et à la"
+" précision."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 label"
+msgid "Small Feature Initial Layer Speed"
+msgstr "Vitesse de la couche initiale de petite structure"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 description"
+msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "Les petites structures sur la première couche seront imprimées à ce pourcentage de la vitesse d'impression normale. Une impression plus lente peut aider"
+" à l'adhésion et à la précision."
+
#: fdmprinter.def.json
msgctxt "command_line_settings label"
msgid "Command Line Settings"
@@ -5692,6 +6300,234 @@ msgctxt "mesh_rotation_matrix description"
msgid "Transformation matrix to be applied to the model when loading it from file."
msgstr "Matrice de transformation à appliquer au modèle lors de son chargement depuis le fichier."
+#~ msgctxt "minimum_interface_area description"
+#~ msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Taille minimale de la surface des polygones d'interface de support : les polygones dont la surface est inférieure à cette valeur ne seront pas générés."
+
+#~ msgctxt "minimum_roof_area description"
+#~ msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Taille minimale de la surface des plafonds du support : les polygones dont la surface est inférieure à cette valeur ne seront pas générés."
+
+#~ msgctxt "minimum_bottom_area description"
+#~ msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Taille minimale de la surface des bas du support : les polygones dont la surface est inférieure à cette valeur ne seront pas générés."
+
+#~ msgctxt "skin_alternate_rotation label"
+#~ msgid "Alternate Skin Rotation"
+#~ msgstr "Alterner la rotation dans les couches extérieures"
+
+#~ msgctxt "skin_alternate_rotation description"
+#~ msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
+#~ msgstr "Alterne le sens d'impression des couches du dessus/dessous. Elles sont généralement imprimées uniquement en diagonale. Ce paramètre ajoute les sens X uniquement et Y uniquement."
+
+#~ msgctxt "flow_rate_max_extrusion_offset label"
+#~ msgid "Flow rate compensation max extrusion offset"
+#~ msgstr "Décalage d'extrusion max. pour compensation du débit"
+
+#~ msgctxt "flow_rate_max_extrusion_offset description"
+#~ msgid "The maximum distance in mm to compensate."
+#~ msgstr "Distance de compensation maximum en mm."
+
+#~ msgctxt "flow_rate_extrusion_offset_factor label"
+#~ msgid "Flow rate compensation factor"
+#~ msgstr "Facteur de compensation du débit"
+
+#~ msgctxt "flow_rate_extrusion_offset_factor description"
+#~ msgid "The multiplication factor for the flow rate -> distance translation."
+#~ msgstr "Facteur de multiplication pour le débit -> translation de la distance."
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive Layers Threshold"
+#~ msgstr "Limite des couches adaptatives"
+
+#~ msgctxt "adaptive_layer_height_threshold description"
+#~ msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
+#~ msgstr "Limite indiquant d'utiliser ou non une couche plus petite. Ce nombre est comparé à la tangente de la pente la plus raide d'une couche."
+
+#~ msgctxt "wall_overhang_angle description"
+#~ msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
+#~ msgstr "Les parois ayant un angle supérieur à cette valeur seront imprimées en utilisant les paramètres de parois en porte-à-faux. Si la valeur est 90, aucune paroi ne sera considérée comme étant en porte-à-faux."
+
+#~ msgctxt "small_feature_speed_factor description"
+#~ msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "Les petites structures seront imprimées à ce pourcentage de la vitesse d'impression normale. Une impression plus lente peut aider à l'adhésion et à la précision."
+
+#~ msgctxt "small_feature_speed_factor_0 label"
+#~ msgid "First Layer Speed"
+#~ msgstr "Vitesse de la première couche"
+
+#~ msgctxt "small_feature_speed_factor_0 description"
+#~ msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "Les petites structures sur la première couche seront imprimées à ce pourcentage de la vitesse d'impression normale. Une impression plus lente peut aider à l'adhésion et à la précision."
+
+#~ msgctxt "ironing_enabled description"
+#~ msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
+#~ msgstr "Aller au-dessus de la surface supérieure une fois supplémentaire, mais sans extruder de matériau. Cela signifie de faire fondre le plastique en haut un peu plus, pour créer une surface lisse."
+
+#~ msgctxt "start_layers_at_same_position label"
+#~ msgid "Start Layers with the Same Part"
+#~ msgstr "Démarrer les couches avec la même partie"
+
+#~ msgctxt "start_layers_at_same_position description"
+#~ msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
+#~ msgstr "Dans chaque couche, démarre l'impression de l'objet à proximité du même point, de manière à ce que nous ne commencions pas une nouvelle couche en imprimant la pièce avec laquelle la couche précédente s'est terminée. Cela renforce les porte-à-faux et les petites pièces, mais augmente le temps d'impression."
+
+#~ msgctxt "support_infill_angles description"
+#~ msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
+#~ msgstr "Orientation du motif de remplissage pour les supports. Le motif de remplissage du support pivote dans le plan horizontal."
+
+#~ msgctxt "meshfix_maximum_deviation description"
+#~ msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller."
+#~ msgstr "L'écart maximum autorisé lors de la réduction de la résolution pour le paramètre Résolution maximum. Si vous augmentez cette valeur, l'impression sera moins précise, mais le G-Code sera plus petit."
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code Flavour"
+#~ msgstr "Parfum G-Code"
+
+#~ msgctxt "z_seam_corner description"
+#~ msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
+#~ msgstr "Vérifie si les angles du contour du modèle influencent l'emplacement de la jointure. « Aucune » signifie que les angles n'ont aucune influence sur l'emplacement de la jointure. « Masquer jointure » génère généralement le positionnement de la jointure sur un angle intérieur. « Exposer jointure » génère généralement le positionnement de la jointure sur un angle extérieur. « Masquer ou exposer jointure » génère généralement le positionnement de la jointure sur un angle intérieur ou extérieur."
+
+#~ msgctxt "skin_no_small_gaps_heuristic label"
+#~ msgid "Ignore Small Z Gaps"
+#~ msgstr "Ignorer les petits trous en Z"
+
+#~ msgctxt "skin_no_small_gaps_heuristic description"
+#~ msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
+#~ msgstr "Quand le modèle présente de petits trous verticaux, environ 5 % de temps de calcul supplémentaire peut être alloué à la génération de couches du dessus et du dessous dans ces espaces étroits. Dans ce cas, désactivez ce paramètre."
+
+#~ msgctxt "build_volume_temperature description"
+#~ msgid "The temperature used for build volume. If this is 0, the build volume temperature will not be adjusted."
+#~ msgstr "La température utilisée pour le volume d'impression. Si cette valeur est 0, la température du volume d'impression ne sera pas ajustée."
+
+#~ msgctxt "limit_support_retractions description"
+#~ msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
+#~ msgstr "Omettre la rétraction lors du passage entre supports en ligne droite. L'activation de ce paramètre permet de gagner du temps lors de l'impression, mais peut conduire à un cordage excessif à l'intérieur de la structure de support."
+
+#~ msgctxt "max_feedrate_z_override label"
+#~ msgid "Maximum Z Speed"
+#~ msgstr "Vitesse Z maximale"
+
+#~ msgctxt "max_feedrate_z_override description"
+#~ msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
+#~ msgstr "La vitesse maximale à laquelle le plateau se déplace. Définir cette valeur sur zéro impose à l'impression d'utiliser les valeurs par défaut du firmware pour la vitesse z maximale."
+
+#~ msgctxt "support_join_distance description"
+#~ msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
+#~ msgstr "La distance maximale entre les supports dans les directions X/Y. Lorsque des supports séparés sont plus rapprochés que cette valeur, ils fusionnent."
+
+#~ msgctxt "support_minimal_diameter label"
+#~ msgid "Minimum Diameter"
+#~ msgstr "Diamètre minimal"
+
+#~ msgctxt "support_minimal_diameter description"
+#~ msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+#~ msgstr "Le diamètre minimal sur les axes X/Y d’une petite zone qui doit être soutenue par une tour de soutien spéciale."
+
+#~ msgctxt "prime_tower_circular label"
+#~ msgid "Circular Prime Tower"
+#~ msgstr "Tour primaire circulaire"
+
+#~ msgctxt "prime_tower_circular description"
+#~ msgid "Make the prime tower as a circular shape."
+#~ msgstr "Réaliser la tour primaire en forme circulaire."
+
+#~ msgctxt "prime_tower_flow description"
+#~ msgid "Flow compensation: the amount of material extruded is multiplied by this value."
+#~ msgstr "Compensation du débit : la quantité de matériau extrudée est multipliée par cette valeur."
+
+#~ msgctxt "smooth_spiralized_contours description"
+#~ msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+#~ msgstr "Lisser les contours spiralisés pour réduire la visibilité de la jointure en Z (la jointure en Z doit être à peine visible sur l'impression mais sera toujours visible dans la vue en couches). Veuillez remarquer que le lissage aura tendance à estomper les détails fins de la surface."
+
+#~ msgctxt "support_conical_enabled description"
+#~ msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
+#~ msgstr "Fonctionnalité expérimentale : rendre les aires de support plus petites en bas qu'au niveau du porte-à-faux à supporter."
+
+#~ msgctxt "extruders_enabled_count label"
+#~ msgid "Number of Extruders that are enabled"
+#~ msgstr "Nombre d'extrudeuses activées"
+
+#~ msgctxt "machine_nozzle_tip_outer_diameter label"
+#~ msgid "Outer nozzle diameter"
+#~ msgstr "Diamètre extérieur de la buse"
+
+#~ msgctxt "machine_nozzle_head_distance label"
+#~ msgid "Nozzle length"
+#~ msgstr "Longueur de la buse"
+
+#~ msgctxt "machine_nozzle_expansion_angle label"
+#~ msgid "Nozzle angle"
+#~ msgstr "Angle de la buse"
+
+#~ msgctxt "machine_heat_zone_length label"
+#~ msgid "Heat zone length"
+#~ msgstr "Longueur de la zone chauffée"
+
+#~ msgctxt "machine_nozzle_heat_up_speed label"
+#~ msgid "Heat up speed"
+#~ msgstr "Vitesse de chauffage"
+
+#~ msgctxt "machine_nozzle_cool_down_speed label"
+#~ msgid "Cool down speed"
+#~ msgstr "Vitesse de refroidissement"
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code flavour"
+#~ msgstr "Parfum G-Code"
+
+#~ msgctxt "machine_disallowed_areas label"
+#~ msgid "Disallowed areas"
+#~ msgstr "Zones interdites"
+
+#~ msgctxt "machine_head_polygon label"
+#~ msgid "Machine head polygon"
+#~ msgstr "Polygone de la tête de machine"
+
+#~ msgctxt "machine_head_with_fans_polygon label"
+#~ msgid "Machine head & Fan polygon"
+#~ msgstr "Tête de la machine et polygone du ventilateur"
+
+#~ msgctxt "gantry_height label"
+#~ msgid "Gantry height"
+#~ msgstr "Hauteur du portique"
+
+#~ msgctxt "machine_use_extruder_offset_to_offset_coords label"
+#~ msgid "Offset With Extruder"
+#~ msgstr "Décalage avec extrudeuse"
+
+#~ msgctxt "adaptive_layer_height_enabled label"
+#~ msgid "Use adaptive layers"
+#~ msgstr "Utiliser des couches adaptatives"
+
+#~ msgctxt "adaptive_layer_height_variation label"
+#~ msgid "Adaptive layers maximum variation"
+#~ msgstr "Variation maximale des couches adaptatives"
+
+#~ msgctxt "adaptive_layer_height_variation_step label"
+#~ msgid "Adaptive layers variation step size"
+#~ msgstr "Taille des étapes de variation des couches adaptatives"
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive layers threshold"
+#~ msgstr "Limite des couches adaptatives"
+
+#~ msgctxt "skin_overlap description"
+#~ msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
+#~ msgstr "Le montant de chevauchement entre la couche extérieure et les parois en pourcentage de la largeur de ligne de couche extérieure. Un chevauchement faible permet aux parois de se connecter fermement à la couche extérieure. Ce montant est un pourcentage des largeurs moyennes des lignes de la couche extérieure et de la paroi la plus intérieure."
+
+#~ msgctxt "skin_overlap_mm description"
+#~ msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
+#~ msgstr "Le degré de chevauchement entre la couche extérieure et les parois. Un léger chevauchement permet de lier fermement les parois à la couche externe."
+
+#~ msgctxt "switch_extruder_retraction_amount description"
+#~ msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+#~ msgstr "La quantité de rétraction : définir à 0 pour aucune rétraction. Cette valeur doit généralement être égale à la longueur de la zone chauffée."
+
+#~ msgctxt "retraction_combing description"
+#~ msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
+#~ msgstr "Les détours maintiennent la buse dans les zones déjà imprimées lors des déplacements. Cela résulte en des déplacements légèrement plus longs mais réduit le recours aux rétractions. Si les détours sont désactivés, le matériau se rétractera et la buse se déplacera en ligne droite jusqu'au point suivant. Il est également possible d'éviter les détours sur les zones de la couche extérieure supérieure / inférieure et aussi de n'effectuer les détours que dans le remplissage. Notez que l'option « À l'intérieur du remplissage » se comporte exactement comme l'option « Pas dans la couche extérieure » dans les versions précédentes de Cura."
+
#~ msgctxt "connect_skin_polygons description"
#~ msgid "Connect top/bottom skin paths where they run next to each other. For the concentric pattern enabling this setting greatly reduces the travel time, but because the connections can happend midway over infill this feature can reduce the top surface quality."
#~ msgstr "Relier les voies de couche extérieure supérieures / inférieures lorsqu'elles sont côte à côte. Pour le motif concentrique, ce paramètre réduit considérablement le temps de parcours, mais comme les liens peuvent se trouver à mi-chemin sur le remplissage, cette fonctionnalité peut réduire la qualité de la surface supérieure."
diff --git a/resources/i18n/it_IT/cura.po b/resources/i18n/it_IT/cura.po
index d285cbfdc3..b215eae599 100644
--- a/resources/i18n/it_IT/cura.po
+++ b/resources/i18n/it_IT/cura.po
@@ -1,24 +1,24 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0100\n"
-"PO-Revision-Date: 2018-09-28 15:01+0200\n"
-"Last-Translator: Bothof \n"
-"Language-Team: Italian\n"
+"POT-Creation-Date: 2019-11-05 13:13+0100\n"
+"PO-Revision-Date: 2019-07-29 15:51+0100\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: Italian , Italian \n"
"Language: it_IT\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.1.1\n"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:22
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:30
msgctxt "@action"
msgid "Machine Settings"
msgstr "Impostazioni macchina"
@@ -40,23 +40,23 @@ msgctxt "@item:inlistbox"
msgid "G-code File"
msgstr "File G-Code"
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:67
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:66
msgctxt "@error:not supported"
msgid "GCodeWriter does not support non-text mode."
msgstr "GCodeWriter non supporta la modalità non di testo."
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:73
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:89
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:72
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:88
msgctxt "@warning:status"
msgid "Please prepare G-code before exporting."
msgstr "Preparare il codice G prima dell’esportazione."
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:30
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:31
msgctxt "@info:title"
msgid "3D Model Assistant"
msgstr "Assistente modello 3D"
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:80
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:92
#, python-brace-format
msgctxt "@info:status"
msgid ""
@@ -64,68 +64,56 @@ msgid ""
"
{model_names}
\n"
"
Find out how to ensure the best possible print quality and reliability.
"
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py:25
msgctxt "@action"
msgid "Update Firmware"
msgstr "Aggiornamento firmware"
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:23
-msgctxt "@item:inmenu"
-msgid "Flatten active settings"
-msgstr "Impostazioni attive profilo appiattito"
+#: /home/ruben/Projects/Cura/plugins/AMFReader/__init__.py:15
+msgctxt "@item:inlistbox"
+msgid "AMF File"
+msgstr "File AMF"
-#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:35
-msgctxt "@info:status"
-msgid "Profile has been flattened & activated."
-msgstr "Il profilo è stato appiattito e attivato."
-
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:32
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:42
msgctxt "@item:inmenu"
msgid "USB printing"
msgstr "Stampa USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:33
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:43
msgctxt "@action:button Preceded by 'Ready to'."
msgid "Print via USB"
msgstr "Stampa tramite USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:34
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:44
msgctxt "@info:tooltip"
msgid "Print via USB"
msgstr "Stampa tramite USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:69
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:80
msgctxt "@info:status"
msgid "Connected via USB"
msgstr "Connesso tramite USB"
-#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:92
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:105
msgctxt "@label"
msgid "A USB print is in progress, closing Cura will stop this print. Are you sure?"
msgstr "Stampa tramite USB in corso, la chiusura di Cura interrompe la stampa. Confermare?"
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/install/X3GWriter/__init__.py:15
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/__init__.py:15
-msgctxt "X3G Writer File Description"
-msgid "X3G File"
-msgstr "File X3G"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid "A print is still in progress. Cura cannot start another print via USB until the previous print has completed."
+msgstr "Stampa ancora in corso. Cura non può avviare un'altra stampa tramite USB finché la precedente non è stata completata."
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:16
-msgctxt "X3g Writer Plugin Description"
-msgid "Writes X3g to files"
-msgstr "Scrive X3g sui file"
-
-#: /home/ruben/Projects/Cura/plugins/X3GWriter/build/GPX-prefix/src/GPX/slicerplugins/cura15.06/X3gWriter/__init__.py:21
-msgctxt "X3g Writer File Description"
-msgid "X3g File"
-msgstr "File X3g"
+#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:127
+msgctxt "@message"
+msgid "Print in Progress"
+msgstr "Stampa in corso"
#: /home/ruben/Projects/Cura/plugins/GCodeGzWriter/__init__.py:17
#: /home/ruben/Projects/Cura/plugins/GCodeGzReader/__init__.py:17
@@ -139,6 +127,7 @@ msgid "GCodeGzWriter does not support text mode."
msgstr "GCodeGzWriter non supporta la modalità di testo."
#: /home/ruben/Projects/Cura/plugins/UFPWriter/__init__.py:28
+#: /home/ruben/Projects/Cura/plugins/UFPReader/__init__.py:22
msgctxt "@item:inlistbox"
msgid "Ultimaker Format Package"
msgstr "Pacchetto formato Ultimaker"
@@ -160,7 +149,7 @@ msgid "Save to Removable Drive {0}"
msgstr "Salva su unità rimovibile {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:64
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:133
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/MeshFormatHandler.py:107
msgctxt "@info:status"
msgid "There are no file formats available to write with!"
msgstr "Non ci sono formati di file disponibili per la scrittura!"
@@ -197,9 +186,9 @@ msgid "Could not save to removable drive {0}: {1}"
msgstr "Impossibile salvare su unità rimovibile {0}: {1}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:137
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:133
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:140
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1607
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:139
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:146
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1668
msgctxt "@info:title"
msgid "Error"
msgstr "Errore"
@@ -228,8 +217,9 @@ msgstr "Rimuovi il dispositivo rimovibile {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:151
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:163
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1597
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1695
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1658
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1758
msgctxt "@info:title"
msgid "Warning"
msgstr "Avvertenza"
@@ -256,232 +246,164 @@ msgctxt "@item:intext"
msgid "Removable Drive"
msgstr "Unità rimovibile"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:73
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:88
-msgctxt "@action:button Preceded by 'Ready to'."
-msgid "Print over network"
-msgstr "Stampa sulla rete"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:74
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:89
-msgctxt "@properties:tooltip"
-msgid "Print over network"
-msgstr "Stampa sulla rete"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:87
-msgctxt "@info:status"
-msgid "Connected over the network."
-msgstr "Collegato alla rete."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:90
-msgctxt "@info:status"
-msgid "Connected over the network. Please approve the access request on the printer."
-msgstr "Collegato alla rete. Si prega di approvare la richiesta di accesso sulla stampante."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:92
-msgctxt "@info:status"
-msgid "Connected over the network. No access to control the printer."
-msgstr "Collegato alla rete. Nessun accesso per controllare la stampante."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:97
-msgctxt "@info:status"
-msgid "Access to the printer requested. Please approve the request on the printer"
-msgstr "Richiesto accesso alla stampante. Approvare la richiesta sulla stampante"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:100
-msgctxt "@info:title"
-msgid "Authentication status"
-msgstr "Stato di autenticazione"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:102
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:108
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:112
-msgctxt "@info:title"
-msgid "Authentication Status"
-msgstr "Stato di autenticazione"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:103
-msgctxt "@action:button"
-msgid "Retry"
-msgstr "Riprova"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:104
-msgctxt "@info:tooltip"
-msgid "Re-send the access request"
-msgstr "Invia nuovamente la richiesta di accesso"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:107
-msgctxt "@info:status"
-msgid "Access to the printer accepted"
-msgstr "Accesso alla stampante accettato"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:111
-msgctxt "@info:status"
-msgid "No access to print with this printer. Unable to send print job."
-msgstr "Nessun accesso per stampare con questa stampante. Impossibile inviare il processo di stampa."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:113
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:33
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:70
-msgctxt "@action:button"
-msgid "Request Access"
-msgstr "Richiesta di accesso"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:115
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:34
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:71
-msgctxt "@info:tooltip"
-msgid "Send access request to the printer"
-msgstr "Invia la richiesta di accesso alla stampante"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:200
-msgctxt "@label"
-msgid "Unable to start a new print job."
-msgstr "Impossibile avviare un nuovo processo di stampa."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:202
-msgctxt "@label"
-msgid "There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. Please resolve this issues before continuing."
-msgstr "È presente un problema di configurazione della stampante che rende impossibile l’avvio della stampa. Risolvere il problema prima di continuare."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:208
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:230
-msgctxt "@window:title"
-msgid "Mismatched configuration"
-msgstr "Mancata corrispondenza della configurazione"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:222
-msgctxt "@label"
-msgid "Are you sure you wish to print with the selected configuration?"
-msgstr "Sei sicuro di voler stampare con la configurazione selezionata?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:224
-msgctxt "@label"
-msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "Le configurazioni o la calibrazione della stampante e di Cura non corrispondono. Per ottenere i migliori risultati, sezionare sempre per i PrintCore e i materiali inseriti nella stampante utilizzata."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:251
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:199
-msgctxt "@info:status"
-msgid "Sending new jobs (temporarily) blocked, still sending the previous print job."
-msgstr "Invio nuovi processi (temporaneamente) bloccato, invio in corso precedente processo di stampa."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:258
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:218
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:234
-msgctxt "@info:status"
-msgid "Sending data to printer"
-msgstr "Invio dati alla stampante in corso"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:259
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:219
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:235
-msgctxt "@info:title"
-msgid "Sending Data"
-msgstr "Invio dati"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:260
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:236
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:80
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:381
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:20
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:143
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:391
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:87
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:279
-msgctxt "@action:button"
-msgid "Cancel"
-msgstr "Annulla"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:323
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No Printcore loaded in slot {slot_number}"
-msgstr "Nessun PrintCore caricato nello slot {slot_number}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:329
-#, python-brace-format
-msgctxt "@info:status"
-msgid "No material loaded in slot {slot_number}"
-msgstr "Nessun materiale caricato nello slot {slot_number}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:352
-#, python-brace-format
-msgctxt "@label"
-msgid "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}"
-msgstr "PrintCore diverso (Cura: {cura_printcore_name}, Stampante: {remote_printcore_name}) selezionata per estrusore {extruder_id}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:361
-#, python-brace-format
-msgctxt "@label"
-msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
-msgstr "Materiale diverso (Cura: {0}, Stampante: {1}) selezionato per l’estrusore {2}"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:547
-msgctxt "@window:title"
-msgid "Sync with your printer"
-msgstr "Sincronizzazione con la stampante"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:549
-msgctxt "@label"
-msgid "Would you like to use your current printer configuration in Cura?"
-msgstr "Desideri utilizzare la configurazione corrente della tua stampante in Cura?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/LegacyUM3OutputDevice.py:551
-msgctxt "@label"
-msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "I PrintCore e/o i materiali sulla stampante differiscono da quelli contenuti nel tuo attuale progetto. Per ottenere i risultati migliori, sezionare sempre per i PrintCore e i materiali inseriti nella stampante utilizzata."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:91
-msgctxt "@info:status"
-msgid "Connected over the network"
-msgstr "Collegato alla rete"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:303
-msgctxt "@info:status"
-msgid "Print job was successfully sent to the printer."
-msgstr "Processo di stampa inviato con successo alla stampante."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:305
-msgctxt "@info:title"
-msgid "Data Sent"
-msgstr "Dati inviati"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:306
-msgctxt "@action:button"
-msgid "View in Monitor"
-msgstr "Visualizzazione in Controlla"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:422
-#, python-brace-format
-msgctxt "@info:status"
-msgid "Printer '{printer_name}' has finished printing '{job_name}'."
-msgstr "La stampante '{printer_name}' ha finito di stampare '{job_name}'."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:424
-#, python-brace-format
-msgctxt "@info:status"
-msgid "The print job '{job_name}' was finished."
-msgstr "Il processo di stampa '{job_name}' è terminato."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/ClusterUM3OutputDevice.py:425
-msgctxt "@info:status"
-msgid "Print finished"
-msgstr "Stampa finita"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/DiscoverUM3Action.py:26
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py:26
msgctxt "@action"
msgid "Connect via Network"
msgstr "Collega tramite rete"
-#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:13
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:57
+msgctxt "@action:button Preceded by 'Ready to'."
+msgid "Print over network"
+msgstr "Stampa sulla rete"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:58
+msgctxt "@properties:tooltip"
+msgid "Print over network"
+msgstr "Stampa sulla rete"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py:59
+msgctxt "@info:status"
+msgid "Connected over the network"
+msgstr "Collegato alla rete"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:15
+msgctxt "@info:status"
+msgid "Please wait until the current job has been sent."
+msgstr "Attendere che sia stato inviato il processo corrente."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadBlockedMessage.py:16
+msgctxt "@info:title"
+msgid "Print error"
+msgstr "Errore di stampa"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:21
+msgctxt "@info:title"
+msgid "New cloud printers found"
+msgstr "Nuove stampanti in cloud rilevate"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:22
+msgctxt "@info:message"
+msgid "New printers have been found connected to your account, you can find them in your list of discovered printers."
+msgstr "Sono state trovate nuove stampanti collegate al tuo account. Puoi vederle nell'elenco delle stampanti rilevate."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudPrinterDetectedMessage.py:27
+msgctxt "@info:option_text"
+msgid "Do not show this message again"
+msgstr "Non mostrare nuovamente questo messaggio"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:27
+#, python-brace-format
+msgctxt "@info:status"
+msgid "You are attempting to connect to {0} but it is not the host of a group. You can visit the web page to configure it as a group host."
+msgstr "Tentativo di connessione a {0} in corso, che non è l'host di un gruppo. È possibile visitare la pagina web per configurarla come host del gruppo."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:30
+msgctxt "@info:title"
+msgid "Not a group host"
+msgstr "Non host del gruppo"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py:35
+msgctxt "@action"
+msgid "Configure group"
+msgstr "Configurare il gruppo"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:27
+msgctxt "@info:status"
+msgid "Send and monitor print jobs from anywhere using your Ultimaker account."
+msgstr "Invia e controlla i processi di stampa ovunque con l’account Ultimaker."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:33
+msgctxt "@info:status Ultimaker Cloud should not be translated."
+msgid "Connect to Ultimaker Cloud"
+msgstr "Connettiti a Ultimaker Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py:36
+msgctxt "@action"
+msgid "Get started"
+msgstr "Per iniziare"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:14
+msgctxt "@info:status"
+msgid "Sending Print Job"
+msgstr "Invio di un processo di stampa"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadProgressMessage.py:15
+msgctxt "@info:status"
+msgid "Uploading print job to printer."
+msgstr "Caricamento del processo di stampa sulla stampante."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:15
+msgctxt "@info:status"
+msgid "Print job was successfully sent to the printer."
+msgstr "Processo di stampa inviato con successo alla stampante."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadSuccessMessage.py:16
+msgctxt "@info:title"
+msgid "Data Sent"
+msgstr "Dati inviati"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:18
+msgctxt "@info:status"
+msgid "You are attempting to connect to a printer that is not running Ultimaker Connect. Please update the printer to the latest firmware."
+msgstr "Si sta tentando di connettersi a una stampante che non esegue Ultimaker Connect. Aggiornare la stampante con il firmware più recente."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/LegacyDeviceNoLongerSupportedMessage.py:21
+msgctxt "@info:title"
+msgid "Update your printer"
+msgstr "Aggiornare la stampante"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:24
+#, python-brace-format
+msgctxt "@info:status"
+msgid "Cura has detected material profiles that were not yet installed on the host printer of group {0}."
+msgstr "Cura ha rilevato dei profili di materiale non ancora installati sulla stampante host del gruppo {0}."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py:26
+msgctxt "@info:title"
+msgid "Sending materials to printer"
+msgstr "Invio dei materiali alla stampante"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:15
+msgctxt "@info:text"
+msgid "Could not upload the data to the printer."
+msgstr "Impossibile caricare i dati sulla stampante."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Messages/PrintJobUploadErrorMessage.py:16
+msgctxt "@info:title"
+msgid "Network error"
+msgstr "Errore di rete"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:27
+msgctxt "@info:status"
+msgid "tomorrow"
+msgstr "domani"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Utils.py:30
+msgctxt "@info:status"
+msgid "today"
+msgstr "oggi"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:138
+msgctxt "@action:button"
+msgid "Print via Cloud"
+msgstr "Stampa tramite Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:139
+msgctxt "@properties:tooltip"
+msgid "Print via Cloud"
+msgstr "Stampa tramite Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py:140
+msgctxt "@info:status"
+msgid "Connected via Cloud"
+msgstr "Collegato tramite Cloud"
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:14
msgctxt "@item:inmenu"
msgid "Monitor"
msgstr "Controlla"
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:119
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:125
msgctxt "@info"
msgid "Could not access update information."
msgstr "Non è possibile accedere alle informazioni di aggiornamento."
@@ -503,24 +425,30 @@ msgctxt "@action:button"
msgid "How to update"
msgstr "Modalità di aggiornamento"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:14
+#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:15
msgctxt "@item:inlistbox"
msgid "Layer view"
msgstr "Visualizzazione strato"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:113
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:117
msgctxt "@info:status"
msgid "Cura does not accurately display layers when Wire Printing is enabled"
msgstr "Cura non visualizza in modo accurato gli strati se la funzione Wire Printing è abilitata"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:114
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:118
msgctxt "@info:title"
msgid "Simulation View"
msgstr "Vista simulazione"
#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:35
+msgctxt "@item:inmenu"
+msgid "Post Processing"
+msgstr "Post-elaborazione"
+
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:36
+msgctxt "@item:inmenu"
msgid "Modify G-Code"
-msgstr "Modifica G-code"
+msgstr "Modifica codice G"
#: /home/ruben/Projects/Cura/plugins/SupportEraser/__init__.py:12
msgctxt "@label"
@@ -532,36 +460,6 @@ msgctxt "@info:tooltip"
msgid "Create a volume in which supports are not printed."
msgstr "Crea un volume in cui i supporti non vengono stampati."
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:52
-msgctxt "@info"
-msgid "Cura collects anonymized usage statistics."
-msgstr "Cura raccoglie statistiche di utilizzo in forma anonima."
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:55
-msgctxt "@info:title"
-msgid "Collecting Data"
-msgstr "Acquisizione dati"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:57
-msgctxt "@action:button"
-msgid "More info"
-msgstr "Per saperne di più"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:58
-msgctxt "@action:tooltip"
-msgid "See more information on what data Cura sends."
-msgstr "Vedere ulteriori informazioni sui dati inviati da Cura."
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:60
-msgctxt "@action:button"
-msgid "Allow"
-msgstr "Consenti"
-
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:61
-msgctxt "@action:tooltip"
-msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
-msgstr "Consente a Cura di inviare in forma anonima statistiche d’uso, riguardanti alcune delle preferenze e impostazioni, la versione cura e una serie di modelli in sezionamento, per aiutare a dare priorità a miglioramenti futuri in Cura."
-
#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
msgid "Cura 15.04 profiles"
@@ -592,56 +490,86 @@ msgctxt "@item:inlistbox"
msgid "GIF Image"
msgstr "Immagine GIF"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:15
+msgctxt "@item:inlistbox 'Open' is part of the name of this file format."
+msgid "Open Compressed Triangle Mesh"
+msgstr "Open Compressed Triangle Mesh"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:19
+msgctxt "@item:inlistbox"
+msgid "COLLADA Digital Asset Exchange"
+msgstr "COLLADA Digital Asset Exchange"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:23
+msgctxt "@item:inlistbox"
+msgid "glTF Binary"
+msgstr "glTF Binary"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:27
+msgctxt "@item:inlistbox"
+msgid "glTF Embedded JSON"
+msgstr "glTF Embedded JSON"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:36
+msgctxt "@item:inlistbox"
+msgid "Stanford Triangle Format"
+msgstr "Stanford Triangle Format"
+
+#: /home/ruben/Projects/Cura/plugins/TrimeshReader/__init__.py:40
+msgctxt "@item:inlistbox"
+msgid "Compressed COLLADA Digital Asset Exchange"
+msgstr "Compressed COLLADA Digital Asset Exchange"
+
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
msgctxt "@info:status"
msgid "Unable to slice with the current material as it is incompatible with the selected machine or configuration."
msgstr "Impossibile eseguire il sezionamento con il materiale corrente in quanto incompatibile con la macchina o la configurazione selezionata."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:332
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:363
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:387
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:396
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:405
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:414
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:331
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
msgctxt "@info:title"
msgid "Unable to slice"
msgstr "Sezionamento impossibile"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:362
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:361
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice with the current settings. The following settings have errors: {0}"
msgstr "Impossibile eseguire il sezionamento con le impostazioni attuali. Le seguenti impostazioni presentano errori: {0}"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:386
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:385
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice due to some per-model settings. The following settings have errors on one or more models: {error_labels}"
msgstr "Impossibile eseguire il sezionamento a causa di alcune impostazioni per modello. Le seguenti impostazioni presentano errori su uno o più modelli: {error_labels}"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:395
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:394
msgctxt "@info:status"
msgid "Unable to slice because the prime tower or prime position(s) are invalid."
msgstr "Impossibile eseguire il sezionamento perché la torre di innesco o la posizione di innesco non sono valide."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:404
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:403
#, python-format
msgctxt "@info:status"
msgid "Unable to slice because there are objects associated with disabled Extruder %s."
msgstr "Impossibile effettuare il sezionamento in quanto vi sono oggetti associati a Extruder %s disabilitato."
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:413
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:412
msgctxt "@info:status"
-msgid "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."
-msgstr "Nulla da sezionare in quanto nessuno dei modelli corrisponde al volume di stampa. Ridimensionare o ruotare i modelli secondo necessità."
+msgid "Nothing to slice because none of the models fit the build volume or are assigned to a disabled extruder. Please scale or rotate models to fit, or enable an extruder."
+msgstr "Nulla da sezionare in quanto nessuno dei modelli corrisponde al volume di stampa o è assegnato a un estrusore disabilitato. Ridimensionare o ruotare i modelli secondo necessità o abilitare un estrusore."
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:50
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:status"
msgid "Processing Layers"
msgstr "Elaborazione dei livelli"
-#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:255
+#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
msgctxt "@info:title"
msgid "Information"
msgstr "Informazioni"
@@ -656,14 +584,12 @@ msgctxt "@info:tooltip"
msgid "Configure Per Model Settings"
msgstr "Configura impostazioni per modello"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:175
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:575
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:186
msgctxt "@title:tab"
msgid "Recommended"
msgstr "Consigliata"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:177
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:580
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:188
msgctxt "@title:tab"
msgid "Custom"
msgstr "Personalizzata"
@@ -674,19 +600,19 @@ msgctxt "@item:inlistbox"
msgid "3MF File"
msgstr "File 3MF"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:190
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:714
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:198
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:651
msgctxt "@label"
msgid "Nozzle"
msgstr "Ugello"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:468
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:496
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Project file {0} contains an unknown machine type {1}. Cannot import the machine. Models will be imported instead."
msgstr "Il file di progetto {0} contiene un tipo di macchina sconosciuto {1}. Impossibile importare la macchina. Verranno invece importati i modelli."
-#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:471
+#: /home/ruben/Projects/Cura/plugins/3MFReader/ThreeMFWorkspaceReader.py:499
msgctxt "@info:title"
msgid "Open Project File"
msgstr "Apri file progetto"
@@ -701,22 +627,65 @@ msgctxt "@item:inlistbox"
msgid "G File"
msgstr "File G"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:324
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:335
msgctxt "@info:status"
msgid "Parsing G-code"
msgstr "Parsing codice G"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:326
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:474
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:337
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:491
msgctxt "@info:title"
msgid "G-code Details"
msgstr "Dettagli codice G"
-#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:472
+#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:489
msgctxt "@info:generic"
msgid "Make sure the g-code is suitable for your printer and printer configuration before sending the file to it. The g-code representation may not be accurate."
msgstr "Verifica che il codice G sia idoneo alla tua stampante e alla sua configurazione prima di trasmettere il file. La rappresentazione del codice G potrebbe non essere accurata."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:64
+msgctxt "@item:inmenu"
+msgid "Manage backups"
+msgstr "Gestione backup"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:107
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DrivePluginExtension.py:113
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:104
+msgctxt "@info:title"
+msgid "Backup"
+msgstr "Backup"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:55
+msgctxt "@info:backup_status"
+msgid "There was an error listing your backups."
+msgstr "Si è verificato un errore nell’elenco dei backup."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:132
+msgctxt "@info:backup_status"
+msgid "There was an error trying to restore your backup."
+msgstr "Si è verificato un errore cercando di ripristinare il backup."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:15
+msgctxt "@info:title"
+msgid "Backups"
+msgstr "Backup"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:27
+msgctxt "@info:backup_status"
+msgid "Uploading your backup..."
+msgstr "Caricamento backup in corso..."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:36
+msgctxt "@info:backup_status"
+msgid "There was an error while uploading your backup."
+msgstr "Si è verificato un errore durante il caricamento del backup."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/UploadBackupJob.py:39
+msgctxt "@info:backup_status"
+msgid "Your backup has finished uploading."
+msgstr "Caricamento backup completato."
+
#: /home/ruben/Projects/Cura/plugins/CuraProfileWriter/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
@@ -738,330 +707,453 @@ msgctxt "@error:zip"
msgid "Error writing 3mf file."
msgstr "Errore scrittura file 3MF."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelection.py:17
+#: /home/ruben/Projects/Cura/plugins/PreviewStage/__init__.py:13
+msgctxt "@item:inmenu"
+msgid "Preview"
+msgstr "Anteprima"
+
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelection.py:18
msgctxt "@action"
msgid "Select upgrades"
msgstr "Seleziona aggiornamenti"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py:14
-msgctxt "@action"
-msgid "Checkup"
-msgstr "Controllo"
-
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.py:21
msgctxt "@action"
msgid "Level build plate"
msgstr "Livella piano di stampa"
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:82
-msgctxt "@tooltip"
-msgid "Outer Wall"
-msgstr "Parete esterna"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:83
-msgctxt "@tooltip"
-msgid "Inner Walls"
-msgstr "Pareti interne"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:84
-msgctxt "@tooltip"
-msgid "Skin"
-msgstr "Rivestimento esterno"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:85
-msgctxt "@tooltip"
-msgid "Infill"
-msgstr "Riempimento"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:86
-msgctxt "@tooltip"
-msgid "Support Infill"
-msgstr "Riempimento del supporto"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:87
-msgctxt "@tooltip"
-msgid "Support Interface"
-msgstr "Interfaccia supporto"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:88
-msgctxt "@tooltip"
-msgid "Support"
-msgstr "Supporto"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:89
-msgctxt "@tooltip"
-msgid "Skirt"
-msgstr "Skirt"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:90
-msgctxt "@tooltip"
-msgid "Travel"
-msgstr "Spostamenti"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:91
-msgctxt "@tooltip"
-msgid "Retractions"
-msgstr "Retrazioni"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:92
-msgctxt "@tooltip"
-msgid "Other"
-msgstr "Altro"
-
-#: /home/ruben/Projects/Cura/cura/PrintInformation.py:310
-#, python-brace-format
-msgctxt "@label"
-msgid "Pre-sliced file {0}"
-msgstr "File pre-sezionato {0}"
-
-#: /home/ruben/Projects/Cura/cura/API/Account.py:71
+#: /home/ruben/Projects/Cura/cura/API/Account.py:82
msgctxt "@info:title"
msgid "Login failed"
msgstr "Login non riuscito"
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:201
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:121
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:36
+msgctxt "@info:not supported profile"
+msgid "Not supported"
+msgstr "Non supportato"
+
+#: /home/ruben/Projects/Cura/cura/Settings/cura_empty_instance_containers.py:55
+msgctxt "@info:No intent profile selected"
+msgid "Default"
+msgstr "Default"
+
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:196
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:125
msgctxt "@title:window"
msgid "File Already Exists"
msgstr "Il file esiste già"
-#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:202
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:122
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:197
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:126
#, python-brace-format
msgctxt "@label Don't translate the XML tag !"
msgid "The file {0} already exists. Are you sure you want to overwrite it?"
msgstr "Il file {0} esiste già. Sei sicuro di volerlo sovrascrivere?"
-#: /home/ruben/Projects/Cura/cura/Settings/ExtrudersModel.py:212
-msgctxt "@menuitem"
-msgid "Not overridden"
-msgstr "Non sottoposto a override"
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:117
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:430
+#: /home/ruben/Projects/Cura/cura/Settings/ContainerManager.py:433
msgctxt "@info:status"
-msgid "The selected material is incompatible with the selected machine or configuration."
-msgstr "Il materiale selezionato è incompatibile con la macchina o la configurazione selezionata."
+msgid "Invalid file URL:"
+msgstr "File URL non valido:"
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:118
-msgctxt "@info:title"
-msgid "Incompatible Material"
-msgstr "Materiale incompatibile"
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:780
+msgctxt "@info:message Followed by a list of settings."
+msgid "Settings have been changed to match the current availability of extruders:"
+msgstr "Le impostazioni sono state modificate in base all’attuale disponibilità di estrusori:"
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:866
-#, python-format
-msgctxt "@info:generic"
-msgid "Settings have been changed to match the current availability of extruders: [%s]"
-msgstr "Le impostazioni sono state modificate in base all’attuale disponibilità di estrusori: [%s]"
-
-#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:868
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:782
msgctxt "@info:title"
msgid "Settings updated"
msgstr "Impostazioni aggiornate"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:131
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1334
+msgctxt "@info:title"
+msgid "Extruder(s) Disabled"
+msgstr "Estrusore disabilitato"
+
+#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:1457
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:99
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:86
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:182
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:223
+msgctxt "@label"
+msgid "Unknown"
+msgstr "Sconosciuto"
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:137
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Failed to export profile to {0}: {1}"
msgstr "Impossibile esportare il profilo su {0}: {1}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:138
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid "Failed to export profile to {0}: Writer plugin reported failure."
msgstr "Impossibile esportare il profilo su {0}: Rilevata anomalia durante scrittura plugin."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:143
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:149
#, python-brace-format
msgctxt "@info:status Don't translate the XML tag !"
msgid "Exported profile to {0}"
msgstr "Profilo esportato su {0}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:144
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:150
msgctxt "@info:title"
msgid "Export succeeded"
msgstr "Esportazione riuscita"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:170
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:177
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
-msgid "Failed to import profile from {0}: {1}"
-msgstr "Impossibile importare il profilo da {0}: {1}"
+msgctxt "@info:status Don't translate the XML tags !"
+msgid "Failed to import profile from {0}: {1}"
+msgstr "Impossibile importare il profilo da {0}: {1}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:190
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:181
+#, python-brace-format
+msgctxt "@info:status Don't translate the XML tags !"
+msgid "Can't import profile from {0} before a printer is added."
+msgstr "Impossibile importare il profilo da {0} prima di aggiungere una stampante."
+
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:198
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "No custom profile to import in file {0}"
msgstr "Nessun profilo personalizzato da importare nel file {0}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:194
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:202
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "Failed to import profile from {0}:"
msgstr "Impossibile importare il profilo da {0}:"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:218
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:228
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:226
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:236
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags !"
msgid "This profile {0} contains incorrect data, could not import it."
msgstr "Questo profilo {0} contiene dati errati, impossibile importarlo."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:241
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:325
#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags !"
-msgid "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it."
-msgstr "La macchina definita nel profilo {0} ({1}) non corrisponde alla macchina corrente ({2}), impossibile importarla."
-
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:312
-#, python-brace-format
-msgctxt "@info:status Don't translate the XML tags or !"
+msgctxt "@info:status Don't translate the XML tag !"
msgid "Failed to import profile from {0}:"
msgstr "Impossibile importare il profilo da {0}:"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:315
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:328
#, python-brace-format
msgctxt "@info:status"
msgid "Successfully imported profile {0}"
msgstr "Profilo importato correttamente {0}"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:318
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:331
#, python-brace-format
msgctxt "@info:status"
msgid "File {0} does not contain any valid profile."
msgstr "Il file {0} non contiene nessun profilo valido."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:321
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:334
#, python-brace-format
msgctxt "@info:status"
msgid "Profile {0} has an unknown file type or is corrupted."
msgstr "Il profilo {0} ha un tipo di file sconosciuto o corrotto."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:339
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
msgctxt "@label"
msgid "Custom profile"
msgstr "Profilo personalizzato"
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:355
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:385
msgctxt "@info:status"
msgid "Profile is missing a quality type."
msgstr "Il profilo è privo del tipo di qualità."
-#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:369
+#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:399
#, python-brace-format
msgctxt "@info:status"
msgid "Could not find a quality type {0} for the current configuration."
msgstr "Impossibile trovare un tipo qualità {0} per la configurazione corrente."
-#: /home/ruben/Projects/Cura/cura/ObjectsModel.py:63
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:76
+msgctxt "@tooltip"
+msgid "Outer Wall"
+msgstr "Parete esterna"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:77
+msgctxt "@tooltip"
+msgid "Inner Walls"
+msgstr "Pareti interne"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:78
+msgctxt "@tooltip"
+msgid "Skin"
+msgstr "Rivestimento esterno"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:79
+msgctxt "@tooltip"
+msgid "Infill"
+msgstr "Riempimento"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:80
+msgctxt "@tooltip"
+msgid "Support Infill"
+msgstr "Riempimento del supporto"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:81
+msgctxt "@tooltip"
+msgid "Support Interface"
+msgstr "Interfaccia supporto"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:82
+msgctxt "@tooltip"
+msgid "Support"
+msgstr "Supporto"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:83
+msgctxt "@tooltip"
+msgid "Skirt"
+msgstr "Skirt"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:84
+msgctxt "@tooltip"
+msgid "Prime Tower"
+msgstr "Torre di innesco"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:85
+msgctxt "@tooltip"
+msgid "Travel"
+msgstr "Spostamenti"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:86
+msgctxt "@tooltip"
+msgid "Retractions"
+msgstr "Retrazioni"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:87
+msgctxt "@tooltip"
+msgid "Other"
+msgstr "Altro"
+
+#: /home/ruben/Projects/Cura/cura/UI/PrintInformation.py:302
+#, python-brace-format
+msgctxt "@label"
+msgid "Pre-sliced file {0}"
+msgstr "File pre-sezionato {0}"
+
+#: /home/ruben/Projects/Cura/cura/UI/WelcomePagesModel.py:56
+msgctxt "@action:button"
+msgid "Next"
+msgstr "Avanti"
+
+#: /home/ruben/Projects/Cura/cura/UI/ObjectsModel.py:62
#, python-brace-format
msgctxt "@label"
msgid "Group #{group_nr}"
msgstr "Gruppo #{group_nr}"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:65
-msgctxt "@info:title"
-msgid "Network enabled printers"
-msgstr "Stampanti abilitate per la rete"
+#: /home/ruben/Projects/Cura/cura/UI/WhatsNewPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:482
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:124
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:169
+msgctxt "@action:button"
+msgid "Close"
+msgstr "Chiudi"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/MachineManagementModel.py:80
-msgctxt "@info:title"
-msgid "Local printers"
-msgstr "Stampanti locali"
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:17
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
+msgctxt "@action:button"
+msgid "Add"
+msgstr "Aggiungi"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:109
+#: /home/ruben/Projects/Cura/cura/UI/AddPrinterPagesModel.py:18
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:81
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:352
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:58
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:149
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:188
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:406
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:294
+msgctxt "@action:button"
+msgid "Cancel"
+msgstr "Annulla"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:36
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:320
+msgctxt "@label"
+msgid "Default"
+msgstr "Default"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:39
+msgctxt "@label"
+msgid "Visual"
+msgstr "Visivo"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:40
+msgctxt "@text"
+msgid "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality."
+msgstr "Il profilo visivo è destinato alla stampa di prototipi e modelli visivi, con l'intento di ottenere una qualità visiva e della superficie elevata."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:43
+msgctxt "@label"
+msgid "Engineering"
+msgstr "Engineering"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:44
+msgctxt "@text"
+msgid "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances."
+msgstr "Il profilo di progettazione è destinato alla stampa di prototipi funzionali e di componenti d'uso finale, allo scopo di ottenere maggiore precisione e"
+" tolleranze strette."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:47
+msgctxt "@label"
+msgid "Draft"
+msgstr "Bozza"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/IntentCategoryModel.py:48
+msgctxt "@text"
+msgid "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction."
+msgstr "Il profilo bozza è destinato alla stampa dei prototipi iniziali e alla convalida dei concept, con l'intento di ridurre in modo significativo il tempo di"
+" stampa."
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/ExtrudersModel.py:208
+msgctxt "@menuitem"
+msgid "Not overridden"
+msgstr "Non sottoposto a override"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:357
+msgctxt "@label"
+msgid "Custom profiles"
+msgstr "Profili personalizzati"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:391
#, python-brace-format
msgctxt "@item:inlistbox"
msgid "All Supported Types ({0})"
msgstr "Tutti i tipi supportati ({0})"
-#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:110
+#: /home/ruben/Projects/Cura/cura/Machines/Models/QualityManagementModel.py:392
msgctxt "@item:inlistbox"
msgid "All Files (*)"
msgstr "Tutti i file (*)"
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:636
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:213
msgctxt "@label"
msgid "Custom Material"
msgstr "Materiale personalizzato"
-#: /home/ruben/Projects/Cura/cura/Machines/MaterialManager.py:637
+#: /home/ruben/Projects/Cura/cura/Machines/Models/MaterialManagementModel.py:214
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:205
msgctxt "@label"
msgid "Custom"
msgstr "Personalizzata"
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:81
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:116
+msgctxt "@label"
+msgid "The printer(s) below cannot be connected because they are part of a group"
+msgstr "Le stampanti riportate di seguito non possono essere collegate perché fanno parte di un gruppo"
+
+#: /home/ruben/Projects/Cura/cura/Machines/Models/DiscoveredPrintersModel.py:118
+msgctxt "@label"
+msgid "Available networked printers"
+msgstr "Stampanti disponibili in rete"
+
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:90
msgctxt "@info:status"
msgid "The build volume height has been reduced due to the value of the \"Print Sequence\" setting to prevent the gantry from colliding with printed models."
msgstr "L’altezza del volume di stampa è stata ridotta a causa del valore dell’impostazione \"Sequenza di stampa” per impedire la collisione del gantry con i modelli stampati."
-#: /home/ruben/Projects/Cura/cura/BuildVolume.py:83
+#: /home/ruben/Projects/Cura/cura/BuildVolume.py:92
msgctxt "@info:title"
msgid "Build Volume"
msgstr "Volume di stampa"
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:98
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:99
msgctxt "@info:backup_failed"
msgid "Could not create archive from user data directory: {}"
msgstr "Impossibile creare un archivio dalla directory dei dati utente: {}"
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:103
-msgctxt "@info:title"
-msgid "Backup"
-msgstr "Backup"
-
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:113
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:114
msgctxt "@info:backup_failed"
msgid "Tried to restore a Cura backup without having proper data or meta data."
msgstr "Tentativo di ripristinare un backup di Cura senza dati o metadati appropriati."
-#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:123
+#: /home/ruben/Projects/Cura/cura/Backups/Backup.py:125
msgctxt "@info:backup_failed"
-msgid "Tried to restore a Cura backup that does not match your current version."
-msgstr "Tentativo di ripristinare un backup di Cura non corrispondente alla versione corrente."
+msgid "Tried to restore a Cura backup that is higher than the current version."
+msgstr "Tentativo di ripristinare un backup di Cura di versione superiore rispetto a quella corrente."
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:27
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationHelpers.py:79
+msgctxt "@message"
+msgid "Could not read response."
+msgstr "Impossibile leggere la risposta."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationService.py:201
+msgctxt "@info"
+msgid "Unable to reach the Ultimaker account server."
+msgstr "Impossibile raggiungere il server account Ultimaker."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:70
+msgctxt "@message"
+msgid "Please give the required permissions when authorizing this application."
+msgstr "Fornire i permessi necessari al momento dell'autorizzazione di questa applicazione."
+
+#: /home/ruben/Projects/Cura/cura/OAuth2/AuthorizationRequestHandler.py:77
+msgctxt "@message"
+msgid "Something unexpected happened when trying to log in, please try again."
+msgstr "Si è verificato qualcosa di inatteso durante il tentativo di accesso, riprovare."
+
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:29
msgctxt "@info:status"
msgid "Multiplying and placing objects"
msgstr "Moltiplicazione e collocazione degli oggetti"
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:28
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:30
msgctxt "@info:title"
-msgid "Placing Object"
-msgstr "Sistemazione oggetto"
+msgid "Placing Objects"
+msgstr "Sistemazione oggetti"
-#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:100
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:96
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:103
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:149
msgctxt "@info:status"
msgid "Unable to find a location within the build volume for all objects"
msgstr "Impossibile individuare una posizione nel volume di stampa per tutti gli oggetti"
+#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:108
+msgctxt "@info:title"
+msgid "Placing Object"
+msgstr "Sistemazione oggetto"
+
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:30
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:67
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:66
msgctxt "@info:status"
msgid "Finding new location for objects"
msgstr "Ricerca nuova posizione per gli oggetti"
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:34
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:71
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:70
msgctxt "@info:title"
msgid "Finding Location"
msgstr "Ricerca posizione"
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:97
-#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:151
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:104
+#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsAllBuildPlatesJob.py:150
msgctxt "@info:title"
msgid "Can't Find Location"
msgstr "Impossibile individuare posizione"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:87
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:83
msgctxt "@title:window"
msgid "Cura can't start"
msgstr "Impossibile avviare Cura"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:93
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:89
msgctxt "@label crash message"
msgid ""
"
Oops, Ultimaker Cura has encountered something that doesn't seem right.
\n"
@@ -1069,356 +1161,328 @@ msgid ""
"
Backups can be found in the configuration folder.
\n"
"
Please send us this Crash Report to fix the problem.
\n"
" "
-msgstr "
Oops, Ultimaker Cura ha rilevato qualcosa che non sembra corretto.
\n
Abbiamo riscontrato un errore irrecuperabile durante l’avvio. È stato probabilmente causato da alcuni file di configurazione errati. Suggeriamo di effettuare il backup e ripristinare la configurazione.
\n
I backup sono contenuti nella cartella configurazione.
\n
Si prega di inviare questo Rapporto su crash per correggere il problema.
\n "
+msgstr ""
+"
Oops, Ultimaker Cura ha rilevato qualcosa che non sembra corretto.
\n"
+"
Abbiamo riscontrato un errore irrecuperabile durante l’avvio. È stato probabilmente causato da alcuni file di configurazione errati. Suggeriamo di effettuare il backup e ripristinare la configurazione.
\n"
+"
I backup sono contenuti nella cartella configurazione.
\n"
+"
Si prega di inviare questo Rapporto su crash per correggere il problema.
\n"
+" "
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:102
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:98
msgctxt "@action:button"
msgid "Send crash report to Ultimaker"
msgstr "Inviare il rapporto su crash a Ultimaker"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:105
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:101
msgctxt "@action:button"
msgid "Show detailed crash report"
msgstr "Mostra il rapporto su crash dettagliato"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:109
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:105
msgctxt "@action:button"
msgid "Show configuration folder"
msgstr "Mostra cartella di configurazione"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:120
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:116
msgctxt "@action:button"
msgid "Backup and Reset Configuration"
msgstr "Backup e reset configurazione"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:149
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:145
msgctxt "@title:window"
msgid "Crash Report"
msgstr "Rapporto su crash"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:169
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:165
msgctxt "@label crash message"
msgid ""
"
A fatal error has occurred in Cura. Please send us this Crash Report to fix the problem
\n"
"
Please use the \"Send report\" button to post a bug report automatically to our servers
\n"
" "
-msgstr "
Si è verificato un errore fatale in Cura. Si prega di inviare questo Rapporto su crash per correggere il problema
\n
Usare il pulsante “Invia report\" per inviare automaticamente una segnalazione errore ai nostri server
\n "
+msgstr ""
+"
Si è verificato un errore fatale in Cura. Si prega di inviare questo Rapporto su crash per correggere il problema
\n"
+"
Usare il pulsante “Invia report\" per inviare automaticamente una segnalazione errore ai nostri server
"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:222
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:218
msgctxt "@title:groupbox"
msgid "Error traceback"
msgstr "Analisi errori"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:303
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:299
msgctxt "@title:groupbox"
msgid "Logs"
msgstr "Registri"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:326
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:322
msgctxt "@title:groupbox"
-msgid "User description"
-msgstr "Descrizione utente"
+msgid "User description (Note: Developers may not speak your language, please use English if possible)"
+msgstr "Descrizione utente (Nota: gli sviluppatori potrebbero non parlare la lingua dell'utente. Se possibile, usare l'inglese)"
-#: /home/ruben/Projects/Cura/cura/CrashHandler.py:345
+#: /home/ruben/Projects/Cura/cura/CrashHandler.py:342
msgctxt "@action:button"
msgid "Send report"
msgstr "Invia report"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:473
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:513
msgctxt "@info:progress"
msgid "Loading machines..."
msgstr "Caricamento macchine in corso..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:775
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:520
+msgctxt "@info:progress"
+msgid "Setting up preferences..."
+msgstr "Impostazione delle preferenze..."
+
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:824
msgctxt "@info:progress"
msgid "Setting up scene..."
msgstr "Impostazione scena in corso..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:811
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:859
msgctxt "@info:progress"
msgid "Loading interface..."
msgstr "Caricamento interfaccia in corso..."
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1037
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1150
#, python-format
msgctxt "@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm."
msgid "%(width).1f x %(depth).1f x %(height).1f mm"
msgstr "%(width).1f x %(depth).1f x %(height).1f mm"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1596
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1657
#, python-brace-format
msgctxt "@info:status"
msgid "Only one G-code file can be loaded at a time. Skipped importing {0}"
msgstr "È possibile caricare un solo file codice G per volta. Importazione saltata {0}"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1606
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1667
#, python-brace-format
msgctxt "@info:status"
msgid "Can't open any other file if G-code is loading. Skipped importing {0}"
msgstr "Impossibile aprire altri file durante il caricamento del codice G. Importazione saltata {0}"
-#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1694
+#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1757
msgctxt "@info:status"
msgid "The selected model was too small to load."
msgstr "Il modello selezionato è troppo piccolo per il caricamento."
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:61
-msgctxt "@title"
-msgid "Machine Settings"
-msgstr "Impostazioni macchina"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:80
-msgctxt "@title:tab"
-msgid "Printer"
-msgstr "Stampante"
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:99
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:56
+msgctxt "@title:label"
msgid "Printer Settings"
msgstr "Impostazioni della stampante"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:110
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:70
msgctxt "@label"
msgid "X (Width)"
msgstr "X (Larghezza)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:111
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:121
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:131
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:237
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:386
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:402
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:428
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:440
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:896
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:74
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:88
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:102
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:243
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:265
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:285
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:79
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:93
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:109
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:124
msgctxt "@label"
msgid "mm"
msgstr "mm"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:120
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:84
msgctxt "@label"
msgid "Y (Depth)"
msgstr "Y (Profondità)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:130
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:98
msgctxt "@label"
msgid "Z (Height)"
msgstr "Z (Altezza)"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:142
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:112
msgctxt "@label"
msgid "Build plate shape"
msgstr "Forma del piano di stampa"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:151
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:125
+msgctxt "@label"
msgid "Origin at center"
msgstr "Origine al centro"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:159
-msgctxt "@option:check"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:137
+msgctxt "@label"
msgid "Heated bed"
msgstr "Piano riscaldato"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:170
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:149
+msgctxt "@label"
+msgid "Heated build volume"
+msgstr "Volume di stampa riscaldato"
+
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:161
msgctxt "@label"
msgid "G-code flavor"
msgstr "Versione codice G"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:183
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:185
+msgctxt "@title:label"
msgid "Printhead Settings"
msgstr "Impostazioni della testina di stampa"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:193
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:199
msgctxt "@label"
msgid "X min"
msgstr "X min"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:194
-msgctxt "@tooltip"
-msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distanza tra il lato sinistro della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:203
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:219
msgctxt "@label"
msgid "Y min"
msgstr "Y min"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:204
-msgctxt "@tooltip"
-msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distanza tra il lato anteriore della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:213
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:239
msgctxt "@label"
msgid "X max"
msgstr "X max"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:214
-msgctxt "@tooltip"
-msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distanza tra il lato destro della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:223
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:261
msgctxt "@label"
msgid "Y max"
msgstr "Y max"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:224
-msgctxt "@tooltip"
-msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distanza tra il lato posteriore della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:236
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:281
msgctxt "@label"
-msgid "Gantry height"
+msgid "Gantry Height"
msgstr "Altezza gantry"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:238
-msgctxt "@tooltip"
-msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
-msgstr "La differenza di altezza tra la punta dell’ugello e il sistema gantry (assi X e Y). Utilizzata per evitare collisioni tra le stampe precedenti e il gantry durante la stampa \"Uno alla volta\"."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:257
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:295
msgctxt "@label"
msgid "Number of Extruders"
msgstr "Numero di estrusori"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:313
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:355
+msgctxt "@title:label"
msgid "Start G-code"
msgstr "Codice G avvio"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:323
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very start."
-msgstr "Comandi codice G da eseguire all’avvio."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:332
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml:366
+msgctxt "@title:label"
msgid "End G-code"
msgstr "Codice G fine"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:342
-msgctxt "@tooltip"
-msgid "G-code commands to be executed at the very end."
-msgstr "Comandi codice G da eseguire alla fine."
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:42
+msgctxt "@title:tab"
+msgid "Printer"
+msgstr "Stampante"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:373
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:63
+msgctxt "@title:label"
msgid "Nozzle Settings"
msgstr "Impostazioni ugello"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:385
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:75
msgctxt "@label"
msgid "Nozzle size"
msgstr "Dimensione ugello"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:401
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:89
msgctxt "@label"
msgid "Compatible material diameter"
msgstr "Diametro del materiale compatibile"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:403
-msgctxt "@tooltip"
-msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
-msgstr "Diametro nominale del filamento supportato dalla stampante. Il diametro esatto verrà sovrapposto dal materiale e/o dal profilo."
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:427
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:105
msgctxt "@label"
msgid "Nozzle offset X"
msgstr "Scostamento X ugello"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:439
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:120
msgctxt "@label"
msgid "Nozzle offset Y"
msgstr "Scostamento Y ugello"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:451
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:135
msgctxt "@label"
msgid "Cooling Fan Number"
msgstr "Numero ventola di raffreddamento"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:452
-msgctxt "@label"
-msgid ""
-msgstr ""
-
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:472
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:162
+msgctxt "@title:label"
msgid "Extruder Start G-code"
msgstr "Codice G avvio estrusore"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:490
-msgctxt "@label"
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml:176
+msgctxt "@title:label"
msgid "Extruder End G-code"
msgstr "Codice G fine estrusore"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:18
msgctxt "@action:button"
msgid "Install"
msgstr "Installazione"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxProgressButton.qml:20
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
msgctxt "@action:button"
msgid "Installed"
msgstr "Installa"
@@ -1428,69 +1492,82 @@ msgctxt "@info"
msgid "Could not connect to the Cura Package database. Please check your connection."
msgstr "Impossibile connettersi al database pacchetto Cura. Verificare la connessione."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:38
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:28
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/SmallRatingWidget.qml:27
+msgctxt "@label"
+msgid "ratings"
+msgstr "valori"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:30
msgctxt "@title:tab"
msgid "Plugins"
msgstr "Plugin"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:75
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:42
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:66
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml:77
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:44
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:89
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:417
msgctxt "@title:tab"
msgid "Materials"
msgstr "Materiali"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:79
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+msgctxt "@label"
+msgid "Your rating"
+msgstr "I tuoi valori"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:99
msgctxt "@label"
msgid "Version"
msgstr "Versione"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:85
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:106
msgctxt "@label"
msgid "Last updated"
msgstr "Ultimo aggiornamento"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:91
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:113
msgctxt "@label"
msgid "Author"
msgstr "Autore"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:120
msgctxt "@label"
msgid "Downloads"
msgstr "Download"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:116
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml:158
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:258
-msgctxt "@label"
-msgid "Unknown"
-msgstr "Sconosciuto"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:56
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to install or update"
+msgstr "Log in deve essere installato o aggiornato"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:44
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:30
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:80
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Buy material spools"
+msgstr "Acquista bobine di materiale"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:96
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:34
msgctxt "@action:button"
msgid "Update"
msgstr "Aggiorna"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:45
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:97
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:35
msgctxt "@action:button"
msgid "Updating"
msgstr "Aggiornamento in corso"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:46
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:32
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDetailTileActions.qml:98
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:36
msgctxt "@action:button"
msgid "Updated"
msgstr "Aggiornamento eseguito"
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/Toolbox.qml:13
msgctxt "@title"
-msgid "Toolbox"
-msgstr "Casella degli strumenti"
+msgid "Marketplace"
+msgstr "Mercato"
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml:25
msgctxt "@action:button"
@@ -1517,52 +1594,67 @@ msgctxt "@text:window"
msgid "Profiles"
msgstr "Profili"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:89
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxConfirmUninstallResetDialog.qml:90
msgctxt "@action:button"
msgid "Confirm"
msgstr "Conferma"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:17
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to login first before you can rate"
+msgstr "Prima della valutazione è necessario effettuare l’accesso"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/RatingWidget.qml:54
+msgctxt "@label"
+msgid "You need to install the package before you can rate"
+msgstr "Prima della valutazione è necessario installare il pacchetto"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:19
msgctxt "@info"
msgid "You will need to restart Cura before changes in packages have effect."
msgstr "Riavviare Cura per rendere effettive le modifiche apportate ai pacchetti."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxFooter.qml:45
msgctxt "@info:button"
msgid "Quit Cura"
msgstr "Esci da Cura"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Contributions"
msgstr "Contributi della comunità"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:34
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:31
msgctxt "@label"
msgid "Community Plugins"
msgstr "Plugin della comunità"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:43
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml:40
msgctxt "@label"
msgid "Generic Materials"
msgstr "Materiali generici"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:56
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxHeader.qml:59
msgctxt "@title:tab"
msgid "Installed"
msgstr "Installa"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:19
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:22
msgctxt "@label"
msgid "Will install upon restarting"
msgstr "L'installazione sarà eseguita al riavvio"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:53
+msgctxt "@label:The string between and is the highlighted link"
+msgid "Log in is required to update"
+msgstr "Log in deve essere aggiornato"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Downgrade"
msgstr "Downgrade"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:51
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxInstalledTileActions.qml:71
msgctxt "@action:button"
msgid "Uninstall"
msgstr "Disinstalla"
@@ -1578,14 +1670,17 @@ msgid ""
"This plugin contains a license.\n"
"You need to accept this license to install this plugin.\n"
"Do you agree with the terms below?"
-msgstr "Questo plugin contiene una licenza.\nÈ necessario accettare questa licenza per poter installare il plugin.\nAccetti i termini sotto riportati?"
+msgstr ""
+"Questo plugin contiene una licenza.\n"
+"È necessario accettare questa licenza per poter installare il plugin.\n"
+"Accetti i termini sotto riportati?"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:54
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:55
msgctxt "@action:button"
msgid "Accept"
msgstr "Accetto"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:65
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml:66
msgctxt "@action:button"
msgid "Decline"
msgstr "Non accetto"
@@ -1595,22 +1690,62 @@ msgctxt "@label"
msgid "Featured"
msgstr "In primo piano"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:31
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:34
msgctxt "@label"
msgid "Compatibility"
msgstr "Compatibilità"
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:124
+msgctxt "@label:table_header"
+msgid "Machine"
+msgstr "Macchina"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:137
+msgctxt "@label:table_header"
+msgid "Build Plate"
+msgstr "Piano di stampa"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:143
+msgctxt "@label:table_header"
+msgid "Support"
+msgstr "Supporto"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:149
+msgctxt "@label:table_header"
+msgid "Quality"
+msgstr "Qualità"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:170
+msgctxt "@action:label"
+msgid "Technical Data Sheet"
+msgstr "Scheda dati tecnici"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:179
+msgctxt "@action:label"
+msgid "Safety Data Sheet"
+msgstr "Scheda dati di sicurezza"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:188
+msgctxt "@action:label"
+msgid "Printing Guidelines"
+msgstr "Linee guida di stampa"
+
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxCompatibilityChart.qml:197
+msgctxt "@action:label"
+msgid "Website"
+msgstr "Sito web"
+
#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml:16
msgctxt "@info"
msgid "Fetching packages..."
msgstr "Recupero dei pacchetti..."
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:88
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:91
msgctxt "@label"
msgid "Website"
msgstr "Sito web"
-#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:94
+#: /home/ruben/Projects/Cura/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml:98
msgctxt "@label"
msgid "Email"
msgstr "E-mail"
@@ -1620,23 +1755,6 @@ msgctxt "@info:tooltip"
msgid "Some things could be problematic in this print. Click to see tips for adjustment."
msgstr "Alcune parti potrebbero risultare problematiche in questa stampa. Fare click per visualizzare i suggerimenti per la regolazione."
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18
-msgctxt "@label"
-msgid "Changelog"
-msgstr "Registro modifiche"
-
-#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:37
-#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:185
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:53
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:467
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:514
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:121
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:166
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:38
-msgctxt "@action:button"
-msgid "Close"
-msgstr "Chiudi"
-
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml:31
msgctxt "@title"
msgid "Update Firmware"
@@ -1712,423 +1830,505 @@ msgctxt "@label"
msgid "Firmware update failed due to missing firmware."
msgstr "Aggiornamento firmware non riuscito per firmware mancante."
-#: /home/ruben/Projects/Cura/plugins/UserAgreement/UserAgreement.qml:16
-msgctxt "@title:window"
-msgid "User Agreement"
-msgstr "Contratto di licenza"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:155
+msgctxt "@label link to Connect and Cloud interfaces"
+msgid "Manage printer"
+msgstr "Gestione stampanti"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:46
-msgctxt "@window:title"
-msgid "Existing Connection"
-msgstr "Collegamento esistente"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:192
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:183
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:153
+msgctxt "@label"
+msgid "Glass"
+msgstr "Vetro"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:48
-msgctxt "@message:text"
-msgid "This printer/group is already added to Cura. Please select another printer/group."
-msgstr "Stampante/gruppo già aggiunto a Cura. Selezionare un’altra stampante o un altro gruppo."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:256
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:514
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:248
+msgctxt "@info"
+msgid "Please update your printer's firmware to manage the queue remotely."
+msgstr "Aggiornare il firmware della stampante per gestire la coda da remoto."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:65
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:289
+msgctxt "@info"
+msgid "The webcam is not available because you are monitoring a cloud printer."
+msgstr "La webcam non è disponibile perché si sta controllando una stampante cloud."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:348
+msgctxt "@label:status"
+msgid "Loading..."
+msgstr "Caricamento in corso..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:352
+msgctxt "@label:status"
+msgid "Unavailable"
+msgstr "Non disponibile"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:356
+msgctxt "@label:status"
+msgid "Unreachable"
+msgstr "Non raggiungibile"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:360
+msgctxt "@label:status"
+msgid "Idle"
+msgstr "Ferma"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:401
+msgctxt "@label"
+msgid "Untitled"
+msgstr "Senza titolo"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:422
+msgctxt "@label"
+msgid "Anonymous"
+msgstr "Anonimo"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:449
+msgctxt "@label:status"
+msgid "Requires configuration changes"
+msgstr "Richiede modifiche di configurazione"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml:487
+msgctxt "@action:button"
+msgid "Details"
+msgstr "Dettagli"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:132
+msgctxt "@label"
+msgid "Unavailable printer"
+msgstr "Stampante non disponibile"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobCard.qml:134
+msgctxt "@label"
+msgid "First available"
+msgstr "Primo disponibile"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:31
+msgctxt "@label"
+msgid "Queued"
+msgstr "Coda di stampa"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:67
+msgctxt "@label link to connect manager"
+msgid "Manage in browser"
+msgstr "Gestisci nel browser"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:100
+msgctxt "@label"
+msgid "There are no print jobs in the queue. Slice and send a job to add one."
+msgstr "Non sono presenti processi di stampa nella coda. Eseguire lo slicing e inviare un processo per aggiungerne uno."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:115
+msgctxt "@label"
+msgid "Print jobs"
+msgstr "Processi di stampa"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:131
+msgctxt "@label"
+msgid "Total print time"
+msgstr "Tempo di stampa totale"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml:147
+msgctxt "@label"
+msgid "Waiting for"
+msgstr "In attesa"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:45
msgctxt "@title:window"
msgid "Connect to Networked Printer"
msgstr "Collega alla stampante in rete"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:75
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
msgctxt "@label"
-msgid ""
-"To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
-"\n"
-"Select your printer from the list below:"
-msgstr "Per stampare direttamente sulla stampante in rete, verificare che la stampante desiderata sia collegata alla rete mediante un cavo di rete o mediante collegamento alla rete WIFI. Se si collega Cura alla stampante, è comunque possibile utilizzare una chiavetta USB per trasferire i file codice G alla stampante.\n\nSelezionare la stampante dall’elenco seguente:"
+msgid "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer."
+msgstr "Per stampare direttamente sulla stampante in rete, verificare che la stampante desiderata sia collegata alla rete mediante un cavo di rete o mediante collegamento alla rete WIFI. Se non si esegue il collegamento di Cura alla stampante, è comunque possibile utilizzare una chiavetta USB per trasferire i file codice G alla stampante."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:85
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:42
-msgctxt "@action:button"
-msgid "Add"
-msgstr "Aggiungi"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:57
+msgctxt "@label"
+msgid "Select your printer from the list below:"
+msgstr "Selezionare la stampante dall’elenco seguente:"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:95
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:77
msgctxt "@action:button"
msgid "Edit"
msgstr "Modifica"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:106
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:128
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:48
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:117
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:88
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:138
msgctxt "@action:button"
msgid "Remove"
msgstr "Rimuovi"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:114
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:96
msgctxt "@action:button"
msgid "Refresh"
msgstr "Aggiorna"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:207
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:176
msgctxt "@label"
msgid "If your printer is not listed, read the network printing troubleshooting guide"
msgstr "Se la stampante non è nell’elenco, leggere la guida alla risoluzione dei problemi per la stampa in rete"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:234
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:205
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:258
msgctxt "@label"
msgid "Type"
msgstr "Tipo"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:271
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:274
msgctxt "@label"
msgid "Firmware version"
msgstr "Versione firmware"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:290
msgctxt "@label"
msgid "Address"
msgstr "Indirizzo"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:305
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:263
msgctxt "@label"
msgid "This printer is not set up to host a group of printers."
msgstr "Questa stampante non è predisposta per comandare un gruppo di stampanti."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:309
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:267
msgctxt "@label"
msgid "This printer is the host for a group of %1 printers."
msgstr "Questa stampante comanda un gruppo di %1 stampanti."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:319
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:278
msgctxt "@label"
msgid "The printer at this address has not yet responded."
msgstr "La stampante a questo indirizzo non ha ancora risposto."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:324
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:283
msgctxt "@action:button"
msgid "Connect"
msgstr "Collega"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:338
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:296
+msgctxt "@title:window"
+msgid "Invalid IP address"
+msgstr "Indirizzo IP non valido"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:146
+msgctxt "@text"
+msgid "Please enter a valid IP address."
+msgstr "Inserire un indirizzo IP valido."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:308
msgctxt "@title:window"
msgid "Printer Address"
msgstr "Indirizzo stampante"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
-msgctxt "@alabel"
-msgid "Enter the IP address or hostname of your printer on the network."
-msgstr "Inserire l’indirizzo IP o l’hostname della stampante sulla rete."
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:102
+msgctxt "@label"
+msgid "Enter the IP address of your printer on the network."
+msgstr "Inserire l'indirizzo IP della stampante in rete."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:390
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:132
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml:361
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:138
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:181
msgctxt "@action:button"
msgid "OK"
msgstr "OK"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:44
-msgctxt "@action:button"
-msgid "Print"
-msgstr "Stampa"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:47
-msgctxt "@title:window"
-msgid "Print over network"
-msgstr "Stampa sulla rete"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:79
-msgctxt "@label"
-msgid "Printer selection"
-msgstr "Selezione stampante"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:173
-msgctxt "@label"
-msgid "Not available"
-msgstr "Non disponibile"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:175
-msgctxt "@label"
-msgid "Unreachable"
-msgstr "Non raggiungibile"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCard.qml:180
-msgctxt "@label"
-msgid "Available"
-msgstr "Disponibile"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:37
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:44
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:46
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:78
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:90
msgctxt "@label:status"
msgid "Aborted"
msgstr "Interrotto"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:39
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:80
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:82
msgctxt "@label:status"
msgid "Finished"
msgstr "Terminato"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:42
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:84
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:86
msgctxt "@label:status"
-msgid "Preparing"
-msgstr "Preparazione in corso"
+msgid "Preparing..."
+msgstr "Preparazione in corso..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:48
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:88
msgctxt "@label:status"
-msgid "Pausing"
-msgstr "Messa in pausa"
+msgid "Aborting..."
+msgstr "Interr. in corso..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:52
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:92
msgctxt "@label:status"
-msgid "Resuming"
-msgstr "Ripresa"
+msgid "Pausing..."
+msgstr "Messa in pausa..."
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrinterCardProgressBar.qml:54
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:94
+msgctxt "@label:status"
+msgid "Paused"
+msgstr "In pausa"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:96
+msgctxt "@label:status"
+msgid "Resuming..."
+msgstr "Ripresa in corso..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:98
msgctxt "@label:status"
msgid "Action required"
msgstr "Richiede un'azione"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:213
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobProgressBar.qml:100
+msgctxt "@label:status"
+msgid "Finishes %1 at %2"
+msgstr "Finisce %1 a %2"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:11
+msgctxt "@title:window"
+msgid "Print over network"
+msgstr "Stampa sulla rete"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:52
+msgctxt "@action:button"
+msgid "Print"
+msgstr "Stampa"
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintWindow.qml:80
msgctxt "@label"
-msgid "Waiting for: Unavailable printer"
-msgstr "In attesa: stampante non disponibile"
+msgid "Printer selection"
+msgstr "Selezione stampante"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:215
-msgctxt "@label"
-msgid "Waiting for: First available"
-msgstr "In attesa della prima disponibile"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:217
-msgctxt "@label"
-msgid "Waiting for: "
-msgstr "In attesa: "
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:299
-msgctxt "@label"
-msgid "Configuration change"
-msgstr "Modifica configurazione"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:365
-msgctxt "@label"
-msgid "The assigned printer, %1, requires the following configuration change(s):"
-msgstr "La stampante assegnata, %1, richiede le seguenti modifiche di configurazione:"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:367
-msgctxt "@label"
-msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
-msgstr "La stampante %1 è assegnata, ma il processo contiene una configurazione materiale sconosciuta."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:375
-msgctxt "@label"
-msgid "Change material %1 from %2 to %3."
-msgstr "Cambia materiale %1 da %2 a %3."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:378
-msgctxt "@label"
-msgid "Load %3 as material %1 (This cannot be overridden)."
-msgstr "Caricare %3 come materiale %1 (Operazione non annullabile)."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:381
-msgctxt "@label"
-msgid "Change print core %1 from %2 to %3."
-msgstr "Cambia print core %1 da %2 a %3."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:384
-msgctxt "@label"
-msgid "Change build plate to %1 (This cannot be overridden)."
-msgstr "Cambia piano di stampa a %1 (Operazione non annullabile)."
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:404
-msgctxt "@label"
-msgid "Override"
-msgstr "Override"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:432
-msgctxt "@label"
-msgid "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?"
-msgstr "L’avvio di un processo di stampa con una configurazione non compatibile potrebbe danneggiare la stampante 3D. Sei sicuro di voler annullare la configurazione e stampare %1?"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:435
-msgctxt "@window:title"
-msgid "Override configuration configuration and start print"
-msgstr "Annullare la configurazione e avviare la stampa"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:466
-msgctxt "@label"
-msgid "Glass"
-msgstr "Vetro"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml:469
-msgctxt "@label"
-msgid "Aluminum"
-msgstr "Alluminio"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:39
-msgctxt "@label link to connect manager"
-msgid "Manage queue"
-msgstr "Gestione coda di stampa"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml:60
-msgctxt "@label"
-msgid "Queued"
-msgstr "Coda di stampa"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:36
-msgctxt "@label"
-msgid "Printing"
-msgstr "Stampa in corso"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml:49
-msgctxt "@label link to connect manager"
-msgid "Manage printers"
-msgstr "Gestione stampanti"
-
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:115
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:54
msgctxt "@label"
msgid "Move to top"
msgstr "Sposta in alto"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:124
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:70
msgctxt "@label"
msgid "Delete"
msgstr "Cancella"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:100
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:289
msgctxt "@label"
msgid "Resume"
msgstr "Riprendi"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:137
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:102
+msgctxt "@label"
+msgid "Pausing..."
+msgstr "Messa in pausa..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:104
+msgctxt "@label"
+msgid "Resuming..."
+msgstr "Ripresa in corso..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:106
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:284
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:293
msgctxt "@label"
msgid "Pause"
msgstr "Pausa"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:146
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
+msgctxt "@label"
+msgid "Aborting..."
+msgstr "Interr. in corso..."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:124
msgctxt "@label"
msgid "Abort"
msgstr "Interrompi"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:178
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:143
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to move %1 to the top of the queue?"
-msgstr "Sei sicuro di voler spostare 1% all’inizio della coda?"
+msgstr "Sei sicuro di voler spostare %1 all’inizio della coda?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:179
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:144
msgctxt "@window:title"
msgid "Move print job to top"
msgstr "Sposta il processo di stampa in alto"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:188
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:153
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to delete %1?"
msgstr "Sei sicuro di voler cancellare %1?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:189
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:154
msgctxt "@window:title"
msgid "Delete print job"
msgstr "Cancella processo di stampa"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:198
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:163
msgctxt "@label %1 is the name of a print job."
msgid "Are you sure you want to abort %1?"
msgstr "Sei sicuro di voler interrompere %1?"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/PrintJobContextMenu.qml:199
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorContextMenu.qml:164
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:335
msgctxt "@window:title"
msgid "Abort print"
msgstr "Interrompi la stampa"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:43
-msgctxt "@info:tooltip"
-msgid "Connect to a printer"
-msgstr "Collega a una stampante"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:20
+msgctxt "@title:window"
+msgid "Configuration Changes"
+msgstr "Modifiche configurazione"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:121
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:27
msgctxt "@action:button"
-msgid "Activate Configuration"
-msgstr "Attiva la configurazione"
+msgid "Override"
+msgstr "Override"
-#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/UM3InfoComponents.qml:122
-msgctxt "@info:tooltip"
-msgid "Load the configuration of the printer into Cura"
-msgstr "Carica la configurazione della stampante in Cura"
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:85
+msgctxt "@label"
+msgid "The assigned printer, %1, requires the following configuration change:"
+msgid_plural "The assigned printer, %1, requires the following configuration changes:"
+msgstr[0] "La stampante assegnata, %1, richiede la seguente modifica di configurazione:"
+msgstr[1] "La stampante assegnata, %1, richiede le seguenti modifiche di configurazione:"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:130
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:89
+msgctxt "@label"
+msgid "The printer %1 is assigned, but the job contains an unknown material configuration."
+msgstr "La stampante %1 è assegnata, ma il processo contiene una configurazione materiale sconosciuta."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:99
+msgctxt "@label"
+msgid "Change material %1 from %2 to %3."
+msgstr "Cambia materiale %1 da %2 a %3."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:102
+msgctxt "@label"
+msgid "Load %3 as material %1 (This cannot be overridden)."
+msgstr "Caricare %3 come materiale %1 (Operazione non annullabile)."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:105
+msgctxt "@label"
+msgid "Change print core %1 from %2 to %3."
+msgstr "Cambia print core %1 da %2 a %3."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:108
+msgctxt "@label"
+msgid "Change build plate to %1 (This cannot be overridden)."
+msgstr "Cambia piano di stampa a %1 (Operazione non annullabile)."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:115
+msgctxt "@label"
+msgid "Override will use the specified settings with the existing printer configuration. This may result in a failed print."
+msgstr "L’override utilizza le impostazioni specificate con la configurazione stampante esistente. Ciò può causare una stampa non riuscita."
+
+#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/resources/qml/MonitorConfigOverrideDialog.qml:156
+msgctxt "@label"
+msgid "Aluminum"
+msgstr "Alluminio"
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:100
+msgctxt "@info"
+msgid ""
+"Please make sure your printer has a connection:\n"
+"- Check if the printer is turned on.\n"
+"- Check if the printer is connected to the network.\n"
+"- Check if you are signed in to discover cloud-connected printers."
+msgstr ""
+"Accertarsi che la stampante sia collegata:\n"
+"- Controllare se la stampante è accesa.\n"
+"- Controllare se la stampante è collegata alla rete.\n"
+"- Controllare se è stato effettuato l'accesso per rilevare le stampanti collegate al cloud."
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:117
+msgctxt "@info"
+msgid "Please connect your printer to the network."
+msgstr "Collegare la stampante alla rete."
+
+#: /home/ruben/Projects/Cura/plugins/MonitorStage/MonitorMain.qml:156
+msgctxt "@label link to technical assistance"
+msgid "View user manuals online"
+msgstr "Visualizza i manuali utente online"
+
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:20
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:49
msgctxt "@label"
msgid "Color scheme"
msgstr "Schema colori"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:145
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:107
msgctxt "@label:listbox"
msgid "Material Color"
msgstr "Colore materiale"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:149
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:111
msgctxt "@label:listbox"
msgid "Line Type"
msgstr "Tipo di linea"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:153
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:115
msgctxt "@label:listbox"
msgid "Feedrate"
msgstr "Velocità"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:157
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:119
msgctxt "@label:listbox"
msgid "Layer thickness"
msgstr "Spessore strato"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:198
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:156
msgctxt "@label"
msgid "Compatibility Mode"
msgstr "Modalità di compatibilità"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:284
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:230
msgctxt "@label"
-msgid "Show Travels"
-msgstr "Mostra spostamenti"
+msgid "Travels"
+msgstr "Spostamenti"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:290
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:236
msgctxt "@label"
-msgid "Show Helpers"
-msgstr "Mostra helper"
+msgid "Helpers"
+msgstr "Helper"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:296
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:242
msgctxt "@label"
-msgid "Show Shell"
-msgstr "Mostra guscio"
+msgid "Shell"
+msgstr "Guscio"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:302
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:248
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:65
msgctxt "@label"
-msgid "Show Infill"
-msgstr "Mostra riempimento"
+msgid "Infill"
+msgstr "Riempimento"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:355
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:298
msgctxt "@label"
msgid "Only Show Top Layers"
msgstr "Mostra solo strati superiori"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:366
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:308
msgctxt "@label"
msgid "Show 5 Detailed Layers On Top"
msgstr "Mostra 5 strati superiori in dettaglio"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:379
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:322
msgctxt "@label"
msgid "Top / Bottom"
msgstr "Superiore / Inferiore"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:383
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:326
msgctxt "@label"
msgid "Inner Wall"
msgstr "Parete interna"
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:448
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:384
msgctxt "@label"
msgid "min"
msgstr "min."
-#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:500
+#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:433
msgctxt "@label"
msgid "max"
msgstr "max."
@@ -2143,40 +2343,40 @@ msgctxt "@label"
msgid "Post Processing Scripts"
msgstr "Script di post-elaborazione"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:227
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:233
msgctxt "@action"
msgid "Add a script"
msgstr "Aggiungi uno script"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:273
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:279
msgctxt "@label"
msgid "Settings"
msgstr "Impostazioni"
-#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:477
+#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:493
msgctxt "@info:tooltip"
msgid "Change active post-processing scripts"
msgstr "Modifica script di post-elaborazione attivi"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:16
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:17
msgctxt "@title:window"
msgid "More information on anonymous data collection"
msgstr "Maggiori informazioni sulla raccolta di dati anonimi"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:66
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:74
msgctxt "@text:window"
-msgid "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent."
-msgstr "Cura invia dati anonimi ad Ultimaker per migliorare la qualità di stampa e l'esperienza dell'utente. Di seguito è riportato un esempio dei dati inviati."
+msgid "Ultimaker Cura collects anonymous data in order to improve the print quality and user experience. Below is an example of all the data that is shared:"
+msgstr "Ultimaker Cura acquisisce dati anonimi per migliorare la qualità di stampa e l'esperienza dell'utente. Di seguito è riportato un esempio dei dati condivisi:"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:101
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:109
msgctxt "@text:window"
-msgid "I don't want to send these data"
-msgstr "Non voglio inviare questi dati"
+msgid "I don't want to send anonymous data"
+msgstr "Non desidero inviare dati anonimi"
-#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:111
+#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/MoreInfoWindow.qml:118
msgctxt "@text:window"
-msgid "Allow sending these data to Ultimaker and help us improve Cura"
-msgstr "Il consenso all'invio di questi dati ad Ultimaker ci aiuta ad ottimizzare Cura"
+msgid "Allow sending anonymous data"
+msgstr "Consenti l'invio di dati anonimi"
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:19
msgctxt "@title:window"
@@ -2225,19 +2425,19 @@ msgstr "Profondità (mm)"
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:126
msgctxt "@info:tooltip"
-msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
-msgstr "Per impostazione predefinita, i pixel bianchi rappresentano i punti alti sulla griglia, mentre i pixel neri rappresentano i punti bassi sulla griglia. Modificare questa opzione per invertire la situazione in modo tale che i pixel neri rappresentino i punti alti sulla griglia e i pixel bianchi rappresentino i punti bassi."
-
-#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
-msgctxt "@item:inlistbox"
-msgid "Lighter is higher"
-msgstr "Più chiaro è più alto"
+msgid "For lithophanes dark pixels should correspond to thicker locations in order to block more light coming through. For height maps lighter pixels signify higher terrain, so lighter pixels should correspond to thicker locations in the generated 3D model."
+msgstr "Per le litofanie, i pixel scuri devono corrispondere alle posizioni più spesse per bloccare maggiormente il passaggio della luce. Per le mappe con altezze superiori, i pixel più chiari indicano un terreno più elevato, quindi nel modello 3D generato i pixel più chiari devono corrispondere alle posizioni più spesse."
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
msgctxt "@item:inlistbox"
msgid "Darker is higher"
msgstr "Più scuro è più alto"
+#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:139
+msgctxt "@item:inlistbox"
+msgid "Lighter is higher"
+msgstr "Più chiaro è più alto"
+
#: /home/ruben/Projects/Cura/plugins/ImageReader/ConfigUI.qml:149
msgctxt "@info:tooltip"
msgid "The amount of smoothing to apply to the image."
@@ -2248,81 +2448,80 @@ msgctxt "@action:label"
msgid "Smoothing"
msgstr "Smoothing"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:37
-msgctxt "@label"
-msgid "Mesh Type"
-msgstr "Tipo di maglia"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:68
-msgctxt "@label"
-msgid "Normal model"
-msgstr "Modello normale"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:75
-msgctxt "@label"
-msgid "Print as support"
-msgstr "Stampa come supporto"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:83
-msgctxt "@label"
-msgid "Don't support overlap with other models"
-msgstr "Non supporta sovrapposizione con altri modelli"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:91
-msgctxt "@label"
-msgid "Modify settings for overlap with other models"
-msgstr "Modifica impostazioni per sovrapposizione con altri modelli"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:99
-msgctxt "@label"
-msgid "Modify settings for infill of other models"
-msgstr "Modifica impostazioni per riempimento di altri modelli"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:347
-msgctxt "@action:button"
-msgid "Select settings"
-msgstr "Seleziona impostazioni"
-
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:389
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:13
msgctxt "@title:window"
msgid "Select Settings to Customize for this model"
msgstr "Seleziona impostazioni di personalizzazione per questo modello"
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:437
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:98
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:56
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:94
msgctxt "@label:textbox"
msgid "Filter..."
msgstr "Filtro..."
-#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:451
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:70
msgctxt "@label:checkbox"
msgid "Show all"
msgstr "Mostra tutto"
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:44
+msgctxt "@label"
+msgid "Mesh Type"
+msgstr "Tipo di maglia"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:85
+msgctxt "@label"
+msgid "Normal model"
+msgstr "Modello normale"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:97
+msgctxt "@label"
+msgid "Print as support"
+msgstr "Stampa come supporto"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:109
+msgctxt "@label"
+msgid "Modify settings for overlaps"
+msgstr "Modificare le impostazioni per le sovrapposizioni"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:121
+msgctxt "@label"
+msgid "Don't support overlaps"
+msgstr "Non supportano le sovrapposizioni"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:145
+msgctxt "@action:checkbox"
+msgid "Infill only"
+msgstr "Solo riempimento"
+
+#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:368
+msgctxt "@action:button"
+msgid "Select settings"
+msgstr "Seleziona impostazioni"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:14
msgctxt "@title:window"
msgid "Open Project"
msgstr "Apri progetto"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:58
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Update/override existing profile"
msgid "Update existing"
msgstr "Aggiorna esistente"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:59
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
-msgctxt "@action:ComboBox option"
+msgctxt "@action:ComboBox Save settings in a new profile"
msgid "Create new"
msgstr "Crea nuovo"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:70
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:73
msgctxt "@action:title"
msgid "Summary - Cura Project"
msgstr "Riepilogo - Progetto Cura"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:92
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:97
msgctxt "@action:label"
msgid "Printer settings"
msgstr "Impostazioni della stampante"
@@ -2338,20 +2537,25 @@ msgctxt "@action:ComboBox option"
msgid "Update"
msgstr "Aggiorna"
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:116
+msgctxt "@action:ComboBox option"
+msgid "Create new"
+msgstr "Crea nuovo"
+
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:143
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:105
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:106
msgctxt "@action:label"
msgid "Type"
msgstr "Tipo"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:159
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
msgctxt "@action:label"
msgid "Printer Group"
msgstr "Gruppo stampanti"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:180
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:196
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:220
msgctxt "@action:label"
msgid "Profile settings"
msgstr "Impostazioni profilo"
@@ -2362,226 +2566,222 @@ msgid "How should the conflict in the profile be resolved?"
msgstr "Come può essere risolto il conflitto nel profilo?"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:216
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:120
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:220
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:323
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:244
msgctxt "@action:label"
msgid "Name"
msgstr "Nome"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:231
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:204
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:261
+msgctxt "@action:label"
+msgid "Intent"
+msgstr "Intent"
+
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:246
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:228
msgctxt "@action:label"
msgid "Not in profile"
msgstr "Non nel profilo"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:236
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:209
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:251
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:233
msgctxt "@action:label"
msgid "%1 override"
msgid_plural "%1 overrides"
msgstr[0] "%1 override"
msgstr[1] "%1 override"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:247
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:262
msgctxt "@action:label"
msgid "Derivative from"
msgstr "Derivato da"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:252
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:267
msgctxt "@action:label"
msgid "%1, %2 override"
msgid_plural "%1, %2 overrides"
msgstr[0] "%1, %2 override"
msgstr[1] "%1, %2 override"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:268
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:283
msgctxt "@action:label"
msgid "Material settings"
msgstr "Impostazioni materiale"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:284
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:299
msgctxt "@info:tooltip"
msgid "How should the conflict in the material be resolved?"
msgstr "Come può essere risolto il conflitto nel materiale?"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:327
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:237
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:342
msgctxt "@action:label"
msgid "Setting visibility"
msgstr "Impostazione visibilità"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:336
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:351
msgctxt "@action:label"
msgid "Mode"
msgstr "Modalità"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:352
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:246
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:367
msgctxt "@action:label"
msgid "Visible settings:"
msgstr "Impostazioni visibili:"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:357
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:251
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:372
msgctxt "@action:label"
msgid "%1 out of %2"
msgstr "%1 su %2"
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:383
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:398
msgctxt "@action:warning"
msgid "Loading a project will clear all models on the build plate."
msgstr "Il caricamento di un progetto annulla tutti i modelli sul piano di stampa."
-#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:401
+#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:416
msgctxt "@action:button"
msgid "Open"
msgstr "Apri"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:26
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:25
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:28
msgctxt "@title"
-msgid "Select Printer Upgrades"
-msgstr "Seleziona gli aggiornamenti della stampante"
+msgid "My Backups"
+msgstr "I miei backup"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:38
-msgctxt "@label"
-msgid "Please select any upgrades made to this Ultimaker 2."
-msgstr "Seleziona qualsiasi aggiornamento realizzato per questa Ultimaker 2."
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:38
+msgctxt "@empty_state"
+msgid "You don't have any backups currently. Use the 'Backup Now' button to create one."
+msgstr "Nessun backup. Usare il pulsante ‘Esegui backup adesso’ per crearne uno."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:47
-msgctxt "@label"
-msgid "Olsson Block"
-msgstr "Blocco Olsson"
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/BackupsPage.qml:60
+msgctxt "@backup_limit_info"
+msgid "During the preview phase, you'll be limited to 5 visible backups. Remove a backup to see older ones."
+msgstr "Durante la fase di anteprima, saranno visibili solo 5 backup. Rimuovi un backup per vedere quelli precedenti."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:27
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:34
+msgctxt "@description"
+msgid "Backup and synchronize your Cura settings."
+msgstr "Backup e sincronizzazione delle impostazioni Cura."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/pages/WelcomePage.qml:51
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:68
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:138
+msgctxt "@button"
+msgid "Sign in"
+msgstr "Accedi"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/main.qml:24
+msgctxt "@title:window"
+msgid "Cura Backups"
+msgstr "Backup Cura"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:21
+msgctxt "@backuplist:label"
+msgid "Cura Version"
+msgstr "Versione Cura"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:29
+msgctxt "@backuplist:label"
+msgid "Machines"
+msgstr "Macchine"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:37
+msgctxt "@backuplist:label"
+msgid "Materials"
+msgstr "Materiali"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:45
+msgctxt "@backuplist:label"
+msgid "Profiles"
+msgstr "Profili"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItemDetails.qml:53
+msgctxt "@backuplist:label"
+msgid "Plugins"
+msgstr "Plugin"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:71
+msgctxt "@button"
+msgid "Restore"
+msgstr "Ripristina"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:99
+msgctxt "@dialog:title"
+msgid "Delete Backup"
+msgstr "Cancella backup"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:100
+msgctxt "@dialog:info"
+msgid "Are you sure you want to delete this backup? This cannot be undone."
+msgstr "Sei sicuro di voler cancellare questo backup? Questa operazione non può essere annullata."
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:108
+msgctxt "@dialog:title"
+msgid "Restore Backup"
+msgstr "Ripristina backup"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListItem.qml:109
+msgctxt "@dialog:info"
+msgid "You will need to restart Cura before your backup is restored. Do you want to close Cura now?"
+msgstr "Riavviare Cura prima di ripristinare il backup. Chiudere Cura adesso?"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:22
+msgctxt "@button"
+msgid "Want more?"
+msgstr "Ulteriori informazioni?"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:31
+msgctxt "@button"
+msgid "Backup Now"
+msgstr "Esegui backup adesso"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:43
+msgctxt "@checkbox:description"
+msgid "Auto Backup"
+msgstr "Backup automatico"
+
+#: /home/ruben/Projects/Cura/plugins/CuraDrive/src/qml/components/BackupListFooter.qml:44
+msgctxt "@checkbox:description"
+msgid "Automatically create a backup each day that Cura is started."
+msgstr "Crea automaticamente un backup ogni giorno in cui viene avviata Cura."
+
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:30
msgctxt "@title"
msgid "Build Plate Leveling"
msgstr "Livellamento del piano di stampa"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:38
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:44
msgctxt "@label"
msgid "To make sure your prints will come out great, you can now adjust your buildplate. When you click 'Move to Next Position' the nozzle will move to the different positions that can be adjusted."
msgstr "Per assicurarsi stampe di alta qualità, è ora possibile regolare il piano di stampa. Quando si fa clic su 'Spostamento alla posizione successiva' l'ugello si sposterà in diverse posizioni che è possibile regolare."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:47
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:57
msgctxt "@label"
msgid "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle."
msgstr "Per ciascuna posizione: inserire un pezzo di carta sotto l'ugello e regolare la stampa dell'altezza del piano di stampa. L'altezza del piano di stampa è corretta quando la carta sfiora la punta dell'ugello."
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:62
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:75
msgctxt "@action:button"
msgid "Start Build Plate Leveling"
msgstr "Avvio livellamento del piano di stampa"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:74
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:87
msgctxt "@action:button"
msgid "Move to Next Position"
msgstr "Spostamento alla posizione successiva"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:37
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:30
msgctxt "@label"
msgid "Please select any upgrades made to this Ultimaker Original"
msgstr "Seleziona qualsiasi aggiornamento realizzato per questa Ultimaker Original"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:45
+#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:41
msgctxt "@label"
msgid "Heated Build Plate (official kit or self-built)"
msgstr "Piano di stampa riscaldato (kit ufficiale o integrato)"
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:27
-msgctxt "@title"
-msgid "Check Printer"
-msgstr "Controllo stampante"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:39
-msgctxt "@label"
-msgid "It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional"
-msgstr "È consigliabile eseguire alcuni controlli di integrità sulla Ultimaker. È possibile saltare questo passaggio se si è certi che la macchina funziona correttamente"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:53
-msgctxt "@action:button"
-msgid "Start Printer Check"
-msgstr "Avvia controllo stampante"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:80
-msgctxt "@label"
-msgid "Connection: "
-msgstr "Collegamento: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Connected"
-msgstr "Collegato"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:89
-msgctxt "@info:status"
-msgid "Not connected"
-msgstr "Non collegato"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:99
-msgctxt "@label"
-msgid "Min endstop X: "
-msgstr "Endstop min. asse X: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-msgctxt "@info:status"
-msgid "Works"
-msgstr "Funziona"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:151
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:173
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Not checked"
-msgstr "Controllo non selezionato"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:120
-msgctxt "@label"
-msgid "Min endstop Y: "
-msgstr "Endstop min. asse Y: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:141
-msgctxt "@label"
-msgid "Min endstop Z: "
-msgstr "Endstop min. asse Z: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:163
-msgctxt "@label"
-msgid "Nozzle temperature check: "
-msgstr "Controllo temperatura ugello: "
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Stop Heating"
-msgstr "Arresto riscaldamento"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:187
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:248
-msgctxt "@action:button"
-msgid "Start Heating"
-msgstr "Avvio riscaldamento"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:223
-msgctxt "@label"
-msgid "Build plate temperature check:"
-msgstr "Controllo temperatura piano di stampa:"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:234
-msgctxt "@info:status"
-msgid "Checked"
-msgstr "Controllo eseguito"
-
-#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:284
-msgctxt "@label"
-msgid "Everything is in order! You're done with your CheckUp."
-msgstr "È tutto in ordine! Controllo terminato."
-
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:119
msgctxt "@label:MonitorStatus"
msgid "Not connected to a printer"
@@ -2593,7 +2793,6 @@ msgid "Printer does not accept commands"
msgstr "La stampante non accetta comandi"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:133
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:197
msgctxt "@label:MonitorStatus"
msgid "In maintenance. Please check the printer"
msgstr "In manutenzione. Controllare la stampante"
@@ -2604,19 +2803,16 @@ msgid "Lost connection with the printer"
msgstr "Persa connessione con la stampante"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:146
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:187
msgctxt "@label:MonitorStatus"
msgid "Printing..."
msgstr "Stampa in corso..."
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:149
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:189
msgctxt "@label:MonitorStatus"
msgid "Paused"
msgstr "In pausa"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:152
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:191
msgctxt "@label:MonitorStatus"
msgid "Preparing..."
msgstr "Preparazione in corso..."
@@ -2636,233 +2832,176 @@ msgctxt "@label"
msgid "Are you sure you want to abort the print?"
msgstr "Sei sicuro di voler interrompere la stampa?"
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:15
-msgctxt "@title:window"
-msgid "Discard or Keep changes"
-msgstr "Elimina o mantieni modifiche"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:57
-msgctxt "@text:window"
-msgid ""
-"You have customized some profile settings.\n"
-"Would you like to keep or discard those settings?"
-msgstr "Sono state personalizzate alcune impostazioni del profilo.\nMantenere o eliminare tali impostazioni?"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:110
-msgctxt "@title:column"
-msgid "Profile settings"
-msgstr "Impostazioni profilo"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:117
-msgctxt "@title:column"
-msgid "Default"
-msgstr "Valore predefinito"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:124
-msgctxt "@title:column"
-msgid "Customized"
-msgstr "Valore personalizzato"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:157
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:637
-msgctxt "@option:discardOrKeep"
-msgid "Always ask me this"
-msgstr "Chiedi sempre"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:158
-msgctxt "@option:discardOrKeep"
-msgid "Discard and never ask again"
-msgstr "Elimina e non chiedere nuovamente"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:159
-msgctxt "@option:discardOrKeep"
-msgid "Keep and never ask again"
-msgstr "Mantieni e non chiedere nuovamente"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:196
-msgctxt "@action:button"
-msgid "Discard"
-msgstr "Elimina"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:209
-msgctxt "@action:button"
-msgid "Keep"
-msgstr "Mantieni"
-
-#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:222
-msgctxt "@action:button"
-msgid "Create New Profile"
-msgstr "Crea nuovo profilo"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:71
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:72
msgctxt "@title"
msgid "Information"
msgstr "Informazioni"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:100
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
msgctxt "@title:window"
msgid "Confirm Diameter Change"
msgstr "Conferma modifica diametro"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:102
msgctxt "@label (%1 is a number)"
msgid "The new filament diameter is set to %1 mm, which is not compatible with the current extruder. Do you wish to continue?"
msgstr "Il nuovo diametro del filamento impostato a %1 mm non è compatibile con l'attuale estrusore. Continuare?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:133
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:128
msgctxt "@label"
msgid "Display Name"
msgstr "Visualizza nome"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:143
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:138
msgctxt "@label"
msgid "Brand"
msgstr "Marchio"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:148
msgctxt "@label"
msgid "Material Type"
msgstr "Tipo di materiale"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:158
msgctxt "@label"
msgid "Color"
msgstr "Colore"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:212
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:208
msgctxt "@label"
msgid "Properties"
msgstr "Proprietà"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:214
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:210
msgctxt "@label"
msgid "Density"
msgstr "Densità"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:229
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:225
msgctxt "@label"
msgid "Diameter"
msgstr "Diametro"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:263
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:259
msgctxt "@label"
msgid "Filament Cost"
msgstr "Costo del filamento"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:280
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:276
msgctxt "@label"
msgid "Filament weight"
msgstr "Peso del filamento"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:298
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:294
msgctxt "@label"
msgid "Filament length"
msgstr "Lunghezza del filamento"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:307
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:303
msgctxt "@label"
msgid "Cost per Meter"
msgstr "Costo al metro"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:321
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:317
msgctxt "@label"
msgid "This material is linked to %1 and shares some of its properties."
msgstr "Questo materiale è collegato a %1 e condivide alcune delle sue proprietà."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:328
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:324
msgctxt "@label"
msgid "Unlink Material"
msgstr "Scollega materiale"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:335
msgctxt "@label"
msgid "Description"
msgstr "Descrizione"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:352
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:348
msgctxt "@label"
msgid "Adhesion Information"
msgstr "Informazioni sull’aderenza"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:378
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsView.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:19
msgctxt "@label"
msgid "Print settings"
msgstr "Impostazioni di stampa"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:84
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:35
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:72
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:108
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:40
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:84
msgctxt "@action:button"
msgid "Activate"
msgstr "Attiva"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:101
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:126
msgctxt "@action:button"
msgid "Create"
msgstr "Crea"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:140
msgctxt "@action:button"
msgid "Duplicate"
msgstr "Duplica"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:141
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:170
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:167
msgctxt "@action:button"
msgid "Import"
msgstr "Importa"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:154
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:184
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:179
msgctxt "@action:button"
msgid "Export"
msgstr "Esporta"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:233
msgctxt "@action:label"
msgid "Printer"
msgstr "Stampante"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:262
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:239
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:297
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:274
msgctxt "@title:window"
msgid "Confirm Remove"
msgstr "Conferma rimozione"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:263
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:240
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:300
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:275
msgctxt "@label (%1 is object name)"
msgid "Are you sure you wish to remove %1? This cannot be undone!"
msgstr "Sei sicuro di voler rimuovere %1? Questa operazione non può essere annullata!"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:277
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:285
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:314
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:322
msgctxt "@title:window"
msgid "Import Material"
msgstr "Importa materiale"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:286
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:323
msgctxt "@info:status Don't translate the XML tags or !"
msgid "Could not import material %1: %2"
msgstr "Impossibile importare materiale {1}: %2"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:290
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:327
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully imported material %1"
msgstr "Materiale importato correttamente %1"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:308
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:316
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:345
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:353
msgctxt "@title:window"
msgid "Export Material"
msgstr "Esporta materiale"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:320
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:357
msgctxt "@info:status Don't translate the XML tags and !"
msgid "Failed to export material to %1: %2"
msgstr "Impossibile esportare il materiale su %1: %2"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:326
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/Materials/MaterialsPage.qml:363
msgctxt "@info:status Don't translate the XML tag !"
msgid "Successfully exported material to %1"
msgstr "Materiale esportato correttamente su %1"
@@ -2872,817 +3011,784 @@ msgctxt "@title:tab"
msgid "Setting Visibility"
msgstr "Impostazione visibilità"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:46
msgctxt "@label:textbox"
msgid "Check all"
msgstr "Controlla tutto"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:47
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:61
msgctxt "@info:status"
msgid "Calculated"
msgstr "Calcolato"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:60
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:75
msgctxt "@title:column"
msgid "Setting"
msgstr "Impostazione"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:67
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
msgctxt "@title:column"
msgid "Profile"
msgstr "Profilo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:74
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:89
msgctxt "@title:column"
msgid "Current"
msgstr "Corrente"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:82
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfileTab.qml:97
msgctxt "@title:column"
msgid "Unit"
msgstr "Unità"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:15
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:410
msgctxt "@title:tab"
msgid "General"
msgstr "Generale"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:132
msgctxt "@label"
msgid "Interface"
msgstr "Interfaccia"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:153
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:143
msgctxt "@label"
msgid "Language:"
msgstr "Lingua:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:221
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:210
msgctxt "@label"
msgid "Currency:"
msgstr "Valuta:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:235
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:223
msgctxt "@label"
msgid "Theme:"
msgstr "Tema:"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:292
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:279
msgctxt "@label"
msgid "You will need to restart the application for these changes to have effect."
msgstr "Riavviare l'applicazione per rendere effettive le modifiche."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:309
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:296
msgctxt "@info:tooltip"
msgid "Slice automatically when changing settings."
msgstr "Seziona automaticamente alla modifica delle impostazioni."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:317
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:304
msgctxt "@option:check"
msgid "Slice automatically"
msgstr "Seziona automaticamente"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:318
msgctxt "@label"
msgid "Viewport behavior"
msgstr "Comportamento del riquadro di visualizzazione"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:339
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:326
msgctxt "@info:tooltip"
msgid "Highlight unsupported areas of the model in red. Without support these areas will not print properly."
msgstr "Evidenzia in rosso le zone non supportate del modello. In assenza di supporto, queste aree non saranno stampate in modo corretto."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:335
msgctxt "@option:check"
msgid "Display overhang"
msgstr "Visualizza sbalzo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:355
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:343
msgctxt "@info:tooltip"
msgid "Moves the camera so the model is in the center of the view when a model is selected"
msgstr "Sposta la fotocamera in modo che il modello si trovi al centro della visualizzazione quando è selezionato"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:348
msgctxt "@action:button"
msgid "Center camera when item is selected"
msgstr "Centratura fotocamera alla selezione dell'elemento"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:369
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:358
msgctxt "@info:tooltip"
msgid "Should the default zoom behavior of cura be inverted?"
msgstr "Il comportamento dello zoom predefinito di Cura dovrebbe essere invertito?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:374
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:363
msgctxt "@action:button"
msgid "Invert the direction of camera zoom."
msgstr "Inverti la direzione dello zoom della fotocamera."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
msgctxt "@info:tooltip"
msgid "Should zooming move in the direction of the mouse?"
msgstr "Lo zoom si muove nella direzione del mouse?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:389
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:379
+msgctxt "@info:tooltip"
+msgid "Zooming towards the mouse is not supported in the orthographic perspective."
+msgstr "Nella prospettiva ortogonale lo zoom verso la direzione del mouse non è supportato."
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:384
msgctxt "@action:button"
msgid "Zoom toward mouse direction"
msgstr "Zoom verso la direzione del mouse"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:399
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:410
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved so that they no longer intersect?"
msgstr "I modelli sull’area di stampa devono essere spostati per evitare intersezioni?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:404
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:415
msgctxt "@option:check"
msgid "Ensure models are kept apart"
msgstr "Assicurarsi che i modelli siano mantenuti separati"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:413
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:424
msgctxt "@info:tooltip"
msgid "Should models on the platform be moved down to touch the build plate?"
msgstr "I modelli sull’area di stampa devono essere portati a contatto del piano di stampa?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:418
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:429
msgctxt "@option:check"
msgid "Automatically drop models to the build plate"
msgstr "Rilascia automaticamente i modelli sul piano di stampa"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:430
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:441
msgctxt "@info:tooltip"
msgid "Show caution message in g-code reader."
msgstr "Visualizza il messaggio di avvertimento sul lettore codice G."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:439
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:450
msgctxt "@option:check"
msgid "Caution message in g-code reader"
msgstr "Messaggio di avvertimento sul lettore codice G"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:447
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:458
msgctxt "@info:tooltip"
msgid "Should layer be forced into compatibility mode?"
msgstr "Lo strato deve essere forzato in modalità di compatibilità?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:452
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:463
msgctxt "@option:check"
msgid "Force layer view compatibility mode (restart required)"
msgstr "Forzare la modalità di compatibilità visualizzazione strato (riavvio necessario)"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:468
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:473
+msgctxt "@info:tooltip"
+msgid "Should Cura open at the location it was closed?"
+msgstr "Aprire Cura nel punto in cui è stato chiuso?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:478
+msgctxt "@option:check"
+msgid "Restore window position on start"
+msgstr "Ripristinare la posizione della finestra all'avvio"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:488
+msgctxt "@info:tooltip"
+msgid "What type of camera rendering should be used?"
+msgstr "Quale tipo di rendering della fotocamera è necessario utilizzare?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+msgctxt "@window:text"
+msgid "Camera rendering:"
+msgstr "Rendering fotocamera:"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:506
+msgid "Perspective"
+msgstr "Prospettiva"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:507
+msgid "Orthographic"
+msgstr "Ortogonale"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:538
msgctxt "@label"
msgid "Opening and saving files"
msgstr "Apertura e salvataggio file"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:475
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:545
msgctxt "@info:tooltip"
msgid "Should models be scaled to the build volume if they are too large?"
msgstr "I modelli devono essere ridimensionati al volume di stampa, se troppo grandi?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:550
msgctxt "@option:check"
msgid "Scale large models"
msgstr "Ridimensiona i modelli troppo grandi"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:490
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:560
msgctxt "@info:tooltip"
msgid "An model may appear extremely small if its unit is for example in meters rather than millimeters. Should these models be scaled up?"
msgstr "Un modello può apparire eccessivamente piccolo se la sua unità di misura è espressa in metri anziché in millimetri. Questi modelli devono essere aumentati?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:495
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:565
msgctxt "@option:check"
msgid "Scale extremely small models"
msgstr "Ridimensiona i modelli eccessivamente piccoli"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:505
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:575
msgctxt "@info:tooltip"
msgid "Should models be selected after they are loaded?"
msgstr "I modelli devono essere selezionati dopo essere stati caricati?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:510
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:580
msgctxt "@option:check"
msgid "Select models when loaded"
msgstr "Selezionare i modelli dopo il caricamento"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:520
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:590
msgctxt "@info:tooltip"
msgid "Should a prefix based on the printer name be added to the print job name automatically?"
msgstr "Al nome del processo di stampa deve essere aggiunto automaticamente un prefisso basato sul nome della stampante?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:525
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:595
msgctxt "@option:check"
msgid "Add machine prefix to job name"
msgstr "Aggiungi al nome del processo un prefisso macchina"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:535
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:605
msgctxt "@info:tooltip"
msgid "Should a summary be shown when saving a project file?"
msgstr "Quando si salva un file di progetto deve essere visualizzato un riepilogo?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
msgctxt "@option:check"
msgid "Show summary dialog when saving project"
msgstr "Visualizza una finestra di riepilogo quando si salva un progetto"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:619
msgctxt "@info:tooltip"
msgid "Default behavior when opening a project file"
msgstr "Comportamento predefinito all'apertura di un file progetto"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:557
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:627
msgctxt "@window:text"
msgid "Default behavior when opening a project file: "
msgstr "Comportamento predefinito all'apertura di un file progetto: "
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:571
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:641
msgctxt "@option:openProject"
msgid "Always ask me this"
msgstr "Chiedi sempre"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:572
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:642
msgctxt "@option:openProject"
msgid "Always open as a project"
msgstr "Apri sempre come progetto"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:573
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:643
msgctxt "@option:openProject"
msgid "Always import models"
msgstr "Importa sempre i modelli"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:679
msgctxt "@info:tooltip"
msgid "When you have made changes to a profile and switched to a different one, a dialog will be shown asking whether you want to keep your modifications or not, or you can choose a default behaviour and never show that dialog again."
msgstr "Dopo aver modificato un profilo ed essere passati a un altro, si apre una finestra di dialogo che chiede se mantenere o eliminare le modifiche oppure se scegliere un comportamento predefinito e non visualizzare più tale finestra di dialogo."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:618
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:688
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:52
msgctxt "@label"
msgid "Profiles"
msgstr "Profili"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:623
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:693
msgctxt "@window:text"
msgid "Default behavior for changed setting values when switching to a different profile: "
msgstr "Comportamento predefinito per i valori di impostazione modificati al passaggio a un profilo diverso: "
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:638
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:707
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:157
+msgctxt "@option:discardOrKeep"
+msgid "Always ask me this"
+msgstr "Chiedi sempre"
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:708
msgctxt "@option:discardOrKeep"
msgid "Always discard changed settings"
msgstr "Elimina sempre le impostazioni modificate"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:639
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:709
msgctxt "@option:discardOrKeep"
msgid "Always transfer changed settings to new profile"
msgstr "Trasferisci sempre le impostazioni modificate a un nuovo profilo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:673
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:743
msgctxt "@label"
msgid "Privacy"
msgstr "Privacy"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:681
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:750
msgctxt "@info:tooltip"
msgid "Should Cura check for updates when the program is started?"
msgstr "Cura deve verificare la presenza di eventuali aggiornamenti all’avvio del programma?"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:686
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:755
msgctxt "@option:check"
msgid "Check for updates on start"
msgstr "Controlla aggiornamenti all’avvio"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:697
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:765
msgctxt "@info:tooltip"
msgid "Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored."
msgstr "I dati anonimi sulla stampa devono essere inviati a Ultimaker? Nota, non sono trasmessi o memorizzati modelli, indirizzi IP o altre informazioni personali."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:702
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:770
msgctxt "@option:check"
msgid "Send (anonymous) print information"
msgstr "Invia informazioni di stampa (anonime)"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:711
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:779
msgctxt "@action:button"
msgid "More information"
msgstr "Ulteriori informazioni"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:729
-msgctxt "@label"
-msgid "Experimental"
-msgstr "Sperimentale"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:736
-msgctxt "@info:tooltip"
-msgid "Use multi build plate functionality"
-msgstr "Utilizzare la funzionalità piano di stampa multiplo"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:741
-msgctxt "@option:check"
-msgid "Use multi build plate functionality (restart required)"
-msgstr "Utilizzare la funzionalità piano di stampa multiplo (necessario riavvio)"
-
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:16
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:549
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:415
msgctxt "@title:tab"
msgid "Printers"
msgstr "Stampanti"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:55
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:63
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:152
msgctxt "@action:button"
msgid "Rename"
msgstr "Rinomina"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:147
-msgctxt "@label"
-msgid "Printer type:"
-msgstr "Tipo di stampante:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:156
-msgctxt "@label"
-msgid "Connection:"
-msgstr "Collegamento:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:162
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
-msgctxt "@info:status"
-msgid "The printer is not connected."
-msgstr "La stampante non è collegata."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:168
-msgctxt "@label"
-msgid "State:"
-msgstr "Stato:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:181
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for a printjob"
-msgstr "In attesa di un processo di stampa"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:193
-msgctxt "@label:MonitorStatus"
-msgid "Waiting for someone to clear the build plate"
-msgstr "In attesa di qualcuno che cancelli il piano di stampa"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:199
-msgctxt "@label:MonitorStatus"
-msgid "Aborting print..."
-msgstr "Interruzione stampa in corso..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:553
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:34
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:419
msgctxt "@title:tab"
msgid "Profiles"
msgstr "Profili"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:104
msgctxt "@label"
msgid "Create"
msgstr "Crea"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:102
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:121
msgctxt "@label"
msgid "Duplicate"
msgstr "Duplica"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:174
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:202
msgctxt "@title:window"
msgid "Create Profile"
msgstr "Crea profilo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:225
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:204
+msgctxt "@info"
+msgid "Please provide a name for this profile."
+msgstr "Indica un nome per questo profilo."
+
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:260
msgctxt "@title:window"
msgid "Duplicate Profile"
msgstr "Duplica profilo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:256
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:291
msgctxt "@title:window"
msgid "Rename Profile"
msgstr "Rinomina profilo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:304
msgctxt "@title:window"
msgid "Import Profile"
msgstr "Importa profilo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:333
msgctxt "@title:window"
msgid "Export Profile"
msgstr "Esporta profilo"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:350
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:396
msgctxt "@label %1 is printer name"
msgid "Printer: %1"
msgstr "Stampante: %1"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Protected profiles"
-msgstr "Profili protetti"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:403
-msgctxt "@label"
-msgid "Custom profiles"
-msgstr "Profili personalizzati"
-
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:480
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:554
msgctxt "@action:button"
msgid "Update profile with current settings/overrides"
msgstr "Aggiorna il profilo con le impostazioni/esclusioni correnti"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:487
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:561
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:257
msgctxt "@action:button"
msgid "Discard current changes"
msgstr "Elimina le modifiche correnti"
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:504
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:580
msgctxt "@action:label"
msgid "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below."
msgstr "Questo profilo utilizza le impostazioni predefinite dalla stampante, perciò non ci sono impostazioni/esclusioni nell’elenco riportato di seguito."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:511
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:588
msgctxt "@action:label"
msgid "Your current settings match the selected profile."
msgstr "Le impostazioni correnti corrispondono al profilo selezionato."
-#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:530
+#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:606
msgctxt "@title:tab"
msgid "Global Settings"
msgstr "Impostazioni globali"
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:18
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:953
-msgctxt "@title:window"
-msgid "Add Printer"
-msgstr "Aggiungi stampante"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:195
-msgctxt "@label"
-msgid "Printer Name:"
-msgstr "Nome stampante:"
-
-#: /home/ruben/Projects/Cura/resources/qml/AddMachineDialog.qml:219
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/MainWindowHeader.qml:90
msgctxt "@action:button"
-msgid "Add Printer"
-msgstr "Aggiungi stampante"
+msgid "Marketplace"
+msgstr "Mercato"
-#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:84
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:27
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&File"
+msgstr "&File"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:31
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Edit"
+msgstr "&Modifica"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:48
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
+msgctxt "@title:menu menubar:toplevel"
+msgid "&View"
+msgstr "&Visualizza"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:50
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:13
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Settings"
+msgstr "&Impostazioni"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:55
+msgctxt "@title:menu menubar:toplevel"
+msgid "E&xtensions"
+msgstr "Es&tensioni"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:89
+msgctxt "@title:menu menubar:toplevel"
+msgid "P&references"
+msgstr "P&referenze"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:97
+msgctxt "@title:menu menubar:toplevel"
+msgid "&Help"
+msgstr "&Help"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:124
+msgctxt "@title:window"
+msgid "New project"
+msgstr "Nuovo progetto"
+
+#: /home/ruben/Projects/Cura/resources/qml/MainWindow/ApplicationMenu.qml:125
+msgctxt "@info:question"
+msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
+msgstr "Sei sicuro di voler aprire un nuovo progetto? Questo cancellerà il piano di stampa e tutte le impostazioni non salvate."
+
+#: /home/ruben/Projects/Cura/resources/qml/JobSpecs.qml:88
msgctxt "@text Print job name"
msgid "Untitled"
msgstr "Senza titolo"
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:15
-msgctxt "@title:window"
-msgid "About Cura"
-msgstr "Informazioni su Cura"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:55
-msgctxt "@label"
-msgid "version: %1"
-msgstr "versione: %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:69
-msgctxt "@label"
-msgid "End-to-end solution for fused filament 3D printing."
-msgstr "Soluzione end-to-end per la stampa 3D con filamento fuso."
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:82
-msgctxt "@info:credit"
-msgid ""
-"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
-"Cura proudly uses the following open source projects:"
-msgstr "Cura è stato sviluppato da Ultimaker B.V. in cooperazione con la comunità.\nCura è orgogliosa di utilizzare i seguenti progetti open source:"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:132
-msgctxt "@label"
-msgid "Graphical user interface"
-msgstr "Interfaccia grafica utente"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:133
-msgctxt "@label"
-msgid "Application framework"
-msgstr "Struttura applicazione"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:134
-msgctxt "@label"
-msgid "G-code generator"
-msgstr "Generatore codice G"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:135
-msgctxt "@label"
-msgid "Interprocess communication library"
-msgstr "Libreria di comunicazione intra-processo"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:137
-msgctxt "@label"
-msgid "Programming language"
-msgstr "Lingua di programmazione"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:138
-msgctxt "@label"
-msgid "GUI framework"
-msgstr "Struttura GUI"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139
-msgctxt "@label"
-msgid "GUI framework bindings"
-msgstr "Vincoli struttura GUI"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:140
-msgctxt "@label"
-msgid "C/C++ Binding library"
-msgstr "Libreria vincoli C/C++"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:141
-msgctxt "@label"
-msgid "Data interchange format"
-msgstr "Formato scambio dati"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:142
-msgctxt "@label"
-msgid "Support library for scientific computing"
-msgstr "Libreria di supporto per calcolo scientifico"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:143
-msgctxt "@label"
-msgid "Support library for faster math"
-msgstr "Libreria di supporto per calcolo rapido"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:144
-msgctxt "@label"
-msgid "Support library for handling STL files"
-msgstr "Libreria di supporto per gestione file STL"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:145
-msgctxt "@label"
-msgid "Support library for handling planar objects"
-msgstr "Libreria di supporto per gestione oggetti planari"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:146
-msgctxt "@label"
-msgid "Support library for handling triangular meshes"
-msgstr "Libreria di supporto per gestione maglie triangolari"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:147
-msgctxt "@label"
-msgid "Support library for analysis of complex networks"
-msgstr "Libreria di supporto per l’analisi di reti complesse"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:148
-msgctxt "@label"
-msgid "Support library for handling 3MF files"
-msgstr "Libreria di supporto per gestione file 3MF"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:149
-msgctxt "@label"
-msgid "Support library for file metadata and streaming"
-msgstr "Libreria di supporto per metadati file e streaming"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:150
-msgctxt "@label"
-msgid "Serial communication library"
-msgstr "Libreria di comunicazione seriale"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:151
-msgctxt "@label"
-msgid "ZeroConf discovery library"
-msgstr "Libreria scoperta ZeroConf"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:152
-msgctxt "@label"
-msgid "Polygon clipping library"
-msgstr "Libreria ritaglio poligono"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:153
-msgctxt "@Label"
-msgid "Python HTTP library"
-msgstr "Libreria Python HTTP"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:155
-msgctxt "@label"
-msgid "Font"
-msgstr "Font"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:156
-msgctxt "@label"
-msgid "SVG icons"
-msgstr "Icone SVG"
-
-#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:157
-msgctxt "@label"
-msgid "Linux cross-distribution application deployment"
-msgstr "Apertura applicazione distribuzione incrociata Linux"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:42
-msgctxt "@label"
-msgid "Profile:"
-msgstr "Profilo:"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:104
-msgctxt "@tooltip"
-msgid ""
-"Some setting/override values are different from the values stored in the profile.\n"
-"\n"
-"Click to open the profile manager."
-msgstr "Alcuni valori di impostazione/esclusione sono diversi dai valori memorizzati nel profilo.\n\nFare clic per aprire la gestione profili."
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:200
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:68
msgctxt "@label:textbox"
-msgid "Search..."
-msgstr "Ricerca..."
+msgid "Search settings"
+msgstr "Impostazioni ricerca"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:545
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:462
msgctxt "@action:menu"
msgid "Copy value to all extruders"
msgstr "Copia valore su tutti gli estrusori"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:554
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:471
msgctxt "@action:menu"
msgid "Copy all changed values to all extruders"
msgstr "Copia tutti i valori modificati su tutti gli estrusori"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:591
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:508
msgctxt "@action:menu"
msgid "Hide this setting"
msgstr "Nascondi questa impostazione"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:609
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:521
msgctxt "@action:menu"
msgid "Don't show this setting"
msgstr "Nascondi questa impostazione"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:613
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:525
msgctxt "@action:menu"
msgid "Keep this setting visible"
msgstr "Mantieni visibile questa impostazione"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:637
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:417
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:544
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:434
msgctxt "@action:menu"
msgid "Configure setting visibility..."
msgstr "Configura visibilità delle impostazioni..."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:644
-msgctxt "@action:inmenu"
-msgid "Collapse All"
-msgstr "Comprimi tutto"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:649
-msgctxt "@action:inmenu"
-msgid "Expand All"
-msgstr "Espandi tutto"
-
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:253
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingCategory.qml:237
msgctxt "@label"
msgid ""
"Some hidden settings use values different from their normal calculated value.\n"
"\n"
"Click to make these settings visible."
-msgstr "Alcune impostazioni nascoste utilizzano valori diversi dal proprio valore normale calcolato.\n\nFare clic per rendere visibili queste impostazioni."
+msgstr ""
+"Alcune impostazioni nascoste utilizzano valori diversi dal proprio valore normale calcolato.\n"
+"\n"
+"Fare clic per rendere visibili queste impostazioni."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:81
+msgctxt "@label"
+msgid "This setting is not used because all the settings that it influences are overridden."
+msgstr "Questa impostazione non è utilizzata perché tutte le impostazioni che influenza sono sottoposte a override."
+
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:86
msgctxt "@label Header for list of settings."
msgid "Affects"
msgstr "Influisce su"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:91
msgctxt "@label Header for list of settings."
msgid "Affected By"
msgstr "Influenzato da"
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:155
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:187
msgctxt "@label"
msgid "This setting is always shared between all extruders. Changing it here will change the value for all extruders."
msgstr "Questa impostazione è sempre condivisa tra tutti gli estrusori. La sua modifica varierà il valore per tutti gli estrusori."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:158
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:191
msgctxt "@label"
msgid "The value is resolved from per-extruder values "
msgstr "Questo valore è risolto da valori per estrusore "
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:189
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:230
msgctxt "@label"
msgid ""
"This setting has a value that is different from the profile.\n"
"\n"
"Click to restore the value of the profile."
-msgstr "Questa impostazione ha un valore diverso dal profilo.\n\nFare clic per ripristinare il valore del profilo."
+msgstr ""
+"Questa impostazione ha un valore diverso dal profilo.\n"
+"\n"
+"Fare clic per ripristinare il valore del profilo."
-#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:281
+#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:329
msgctxt "@label"
msgid ""
"This setting is normally calculated, but it currently has an absolute value set.\n"
"\n"
"Click to restore the calculated value."
-msgstr "Questa impostazione normalmente viene calcolata, ma attualmente ha impostato un valore assoluto.\n\nFare clic per ripristinare il valore calcolato."
+msgstr ""
+"Questa impostazione normalmente viene calcolata, ma attualmente ha impostato un valore assoluto.\n"
+"\n"
+"Fare clic per ripristinare il valore calcolato."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:129
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/NoIntentIcon.qml:31
+msgctxt "@label %1 is filled in with the type of a profile. %2 is filled with a list of numbers (eg '1' or '1, 2')"
+msgid "There is no %1 profile for the configuration in extruder %2. The default intent will be used instead"
+msgid_plural "There is no %1 profile for the configurations in extruders %2. The default intent will be used instead"
+msgstr[0] ""
+msgstr[1] ""
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:144
+msgctxt "@button"
+msgid "Recommended"
+msgstr "Consigliata"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml:158
+msgctxt "@button"
+msgid "Custom"
+msgstr "Personalizzata"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:193
+msgctxt "@label"
+msgid "Gradual infill"
+msgstr "Riempimento graduale"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml:232
+msgctxt "@label"
+msgid "Gradual infill will gradually increase the amount of infill towards the top."
+msgstr "Un riempimento graduale aumenterà gradualmente la quantità di riempimento verso l'alto."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:30
+msgctxt "@label"
+msgid "Support"
+msgstr "Supporto"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml:71
+msgctxt "@label"
+msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
+msgstr "Genera strutture per supportare le parti del modello a sbalzo. Senza queste strutture, queste parti collasserebbero durante la stampa."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:29
+msgctxt "@label"
+msgid "Adhesion"
+msgstr "Adesione"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedAdhesionSelector.qml:74
+msgctxt "@label"
+msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
+msgstr "Abilita stampa di brim o raft. Questa funzione aggiunge un’area piana attorno o sotto l’oggetto, facile da tagliare successivamente."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Recommended/RecommendedQualityProfileSelector.qml:81
+msgctxt "@tooltip"
+msgid "You have modified some profile settings. If you want to change these go to custom mode."
+msgstr "Sono state modificate alcune impostazioni del profilo. Per modificarle, andare alla modalità personalizzata."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:13
+msgctxt "@label:Should be short"
+msgid "On"
+msgstr "Inserita"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:14
+msgctxt "@label:Should be short"
+msgid "Off"
+msgstr "Disinserita"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelectorHeader.qml:33
+msgctxt "@label"
+msgid "Experimental"
+msgstr "Sperimentale"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:47
+msgctxt "@label"
+msgid "Profile"
+msgstr "Profilo"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml:172
+msgctxt "@tooltip"
+msgid ""
+"Some setting/override values are different from the values stored in the profile.\n"
+"\n"
+"Click to open the profile manager."
+msgstr ""
+"Alcuni valori di impostazione/esclusione sono diversi dai valori memorizzati nel profilo.\n"
+"\n"
+"Fare clic per aprire la gestione profili."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/Custom/QualitiesWithIntentMenu.qml:160
+msgctxt "@label:header"
+msgid "Custom profiles"
+msgstr "Profili personalizzati"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrintSetupSelector/PrintSetupSelector.qml:21
+msgctxt "@label shown when we load a Gcode file"
+msgid "Print setup disabled. G-code file can not be modified."
+msgstr "Impostazione di stampa disabilitata. Il file G-code non può essere modificato."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:52
msgctxt "@label"
msgid "Printer control"
msgstr "Comando stampante"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:144
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:67
msgctxt "@label"
msgid "Jog Position"
msgstr "Posizione Jog"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:85
msgctxt "@label"
msgid "X/Y"
msgstr "X/Y"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:192
msgctxt "@label"
msgid "Z"
msgstr "Z"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:257
msgctxt "@label"
msgid "Jog Distance"
msgstr "Distanza Jog"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:443
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:301
msgctxt "@label"
msgid "Send G-code"
msgstr "Invia codice G"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:506
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ManualPrinterControl.qml:365
msgctxt "@tooltip of G-code command input"
msgid "Send a custom G-code command to the connected printer. Press 'enter' to send the command."
msgstr "Invia un comando codice G personalizzato alla stampante connessa. Premere ‘invio’ per inviare il comando."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:36
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:272
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:41
msgctxt "@label"
msgid "Extruder"
msgstr "Estrusore"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:66
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:71
msgctxt "@tooltip"
msgid "The target temperature of the hotend. The hotend will heat up or cool down towards this temperature. If this is 0, the hotend heating is turned off."
msgstr "Temperatura target dell'estremità riscaldata. L'estremità riscaldata si riscalderà o raffredderà sino a questo valore di temperatura. Se questo è 0, l'estremità riscaldata verrà spenta."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:98
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:103
msgctxt "@tooltip"
msgid "The current temperature of this hotend."
msgstr "La temperatura corrente di questa estremità calda."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:172
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:177
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the hotend to."
msgstr "La temperatura di preriscaldo dell’estremità calda."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:336
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:331
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:341
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:332
msgctxt "@button Cancel pre-heating"
msgid "Cancel"
msgstr "Annulla"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:339
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:334
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:344
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:335
msgctxt "@button"
msgid "Pre-heat"
msgstr "Pre-riscaldo"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:365
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:370
msgctxt "@tooltip of pre-heat"
msgid "Heat the hotend in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the hotend to heat up when you're ready to print."
msgstr "Riscalda l’estremità calda prima della stampa. È possibile continuare a regolare la stampa durante il riscaldamento e non è necessario attendere il riscaldamento dell’estremità calda quando si è pronti per la stampa."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:401
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:406
msgctxt "@tooltip"
msgid "The colour of the material in this extruder."
msgstr "Il colore del materiale di questo estrusore."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:433
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:438
msgctxt "@tooltip"
msgid "The material in this extruder."
msgstr "Il materiale di questo estrusore."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:465
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/ExtruderBox.qml:470
msgctxt "@tooltip"
msgid "The nozzle inserted in this extruder."
msgstr "L’ugello inserito in questo estrusore."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:25
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:493
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/OutputDeviceHeader.qml:55
+msgctxt "@info:status"
+msgid "The printer is not connected."
+msgstr "La stampante non è collegata."
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:26
msgctxt "@label"
msgid "Build plate"
msgstr "Piano di stampa"
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:55
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:56
msgctxt "@tooltip"
msgid "The target temperature of the heated bed. The bed will heat up or cool down towards this temperature. If this is 0, the bed heating is turned off."
msgstr "La temperatura target del piano riscaldato. Il piano verrà riscaldato o raffreddato a questa temperatura. Se è 0, il riscaldamento del piano viene disattivato."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:87
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:88
msgctxt "@tooltip"
msgid "The current temperature of the heated bed."
msgstr "La temperatura corrente del piano riscaldato."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:160
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:161
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the bed to."
msgstr "La temperatura di preriscaldo del piano."
-#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:360
+#: /home/ruben/Projects/Cura/resources/qml/PrinterOutput/HeatedBedBox.qml:361
msgctxt "@tooltip of pre-heat"
msgid "Heat the bed in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the bed to heat up when you're ready to print."
msgstr "Riscalda il piano prima della stampa. È possibile continuare a regolare la stampa durante il riscaldamento e non è necessario attendere il riscaldamento del piano quando si è pronti per la stampa."
@@ -3692,12 +3798,12 @@ msgctxt "@label:category menu label"
msgid "Material"
msgstr "Materiale"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:37
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:46
msgctxt "@label:category menu label"
msgid "Favorites"
msgstr "Preferiti"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:61
+#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:71
msgctxt "@label:category menu label"
msgid "Generic"
msgstr "Generale"
@@ -3712,17 +3818,52 @@ msgctxt "@label:category menu label"
msgid "Local printers"
msgstr "Stampanti locali"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:12
-msgctxt "@title:menu menubar:toplevel"
-msgid "&View"
-msgstr "&Visualizza"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:15
+msgctxt "@title:menu menubar:settings"
+msgid "&Printer"
+msgstr "S&tampante"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:42
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:27
+msgctxt "@title:menu"
+msgid "&Material"
+msgstr "Ma&teriale"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:36
+msgctxt "@action:inmenu"
+msgid "Set as Active Extruder"
+msgstr "Imposta come estrusore attivo"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:42
+msgctxt "@action:inmenu"
+msgid "Enable Extruder"
+msgstr "Abilita estrusore"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingsMenu.qml:49
+msgctxt "@action:inmenu"
+msgid "Disable Extruder"
+msgstr "Disabilita estrusore"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:19
msgctxt "@action:inmenu menubar:view"
msgid "&Camera position"
msgstr "&Posizione fotocamera"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:58
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:44
+msgctxt "@action:inmenu menubar:view"
+msgid "Camera view"
+msgstr "Visualizzazione fotocamera"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:47
+msgctxt "@action:inmenu menubar:view"
+msgid "Perspective"
+msgstr "Prospettiva"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:59
+msgctxt "@action:inmenu menubar:view"
+msgid "Orthographic"
+msgstr "Ortogonale"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:80
msgctxt "@action:inmenu menubar:view"
msgid "&Build plate"
msgstr "P&iano di stampa"
@@ -3742,6 +3883,21 @@ msgctxt "@action:inmenu"
msgid "Manage Setting Visibility..."
msgstr "Gestisci Impostazione visibilità..."
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:33
+msgctxt "@title:menu menubar:file"
+msgid "&Save..."
+msgstr "&Salva..."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:54
+msgctxt "@title:menu menubar:file"
+msgid "&Export..."
+msgstr "&Esporta..."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/FileMenu.qml:65
+msgctxt "@action:inmenu menubar:file"
+msgid "Export Selection..."
+msgstr "Esporta selezione..."
+
#: /home/ruben/Projects/Cura/resources/qml/Menus/ContextMenu.qml:27
msgctxt "@label"
msgid "Print Selected Model With:"
@@ -3761,654 +3917,509 @@ msgctxt "@label"
msgid "Number of Copies"
msgstr "Numero di copie"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:33
-msgctxt "@label:header configurations"
-msgid "Available configurations"
-msgstr "Configurazioni disponibili"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/AutoConfiguration.qml:18
+msgctxt "@header"
+msgid "Configurations"
+msgstr "Configurazioni"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml:28
-msgctxt "@label:extruder label"
-msgid "Extruder"
-msgstr "Estrusore"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:112
+msgctxt "@label"
+msgid "Select configuration"
+msgstr "Seleziona configurazione"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "Yes"
-msgstr "Sì"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml:223
+msgctxt "@label"
+msgid "Configurations"
+msgstr "Configurazioni"
-#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/SyncButton.qml:16
-msgctxt "@label:extruder label"
-msgid "No"
-msgstr "No"
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:57
+msgctxt "@label"
+msgid "Loading available configurations from the printer..."
+msgstr "Caricamento in corso configurazioni disponibili dalla stampante..."
-#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:13
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml:58
+msgctxt "@label"
+msgid "The configurations are not available because the printer is disconnected."
+msgstr "Le configurazioni non sono disponibili perché la stampante è scollegata."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:25
+msgctxt "@header"
+msgid "Custom"
+msgstr "Personalizzata"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:61
+msgctxt "@label"
+msgid "Printer"
+msgstr "Stampante"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:213
+msgctxt "@label"
+msgid "Enabled"
+msgstr "Abilitato"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:251
+msgctxt "@label"
+msgid "Material"
+msgstr "Materiale"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml:378
+msgctxt "@label"
+msgid "Use glue for better adhesion with this material combination."
+msgstr "Utilizzare la colla per una migliore adesione con questa combinazione di materiali."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:128
+msgctxt "@label"
+msgid "This configuration is not available because %1 is not recognized. Please visit %2 to download the correct material profile."
+msgstr "Questa configurazione non è disponibile perché %1 non viene riconosciuto. Visitare %2 per scaricare il profilo materiale corretto."
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml:129
+msgctxt "@label"
+msgid "Marketplace"
+msgstr "Mercato"
+
+#: /home/ruben/Projects/Cura/resources/qml/Menus/RecentFilesMenu.qml:15
msgctxt "@title:menu menubar:file"
msgid "Open &Recent"
msgstr "Ap&ri recenti"
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid "Print Setup"
-msgstr "Impostazione di stampa"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:150
-msgctxt "@label:listbox"
-msgid ""
-"Print Setup disabled\n"
-"G-code files cannot be modified"
-msgstr "Impostazione di stampa disabilitata\nI file codice G non possono essere modificati"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:340
-msgctxt "@label Hours and minutes"
-msgid "00h 00min"
-msgstr "00h 00min"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:358
-msgctxt "@tooltip"
-msgid "Time specification"
-msgstr "Indicazioni di tempo"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:440
-msgctxt "@label"
-msgid "Cost specification"
-msgstr "Indicazione di costo"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:445
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:454
-msgctxt "@label m for meter"
-msgid "%1m"
-msgstr "%1m"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:446
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:455
-msgctxt "@label g for grams"
-msgid "%1g"
-msgstr "%1g"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:453
-msgctxt "@label"
-msgid "Total:"
-msgstr "Totale:"
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:576
-msgctxt "@tooltip"
-msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
-msgstr "Impostazione di stampa consigliata
Stampa con le impostazioni consigliate per la stampante, il materiale e la qualità selezionati."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrepareSidebar.qml:581
-msgctxt "@tooltip"
-msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
-msgstr "Impostazione di stampa personalizzata
Stampa con il controllo grana fine su ogni sezione finale del processo di sezionamento."
-
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:140
msgctxt "@label"
msgid "Active print"
msgstr "Stampa attiva"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:148
msgctxt "@label"
msgid "Job Name"
msgstr "Nome del processo"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:156
msgctxt "@label"
msgid "Printing Time"
msgstr "Tempo di stampa"
-#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:130
+#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:164
msgctxt "@label"
msgid "Estimated time left"
msgstr "Tempo residuo stimato"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:79
+#: /home/ruben/Projects/Cura/resources/qml/ViewsSelector.qml:50
+msgctxt "@label"
+msgid "View type"
+msgstr "Visualizza tipo"
+
+#: /home/ruben/Projects/Cura/resources/qml/ObjectSelector.qml:59
+msgctxt "@label"
+msgid "Object list"
+msgstr "Elenco oggetti"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:22
+msgctxt "@label The argument is a username."
+msgid "Hi %1"
+msgstr "Alto %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:33
+msgctxt "@button"
+msgid "Ultimaker account"
+msgstr "Account Ultimaker"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/UserOperations.qml:42
+msgctxt "@button"
+msgid "Sign out"
+msgstr "Esci"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/AccountWidget.qml:24
+msgctxt "@action:button"
+msgid "Sign in"
+msgstr "Accedi"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:40
+msgctxt "@label"
+msgid "The next generation 3D printing workflow"
+msgstr "Flusso di stampa 3D di ultima generazione"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:51
+msgctxt "@text"
+msgid ""
+"- Send print jobs to Ultimaker printers outside your local network\n"
+"- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+"- Get exclusive access to print profiles from leading brands"
+msgstr ""
+"- Invia i processi di stampa alle stampanti Ultimaker esterne alla rete locale\n"
+"- Invia le impostazioni Ultimaker Cura nel cloud per usarle ovunque\n"
+"- Ottieni l’accesso esclusivo ai profili di stampa dai principali marchi"
+
+#: /home/ruben/Projects/Cura/resources/qml/Account/GeneralOperations.qml:78
+msgctxt "@button"
+msgid "Create account"
+msgstr "Crea account"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:59
+msgctxt "@label"
+msgid "No time estimation available"
+msgstr "Nessuna stima di tempo disponibile"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:77
+msgctxt "@label"
+msgid "No cost estimation available"
+msgstr "Nessuna stima di costo disponibile"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/OutputProcessWidget.qml:127
+msgctxt "@button"
+msgid "Preview"
+msgstr "Anteprima"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:55
+msgctxt "@label:PrintjobStatus"
+msgid "Slicing..."
+msgstr "Sezionamento in corso..."
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:67
+msgctxt "@label:PrintjobStatus"
+msgid "Unable to slice"
+msgstr "Sezionamento impossibile"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Processing"
+msgstr "Elaborazione in corso"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:103
+msgctxt "@button"
+msgid "Slice"
+msgstr "Sezionamento"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:104
+msgctxt "@label"
+msgid "Start the slicing process"
+msgstr "Avvia il processo di sezionamento"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/SliceProcessWidget.qml:118
+msgctxt "@button"
+msgid "Cancel"
+msgstr "Annulla"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:31
+msgctxt "@label"
+msgid "Time estimation"
+msgstr "Stima del tempo"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:114
+msgctxt "@label"
+msgid "Material estimation"
+msgstr "Stima del materiale"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:164
+msgctxt "@label m for meter"
+msgid "%1m"
+msgstr "%1m"
+
+#: /home/ruben/Projects/Cura/resources/qml/ActionPanel/PrintJobInformation.qml:165
+msgctxt "@label g for grams"
+msgid "%1g"
+msgstr "%1g"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Connected printers"
+msgstr "Stampanti collegate"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelectorList.qml:19
+msgctxt "@label"
+msgid "Preset printers"
+msgstr "Stampanti preimpostate"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:166
+msgctxt "@button"
+msgid "Add printer"
+msgstr "Aggiungi stampante"
+
+#: /home/ruben/Projects/Cura/resources/qml/PrinterSelector/MachineSelector.qml:182
+msgctxt "@button"
+msgid "Manage printers"
+msgstr "Gestione stampanti"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:81
+msgctxt "@action:inmenu"
+msgid "Show Online Troubleshooting Guide"
+msgstr "Mostra la Guida ricerca e riparazione dei guasti online"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:88
msgctxt "@action:inmenu"
msgid "Toggle Full Screen"
msgstr "Attiva/disattiva schermo intero"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:86
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+msgctxt "@action:inmenu"
+msgid "Exit Full Screen"
+msgstr "Esci da schermo intero"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:103
msgctxt "@action:inmenu menubar:edit"
msgid "&Undo"
msgstr "&Annulla"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
msgctxt "@action:inmenu menubar:edit"
msgid "&Redo"
msgstr "Ri&peti"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:106
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:123
msgctxt "@action:inmenu menubar:file"
msgid "&Quit"
msgstr "&Esci"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:114
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:131
msgctxt "@action:inmenu menubar:view"
msgid "3D View"
msgstr "Visualizzazione 3D"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:121
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:138
msgctxt "@action:inmenu menubar:view"
msgid "Front View"
msgstr "Visualizzazione frontale"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:128
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:145
msgctxt "@action:inmenu menubar:view"
msgid "Top View"
msgstr "Visualizzazione superiore"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:135
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:152
msgctxt "@action:inmenu menubar:view"
msgid "Left Side View"
msgstr "Visualizzazione lato sinistro"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:142
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:159
msgctxt "@action:inmenu menubar:view"
msgid "Right Side View"
msgstr "Visualizzazione lato destro"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:149
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:166
msgctxt "@action:inmenu"
msgid "Configure Cura..."
msgstr "Configura Cura..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:156
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:173
msgctxt "@action:inmenu menubar:printer"
msgid "&Add Printer..."
msgstr "&Aggiungi stampante..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:162
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:179
msgctxt "@action:inmenu menubar:printer"
msgid "Manage Pr&inters..."
msgstr "Gestione stampanti..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:169
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:186
msgctxt "@action:inmenu"
msgid "Manage Materials..."
msgstr "Gestione materiali..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:177
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:195
msgctxt "@action:inmenu menubar:profile"
msgid "&Update profile with current settings/overrides"
msgstr "&Aggiorna il profilo con le impostazioni/esclusioni correnti"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:185
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
msgctxt "@action:inmenu menubar:profile"
msgid "&Discard current changes"
msgstr "&Elimina le modifiche correnti"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:197
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:215
msgctxt "@action:inmenu menubar:profile"
msgid "&Create profile from current settings/overrides..."
msgstr "&Crea profilo dalle impostazioni/esclusioni correnti..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:221
msgctxt "@action:inmenu menubar:profile"
msgid "Manage Profiles..."
msgstr "Gestione profili..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:210
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:229
msgctxt "@action:inmenu menubar:help"
msgid "Show Online &Documentation"
msgstr "Mostra documentazione &online"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:218
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:237
msgctxt "@action:inmenu menubar:help"
msgid "Report a &Bug"
msgstr "Se&gnala un errore"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:226
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:245
+msgctxt "@action:inmenu menubar:help"
+msgid "What's New"
+msgstr "Scopri le novità"
+
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:251
msgctxt "@action:inmenu menubar:help"
msgid "About..."
msgstr "Informazioni..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:233
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:258
msgctxt "@action:inmenu menubar:edit"
msgid "Delete Selected Model"
msgid_plural "Delete Selected Models"
msgstr[0] "Cancella modello selezionato"
msgstr[1] "Cancella modelli selezionati"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:243
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:268
msgctxt "@action:inmenu menubar:edit"
msgid "Center Selected Model"
msgid_plural "Center Selected Models"
msgstr[0] "Centra modello selezionato"
msgstr[1] "Centra modelli selezionati"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:277
msgctxt "@action:inmenu menubar:edit"
msgid "Multiply Selected Model"
msgid_plural "Multiply Selected Models"
msgstr[0] "Moltiplica modello selezionato"
msgstr[1] "Moltiplica modelli selezionati"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:261
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:286
msgctxt "@action:inmenu"
msgid "Delete Model"
msgstr "Elimina modello"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:269
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:294
msgctxt "@action:inmenu"
msgid "Ce&nter Model on Platform"
msgstr "C&entra modello su piattaforma"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:275
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:300
msgctxt "@action:inmenu menubar:edit"
msgid "&Group Models"
msgstr "&Raggruppa modelli"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:295
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:320
msgctxt "@action:inmenu menubar:edit"
msgid "Ungroup Models"
msgstr "Separa modelli"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:305
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:330
msgctxt "@action:inmenu menubar:edit"
msgid "&Merge Models"
msgstr "&Unisci modelli"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:315
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:340
msgctxt "@action:inmenu"
msgid "&Multiply Model..."
msgstr "Mo<iplica modello..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:322
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:347
msgctxt "@action:inmenu menubar:edit"
msgid "Select All Models"
msgstr "Seleziona tutti i modelli"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:332
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:357
msgctxt "@action:inmenu menubar:edit"
msgid "Clear Build Plate"
msgstr "Cancellare piano di stampa"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:342
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:367
msgctxt "@action:inmenu menubar:file"
msgid "Reload All Models"
msgstr "Ricarica tutti i modelli"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:376
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models To All Build Plates"
msgstr "Sistema tutti i modelli su tutti i piani di stampa"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:358
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:383
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models"
msgstr "Sistema tutti i modelli"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:366
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:391
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange Selection"
msgstr "Sistema selezione"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:373
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:398
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Positions"
msgstr "Reimposta tutte le posizioni dei modelli"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:380
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:405
msgctxt "@action:inmenu menubar:edit"
msgid "Reset All Model Transformations"
msgstr "Reimposta tutte le trasformazioni dei modelli"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:387
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:412
msgctxt "@action:inmenu menubar:file"
msgid "&Open File(s)..."
msgstr "&Apri file..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:395
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:420
msgctxt "@action:inmenu menubar:file"
msgid "&New Project..."
msgstr "&Nuovo Progetto..."
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:402
-msgctxt "@action:inmenu menubar:help"
-msgid "Show Engine &Log..."
-msgstr "Mostra &log motore..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:410
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:427
msgctxt "@action:inmenu menubar:help"
msgid "Show Configuration Folder"
msgstr "Mostra cartella di configurazione"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:424
+#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:441
msgctxt "@action:menu"
-msgid "Browse packages..."
-msgstr "Sfoglia i pacchetti..."
+msgid "&Marketplace"
+msgstr "&Mercato"
-#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:431
-msgctxt "@action:inmenu menubar:view"
-msgid "Expand/Collapse Sidebar"
-msgstr "Espandi/Riduci barra laterale"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:27
-msgctxt "@label:PrintjobStatus"
-msgid "Please load a 3D model"
-msgstr "Caricare un modello 3D"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:37
-msgctxt "@label:PrintjobStatus"
-msgid "Ready to slice"
-msgstr "Pronto per il sezionamento"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:39
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing..."
-msgstr "Sezionamento in corso..."
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:41
-msgctxt "@label:PrintjobStatus %1 is target operation"
-msgid "Ready to %1"
-msgstr "Pronto a %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:43
-msgctxt "@label:PrintjobStatus"
-msgid "Unable to Slice"
-msgstr "Sezionamento impossibile"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:45
-msgctxt "@label:PrintjobStatus"
-msgid "Slicing unavailable"
-msgstr "Sezionamento non disponibile"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Slice current printjob"
-msgstr "Seziona processo di stampa corrente"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:172
-msgctxt "@info:tooltip"
-msgid "Cancel slicing process"
-msgstr "Annulla processo di sezionamento"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Prepare"
-msgstr "Prepara"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:184
-msgctxt "@label:Printjob"
-msgid "Cancel"
-msgstr "Annulla"
-
-#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:320
-msgctxt "@info:tooltip"
-msgid "Select the active output device"
-msgstr "Seleziona l'unità di uscita attiva"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:19
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:767
-msgctxt "@title:window"
-msgid "Open file(s)"
-msgstr "Apri file"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:64
-msgctxt "@text:window"
-msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
-msgstr "Rilevata la presenza di uno o più file progetto tra i file selezionati. È possibile aprire solo un file progetto alla volta. Si suggerisce di importare i modelli solo da tali file. Vuoi procedere?"
-
-#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:99
-msgctxt "@action:button"
-msgid "Import all as models"
-msgstr "Importa tutto come modelli"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:19
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:24
msgctxt "@title:window"
msgid "Ultimaker Cura"
msgstr "Ultimaker Cura"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:103
-msgctxt "@title:menu menubar:toplevel"
-msgid "&File"
-msgstr "&File"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:121
-msgctxt "@title:menu menubar:file"
-msgid "&Save..."
-msgstr "&Salva..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:142
-msgctxt "@title:menu menubar:file"
-msgid "&Export..."
-msgstr "&Esporta..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:153
-msgctxt "@action:inmenu menubar:file"
-msgid "Export Selection..."
-msgstr "Esporta selezione..."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:174
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Edit"
-msgstr "&Modifica"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:191
-msgctxt "@title:menu"
-msgid "&View"
-msgstr "&Visualizza"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:196
-msgctxt "@title:menu"
-msgid "&Settings"
-msgstr "&Impostazioni"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:198
-msgctxt "@title:menu menubar:settings"
-msgid "&Printer"
-msgstr "S&tampante"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:207
-msgctxt "@title:menu"
-msgid "&Material"
-msgstr "Ma&teriale"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:216
-msgctxt "@action:inmenu"
-msgid "Set as Active Extruder"
-msgstr "Imposta come estrusore attivo"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:222
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:188
-msgctxt "@action:inmenu"
-msgid "Enable Extruder"
-msgstr "Abilita estrusore"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:229
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:194
-msgctxt "@action:inmenu"
-msgid "Disable Extruder"
-msgstr "Disabilita estrusore"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:241
-msgctxt "@title:menu"
-msgid "&Build plate"
-msgstr "&Piano di stampa"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:242
-msgctxt "@title:settings"
-msgid "&Profile"
-msgstr "&Profilo"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:252
-msgctxt "@title:menu menubar:toplevel"
-msgid "E&xtensions"
-msgstr "Es&tensioni"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:286
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Toolbox"
-msgstr "&Casella degli strumenti"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:294
-msgctxt "@title:menu menubar:toplevel"
-msgid "P&references"
-msgstr "P&referenze"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:302
-msgctxt "@title:menu menubar:toplevel"
-msgid "&Help"
-msgstr "&Help"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:348
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:232
msgctxt "@label"
msgid "This package will be installed after restarting."
msgstr "Questo pacchetto sarà installato dopo il riavvio."
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:377
-msgctxt "@action:button"
-msgid "Open File"
-msgstr "Apri file"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:547
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:413
msgctxt "@title:tab"
msgid "Settings"
msgstr "Impostazioni"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:593
-msgctxt "@title:window"
-msgid "New project"
-msgstr "Nuovo progetto"
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:594
-msgctxt "@info:question"
-msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
-msgstr "Sei sicuro di voler aprire un nuovo progetto? Questo cancellerà il piano di stampa e tutte le impostazioni non salvate."
-
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:722
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:538
msgctxt "@title:window"
msgid "Closing Cura"
msgstr "Chiusura di Cura"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:723
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:735
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:539
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:551
msgctxt "@label"
msgid "Are you sure you want to exit Cura?"
msgstr "Sei sicuro di voler uscire da Cura?"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:868
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:589
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:19
+msgctxt "@title:window"
+msgid "Open file(s)"
+msgstr "Apri file"
+
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:695
msgctxt "@window:title"
msgid "Install Package"
msgstr "Installa il pacchetto"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:875
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:703
msgctxt "@title:window"
msgid "Open File(s)"
msgstr "Apri file"
-#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:878
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:706
msgctxt "@text:window"
msgid "We have found one or more G-Code files within the files you have selected. You can only open one G-Code file at a time. If you want to open a G-Code file, please just select only one."
msgstr "Rilevata la presenza di uno o più file codice G tra i file selezionati. È possibile aprire solo un file codice G alla volta. Se desideri aprire un file codice G, selezionane uno solo."
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:14
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:809
msgctxt "@title:window"
-msgid "Save Project"
-msgstr "Salva progetto"
+msgid "Add Printer"
+msgstr "Aggiungi stampante"
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:137
-msgctxt "@action:label"
-msgid "Build plate"
-msgstr "Piano di stampa"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:169
-msgctxt "@action:label"
-msgid "Extruder %1"
-msgstr "Estrusore %1"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:179
-msgctxt "@action:label"
-msgid "%1 & material"
-msgstr "%1 & materiale"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:268
-msgctxt "@action:label"
-msgid "Don't show project summary on save again"
-msgstr "Non mostrare il riepilogo di progetto alla ripetizione di salva"
-
-#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:287
-msgctxt "@action:button"
-msgid "Save"
-msgstr "Salva"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:192
-msgctxt "@label"
-msgid "Layer Height"
-msgstr "Altezza dello strato"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:277
-msgctxt "@tooltip"
-msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
-msgstr "Questo profilo di qualità non è disponibile per il materiale e la configurazione ugello corrente. Modificarli per abilitare questo profilo di qualità"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:450
-msgctxt "@tooltip"
-msgid "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab"
-msgstr "Un profilo personalizzato è attualmente attivo. Per attivare il cursore qualità, selezionare un profilo di qualità predefinito nella scheda Personalizza"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:467
-msgctxt "@label"
-msgid "Print Speed"
-msgstr "Velocità di stampa"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:479
-msgctxt "@label"
-msgid "Slower"
-msgstr "Più lenta"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:490
-msgctxt "@label"
-msgid "Faster"
-msgstr "Più veloce"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:518
-msgctxt "@tooltip"
-msgid "You have modified some profile settings. If you want to change these go to custom mode."
-msgstr "Sono state modificate alcune impostazioni del profilo. Per modificarle, andare alla modalità personalizzata."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:541
-msgctxt "@label"
-msgid "Infill"
-msgstr "Riempimento"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:777
-msgctxt "@label"
-msgid "Gradual infill will gradually increase the amount of infill towards the top."
-msgstr "Un riempimento graduale aumenterà gradualmente la quantità di riempimento verso l'alto."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:791
-msgctxt "@label"
-msgid "Enable gradual"
-msgstr "Consenti variazione graduale"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:858
-msgctxt "@label"
-msgid "Generate Support"
-msgstr "Generazione supporto"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:892
-msgctxt "@label"
-msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
-msgstr "Genera strutture per supportare le parti del modello a sbalzo. Senza queste strutture, queste parti collasserebbero durante la stampa."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:964
-msgctxt "@label"
-msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
-msgstr "Seleziona l’estrusore da utilizzare per la stampa di strutture di supporto. Ciò consentirà di costruire strutture di supporto sotto il modello per evitare cedimenti del modello o di stampare a mezz'aria."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:987
-msgctxt "@label"
-msgid "Build Plate Adhesion"
-msgstr "Adesione piano di stampa"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1042
-msgctxt "@label"
-msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
-msgstr "Abilita stampa di brim o raft. Questa funzione aggiunge un’area piana attorno o sotto l’oggetto, facile da tagliare successivamente."
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:1082
-msgctxt "@label"
-msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
-msgstr "Serve aiuto per migliorare le tue stampe? Leggi la Guida alla ricerca e riparazione guasti Ultimaker"
+#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:817
+msgctxt "@title:window"
+msgid "What's New"
+msgstr "Scopri le novità"
#: /home/ruben/Projects/Cura/resources/qml/ExtruderButton.qml:16
msgctxt "@label %1 is filled in with the name of an extruder"
@@ -4417,75 +4428,503 @@ msgid_plural "Print Selected Models with %1"
msgstr[0] "Stampa modello selezionato con %1"
msgstr[1] "Stampa modelli selezionati con %1"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:20
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:15
+msgctxt "@title:window"
+msgid "Discard or Keep changes"
+msgstr "Elimina o mantieni modifiche"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:57
+msgctxt "@text:window"
+msgid ""
+"You have customized some profile settings.\n"
+"Would you like to keep or discard those settings?"
+msgstr ""
+"Sono state personalizzate alcune impostazioni del profilo.\n"
+"Mantenere o eliminare tali impostazioni?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:110
+msgctxt "@title:column"
+msgid "Profile settings"
+msgstr "Impostazioni profilo"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:117
+msgctxt "@title:column"
+msgid "Default"
+msgstr "Valore predefinito"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:124
+msgctxt "@title:column"
+msgid "Customized"
+msgstr "Valore personalizzato"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:158
+msgctxt "@option:discardOrKeep"
+msgid "Discard and never ask again"
+msgstr "Elimina e non chiedere nuovamente"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:159
+msgctxt "@option:discardOrKeep"
+msgid "Keep and never ask again"
+msgstr "Mantieni e non chiedere nuovamente"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:196
+msgctxt "@action:button"
+msgid "Discard"
+msgstr "Elimina"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:209
+msgctxt "@action:button"
+msgid "Keep"
+msgstr "Mantieni"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml:222
+msgctxt "@action:button"
+msgid "Create New Profile"
+msgstr "Crea nuovo profilo"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:15
+msgctxt "@title:window"
+msgid "About Cura"
+msgstr "Informazioni su Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:57
+msgctxt "@label"
+msgid "version: %1"
+msgstr "versione: %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:72
+msgctxt "@label"
+msgid "End-to-end solution for fused filament 3D printing."
+msgstr "Soluzione end-to-end per la stampa 3D con filamento fuso."
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:85
+msgctxt "@info:credit"
+msgid ""
+"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
+"Cura proudly uses the following open source projects:"
+msgstr ""
+"Cura è stato sviluppato da Ultimaker B.V. in cooperazione con la comunità.\n"
+"Cura è orgogliosa di utilizzare i seguenti progetti open source:"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:135
+msgctxt "@label"
+msgid "Graphical user interface"
+msgstr "Interfaccia grafica utente"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:136
+msgctxt "@label"
+msgid "Application framework"
+msgstr "Struttura applicazione"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:137
+msgctxt "@label"
+msgid "G-code generator"
+msgstr "Generatore codice G"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:138
+msgctxt "@label"
+msgid "Interprocess communication library"
+msgstr "Libreria di comunicazione intra-processo"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:140
+msgctxt "@label"
+msgid "Programming language"
+msgstr "Lingua di programmazione"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:141
+msgctxt "@label"
+msgid "GUI framework"
+msgstr "Struttura GUI"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:142
+msgctxt "@label"
+msgid "GUI framework bindings"
+msgstr "Vincoli struttura GUI"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:143
+msgctxt "@label"
+msgid "C/C++ Binding library"
+msgstr "Libreria vincoli C/C++"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:144
+msgctxt "@label"
+msgid "Data interchange format"
+msgstr "Formato scambio dati"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:145
+msgctxt "@label"
+msgid "Support library for scientific computing"
+msgstr "Libreria di supporto per calcolo scientifico"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:146
+msgctxt "@label"
+msgid "Support library for faster math"
+msgstr "Libreria di supporto per calcolo rapido"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:147
+msgctxt "@label"
+msgid "Support library for handling STL files"
+msgstr "Libreria di supporto per gestione file STL"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:148
+msgctxt "@label"
+msgid "Support library for handling planar objects"
+msgstr "Libreria di supporto per gestione oggetti planari"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:149
+msgctxt "@label"
+msgid "Support library for handling triangular meshes"
+msgstr "Libreria di supporto per gestione maglie triangolari"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:150
+msgctxt "@label"
+msgid "Support library for analysis of complex networks"
+msgstr "Libreria di supporto per l’analisi di reti complesse"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:151
+msgctxt "@label"
+msgid "Support library for handling 3MF files"
+msgstr "Libreria di supporto per gestione file 3MF"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:152
+msgctxt "@label"
+msgid "Support library for file metadata and streaming"
+msgstr "Libreria di supporto per metadati file e streaming"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:153
+msgctxt "@label"
+msgid "Serial communication library"
+msgstr "Libreria di comunicazione seriale"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:154
+msgctxt "@label"
+msgid "ZeroConf discovery library"
+msgstr "Libreria scoperta ZeroConf"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:155
+msgctxt "@label"
+msgid "Polygon clipping library"
+msgstr "Libreria ritaglio poligono"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:156
+msgctxt "@Label"
+msgid "Python HTTP library"
+msgstr "Libreria Python HTTP"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:158
+msgctxt "@label"
+msgid "Font"
+msgstr "Font"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:159
+msgctxt "@label"
+msgid "SVG icons"
+msgstr "Icone SVG"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:160
+msgctxt "@label"
+msgid "Linux cross-distribution application deployment"
+msgstr "Apertura applicazione distribuzione incrociata Linux"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:64
+msgctxt "@text:window"
+msgid "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?"
+msgstr "Rilevata la presenza di uno o più file progetto tra i file selezionati. È possibile aprire solo un file progetto alla volta. Si suggerisce di importare i modelli solo da tali file. Vuoi procedere?"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:99
+msgctxt "@action:button"
+msgid "Import all as models"
+msgstr "Importa tutto come modelli"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:15
+msgctxt "@title:window"
+msgid "Save Project"
+msgstr "Salva progetto"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:177
+msgctxt "@action:label"
+msgid "Extruder %1"
+msgstr "Estrusore %1"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:192
+msgctxt "@action:label"
+msgid "%1 & material"
+msgstr "%1 & materiale"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:194
+msgctxt "@action:label"
+msgid "Material"
+msgstr "Materiale"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:283
+msgctxt "@action:label"
+msgid "Don't show project summary on save again"
+msgstr "Non mostrare il riepilogo di progetto alla ripetizione di salva"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/WorkspaceSummaryDialog.qml:302
+msgctxt "@action:button"
+msgid "Save"
+msgstr "Salva"
+
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:20
msgctxt "@title:window"
msgid "Open project file"
msgstr "Apri file progetto"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:93
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:93
msgctxt "@text:window"
msgid "This is a Cura project file. Would you like to open it as a project or import the models from it?"
msgstr "Questo è un file progetto Cura. Vuoi aprirlo come progetto o importarne i modelli?"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:103
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:103
msgctxt "@text:window"
msgid "Remember my choice"
msgstr "Ricorda la scelta"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:122
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:122
msgctxt "@action:button"
msgid "Open as project"
msgstr "Apri come progetto"
-#: /home/ruben/Projects/Cura/resources/qml/AskOpenAsProjectOrModelsDialog.qml:131
+#: /home/ruben/Projects/Cura/resources/qml/Dialogs/AskOpenAsProjectOrModelsDialog.qml:131
msgctxt "@action:button"
msgid "Import models"
msgstr "Importa i modelli"
-#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15
-msgctxt "@title:window"
-msgid "Engine Log"
-msgstr "Log motore"
-
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:70
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DropDownWidget.qml:93
msgctxt "@label"
-msgid "Printer type"
-msgstr "Tipo di stampante"
+msgid "Empty"
+msgstr "Vuoto"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:376
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:24
msgctxt "@label"
-msgid "Material"
-msgstr "Materiale"
+msgid "Add a printer"
+msgstr "Aggiungi una stampante"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:543
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:39
msgctxt "@label"
-msgid "Use glue with this material combination"
-msgstr "Utilizzare la colla con questa combinazione di materiali"
+msgid "Add a networked printer"
+msgstr "Aggiungi una stampante in rete"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:575
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml:81
msgctxt "@label"
-msgid "Check compatibility"
-msgstr "Controlla compatibilità"
+msgid "Add a non-networked printer"
+msgstr "Aggiungi una stampante non in rete"
-#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:593
-msgctxt "@tooltip"
-msgid "Click to check the material compatibility on Ultimaker.com."
-msgstr "Fai clic per verificare la compatibilità del materiale su Ultimaker.com."
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:70
+msgctxt "@label"
+msgid "Add printer by IP address"
+msgstr "Aggiungi stampante per indirizzo IP"
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:211
-msgctxt "@option:check"
-msgid "See only current build plate"
-msgstr "Vedi solo il piano di stampa corrente"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:133
+msgctxt "@text"
+msgid "Place enter your printer's IP address."
+msgstr "Inserisci l'indirizzo IP della stampante."
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:227
-msgctxt "@action:button"
-msgid "Arrange to all build plates"
-msgstr "Sistema su tutti i piani di stampa"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:158
+msgctxt "@button"
+msgid "Add"
+msgstr "Aggiungi"
-#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:247
-msgctxt "@action:button"
-msgid "Arrange current build plate"
-msgstr "Sistema il piano di stampa corrente"
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:204
+msgctxt "@label"
+msgid "Could not connect to device."
+msgstr "Impossibile connettersi al dispositivo."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:208
+msgctxt "@label"
+msgid "The printer at this address has not responded yet."
+msgstr "La stampante a questo indirizzo non ha ancora risposto."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:240
+msgctxt "@label"
+msgid "This printer cannot be added because it's an unknown printer or it's not the host of a group."
+msgstr "Questa stampante non può essere aggiunta perché è una stampante sconosciuta o non è l'host di un gruppo."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:329
+msgctxt "@button"
+msgid "Back"
+msgstr "Indietro"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:342
+msgctxt "@button"
+msgid "Connect"
+msgstr "Collega"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/FirstStartMachineActionsContent.qml:77
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:123
+msgctxt "@button"
+msgid "Next"
+msgstr "Avanti"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:23
+msgctxt "@label"
+msgid "User Agreement"
+msgstr "Contratto di licenza"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:56
+msgctxt "@button"
+msgid "Agree"
+msgstr "Accetta"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/UserAgreementContent.qml:70
+msgctxt "@button"
+msgid "Decline and close"
+msgstr "Rifiuta e chiudi"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:24
+msgctxt "@label"
+msgid "Help us to improve Ultimaker Cura"
+msgstr "Aiutaci a migliorare Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:57
+msgctxt "@text"
+msgid "Ultimaker Cura collects anonymous data to improve print quality and user experience, including:"
+msgstr "Ultimaker Cura acquisisce dati anonimi per migliorare la qualità di stampa e l'esperienza dell'utente, tra cui:"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:71
+msgctxt "@text"
+msgid "Machine types"
+msgstr "Tipi di macchine"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:77
+msgctxt "@text"
+msgid "Material usage"
+msgstr "Utilizzo dei materiali"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:83
+msgctxt "@text"
+msgid "Number of slices"
+msgstr "Numero di sezionamenti"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:89
+msgctxt "@text"
+msgid "Print settings"
+msgstr "Impostazioni di stampa"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:102
+msgctxt "@text"
+msgid "Data collected by Ultimaker Cura will not contain any personal information."
+msgstr "I dati acquisiti da Ultimaker Cura non conterranno alcuna informazione personale."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/DataCollectionsContent.qml:103
+msgctxt "@text"
+msgid "More information"
+msgstr "Ulteriori informazioni"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WhatsNewContent.qml:24
+msgctxt "@label"
+msgid "What's new in Ultimaker Cura"
+msgstr "Scopri le novità in Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:42
+msgctxt "@label"
+msgid "There is no printer found over your network."
+msgstr "Non è stata trovata alcuna stampante sulla rete."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:179
+msgctxt "@label"
+msgid "Refresh"
+msgstr "Aggiorna"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:190
+msgctxt "@label"
+msgid "Add printer by IP"
+msgstr "Aggiungi stampante per IP"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml:223
+msgctxt "@label"
+msgid "Troubleshooting"
+msgstr "Ricerca e riparazione dei guasti"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:211
+msgctxt "@label"
+msgid "Printer name"
+msgstr "Nome stampante"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml:224
+msgctxt "@text"
+msgid "Please give your printer a name"
+msgstr "Assegna un nome alla stampante"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:36
+msgctxt "@label"
+msgid "Ultimaker Cloud"
+msgstr "Ultimaker Cloud"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:77
+msgctxt "@text"
+msgid "The next generation 3D printing workflow"
+msgstr "Flusso di stampa 3D di ultima generazione"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:94
+msgctxt "@text"
+msgid "- Send print jobs to Ultimaker printers outside your local network"
+msgstr "- Invia i processi di stampa alle stampanti Ultimaker esterne alla rete locale"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:97
+msgctxt "@text"
+msgid "- Store your Ultimaker Cura settings in the cloud for use anywhere"
+msgstr "- Memorizza le impostazioni Ultimaker Cura nel cloud per usarle ovunque"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:100
+msgctxt "@text"
+msgid "- Get exclusive access to print profiles from leading brands"
+msgstr "- Ottieni l'accesso esclusivo ai profili di stampa dai principali marchi"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:119
+msgctxt "@button"
+msgid "Finish"
+msgstr "Fine"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:128
+msgctxt "@button"
+msgid "Create an account"
+msgstr "Crea un account"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:29
+msgctxt "@label"
+msgid "Welcome to Ultimaker Cura"
+msgstr "Benvenuto in Ultimaker Cura"
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:47
+msgctxt "@text"
+msgid ""
+"Please follow these steps to set up\n"
+"Ultimaker Cura. This will only take a few moments."
+msgstr ""
+"Segui questa procedura per configurare\n"
+"Ultimaker Cura. Questa operazione richiederà solo pochi istanti."
+
+#: /home/ruben/Projects/Cura/resources/qml/WelcomePages/WelcomeContent.qml:58
+msgctxt "@button"
+msgid "Get started"
+msgstr "Per iniziare"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:27
+msgctxt "@info:tooltip"
+msgid "3D View"
+msgstr "Visualizzazione 3D"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:40
+msgctxt "@info:tooltip"
+msgid "Front View"
+msgstr "Visualizzazione frontale"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:53
+msgctxt "@info:tooltip"
+msgid "Top View"
+msgstr "Visualizzazione superiore"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:66
+msgctxt "@info:tooltip"
+msgid "Left View"
+msgstr "Vista sinistra"
+
+#: /home/ruben/Projects/Cura/resources/qml/ViewOrientationControls.qml:79
+msgctxt "@info:tooltip"
+msgid "Right View"
+msgstr "Vista destra"
#: MachineSettingsAction/plugin.json
msgctxt "description"
@@ -4547,26 +4986,6 @@ msgctxt "name"
msgid "Model Checker"
msgstr "Controllo modello"
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "description"
-msgid "Dump the contents of all settings to a HTML file."
-msgstr "Scarica contenuto di tutte le impostazioni in un file HTML."
-
-#: cura-god-mode-plugin/src/GodMode/plugin.json
-msgctxt "name"
-msgid "God Mode"
-msgstr "Modalità God"
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "description"
-msgid "Shows changes since latest checked version."
-msgstr "Mostra le modifiche dall'ultima versione selezionata."
-
-#: ChangeLogPlugin/plugin.json
-msgctxt "name"
-msgid "Changelog"
-msgstr "Registro modifiche"
-
#: FirmwareUpdater/plugin.json
msgctxt "description"
msgid "Provides a machine actions for updating firmware."
@@ -4577,15 +4996,15 @@ msgctxt "name"
msgid "Firmware Updater"
msgstr "Aggiornamento firmware"
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "description"
-msgid "Create a flattend quality changes profile."
-msgstr "Crea un profilo appiattito."
+msgid "Provides support for reading AMF files."
+msgstr "Fornisce il supporto per la lettura di file 3MF."
-#: ProfileFlattener/plugin.json
+#: AMFReader/plugin.json
msgctxt "name"
-msgid "Profile flatener"
-msgstr "Appiattitore di profilo"
+msgid "AMF Reader"
+msgstr "Lettore 3MF"
#: USBPrinting/plugin.json
msgctxt "description"
@@ -4597,26 +5016,6 @@ msgctxt "name"
msgid "USB printing"
msgstr "Stampa USB"
-#: UserAgreement/plugin.json
-msgctxt "description"
-msgid "Ask the user once if he/she agrees with our license."
-msgstr "Chiedere una volta all'utente se accetta la nostra licenza."
-
-#: UserAgreement/plugin.json
-msgctxt "name"
-msgid "UserAgreement"
-msgstr "Contratto di licenza"
-
-#: X3GWriter/plugin.json
-msgctxt "description"
-msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
-msgstr "Consente di salvare il sezionamento risultante come un file X3G, per supportare le stampanti che leggono questo formato (Malyan, Makerbot ed altre stampanti basate su firmware Sailfish)."
-
-#: X3GWriter/plugin.json
-msgctxt "name"
-msgid "X3GWriter"
-msgstr "X3GWriter"
-
#: GCodeGzWriter/plugin.json
msgctxt "description"
msgid "Writes g-code to a compressed archive."
@@ -4659,13 +5058,13 @@ msgstr "Plugin dispositivo di output unità rimovibile"
#: UM3NetworkPrinting/plugin.json
msgctxt "description"
-msgid "Manages network connections to Ultimaker 3 printers."
-msgstr "Gestisce le connessioni di rete alle stampanti Ultimaker 3."
+msgid "Manages network connections to Ultimaker networked printers."
+msgstr "Gestisce le connessioni di rete alle stampanti Ultimaker in rete."
#: UM3NetworkPrinting/plugin.json
msgctxt "name"
-msgid "UM3 Network Connection"
-msgstr "Connessione di rete UM3"
+msgid "Ultimaker Network Connection"
+msgstr "Connessione di rete Ultimaker"
#: MonitorStage/plugin.json
msgctxt "description"
@@ -4727,6 +5126,16 @@ msgctxt "name"
msgid "Support Eraser"
msgstr "Cancellazione supporto"
+#: UFPReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading Ultimaker Format Packages."
+msgstr "Fornisce il supporto per la lettura di pacchetti formato Ultimaker."
+
+#: UFPReader/plugin.json
+msgctxt "name"
+msgid "UFP Reader"
+msgstr "Lettore UFP"
+
#: SliceInfoPlugin/plugin.json
msgctxt "description"
msgid "Submits anonymous slice info. Can be disabled through preferences."
@@ -4787,6 +5196,16 @@ msgctxt "name"
msgid "Version Upgrade 3.3 to 3.4"
msgstr "Aggiornamento della versione da 3.3 a 3.4"
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.3 to Cura 4.4."
+msgstr "Aggiorna le configurazioni da Cura 4.3 a Cura 4.4."
+
+#: VersionUpgrade/VersionUpgrade43to44/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.3 to 4.4"
+msgstr "Aggiornamento della versione da 4.3 a 4.4"
+
#: VersionUpgrade/VersionUpgrade25to26/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.5 to Cura 2.6."
@@ -4807,6 +5226,16 @@ msgctxt "name"
msgid "Version Upgrade 2.7 to 3.0"
msgstr "Aggiornamento della versione da 2.7 a 3.0"
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 3.5 to Cura 4.0."
+msgstr "Aggiorna le configurazioni da Cura 3.5 a Cura 4.0."
+
+#: VersionUpgrade/VersionUpgrade35to40/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 3.5 to 4.0"
+msgstr "Aggiornamento della versione da 3.5 a 4.0"
+
#: VersionUpgrade/VersionUpgrade34to35/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.4 to Cura 3.5."
@@ -4817,6 +5246,16 @@ msgctxt "name"
msgid "Version Upgrade 3.4 to 3.5"
msgstr "Aggiornamento della versione da 3.4 a 3.5"
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.0 to Cura 4.1."
+msgstr "Aggiorna le configurazioni da Cura 4.0 a Cura 4.1."
+
+#: VersionUpgrade/VersionUpgrade40to41/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.0 to 4.1"
+msgstr "Aggiornamento della versione da 4.0 a 4.1"
+
#: VersionUpgrade/VersionUpgrade30to31/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 3.0 to Cura 3.1."
@@ -4827,6 +5266,16 @@ msgctxt "name"
msgid "Version Upgrade 3.0 to 3.1"
msgstr "Aggiornamento della versione da 3.0 a 3.1"
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.1 to Cura 4.2."
+msgstr "Aggiorna le configurazioni da Cura 4.1 a Cura 4.2."
+
+#: VersionUpgrade/VersionUpgrade41to42/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.1 to 4.2"
+msgstr "Aggiornamento della versione da 4.1 a 4.2"
+
#: VersionUpgrade/VersionUpgrade26to27/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 2.6 to Cura 2.7."
@@ -4857,6 +5306,16 @@ msgctxt "name"
msgid "Version Upgrade 2.2 to 2.4"
msgstr "Aggiornamento della versione da 2.2 a 2.4"
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "description"
+msgid "Upgrades configurations from Cura 4.2 to Cura 4.3."
+msgstr "Aggiorna le configurazioni da Cura 4.2 a Cura 4.3."
+
+#: VersionUpgrade/VersionUpgrade42to43/plugin.json
+msgctxt "name"
+msgid "Version Upgrade 4.2 to 4.3"
+msgstr "Aggiornamento della versione da 4.2 a 4.3"
+
#: ImageReader/plugin.json
msgctxt "description"
msgid "Enables ability to generate printable geometry from 2D image files."
@@ -4867,6 +5326,16 @@ msgctxt "name"
msgid "Image Reader"
msgstr "Lettore di immagine"
+#: TrimeshReader/plugin.json
+msgctxt "description"
+msgid "Provides support for reading model files."
+msgstr "Fornisce supporto per la lettura dei file modello."
+
+#: TrimeshReader/plugin.json
+msgctxt "name"
+msgid "Trimesh Reader"
+msgstr "Trimesh Reader"
+
#: CuraEngineBackend/plugin.json
msgctxt "description"
msgid "Provides the link to the CuraEngine slicing backend."
@@ -4917,6 +5386,16 @@ msgctxt "name"
msgid "G-code Reader"
msgstr "Lettore codice G"
+#: CuraDrive/plugin.json
+msgctxt "description"
+msgid "Backup and restore your configuration."
+msgstr "Effettua il backup o ripristina la configurazione."
+
+#: CuraDrive/plugin.json
+msgctxt "name"
+msgid "Cura Backups"
+msgstr "Backup Cura"
+
#: CuraProfileWriter/plugin.json
msgctxt "description"
msgid "Provides support for exporting Cura profiles."
@@ -4937,6 +5416,16 @@ msgctxt "name"
msgid "3MF Writer"
msgstr "Writer 3MF"
+#: PreviewStage/plugin.json
+msgctxt "description"
+msgid "Provides a preview stage in Cura."
+msgstr "Fornisce una fase di anteprima in Cura."
+
+#: PreviewStage/plugin.json
+msgctxt "name"
+msgid "Preview Stage"
+msgstr "Fase di anteprima"
+
#: UltimakerMachineActions/plugin.json
msgctxt "description"
msgid "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.)."
@@ -4957,9 +5446,29 @@ msgctxt "name"
msgid "Cura Profile Reader"
msgstr "Lettore profilo Cura"
-#~ msgctxt "@warning:status"
-#~ msgid "Please generate G-code before saving."
-#~ msgstr "Generare il codice G prima di salvare."
+#~ msgctxt "@item:inmenu"
+#~ msgid "Flatten active settings"
+#~ msgstr "Impostazioni attive profilo appiattito"
+
+#~ msgctxt "@info:status"
+#~ msgid "Profile has been flattened & activated."
+#~ msgstr "Il profilo è stato appiattito e attivato."
+
+#~ msgctxt "X3g Writer Plugin Description"
+#~ msgid "Writes X3g to files"
+#~ msgstr "Scrive X3g sui file"
+
+#~ msgctxt "X3g Writer File Description"
+#~ msgid "X3g File"
+#~ msgstr "File X3g"
+
+#~ msgctxt "X3G Writer File Description"
+#~ msgid "X3G File"
+#~ msgstr "File X3G"
+
+#~ msgctxt "@item:inlistbox"
+#~ msgid "Open Compressed Triangle Mesh"
+#~ msgstr ""
#~ msgctxt "@item:inmenu"
#~ msgid "Profile Assistant"
@@ -4969,6 +5478,1032 @@ msgstr "Lettore profilo Cura"
#~ msgid "Profile Assistant"
#~ msgstr "Assistente profilo"
+#~ msgctxt "@action:button"
+#~ msgid "Retry"
+#~ msgstr "Riprova"
+
+#~ msgctxt "@label:table_header"
+#~ msgid "Print Core"
+#~ msgstr "Print Core"
+
+#~ msgctxt "@label"
+#~ msgid "Don't support overlap with other models"
+#~ msgstr "Non supporta sovrapposizione con altri modelli"
+
+#~ msgctxt "@label"
+#~ msgid "Modify settings for overlap with other models"
+#~ msgstr "Modifica impostazioni per sovrapposizione con altri modelli"
+
+#~ msgctxt "@label"
+#~ msgid "Modify settings for infill of other models"
+#~ msgstr "Modifica impostazioni per riempimento di altri modelli"
+
+#~ msgctxt "@action:ComboBox option"
+#~ msgid "Update existing"
+#~ msgstr "Aggiorna esistente"
+
+#~ msgctxt "@label"
+#~ msgid "Not supported"
+#~ msgstr "Non supportato"
+
+#~ msgctxt "@action:button"
+#~ msgid "Previous"
+#~ msgstr "Precedente"
+
+#~ msgctxt "@label"
+#~ msgid "Tip"
+#~ msgstr "Suggerimento"
+
+#~ msgctxt "@label"
+#~ msgid "Print experiment"
+#~ msgstr "Prova di stampa"
+
+#~ msgctxt "@label"
+#~ msgid "Checklist"
+#~ msgstr "Lista di controllo"
+
+#~ msgctxt "@label"
+#~ msgid "Please select any upgrades made to this Ultimaker 2."
+#~ msgstr "Seleziona qualsiasi aggiornamento realizzato per questa Ultimaker 2."
+
+#~ msgctxt "@label"
+#~ msgid "Olsson Block"
+#~ msgstr "Blocco Olsson"
+
+#~ msgctxt "@window:text"
+#~ msgid "Camera rendering: "
+#~ msgstr "Rendering fotocamera: "
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Use multi build plate functionality"
+#~ msgstr "Utilizzare la funzionalità piano di stampa multiplo"
+
+#~ msgctxt "@option:check"
+#~ msgid "Use multi build plate functionality (restart required)"
+#~ msgstr "Utilizzare la funzionalità piano di stampa multiplo (necessario riavvio)"
+
+#~ msgctxt "@label"
+#~ msgid "Default profiles"
+#~ msgstr "Profili predefiniti"
+
+#~ msgctxt "@label:textbox"
+#~ msgid "search settings"
+#~ msgstr "impostazioni ricerca"
+
+#~ msgctxt "@label"
+#~ msgid "Layer Height"
+#~ msgstr "Altezza dello strato"
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile."
+#~ msgstr "Questo profilo di qualità non è disponibile per la configurazione attuale del materiale e degli ugelli. Modificare tali configurazioni per abilitare il profilo di qualità desiderato."
+
+#~ msgctxt "@tooltip"
+#~ msgid "A custom profile is currently active. To enable the quality slider, choose a default quality profile in Custom tab"
+#~ msgstr "Un profilo personalizzato è attualmente attivo. Per attivare il cursore qualità, selezionare un profilo di qualità predefinito nella scheda Personalizza"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Build plate"
+#~ msgstr "&Piano di stampa"
+
+#~ msgctxt "@title:settings"
+#~ msgid "&Profile"
+#~ msgstr "&Profilo"
+
+#~ msgctxt "@action:label"
+#~ msgid "Build plate"
+#~ msgstr "Piano di stampa"
+
+#~ msgctxt "description"
+#~ msgid "Dump the contents of all settings to a HTML file."
+#~ msgstr "Scarica contenuto di tutte le impostazioni in un file HTML."
+
+#~ msgctxt "name"
+#~ msgid "God Mode"
+#~ msgstr "Modalità God"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattened quality changes profile."
+#~ msgstr "Crea un profilo appiattito di modifiche di qualità."
+
+#~ msgctxt "name"
+#~ msgid "Profile Flattener"
+#~ msgstr "Appiattitore di profilo"
+
+#~ msgctxt "description"
+#~ msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
+#~ msgstr "Consente ai produttori di materiali di creare nuovi profili materiale e di qualità utilizzando una UI drop-in."
+
+#~ msgctxt "name"
+#~ msgid "Print Profile Assistant"
+#~ msgstr "Assistente profilo di stampa"
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network."
+#~ msgstr "Collegato alla rete."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. Please approve the access request on the printer."
+#~ msgstr "Collegato alla rete. Si prega di approvare la richiesta di accesso sulla stampante."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected over the network. No access to control the printer."
+#~ msgstr "Collegato alla rete. Nessun accesso per controllare la stampante."
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer requested. Please approve the request on the printer"
+#~ msgstr "Richiesto accesso alla stampante. Approvare la richiesta sulla stampante"
+
+#~ msgctxt "@info:title"
+#~ msgid "Authentication status"
+#~ msgstr "Stato di autenticazione"
+
+#~ msgctxt "@info:title"
+#~ msgid "Authentication Status"
+#~ msgstr "Stato di autenticazione"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Re-send the access request"
+#~ msgstr "Invia nuovamente la richiesta di accesso"
+
+#~ msgctxt "@info:status"
+#~ msgid "Access to the printer accepted"
+#~ msgstr "Accesso alla stampante accettato"
+
+#~ msgctxt "@info:status"
+#~ msgid "No access to print with this printer. Unable to send print job."
+#~ msgstr "Nessun accesso per stampare con questa stampante. Impossibile inviare il processo di stampa."
+
+#~ msgctxt "@action:button"
+#~ msgid "Request Access"
+#~ msgstr "Richiesta di accesso"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Send access request to the printer"
+#~ msgstr "Invia la richiesta di accesso alla stampante"
+
+#~ msgctxt "@label"
+#~ msgid "Unable to start a new print job."
+#~ msgstr "Impossibile avviare un nuovo processo di stampa."
+
+#~ msgctxt "@label"
+#~ msgid "There is an issue with the configuration of your Ultimaker, which makes it impossible to start the print. Please resolve this issues before continuing."
+#~ msgstr "È presente un problema di configurazione della stampante che rende impossibile l’avvio della stampa. Risolvere il problema prima di continuare."
+
+#~ msgctxt "@window:title"
+#~ msgid "Mismatched configuration"
+#~ msgstr "Mancata corrispondenza della configurazione"
+
+#~ msgctxt "@label"
+#~ msgid "Are you sure you wish to print with the selected configuration?"
+#~ msgstr "Sei sicuro di voler stampare con la configurazione selezionata?"
+
+#~ msgctxt "@label"
+#~ msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "Le configurazioni o la calibrazione della stampante e di Cura non corrispondono. Per ottenere i migliori risultati, sezionare sempre per i PrintCore e i materiali inseriti nella stampante utilizzata."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending new jobs (temporarily) blocked, still sending the previous print job."
+#~ msgstr "Invio nuovi processi (temporaneamente) bloccato, invio in corso precedente processo di stampa."
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending data to printer"
+#~ msgstr "Invio dati alla stampante in corso"
+
+#~ msgctxt "@info:title"
+#~ msgid "Sending Data"
+#~ msgstr "Invio dati"
+
+#~ msgctxt "@info:status"
+#~ msgid "No Printcore loaded in slot {slot_number}"
+#~ msgstr "Nessun PrintCore caricato nello slot {slot_number}"
+
+#~ msgctxt "@info:status"
+#~ msgid "No material loaded in slot {slot_number}"
+#~ msgstr "Nessun materiale caricato nello slot {slot_number}"
+
+#~ msgctxt "@label"
+#~ msgid "Different PrintCore (Cura: {cura_printcore_name}, Printer: {remote_printcore_name}) selected for extruder {extruder_id}"
+#~ msgstr "PrintCore diverso (Cura: {cura_printcore_name}, Stampante: {remote_printcore_name}) selezionata per estrusore {extruder_id}"
+
+#~ msgctxt "@label"
+#~ msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
+#~ msgstr "Materiale diverso (Cura: {0}, Stampante: {1}) selezionato per l’estrusore {2}"
+
+#~ msgctxt "@window:title"
+#~ msgid "Sync with your printer"
+#~ msgstr "Sincronizzazione con la stampante"
+
+#~ msgctxt "@label"
+#~ msgid "Would you like to use your current printer configuration in Cura?"
+#~ msgstr "Desideri utilizzare la configurazione corrente della tua stampante in Cura?"
+
+#~ msgctxt "@label"
+#~ msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
+#~ msgstr "I PrintCore e/o i materiali sulla stampante differiscono da quelli contenuti nel tuo attuale progetto. Per ottenere i risultati migliori, sezionare sempre per i PrintCore e i materiali inseriti nella stampante utilizzata."
+
+#~ msgctxt "@action:button"
+#~ msgid "View in Monitor"
+#~ msgstr "Visualizzazione in Controlla"
+
+#~ msgctxt "@info:status"
+#~ msgid "Printer '{printer_name}' has finished printing '{job_name}'."
+#~ msgstr "La stampante '{printer_name}' ha finito di stampare '{job_name}'."
+
+#~ msgctxt "@info:status"
+#~ msgid "The print job '{job_name}' was finished."
+#~ msgstr "Il processo di stampa '{job_name}' è terminato."
+
+#~ msgctxt "@info:status"
+#~ msgid "Print finished"
+#~ msgstr "Stampa finita"
+
+#~ msgctxt "@label:material"
+#~ msgid "Empty"
+#~ msgstr "Vuoto"
+
+#~ msgctxt "@label:material"
+#~ msgid "Unknown"
+#~ msgstr "Sconosciuto"
+
+#~ msgctxt "@info:title"
+#~ msgid "Cloud error"
+#~ msgstr "Errore cloud"
+
+#~ msgctxt "@info:status"
+#~ msgid "Could not export print job."
+#~ msgstr "Impossibile esportare il processo di stampa."
+
+#~ msgctxt "@info:description"
+#~ msgid "There was an error connecting to the cloud."
+#~ msgstr "Si è verificato un errore di collegamento al cloud."
+
+#~ msgctxt "@info:status"
+#~ msgid "Uploading via Ultimaker Cloud"
+#~ msgstr "Caricamento tramite Ultimaker Cloud"
+
+#~ msgctxt "@info:status Ultimaker Cloud is a brand name and shouldn't be translated."
+#~ msgid "Connect to Ultimaker Cloud"
+#~ msgstr "Collegato a Ultimaker Cloud"
+
+#~ msgctxt "@action"
+#~ msgid "Don't ask me again for this printer."
+#~ msgstr "Non chiedere nuovamente per questa stampante."
+
+#~ msgctxt "@info:status"
+#~ msgid "You can now send and monitor print jobs from anywhere using your Ultimaker account."
+#~ msgstr "Ora è possibile inviare e controllare i processi di stampa ovunque con l’account Ultimaker."
+
+#~ msgctxt "@info:status"
+#~ msgid "Connected!"
+#~ msgstr "Collegato!"
+
+#~ msgctxt "@action"
+#~ msgid "Review your connection"
+#~ msgstr "Controlla collegamento"
+
+#~ msgctxt "@info:status Don't translate the XML tags !"
+#~ msgid "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it."
+#~ msgstr "La macchina definita nel profilo {0} ({1}) non corrisponde alla macchina corrente ({2}), impossibile importarla."
+
+#~ msgctxt "@info:status Don't translate the XML tags or !"
+#~ msgid "Failed to import profile from {0}:"
+#~ msgstr "Impossibile importare il profilo da {0}:"
+
+#~ msgctxt "@window:title"
+#~ msgid "Existing Connection"
+#~ msgstr "Collegamento esistente"
+
+#~ msgctxt "@message:text"
+#~ msgid "This printer/group is already added to Cura. Please select another printer/group."
+#~ msgstr "Stampante/gruppo già aggiunto a Cura. Selezionare un’altra stampante o un altro gruppo."
+
+#~ msgctxt "@label"
+#~ msgid "Enter the IP address or hostname of your printer on the network."
+#~ msgstr "Inserire l’indirizzo IP o l’hostname della stampante sulla rete."
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Connect to a printer"
+#~ msgstr "Collega a una stampante"
+
+#~ msgctxt "@title"
+#~ msgid "Cura Settings Guide"
+#~ msgstr "Guida alle impostazioni Cura"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Zooming towards the mouse is not supported in the orthogonal perspective."
+#~ msgstr "Nella prospettiva ortogonale lo zoom verso la direzione del mouse non è supportato."
+
+#~ msgid "Orthogonal"
+#~ msgstr "Ortogonale"
+
+#~ msgctxt "description"
+#~ msgid "Manages network connections to Ultimaker 3 printers."
+#~ msgstr "Gestisce le connessioni di rete alle stampanti Ultimaker 3."
+
+#~ msgctxt "name"
+#~ msgid "UM3 Network Connection"
+#~ msgstr "Connessione di rete UM3"
+
+#~ msgctxt "description"
+#~ msgid "Provides extra information and explanations about settings in Cura, with images and animations."
+#~ msgstr "Fornisce informazioni e spiegazioni aggiuntive sulle impostazioni in Cura, con immagini e animazioni."
+
+#~ msgctxt "name"
+#~ msgid "Settings Guide"
+#~ msgstr "Guida alle impostazioni"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Cura Settings Guide"
+#~ msgstr "Guida alle impostazioni Cura"
+
+#~ msgctxt "@info:generic"
+#~ msgid "Settings have been changed to match the current availability of extruders: [%s]"
+#~ msgstr "Le impostazioni sono state modificate in base all’attuale disponibilità di estrusori: [%s]"
+
+#~ msgctxt "@title:groupbox"
+#~ msgid "User description"
+#~ msgstr "Descrizione utente"
+
+#~ msgctxt "@info"
+#~ msgid "These options are not available because you are monitoring a cloud printer."
+#~ msgstr "Queste opzioni non sono disponibili perché si sta controllando una stampante cloud."
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Go to Cura Connect"
+#~ msgstr "Vai a Cura Connect"
+
+#~ msgctxt "@info"
+#~ msgid "All jobs are printed."
+#~ msgstr "Tutti i processi sono stampati."
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "View print history"
+#~ msgstr "Visualizza cronologia di stampa"
+
+#~ msgctxt "@label"
+#~ msgid ""
+#~ "To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
+#~ "\n"
+#~ "Select your printer from the list below:"
+#~ msgstr ""
+#~ "Per stampare direttamente sulla stampante in rete, verificare che la stampante desiderata sia collegata alla rete mediante un cavo di rete o mediante collegamento alla rete WIFI. Se si collega Cura alla stampante, è comunque possibile utilizzare una chiavetta USB per trasferire i file codice G alla stampante.\n"
+#~ "\n"
+#~ "Selezionare la stampante dall’elenco seguente:"
+
+#~ msgctxt "@info"
+#~ msgid ""
+#~ "Please make sure your printer has a connection:\n"
+#~ "- Check if the printer is turned on.\n"
+#~ "- Check if the printer is connected to the network."
+#~ msgstr ""
+#~ "Accertarsi che la stampante sia collegata:\n"
+#~ "- Controllare se la stampante è accesa.\n"
+#~ "- Controllare se la stampante è collegata alla rete."
+
+#~ msgctxt "@option:check"
+#~ msgid "See only current build plate"
+#~ msgstr "Vedi solo il piano di stampa corrente"
+
+#~ msgctxt "@action:button"
+#~ msgid "Arrange to all build plates"
+#~ msgstr "Sistema su tutti i piani di stampa"
+
+#~ msgctxt "@action:button"
+#~ msgid "Arrange current build plate"
+#~ msgstr "Sistema il piano di stampa corrente"
+
+#~ msgctxt "description"
+#~ msgid "Allows saving the resulting slice as an X3G file, to support printers that read this format (Malyan, Makerbot and other Sailfish-based printers)."
+#~ msgstr "Consente di salvare il sezionamento risultante come un file X3G, per supportare le stampanti che leggono questo formato (Malyan, Makerbot ed altre stampanti basate su firmware Sailfish)."
+
+#~ msgctxt "name"
+#~ msgid "X3GWriter"
+#~ msgstr "X3GWriter"
+
+#~ msgctxt "description"
+#~ msgid "Reads SVG files as toolpaths, for debugging printer movements."
+#~ msgstr "Legge i file SVG come toolpath (percorsi utensile), per eseguire il debug dei movimenti della stampante."
+
+#~ msgctxt "name"
+#~ msgid "SVG Toolpath Reader"
+#~ msgstr "Lettore di toolpath (percorso utensile) SVG"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Changelog"
+#~ msgstr "Registro modifiche"
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Show Changelog"
+#~ msgstr "Visualizza registro modifiche"
+
+#~ msgctxt "@info:status"
+#~ msgid "Sending data to remote cluster"
+#~ msgstr "Invio dati al cluster remoto"
+
+#~ msgctxt "@info:status"
+#~ msgid "Connect to Ultimaker Cloud"
+#~ msgstr "Collegato a Ultimaker Cloud"
+
+#~ msgctxt "@info"
+#~ msgid "Cura collects anonymized usage statistics."
+#~ msgstr "Cura raccoglie statistiche di utilizzo in forma anonima."
+
+#~ msgctxt "@info:title"
+#~ msgid "Collecting Data"
+#~ msgstr "Acquisizione dati"
+
+#~ msgctxt "@action:button"
+#~ msgid "More info"
+#~ msgstr "Per saperne di più"
+
+#~ msgctxt "@action:tooltip"
+#~ msgid "See more information on what data Cura sends."
+#~ msgstr "Vedere ulteriori informazioni sui dati inviati da Cura."
+
+#~ msgctxt "@action:button"
+#~ msgid "Allow"
+#~ msgstr "Consenti"
+
+#~ msgctxt "@action:tooltip"
+#~ msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
+#~ msgstr "Consente a Cura di inviare in forma anonima statistiche d’uso, riguardanti alcune delle preferenze e impostazioni, la versione cura e una serie di modelli in sezionamento, per aiutare a dare priorità a miglioramenti futuri in Cura."
+
+#~ msgctxt "@item:inmenu"
+#~ msgid "Evaluation"
+#~ msgstr "Valutazione"
+
+#~ msgctxt "@info:title"
+#~ msgid "Network enabled printers"
+#~ msgstr "Stampanti abilitate per la rete"
+
+#~ msgctxt "@info:title"
+#~ msgid "Local printers"
+#~ msgstr "Stampanti locali"
+
+#~ msgctxt "@info:backup_failed"
+#~ msgid "Tried to restore a Cura backup that does not match your current version."
+#~ msgstr "Tentativo di ripristinare un backup di Cura non corrispondente alla versione corrente."
+
+#~ msgctxt "@title"
+#~ msgid "Machine Settings"
+#~ msgstr "Impostazioni macchina"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Settings"
+#~ msgstr "Impostazioni della stampante"
+
+#~ msgctxt "@option:check"
+#~ msgid "Origin at center"
+#~ msgstr "Origine al centro"
+
+#~ msgctxt "@option:check"
+#~ msgid "Heated bed"
+#~ msgstr "Piano riscaldato"
+
+#~ msgctxt "@label"
+#~ msgid "Printhead Settings"
+#~ msgstr "Impostazioni della testina di stampa"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distanza tra il lato sinistro della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distanza tra il lato anteriore della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distanza tra il lato destro della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
+#~ msgstr "Distanza tra il lato posteriore della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
+
+#~ msgctxt "@label"
+#~ msgid "Gantry height"
+#~ msgstr "Altezza gantry"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The height difference between the tip of the nozzle and the gantry system (X and Y axes). Used to prevent collisions between previous prints and the gantry when printing \"One at a Time\"."
+#~ msgstr "La differenza di altezza tra la punta dell’ugello e il sistema gantry (assi X e Y). Utilizzata per evitare collisioni tra le stampe precedenti e il gantry durante la stampa \"Uno alla volta\"."
+
+#~ msgctxt "@label"
+#~ msgid "Start G-code"
+#~ msgstr "Codice G avvio"
+
+#~ msgctxt "@tooltip"
+#~ msgid "G-code commands to be executed at the very start."
+#~ msgstr "Comandi codice G da eseguire all’avvio."
+
+#~ msgctxt "@label"
+#~ msgid "End G-code"
+#~ msgstr "Codice G fine"
+
+#~ msgctxt "@tooltip"
+#~ msgid "G-code commands to be executed at the very end."
+#~ msgstr "Comandi codice G da eseguire alla fine."
+
+#~ msgctxt "@label"
+#~ msgid "Nozzle Settings"
+#~ msgstr "Impostazioni ugello"
+
+#~ msgctxt "@tooltip"
+#~ msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
+#~ msgstr "Diametro nominale del filamento supportato dalla stampante. Il diametro esatto verrà sovrapposto dal materiale e/o dal profilo."
+
+#~ msgctxt "@label"
+#~ msgid "Extruder Start G-code"
+#~ msgstr "Codice G avvio estrusore"
+
+#~ msgctxt "@label"
+#~ msgid "Extruder End G-code"
+#~ msgstr "Codice G fine estrusore"
+
+#~ msgctxt "@label"
+#~ msgid "Changelog"
+#~ msgstr "Registro modifiche"
+
+#~ msgctxt "@title:window"
+#~ msgid "User Agreement"
+#~ msgstr "Contratto di licenza"
+
+#~ msgctxt "@alabel"
+#~ msgid "Enter the IP address or hostname of your printer on the network."
+#~ msgstr "Inserire l’indirizzo IP o l’hostname della stampante sulla rete."
+
+#~ msgctxt "@info"
+#~ msgid "Please select a network connected printer to monitor."
+#~ msgstr "Selezionare una stampante collegata alla rete per controllare."
+
+#~ msgctxt "@info"
+#~ msgid "Please connect your Ultimaker printer to your local network."
+#~ msgstr "Collegare la stampante Ultimaker alla rete locale."
+
+#~ msgctxt "@text:window"
+#~ msgid "Cura sends anonymous data to Ultimaker in order to improve the print quality and user experience. Below is an example of all the data that is sent."
+#~ msgstr "Cura invia dati anonimi ad Ultimaker per migliorare la qualità di stampa e l'esperienza dell'utente. Di seguito è riportato un esempio dei dati inviati."
+
+#~ msgctxt "@text:window"
+#~ msgid "I don't want to send this data"
+#~ msgstr "Non desidero inviare questi dati"
+
+#~ msgctxt "@text:window"
+#~ msgid "Allow sending this data to Ultimaker and help us improve Cura"
+#~ msgstr "Consenti l’invio di questi dati ad Ultimaker e aiutaci ad ottimizzare Cura"
+
+#~ msgctxt "@label"
+#~ msgid "No print selected"
+#~ msgstr "Nessuna stampante selezionata"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "By default, white pixels represent high points on the mesh and black pixels represent low points on the mesh. Change this option to reverse the behavior such that black pixels represent high points on the mesh and white pixels represent low points on the mesh."
+#~ msgstr "Per impostazione predefinita, i pixel bianchi rappresentano i punti alti sulla griglia, mentre i pixel neri rappresentano i punti bassi sulla griglia. Modificare questa opzione per invertire la situazione in modo tale che i pixel neri rappresentino i punti alti sulla griglia e i pixel bianchi rappresentino i punti bassi."
+
+#~ msgctxt "@title"
+#~ msgid "Select Printer Upgrades"
+#~ msgstr "Seleziona gli aggiornamenti della stampante"
+
+#~ msgctxt "@label"
+#~ msgid "Select which extruder to use for support. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air."
+#~ msgstr "Seleziona l’estrusore da utilizzare per la stampa di strutture di supporto. Ciò consentirà di costruire strutture di supporto sotto il modello per evitare cedimenti del modello o di stampare a mezz'aria."
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for your current material and nozzle configuration. Please change these to enable this quality profile"
+#~ msgstr "Questo profilo di qualità non è disponibile per il materiale e la configurazione ugello corrente. Modificarli per abilitare questo profilo di qualità"
+
+#~ msgctxt "@label shown when we load a Gcode file"
+#~ msgid "Print setup disabled. G code file can not be modified."
+#~ msgstr "Impostazione di stampa disabilitata. Impossibile modificare il file codice G."
+
+#~ msgctxt "@label"
+#~ msgid "See the material compatibility chart"
+#~ msgstr "Vedere il grafico di compatibilità dei materiali"
+
+#~ msgctxt "@label"
+#~ msgid "View types"
+#~ msgstr "Visualizza tipi"
+
+#~ msgctxt "@label"
+#~ msgid "Hi "
+#~ msgstr "Ciao "
+
+#~ msgctxt "@text"
+#~ msgid ""
+#~ "- Send print jobs to Ultimaker printers outside your local network\n"
+#~ "- Store your Ultimaker Cura settings in the cloud for use anywhere\n"
+#~ "- Get exclusive access to material profiles from leading brands"
+#~ msgstr ""
+#~ "- Invia i processi di stampa alle stampanti Ultimaker esterne alla rete locale\n"
+#~ "- Invia le impostazioni Ultimaker Cura nel cloud per usarle ovunque\n"
+#~ "- Ottieni l’accesso esclusivo ai profili materiale da marchi leader"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Unable to Slice"
+#~ msgstr "Sezionamento impossibile"
+
+#~ msgctxt "@label"
+#~ msgid "Time specification"
+#~ msgstr "Indicazioni di tempo"
+
+#~ msgctxt "@label"
+#~ msgid "Material specification"
+#~ msgstr "Specifiche materiale"
+
+#~ msgctxt "@title:tab"
+#~ msgid "Add a printer to Cura"
+#~ msgstr "Aggiungi una stampante a Cura"
+
+#~ msgctxt "@title:tab"
+#~ msgid ""
+#~ "Select the printer you want to use from the list below.\n"
+#~ "\n"
+#~ "If your printer is not in the list, use the \"Custom FFF Printer\" from the \"Custom\" category and adjust the settings to match your printer in the next dialog."
+#~ msgstr ""
+#~ "Seleziona la stampante da usare dell’elenco seguente.\n"
+#~ "\n"
+#~ "Se la stampante non è nell’elenco, usare la “Stampante FFF personalizzata\" dalla categoria “Personalizzata\" e regolare le impostazioni in modo che corrispondano alla stampante nella finestra di dialogo successiva."
+
+#~ msgctxt "@label"
+#~ msgid "Manufacturer"
+#~ msgstr "Produttore"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Name"
+#~ msgstr "Nome stampante"
+
+#~ msgctxt "@action:button"
+#~ msgid "Add Printer"
+#~ msgstr "Aggiungi stampante"
+
+#~ msgid "Modify G-Code"
+#~ msgstr "Modifica G-code"
+
+#~ msgctxt "@info:status"
+#~ msgid "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."
+#~ msgstr "Nulla da sezionare in quanto nessuno dei modelli corrisponde al volume di stampa. Ridimensionare o ruotare i modelli secondo necessità."
+
+#~ msgctxt "@info:status"
+#~ msgid "The selected material is incompatible with the selected machine or configuration."
+#~ msgstr "Il materiale selezionato è incompatibile con la macchina o la configurazione selezionata."
+
+#~ msgctxt "@info:title"
+#~ msgid "Incompatible Material"
+#~ msgstr "Materiale incompatibile"
+
+#~ msgctxt "@info:status Don't translate the XML tags or !"
+#~ msgid "Failed to import profile from {0}: {1}"
+#~ msgstr "Impossibile importare il profilo da {0}: {1}"
+
+#~ msgctxt "@title"
+#~ msgid "Toolbox"
+#~ msgstr "Casella degli strumenti"
+
+#~ msgctxt "@label"
+#~ msgid "Not available"
+#~ msgstr "Non disponibile"
+
+#~ msgctxt "@label"
+#~ msgid "Unreachable"
+#~ msgstr "Non raggiungibile"
+
+#~ msgctxt "@label"
+#~ msgid "Available"
+#~ msgstr "Disponibile"
+
+#~ msgctxt "@label:status"
+#~ msgid "Preparing"
+#~ msgstr "Preparazione in corso"
+
+#~ msgctxt "@label:status"
+#~ msgid "Pausing"
+#~ msgstr "Messa in pausa"
+
+#~ msgctxt "@label:status"
+#~ msgid "Resuming"
+#~ msgstr "Ripresa"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: Unavailable printer"
+#~ msgstr "In attesa: stampante non disponibile"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: First available"
+#~ msgstr "In attesa della prima disponibile"
+
+#~ msgctxt "@label"
+#~ msgid "Waiting for: "
+#~ msgstr "In attesa: "
+
+#~ msgctxt "@label"
+#~ msgid "Configuration change"
+#~ msgstr "Modifica configurazione"
+
+#~ msgctxt "@label"
+#~ msgid "The assigned printer, %1, requires the following configuration change(s):"
+#~ msgstr "La stampante assegnata, %1, richiede le seguenti modifiche di configurazione:"
+
+#~ msgctxt "@label"
+#~ msgid "Override"
+#~ msgstr "Override"
+
+#~ msgctxt "@label"
+#~ msgid "Starting a print job with an incompatible configuration could damage your 3D printer. Are you sure you want to override the configuration and print %1?"
+#~ msgstr "L’avvio di un processo di stampa con una configurazione non compatibile potrebbe danneggiare la stampante 3D. Sei sicuro di voler annullare la configurazione e stampare %1?"
+
+#~ msgctxt "@window:title"
+#~ msgid "Override configuration configuration and start print"
+#~ msgstr "Annullare la configurazione e avviare la stampa"
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Manage queue"
+#~ msgstr "Gestione coda di stampa"
+
+#~ msgctxt "@label"
+#~ msgid "Printing"
+#~ msgstr "Stampa in corso"
+
+#~ msgctxt "@label link to connect manager"
+#~ msgid "Manage printers"
+#~ msgstr "Gestione stampanti"
+
+#~ msgctxt "@action:button"
+#~ msgid "Activate Configuration"
+#~ msgstr "Attiva la configurazione"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Load the configuration of the printer into Cura"
+#~ msgstr "Carica la configurazione della stampante in Cura"
+
+#~ msgctxt "@label"
+#~ msgid "Show Travels"
+#~ msgstr "Mostra spostamenti"
+
+#~ msgctxt "@label"
+#~ msgid "Show Helpers"
+#~ msgstr "Mostra helper"
+
+#~ msgctxt "@label"
+#~ msgid "Show Shell"
+#~ msgstr "Mostra guscio"
+
+#~ msgctxt "@label"
+#~ msgid "Show Infill"
+#~ msgstr "Mostra riempimento"
+
+#~ msgctxt "@text:window"
+#~ msgid "I don't want to send these data"
+#~ msgstr "Non voglio inviare questi dati"
+
+#~ msgctxt "@text:window"
+#~ msgid "Allow sending these data to Ultimaker and help us improve Cura"
+#~ msgstr "Il consenso all'invio di questi dati ad Ultimaker ci aiuta ad ottimizzare Cura"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type:"
+#~ msgstr "Tipo di stampante:"
+
+#~ msgctxt "@label"
+#~ msgid "Connection:"
+#~ msgstr "Collegamento:"
+
+#~ msgctxt "@label"
+#~ msgid "State:"
+#~ msgstr "Stato:"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for a printjob"
+#~ msgstr "In attesa di un processo di stampa"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Waiting for someone to clear the build plate"
+#~ msgstr "In attesa di qualcuno che cancelli il piano di stampa"
+
+#~ msgctxt "@label:MonitorStatus"
+#~ msgid "Aborting print..."
+#~ msgstr "Interruzione stampa in corso..."
+
+#~ msgctxt "@label"
+#~ msgid "Protected profiles"
+#~ msgstr "Profili protetti"
+
+#~ msgctxt "@label"
+#~ msgid "Printer Name:"
+#~ msgstr "Nome stampante:"
+
+#~ msgctxt "@label"
+#~ msgid "Profile:"
+#~ msgstr "Profilo:"
+
+#~ msgctxt "@label:textbox"
+#~ msgid "Search..."
+#~ msgstr "Ricerca..."
+
+#~ msgctxt "@action:inmenu"
+#~ msgid "Collapse All"
+#~ msgstr "Comprimi tutto"
+
+#~ msgctxt "@action:inmenu"
+#~ msgid "Expand All"
+#~ msgstr "Espandi tutto"
+
+#~ msgctxt "@label:header configurations"
+#~ msgid "Available configurations"
+#~ msgstr "Configurazioni disponibili"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "Extruder"
+#~ msgstr "Estrusore"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "Yes"
+#~ msgstr "Sì"
+
+#~ msgctxt "@label:extruder label"
+#~ msgid "No"
+#~ msgstr "No"
+
+#~ msgctxt "@label:listbox"
+#~ msgid "Print Setup"
+#~ msgstr "Impostazione di stampa"
+
+#~ msgctxt "@label:listbox"
+#~ msgid ""
+#~ "Print Setup disabled\n"
+#~ "G-code files cannot be modified"
+#~ msgstr ""
+#~ "Impostazione di stampa disabilitata\n"
+#~ "I file codice G non possono essere modificati"
+
+#~ msgctxt "@label Hours and minutes"
+#~ msgid "00h 00min"
+#~ msgstr "00h 00min"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Time specification"
+#~ msgstr "Indicazioni di tempo"
+
+#~ msgctxt "@label"
+#~ msgid "Cost specification"
+#~ msgstr "Indicazione di costo"
+
+#~ msgctxt "@label"
+#~ msgid "Total:"
+#~ msgstr "Totale:"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Recommended Print Setup
Print with the recommended settings for the selected printer, material and quality."
+#~ msgstr "Impostazione di stampa consigliata
Stampa con le impostazioni consigliate per la stampante, il materiale e la qualità selezionati."
+
+#~ msgctxt "@tooltip"
+#~ msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
+#~ msgstr "Impostazione di stampa personalizzata
Stampa con il controllo grana fine su ogni sezione finale del processo di sezionamento."
+
+#~ msgctxt "@action:inmenu menubar:help"
+#~ msgid "Show Engine &Log..."
+#~ msgstr "Mostra &log motore..."
+
+#~ msgctxt "@action:menu"
+#~ msgid "Browse packages..."
+#~ msgstr "Sfoglia i pacchetti..."
+
+#~ msgctxt "@action:inmenu menubar:view"
+#~ msgid "Expand/Collapse Sidebar"
+#~ msgstr "Espandi/Riduci barra laterale"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Please load a 3D model"
+#~ msgstr "Caricare un modello 3D"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Ready to slice"
+#~ msgstr "Pronto per il sezionamento"
+
+#~ msgctxt "@label:PrintjobStatus %1 is target operation"
+#~ msgid "Ready to %1"
+#~ msgstr "Pronto a %1"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Slicing unavailable"
+#~ msgstr "Sezionamento non disponibile"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Slice current printjob"
+#~ msgstr "Seziona processo di stampa corrente"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Cancel slicing process"
+#~ msgstr "Annulla processo di sezionamento"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Prepare"
+#~ msgstr "Prepara"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Cancel"
+#~ msgstr "Annulla"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Select the active output device"
+#~ msgstr "Seleziona l'unità di uscita attiva"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&View"
+#~ msgstr "&Visualizza"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Settings"
+#~ msgstr "&Impostazioni"
+
+#~ msgctxt "@title:menu menubar:toplevel"
+#~ msgid "&Toolbox"
+#~ msgstr "&Casella degli strumenti"
+
+#~ msgctxt "@action:button"
+#~ msgid "Open File"
+#~ msgstr "Apri file"
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
+#~ msgstr "Questo profilo di qualità non è disponibile per il materiale e la configurazione ugello corrente. Modificarli per abilitare questo profilo di qualità"
+
+#~ msgctxt "@label"
+#~ msgid "Print Speed"
+#~ msgstr "Velocità di stampa"
+
+#~ msgctxt "@label"
+#~ msgid "Slower"
+#~ msgstr "Più lenta"
+
+#~ msgctxt "@label"
+#~ msgid "Faster"
+#~ msgstr "Più veloce"
+
+#~ msgctxt "@label"
+#~ msgid "Enable gradual"
+#~ msgstr "Consenti variazione graduale"
+
+#~ msgctxt "@label"
+#~ msgid "Generate Support"
+#~ msgstr "Generazione supporto"
+
+#~ msgctxt "@label"
+#~ msgid "Build Plate Adhesion"
+#~ msgstr "Adesione piano di stampa"
+
+#~ msgctxt "@label"
+#~ msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
+#~ msgstr "Serve aiuto per migliorare le tue stampe? Leggi la Guida alla ricerca e riparazione guasti Ultimaker"
+
+#~ msgctxt "@title:window"
+#~ msgid "Engine Log"
+#~ msgstr "Log motore"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type"
+#~ msgstr "Tipo di stampante"
+
+#~ msgctxt "@label"
+#~ msgid "Use glue with this material combination"
+#~ msgstr "Utilizzare la colla con questa combinazione di materiali"
+
+#~ msgctxt "@label"
+#~ msgid "Check compatibility"
+#~ msgstr "Controlla compatibilità"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Click to check the material compatibility on Ultimaker.com."
+#~ msgstr "Fai clic per verificare la compatibilità del materiale su Ultimaker.com."
+
+#~ msgctxt "description"
+#~ msgid "Shows changes since latest checked version."
+#~ msgstr "Mostra le modifiche dall'ultima versione selezionata."
+
+#~ msgctxt "name"
+#~ msgid "Changelog"
+#~ msgstr "Registro modifiche"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattend quality changes profile."
+#~ msgstr "Crea un profilo appiattito."
+
+#~ msgctxt "name"
+#~ msgid "Profile flatener"
+#~ msgstr "Appiattitore di profilo"
+
+#~ msgctxt "description"
+#~ msgid "Ask the user once if he/she agrees with our license."
+#~ msgstr "Chiedere una volta all'utente se accetta la nostra licenza."
+
+#~ msgctxt "name"
+#~ msgid "UserAgreement"
+#~ msgstr "Contratto di licenza"
+
+#~ msgctxt "@warning:status"
+#~ msgid "Please generate G-code before saving."
+#~ msgstr "Generare il codice G prima di salvare."
+
#~ msgctxt "@action"
#~ msgid "Upgrade Firmware"
#~ msgstr "Aggiorna firmware"
@@ -4993,22 +6528,6 @@ msgstr "Lettore profilo Cura"
#~ msgid "Confirm uninstall "
#~ msgstr "Conferma disinstalla "
-#~ msgctxt "@label:status"
-#~ msgid "Paused"
-#~ msgstr "In pausa"
-
-#~ msgctxt "@action:button"
-#~ msgid "Previous"
-#~ msgstr "Precedente"
-
-#~ msgctxt "@action:button"
-#~ msgid "Next"
-#~ msgstr "Avanti"
-
-#~ msgctxt "@label"
-#~ msgid "Tip"
-#~ msgstr "Suggerimento"
-
#~ msgctxt "@label Print estimates: m for meters, g for grams, %4 is currency and %3 is print cost"
#~ msgid "%1m / ~ %2g / ~ %4 %3"
#~ msgstr "%1m / ~ %2g / ~ %4 %3"
@@ -5017,26 +6536,10 @@ msgstr "Lettore profilo Cura"
#~ msgid "%1m / ~ %2g"
#~ msgstr "%1m / ~ %2g"
-#~ msgctxt "@label"
-#~ msgid "Print experiment"
-#~ msgstr "Prova di stampa"
-
-#~ msgctxt "@label"
-#~ msgid "Checklist"
-#~ msgstr "Lista di controllo"
-
#~ msgctxt "@title"
#~ msgid "Upgrade Firmware"
#~ msgstr "Aggiorna firmware"
-#~ msgctxt "description"
-#~ msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
-#~ msgstr "Consente ai produttori di materiali di creare nuovi profili materiale e di qualità utilizzando una UI drop-in."
-
-#~ msgctxt "name"
-#~ msgid "Print Profile Assistant"
-#~ msgstr "Assistente profilo di stampa"
-
#~ msgctxt "@action:button"
#~ msgid "Print with Doodle3D WiFi-Box"
#~ msgstr "Stampa con Doodle3D WiFi-Box"
@@ -5129,10 +6632,6 @@ msgstr "Lettore profilo Cura"
#~ msgid "Lost connection with the printer"
#~ msgstr "Persa connessione con la stampante"
-#~ msgctxt "@label:status"
-#~ msgid "Unavailable"
-#~ msgstr "Non disponibile"
-
#~ msgctxt "@label:status"
#~ msgid "Unknown"
#~ msgstr "Sconosciuto"
diff --git a/resources/i18n/it_IT/fdmextruder.def.json.po b/resources/i18n/it_IT/fdmextruder.def.json.po
index aa170f18be..4d730ebf7c 100644
--- a/resources/i18n/it_IT/fdmextruder.def.json.po
+++ b/resources/i18n/it_IT/fdmextruder.def.json.po
@@ -1,14 +1,14 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 14:25+0100\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-03-13 14:00+0200\n"
"Last-Translator: Bothof \n"
"Language-Team: Italian\n"
"Language: it_IT\n"
@@ -83,8 +83,8 @@ msgstr "Codice G avvio estrusore"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_code description"
-msgid "Start g-code to execute whenever turning the extruder on."
-msgstr "Codice G di avvio da eseguire ogniqualvolta si accende l’estrusore."
+msgid "Start g-code to execute when switching to this extruder."
+msgstr "Inizio codice G da eseguire quando si passa a questo estrusore."
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_abs label"
@@ -123,8 +123,8 @@ msgstr "Codice G fine estrusore"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_code description"
-msgid "End g-code to execute whenever turning the extruder off."
-msgstr "Codice G di fine da eseguire ogniqualvolta si spegne l’estrusore."
+msgid "End g-code to execute when switching away from this extruder."
+msgstr "Fine codice G da eseguire quando si passa a questo estrusore."
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_abs label"
@@ -225,3 +225,11 @@ msgstr "Diametro"
msgctxt "material_diameter description"
msgid "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament."
msgstr "Regolare il diametro del filamento utilizzato. Abbinare questo valore al diametro del filamento utilizzato."
+
+#~ msgctxt "machine_extruder_start_code description"
+#~ msgid "Start g-code to execute whenever turning the extruder on."
+#~ msgstr "Codice G di avvio da eseguire ogniqualvolta si accende l’estrusore."
+
+#~ msgctxt "machine_extruder_end_code description"
+#~ msgid "End g-code to execute whenever turning the extruder off."
+#~ msgstr "Codice G di fine da eseguire ogniqualvolta si spegne l’estrusore."
diff --git a/resources/i18n/it_IT/fdmprinter.def.json.po b/resources/i18n/it_IT/fdmprinter.def.json.po
index e2d013f74c..2f7a93df43 100644
--- a/resources/i18n/it_IT/fdmprinter.def.json.po
+++ b/resources/i18n/it_IT/fdmprinter.def.json.po
@@ -1,16 +1,16 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 15:02+0200\n"
-"Last-Translator: Bothof \n"
-"Language-Team: Italian\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-07-29 15:51+0200\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: Italian , Italian \n"
"Language: it_IT\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -57,7 +57,9 @@ msgctxt "machine_start_gcode description"
msgid ""
"G-code commands to be executed at the very start - separated by \n"
"."
-msgstr "I comandi codice G da eseguire all’avvio, separati da \n."
+msgstr ""
+"I comandi codice G da eseguire all’avvio, separati da \n"
+"."
#: fdmprinter.def.json
msgctxt "machine_end_gcode label"
@@ -69,7 +71,9 @@ msgctxt "machine_end_gcode description"
msgid ""
"G-code commands to be executed at the very end - separated by \n"
"."
-msgstr "I comandi codice G da eseguire alla fine, separati da \n."
+msgstr ""
+"I comandi codice G da eseguire alla fine, separati da \n"
+"."
#: fdmprinter.def.json
msgctxt "material_guid label"
@@ -211,6 +215,16 @@ msgctxt "machine_heated_bed description"
msgid "Whether the machine has a heated build plate present."
msgstr "Indica se la macchina ha un piano di stampa riscaldato."
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume label"
+msgid "Has Build Volume Temperature Stabilization"
+msgstr "È dotato della stabilizzazione della temperatura del volume di stampa"
+
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume description"
+msgid "Whether the machine is able to stabilize the build volume temperature."
+msgstr "Se la macchina è in grado di stabilizzare la temperatura del volume di stampa."
+
#: fdmprinter.def.json
msgctxt "machine_center_is_zero label"
msgid "Is Center Origin"
@@ -233,7 +247,7 @@ msgstr "Il numero di treni di estrusori. Un treno di estrusori è la combinazion
#: fdmprinter.def.json
msgctxt "extruders_enabled_count label"
-msgid "Number of Extruders that are enabled"
+msgid "Number of Extruders That Are Enabled"
msgstr "Numero di estrusori abilitati"
#: fdmprinter.def.json
@@ -243,7 +257,7 @@ msgstr "Numero di treni di estrusori abilitati; impostato automaticamente nel so
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter label"
-msgid "Outer nozzle diameter"
+msgid "Outer Nozzle Diameter"
msgstr "Diametro esterno ugello"
#: fdmprinter.def.json
@@ -253,7 +267,7 @@ msgstr "Il diametro esterno della punta dell'ugello."
#: fdmprinter.def.json
msgctxt "machine_nozzle_head_distance label"
-msgid "Nozzle length"
+msgid "Nozzle Length"
msgstr "Lunghezza ugello"
#: fdmprinter.def.json
@@ -263,7 +277,7 @@ msgstr "La differenza di altezza tra la punta dell’ugello e la parte inferiore
#: fdmprinter.def.json
msgctxt "machine_nozzle_expansion_angle label"
-msgid "Nozzle angle"
+msgid "Nozzle Angle"
msgstr "Angolo ugello"
#: fdmprinter.def.json
@@ -273,7 +287,7 @@ msgstr "L’angolo tra il piano orizzontale e la parte conica esattamente sopra
#: fdmprinter.def.json
msgctxt "machine_heat_zone_length label"
-msgid "Heat zone length"
+msgid "Heat Zone Length"
msgstr "Lunghezza della zona di riscaldamento"
#: fdmprinter.def.json
@@ -303,7 +317,7 @@ msgstr "Per controllare la temperatura da Cura. Disattivare per controllare la t
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed label"
-msgid "Heat up speed"
+msgid "Heat Up Speed"
msgstr "Velocità di riscaldamento"
#: fdmprinter.def.json
@@ -313,7 +327,7 @@ msgstr "La velocità (°C/s) alla quale l’ugello si riscalda calcolando la med
#: fdmprinter.def.json
msgctxt "machine_nozzle_cool_down_speed label"
-msgid "Cool down speed"
+msgid "Cool Down Speed"
msgstr "Velocità di raffreddamento"
#: fdmprinter.def.json
@@ -333,8 +347,8 @@ msgstr "Il tempo minimo in cui un estrusore deve essere inattivo prima che l’u
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor label"
-msgid "G-code flavour"
-msgstr "Tipo di codice G"
+msgid "G-code Flavor"
+msgstr "Versione codice G"
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor description"
@@ -398,7 +412,7 @@ msgstr "Specifica se usare comandi di retrazione firmware (G10/G11) anziché uti
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
-msgid "Disallowed areas"
+msgid "Disallowed Areas"
msgstr "Aree non consentite"
#: fdmprinter.def.json
@@ -418,7 +432,7 @@ msgstr "Un elenco di poligoni con aree alle quali l’ugello non può accedere."
#: fdmprinter.def.json
msgctxt "machine_head_polygon label"
-msgid "Machine head polygon"
+msgid "Machine Head Polygon"
msgstr "Poligono testina macchina"
#: fdmprinter.def.json
@@ -428,7 +442,7 @@ msgstr "Una silhouette 2D della testina di stampa (cappucci ventola esclusi)."
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon label"
-msgid "Machine head & Fan polygon"
+msgid "Machine Head & Fan Polygon"
msgstr "Poligono testina macchina e ventola"
#: fdmprinter.def.json
@@ -438,7 +452,7 @@ msgstr "Una silhouette 2D della testina di stampa (cappucci ventola inclusi)."
#: fdmprinter.def.json
msgctxt "gantry_height label"
-msgid "Gantry height"
+msgid "Gantry Height"
msgstr "Altezza gantry"
#: fdmprinter.def.json
@@ -468,7 +482,7 @@ msgstr "Il diametro interno dell’ugello. Modificare questa impostazione quando
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords label"
-msgid "Offset With Extruder"
+msgid "Offset with Extruder"
msgstr "Offset con estrusore"
#: fdmprinter.def.json
@@ -1016,6 +1030,17 @@ msgctxt "bottom_layers description"
msgid "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number."
msgstr "Indica il numero degli strati inferiori. Quando calcolato mediante lo spessore dello strato inferiore, il valore viene arrotondato a numero intero."
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers label"
+msgid "Initial Bottom Layers"
+msgstr "Layer inferiori iniziali"
+
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers description"
+msgid "The number of initial bottom layers, from the build-plate upwards. When calculated by the bottom thickness, this value is rounded to a whole number."
+msgstr "Il numero di layer inferiori iniziali, dal piano di stampa verso l'alto. Quando viene calcolato mediante lo spessore inferiore, questo valore viene arrotondato"
+" a un numero intero."
+
#: fdmprinter.def.json
msgctxt "top_bottom_pattern label"
msgid "Top/Bottom Pattern"
@@ -1266,6 +1291,56 @@ msgctxt "z_seam_type option sharpest_corner"
msgid "Sharpest Corner"
msgstr "Angolo più acuto"
+#: fdmprinter.def.json
+msgctxt "z_seam_position label"
+msgid "Z Seam Position"
+msgstr "Posizione della cucitura in Z"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position description"
+msgid "The position near where to start printing each part in a layer."
+msgstr "La posizione accanto al punto in cui avviare la stampa di ciascuna parte in uno layer."
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backleft"
+msgid "Back Left"
+msgstr "Indietro a sinistra"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option back"
+msgid "Back"
+msgstr "Indietro"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backright"
+msgid "Back Right"
+msgstr "Indietro a destra"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option right"
+msgid "Right"
+msgstr "Destra"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontright"
+msgid "Front Right"
+msgstr "Avanti a destra"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option front"
+msgid "Front"
+msgstr "Avanti"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontleft"
+msgid "Front Left"
+msgstr "Avanti a sinistra"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option left"
+msgid "Left"
+msgstr "Sinistra"
+
#: fdmprinter.def.json
msgctxt "z_seam_x label"
msgid "Z Seam X"
@@ -1293,8 +1368,8 @@ msgstr "Preferenze angolo giunzione"
#: fdmprinter.def.json
msgctxt "z_seam_corner description"
-msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
-msgstr "Controlla se gli angoli sul profilo del modello influenzano la posizione della giunzione. Nessuno significa che gli angoli non hanno alcuna influenza sulla posizione della giunzione. Nascondi giunzione favorisce la presenza della giunzione su un angolo interno. Esponi giunzione favorisce la presenza della giunzione su un angolo esterno. Nascondi o esponi giunzione favorisce la presenza della giunzione su un angolo interno o esterno."
+msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner. Smart Hiding allows both inside and outside corners, but chooses inside corners more frequently, if appropriate."
+msgstr "Controlla se gli angoli sul profilo del modello influenzano la posizione della giunzione. Nessuno significa che gli angoli non hanno alcuna influenza sulla posizione della giunzione. Nascondi giunzione favorisce la presenza della giunzione su un angolo interno. Esponi giunzione favorisce la presenza della giunzione su un angolo esterno. Nascondi o esponi giunzione favorisce la presenza della giunzione su un angolo interno o esterno. Smart Hiding consente sia gli angoli interni che quelli esterni ma sceglie con maggiore frequenza gli angoli interni, se opportuno."
#: fdmprinter.def.json
msgctxt "z_seam_corner option z_seam_corner_none"
@@ -1316,6 +1391,11 @@ msgctxt "z_seam_corner option z_seam_corner_any"
msgid "Hide or Expose Seam"
msgstr "Nascondi o esponi giunzione"
+#: fdmprinter.def.json
+msgctxt "z_seam_corner option z_seam_corner_weighted"
+msgid "Smart Hiding"
+msgstr "Occultamento intelligente"
+
#: fdmprinter.def.json
msgctxt "z_seam_relative label"
msgid "Z Seam Relative"
@@ -1328,13 +1408,13 @@ msgstr "Se abilitato, le coordinate della giunzione Z sono riferite al centro di
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic label"
-msgid "Ignore Small Z Gaps"
-msgstr "Ignora i piccoli interstizi a Z"
+msgid "No Skin in Z Gaps"
+msgstr "Nessun rivest. est. negli interstizi a Z"
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic description"
-msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
-msgstr "Quando il modello presenta piccoli spazi vuoti verticali, circa il 5% del tempo di calcolo supplementare può essere utilizzato per la generazione di rivestimenti esterni superiori ed inferiori in questi interstizi. In questo caso disabilitare l’impostazione."
+msgid "When the model has small vertical gaps of only a few layers, there should normally be skin around those layers in the narrow space. Enable this setting to not generate skin if the vertical gap is very small. This improves printing time and slicing time, but technically leaves infill exposed to the air."
+msgstr "Quando il modello presenta piccoli spazi vuoti verticali composti da un numero ridotto di strati, intorno a questi strati di norma dovrebbe essere presente un rivestimento esterno nell'interstizio. Abilitare questa impostazione per non generare il rivestimento esterno se l'interstizio verticale è molto piccolo. Ciò consente di migliorare il tempo di stampa e il tempo di sezionamento, ma dal punto di vista tecnico lascia il riempimento esposto all'aria."
#: fdmprinter.def.json
msgctxt "skin_outline_count label"
@@ -1353,8 +1433,8 @@ msgstr "Abilita stiratura"
#: fdmprinter.def.json
msgctxt "ironing_enabled description"
-msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
-msgstr "Ulteriore passaggio sopra la superficie superiore, senza estrusione di materiale. Ha lo scopo di fondere ulteriormente la plastica alla sommità, creando una superficie più uniforme."
+msgid "Go over the top surface one additional time, but this time extruding very little material. This is meant to melt the plastic on top further, creating a smoother surface. The pressure in the nozzle chamber is kept high so that the creases in the surface are filled with material."
+msgstr "Andare ancora una volta sulla superficie superiore, questa volta estrudendo una piccolissima quantità di materiale. Lo scopo è quello di sciogliere ulteriormente la plastica sulla parte superiore, creando una superficie più liscia. La pressione nella camera dell'ugello viene mantenuta elevata, in modo che le grinze nella superficie siano riempite con il materiale."
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer label"
@@ -1446,6 +1526,26 @@ msgctxt "jerk_ironing description"
msgid "The maximum instantaneous velocity change while performing ironing."
msgstr "Indica la variazione della velocità istantanea massima durante la stiratura."
+#: fdmprinter.def.json
+msgctxt "skin_overlap label"
+msgid "Skin Overlap Percentage"
+msgstr "Percentuale di sovrapposizione del rivestimento esterno"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines, as a percentage of the line widths of the skin lines and the innermost wall. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any percentage over 50% may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "Regolare l’entità della sovrapposizione tra le pareti e (i punti finali delle) linee centrali del rivestimento esterno espressa in percentuale delle larghezze delle linee del rivestimento esterno. Una leggera sovrapposizione consente alle pareti di essere saldamente collegate al rivestimento. Si noti che, data una larghezza uguale del rivestimento esterno e della linea perimetrale, qualsiasi percentuale superiore al 50% può già causare il superamento della parete da parte del rivestimento esterno in quanto, in quel punto, la posizione dell’ugello dell’estrusore del rivestimento esterno può già avere superato la parte centrale della parete."
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm label"
+msgid "Skin Overlap"
+msgstr "Sovrapposizione del rivestimento esterno"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any value over half the width of the wall may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "Regolare l’entità della sovrapposizione tra le pareti e (i punti finali delle) linee centrali del rivestimento esterno. Una leggera sovrapposizione consente alle pareti di essere saldamente collegate al rivestimento. Si noti che, data una larghezza uguale del rivestimento esterno e della linea perimetrale, qualsiasi percentuale superiore alla metà della parete può già causare il superamento della parete da parte del rivestimento esterno in quanto, in quel punto, la posizione dell’ugello dell’estrusore del rivestimento esterno può già aver superato la parte centrale della parete."
+
#: fdmprinter.def.json
msgctxt "infill label"
msgid "Infill"
@@ -1611,6 +1711,16 @@ msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
msgstr "Il riempimento si sposta di questa distanza lungo l'asse Y."
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location label"
+msgid "Randomize Infill Start"
+msgstr "Avvio con riempimento casuale"
+
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location description"
+msgid "Randomize which infill line is printed first. This prevents one segment becoming the strongest, but it does so at the cost of an additional travel move."
+msgstr "Decidere in modo casuale quale sarà la linea di riempimento ad essere stampata per prima. In tal modo si evita che un segmento diventi il più resistente sebbene si esegua uno spostamento aggiuntivo."
+
#: fdmprinter.def.json
msgctxt "infill_multiplier label"
msgid "Infill Line Multiplier"
@@ -1631,7 +1741,9 @@ msgctxt "infill_wall_line_count description"
msgid ""
"Add extra walls around the infill area. Such walls can make top/bottom skin lines sag down less which means you need less top/bottom skin layers for the same quality at the cost of some extra material.\n"
"This feature can combine with the Connect Infill Polygons to connect all the infill into a single extrusion path without the need for travels or retractions if configured right."
-msgstr "Aggiunge pareti supplementari intorno alla zona di riempimento. Queste pareti possono ridurre l’abbassamento delle linee del rivestimento esterno superiore/inferiore, pertanto saranno necessari meno strati di rivestimento esterno superiore/inferiore per ottenere la stessa qualità al costo del materiale supplementare.\nQuesta funzione può essere abbinata a Collega poligoni riempimento per collegare tutto il riempimento in un unico percorso di estrusione senza necessità di avanzamenti o arretramenti, se configurata correttamente."
+msgstr ""
+"Aggiunge pareti supplementari intorno alla zona di riempimento. Queste pareti possono ridurre l’abbassamento delle linee del rivestimento esterno superiore/inferiore, pertanto saranno necessari meno strati di rivestimento esterno superiore/inferiore per ottenere la stessa qualità al costo del materiale supplementare.\n"
+"Questa funzione può essere abbinata a Collega poligoni riempimento per collegare tutto il riempimento in un unico percorso di estrusione senza necessità di avanzamenti o arretramenti, se configurata correttamente."
#: fdmprinter.def.json
msgctxt "sub_div_rad_add label"
@@ -1663,26 +1775,6 @@ msgctxt "infill_overlap_mm description"
msgid "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill."
msgstr "Indica la quantità di sovrapposizione tra il riempimento e le pareti. Una leggera sovrapposizione consente il saldo collegamento delle pareti al riempimento."
-#: fdmprinter.def.json
-msgctxt "skin_overlap label"
-msgid "Skin Overlap Percentage"
-msgstr "Percentuale di sovrapposizione del rivestimento esterno"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap description"
-msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
-msgstr "Entità della sovrapposizione tra il rivestimento e le pareti espressa in percentuale della larghezza della linea del rivestimento esterno. Una leggera sovrapposizione consente alle pareti di essere saldamente collegate al rivestimento. È una percentuale delle larghezze medie delle linee del rivestimento e della parete più interna."
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm label"
-msgid "Skin Overlap"
-msgstr "Sovrapposizione del rivestimento esterno"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm description"
-msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
-msgstr "Indica la quantità di sovrapposizione tra il rivestimento esterno e le pareti. Una leggera sovrapposizione consente il saldo collegamento delle pareti al rivestimento esterno."
-
#: fdmprinter.def.json
msgctxt "infill_wipe_dist label"
msgid "Infill Wipe Distance"
@@ -1863,6 +1955,16 @@ msgctxt "default_material_print_temperature description"
msgid "The default temperature used for printing. This should be the \"base\" temperature of a material. All other print temperatures should use offsets based on this value"
msgstr "La temperatura preimpostata utilizzata per la stampa. Deve essere la temperatura “base” di un materiale. Tutte le altre temperature di stampa devono usare scostamenti basati su questo valore"
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature label"
+msgid "Build Volume Temperature"
+msgstr "Temperatura volume di stampa"
+
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature description"
+msgid "The temperature of the environment to print in. If this is 0, the build volume temperature will not be adjusted."
+msgstr "La temperatura dell'ambiente in cui stampare. Se il valore è 0, la temperatura del volume di stampa non verrà regolata."
+
#: fdmprinter.def.json
msgctxt "material_print_temperature label"
msgid "Printing Temperature"
@@ -1973,6 +2075,86 @@ msgctxt "material_shrinkage_percentage description"
msgid "Shrinkage ratio in percentage."
msgstr "Il tasso di contrazione in percentuale."
+#: fdmprinter.def.json
+msgctxt "material_crystallinity label"
+msgid "Crystalline Material"
+msgstr "Materiale cristallino"
+
+#: fdmprinter.def.json
+msgctxt "material_crystallinity description"
+msgid "Is this material the type that breaks off cleanly when heated (crystalline), or is it the type that produces long intertwined polymer chains (non-crystalline)?"
+msgstr "Questo tipo di materiale è quello che si stacca in modo netto quando viene riscaldato (cristallino) oppure è il tipo che produce lunghe catene di polimeri intrecciati (non cristallino)?"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position label"
+msgid "Anti-ooze Retracted Position"
+msgstr "Posizione retratta anti fuoriuscita di materiale"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position description"
+msgid "How far the material needs to be retracted before it stops oozing."
+msgstr "La distanza alla quale deve essere retratto il materiale prima che smetta di fuoriuscire."
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed label"
+msgid "Anti-ooze Retraction Speed"
+msgstr "Velocità di retrazione anti fuoriuscita del materiale"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed description"
+msgid "How fast the material needs to be retracted during a filament switch to prevent oozing."
+msgstr "La velocità a cui deve essere retratto il materiale durante un cambio di filamento per evitare la fuoriuscita di materiale."
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position label"
+msgid "Break Preparation Retracted Position"
+msgstr "Posizione di retrazione prima della rottura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position description"
+msgid "How far the filament can be stretched before it breaks, while heated."
+msgstr "La lunghezza massima di estensione del filamento prima che si rompa durante il riscaldamento."
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed label"
+msgid "Break Preparation Retraction Speed"
+msgstr "Velocità di retrazione prima della rottura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed description"
+msgid "How fast the filament needs to be retracted just before breaking it off in a retraction."
+msgstr "La velocità massima di retrazione del filamento prima che si rompa durante questa operazione."
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position label"
+msgid "Break Retracted Position"
+msgstr "Posizione di retrazione per la rottura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position description"
+msgid "How far to retract the filament in order to break it cleanly."
+msgstr "La distanza di retrazione del filamento al fine di consentirne la rottura netta."
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed label"
+msgid "Break Retraction Speed"
+msgstr "Velocità di retrazione per la rottura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed description"
+msgid "The speed at which to retract the filament in order to break it cleanly."
+msgstr "La velocità alla quale retrarre il filamento al fine di romperlo in modo netto."
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature label"
+msgid "Break Temperature"
+msgstr "Temperatura di rottura"
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature description"
+msgid "The temperature at which the filament is broken for a clean break."
+msgstr "La temperatura a cui il filamento viene rotto, con una rottura netta."
+
#: fdmprinter.def.json
msgctxt "material_flow label"
msgid "Flow"
@@ -1983,6 +2165,126 @@ msgctxt "material_flow description"
msgid "Flow compensation: the amount of material extruded is multiplied by this value."
msgstr "Determina la compensazione del flusso: la quantità di materiale estruso viene moltiplicata per questo valore."
+#: fdmprinter.def.json
+msgctxt "wall_material_flow label"
+msgid "Wall Flow"
+msgstr "Flusso della parete"
+
+#: fdmprinter.def.json
+msgctxt "wall_material_flow description"
+msgid "Flow compensation on wall lines."
+msgstr "Compensazione del flusso sulle linee perimetrali."
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow label"
+msgid "Outer Wall Flow"
+msgstr "Flusso della parete esterna"
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow description"
+msgid "Flow compensation on the outermost wall line."
+msgstr "Compensazione del flusso sulla linea perimetrale più esterna."
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow label"
+msgid "Inner Wall(s) Flow"
+msgstr "Flusso pareti interne"
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow description"
+msgid "Flow compensation on wall lines for all wall lines except the outermost one."
+msgstr "Compensazione del flusso sulle linee perimetrali per tutte le linee perimetrali tranne quella più esterna."
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow label"
+msgid "Top/Bottom Flow"
+msgstr "Flusso superiore/inferiore"
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow description"
+msgid "Flow compensation on top/bottom lines."
+msgstr "Compensazione del flusso sulle linee superiore/inferiore."
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow label"
+msgid "Top Surface Skin Flow"
+msgstr "Flusso rivestimento esterno superficie superiore"
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow description"
+msgid "Flow compensation on lines of the areas at the top of the print."
+msgstr "Compensazione del flusso sulle linee delle aree nella parte superiore della stampa."
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow label"
+msgid "Infill Flow"
+msgstr "Flusso di riempimento"
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow description"
+msgid "Flow compensation on infill lines."
+msgstr "Compensazione del flusso sulle linee di riempimento."
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow label"
+msgid "Skirt/Brim Flow"
+msgstr "Flusso dello skirt/brim"
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow description"
+msgid "Flow compensation on skirt or brim lines."
+msgstr "Compensazione del flusso sulle linee dello skirt o del brim."
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow label"
+msgid "Support Flow"
+msgstr "Flusso del supporto"
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow description"
+msgid "Flow compensation on support structure lines."
+msgstr "Compensazione del flusso sulle linee di supporto."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow label"
+msgid "Support Interface Flow"
+msgstr "Flusso interfaccia di supporto"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow description"
+msgid "Flow compensation on lines of support roof or floor."
+msgstr "Compensazione del flusso sulle linee di supporto superiore o inferiore."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow label"
+msgid "Support Roof Flow"
+msgstr "Flusso supporto superiore"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow description"
+msgid "Flow compensation on support roof lines."
+msgstr "Compensazione del flusso sulle linee di supporto superiore."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow label"
+msgid "Support Floor Flow"
+msgstr "Flusso supporto inferiore"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow description"
+msgid "Flow compensation on support floor lines."
+msgstr "Compensazione del flusso sulle linee di supporto inferiore."
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow label"
+msgid "Prime Tower Flow"
+msgstr "Flusso torre di innesco"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow description"
+msgid "Flow compensation on prime tower lines."
+msgstr "Compensazione del flusso sulle linee della torre di innesco."
+
#: fdmprinter.def.json
msgctxt "material_flow_layer_0 label"
msgid "Initial Layer Flow"
@@ -2100,7 +2402,7 @@ msgstr "Limitazione delle retrazioni del supporto"
#: fdmprinter.def.json
msgctxt "limit_support_retractions description"
-msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
+msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excessive stringing within the support structure."
msgstr "Omettere la retrazione negli spostamenti da un supporto ad un altro in linea retta. L'abilitazione di questa impostazione riduce il tempo di stampa, ma può comportare un'eccessiva produzione di filamenti all'interno della struttura del supporto."
#: fdmprinter.def.json
@@ -2120,8 +2422,8 @@ msgstr "Distanza di retrazione cambio ugello"
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_amount description"
-msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
-msgstr "Indica il valore di retrazione: impostato a 0 per nessuna retrazione. Questo valore generalmente dovrebbe essere lo stesso della lunghezza della zona di riscaldamento."
+msgid "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+msgstr "Indica il valore di retrazione alla commutazione degli estrusori. Impostato a 0 per nessuna retrazione. Questo valore generalmente dovrebbe essere lo stesso della lunghezza della zona di riscaldamento."
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_speeds label"
@@ -2153,6 +2455,16 @@ msgctxt "switch_extruder_prime_speed description"
msgid "The speed at which the filament is pushed back after a nozzle switch retraction."
msgstr "Indica la velocità alla quale il filamento viene sospinto indietro dopo la retrazione per cambio ugello."
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount label"
+msgid "Nozzle Switch Extra Prime Amount"
+msgstr "Quantità di materiale extra della Prime Tower, al cambio ugello"
+
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount description"
+msgid "Extra material to prime after nozzle switching."
+msgstr "Materiale extra per l'innesco dopo il cambio dell'ugello."
+
#: fdmprinter.def.json
msgctxt "speed label"
msgid "Speed"
@@ -2344,14 +2656,14 @@ msgid "The speed at which the skirt and brim are printed. Normally this is done
msgstr "Indica la velocità a cui sono stampati lo skirt ed il brim. Normalmente questa operazione viene svolta alla velocità di stampa dello strato iniziale, ma a volte è possibile che si desideri stampare lo skirt o il brim ad una velocità diversa."
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override label"
-msgid "Maximum Z Speed"
-msgstr "Velocità massima Z"
+msgctxt "speed_z_hop label"
+msgid "Z Hop Speed"
+msgstr "Velocità di sollevamento Z"
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override description"
-msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
-msgstr "Indica la velocità massima di spostamento del piano di stampa. L’impostazione di questo valore a zero causa l’utilizzo per la stampa dei valori preimpostati in fabbrica per la velocità massima Z."
+msgctxt "speed_z_hop description"
+msgid "The speed at which the vertical Z movement is made for Z Hops. This is typically lower than the print speed since the build plate or machine's gantry is harder to move."
+msgstr "Velocità alla quale viene eseguito il movimento Z verticale per i sollevamenti in Z. In genere è inferiore alla velocità di stampa, dal momento che il piano o il corpo di stampa della macchina sono più difficili da spostare."
#: fdmprinter.def.json
msgctxt "speed_slowdown_layers label"
@@ -2780,8 +3092,8 @@ msgstr "Modalità Combing"
#: fdmprinter.def.json
msgctxt "retraction_combing description"
-msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
-msgstr "La funzione Combing tiene l’ugello all’interno delle aree già stampate durante lo spostamento. In tal modo le corse di spostamento sono leggermente più lunghe, ma si riduce l’esigenza di effettuare retrazioni. Se questa funzione viene disabilitata, il materiale viene retratto e l’ugello si sposta in linea retta al punto successivo. È anche possibile evitare il combing sopra le aree del rivestimento esterno superiore/inferiore effettuando il combing solo nel riempimento. Si noti che l’opzione ‘Nel riempimento' si comporta esattamente come l’opzione ‘Non nel rivestimento' delle precedenti versioni Cura."
+msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas or to only comb within the infill."
+msgstr "La funzione Combing tiene l’ugello all’interno delle aree già stampate durante lo spostamento. In tal modo le corse di spostamento sono leggermente più lunghe ma si riduce l’esigenza di effettuare retrazioni. Se questa funzione viene disabilitata, il materiale viene retratto e l’ugello si sposta in linea retta al punto successivo. È anche possibile evitare il combing sopra le aree del rivestimento esterno superiore/inferiore o effettuare il combing solo nel riempimento."
#: fdmprinter.def.json
msgctxt "retraction_combing option off"
@@ -2853,16 +3165,6 @@ msgctxt "travel_avoid_distance description"
msgid "The distance between the nozzle and already printed parts when avoiding during travel moves."
msgstr "La distanza tra l’ugello e le parti già stampate quando si effettua lo spostamento con aggiramento."
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position label"
-msgid "Start Layers with the Same Part"
-msgstr "Avvio strati con la stessa parte"
-
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position description"
-msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
-msgstr "In ciascuno strato inizia la stampa dell’oggetto vicino allo stesso punto, in modo che non si inizia un nuovo strato con la stampa del pezzo con cui è terminato lo strato precedente. Questo consente di ottenere migliori sovrapposizioni e parti piccole, ma aumenta il tempo di stampa."
-
#: fdmprinter.def.json
msgctxt "layer_start_x label"
msgid "Layer Start X"
@@ -2923,6 +3225,16 @@ msgctxt "retraction_hop_after_extruder_switch description"
msgid "After the machine switched from one extruder to the other, the build plate is lowered to create clearance between the nozzle and the print. This prevents the nozzle from leaving oozed material on the outside of a print."
msgstr "Dopo il passaggio della macchina da un estrusore all’altro, il piano di stampa viene abbassato per creare uno spazio tra l’ugello e la stampa. In tal modo si previene il rilascio di materiale fuoriuscito dall’ugello sull’esterno di una stampa."
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height label"
+msgid "Z Hop After Extruder Switch Height"
+msgstr "Z Hop dopo cambio altezza estrusore"
+
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height description"
+msgid "The height difference when performing a Z Hop after extruder switch."
+msgstr "La differenza di altezza durante l'esecuzione di uno Z Hop dopo il cambio dell'estrusore."
+
#: fdmprinter.def.json
msgctxt "cooling label"
msgid "Cooling"
@@ -3193,6 +3505,11 @@ msgctxt "support_pattern option cross"
msgid "Cross"
msgstr "Incrociata"
+#: fdmprinter.def.json
+msgctxt "support_pattern option gyroid"
+msgid "Gyroid"
+msgstr "Gyroid"
+
#: fdmprinter.def.json
msgctxt "support_wall_count label"
msgid "Support Wall Line Count"
@@ -3254,14 +3571,14 @@ msgid "Distance between the printed initial layer support structure lines. This
msgstr "Indica la distanza tra le linee della struttura di supporto dello strato iniziale stampato. Questa impostazione viene calcolata mediante la densità del supporto."
#: fdmprinter.def.json
-msgctxt "support_infill_angle label"
-msgid "Support Infill Line Direction"
+msgctxt "support_infill_angles label"
+msgid "Support Infill Line Directions"
msgstr "Direzione delle linee di riempimento supporto"
#: fdmprinter.def.json
-msgctxt "support_infill_angle description"
-msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
-msgstr "Indica l’orientamento della configurazione del riempimento per i supporti. La configurazione del riempimento del supporto viene ruotata sul piano orizzontale."
+msgctxt "support_infill_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angle 0 degrees."
+msgstr "Elenco di direzioni linee intere da utilizzare. Gli elementi dall'elenco sono utilizzati in sequenza con il progredire dei layers e, al raggiungimento della fine dell'elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l'intero elenco è racchiuso tra parentesi quadre. L’elenco predefinito è vuoto, vale a dire che utilizza l'angolo predefinito di 0 gradi."
#: fdmprinter.def.json
msgctxt "support_brim_enable label"
@@ -3390,8 +3707,8 @@ msgstr "Distanza giunzione supporto"
#: fdmprinter.def.json
msgctxt "support_join_distance description"
-msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
-msgstr "Indica la distanza massima tra le strutture di supporto nelle direzioni X/Y. Quando la distanza tra le strutture è inferiore al valore indicato, le strutture convergono in una unica."
+msgid "The maximum distance between support structures in the X/Y directions. When separate structures are closer together than this value, the structures merge into one."
+msgstr "La distanza massima tra le strutture di supporto nelle direzioni X/Y. Quando la distanza tra le strutture è inferiore al valore indicato, le strutture convergono in una unica."
#: fdmprinter.def.json
msgctxt "support_offset label"
@@ -3433,6 +3750,16 @@ msgctxt "gradual_support_infill_step_height description"
msgid "The height of support infill of a given density before switching to half the density."
msgstr "Indica l’altezza di riempimento del supporto di una data densità prima di passare a metà densità."
+#: fdmprinter.def.json
+msgctxt "minimum_support_area label"
+msgid "Minimum Support Area"
+msgstr "Area minima supporto"
+
+#: fdmprinter.def.json
+msgctxt "minimum_support_area description"
+msgid "Minimum area size for support polygons. Polygons which have an area smaller than this value will not be generated."
+msgstr "Dimensioni minime area per i poligoni del supporto. I poligoni con un’area inferiore a questo valore non verranno generati."
+
#: fdmprinter.def.json
msgctxt "support_interface_enable label"
msgid "Enable Support Interface"
@@ -3658,6 +3985,99 @@ msgctxt "support_bottom_pattern option zigzag"
msgid "Zig Zag"
msgstr "Zig Zag"
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area label"
+msgid "Minimum Support Interface Area"
+msgstr "Area minima interfaccia supporto"
+
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area description"
+msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Dimensione minima dell'area per i poligoni dell'interfaccia di supporto. I poligoni con un'area più piccola rispetto a questo valore saranno stampati come"
+" supporto normale."
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area label"
+msgid "Minimum Support Roof Area"
+msgstr "Area minima parti superiori supporto"
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area description"
+msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Dimensione minima dell'area per le parti superiori del supporto. I poligoni con un'area più piccola rispetto a questo valore saranno stampati come supporto"
+" normale."
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area label"
+msgid "Minimum Support Floor Area"
+msgstr "Area minima parti inferiori supporto"
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area description"
+msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "Dimensione minima dell'area per le parti inferiori del supporto. I poligoni con un'area più piccola rispetto a questo valore saranno stampati come supporto"
+" normale."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset label"
+msgid "Support Interface Horizontal Expansion"
+msgstr "Espansione orizzontale interfaccia supporto"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset description"
+msgid "Amount of offset applied to the support interface polygons."
+msgstr "Entità di offset applicato ai poligoni di interfaccia del supporto."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset label"
+msgid "Support Roof Horizontal Expansion"
+msgstr "Espansione orizzontale parti superiori supporto"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset description"
+msgid "Amount of offset applied to the roofs of the support."
+msgstr "Entità di offset applicato alle parti superiori del supporto."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset label"
+msgid "Support Floor Horizontal Expansion"
+msgstr "Espansione orizzontale parti inferiori supporto"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset description"
+msgid "Amount of offset applied to the floors of the support."
+msgstr "Entità di offset applicato alle parti inferiori del supporto."
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles label"
+msgid "Support Interface Line Directions"
+msgstr "Direzioni della linea dell'interfaccia di supporto"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Elenco di direzioni linee intere da utilizzare. Gli elementi dall'elenco sono utilizzati in sequenza con il progredire dei layers e, al raggiungimento della fine dell'elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l'intero elenco è racchiuso tra parentesi quadre. L'elenco predefinito è vuoto, vale a dire che utilizza gli angoli predefiniti (alterna tra 45 e 135 gradi se le interfacce sono abbastanza spesse oppure 90 gradi)."
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles label"
+msgid "Support Roof Line Directions"
+msgstr "Direzioni delle linee di supporto superiori"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Elenco di direzioni linee intere da utilizzare. Gli elementi dall'elenco sono utilizzati in sequenza con il progredire dei layers e, al raggiungimento della fine dell'elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l'intero elenco è racchiuso tra parentesi quadre. L'elenco predefinito è vuoto, vale a dire che utilizza gli angoli predefiniti (alterna tra 45 e 135 gradi se le interfacce sono abbastanza spesse oppure 90 gradi)."
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles label"
+msgid "Support Floor Line Directions"
+msgstr "Direzioni della larghezza della linea di supporto inferiore"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "Elenco di direzioni linee intere da utilizzare. Gli elementi dall'elenco sono utilizzati in sequenza con il progredire dei layers e, al raggiungimento della fine dell'elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l'intero elenco è racchiuso tra parentesi quadre. L'elenco predefinito è vuoto, vale a dire che utilizza gli angoli predefiniti (alterna tra 45 e 135 gradi se le interfacce sono abbastanza spesse oppure 90 gradi)."
+
#: fdmprinter.def.json
msgctxt "support_fan_enable label"
msgid "Fan Speed Override"
@@ -3699,14 +4119,14 @@ msgid "The diameter of a special tower."
msgstr "Corrisponde al diametro di una torre speciale."
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter label"
-msgid "Minimum Diameter"
-msgstr "Diametro minimo"
+msgctxt "support_tower_maximum_supported_diameter label"
+msgid "Maximum Tower-Supported Diameter"
+msgstr "Diametro supportato dalla torre"
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter description"
-msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
-msgstr "È il diametro minimo nelle direzioni X/Y di una piccola area, che deve essere sostenuta da una torre speciale."
+msgctxt "support_tower_maximum_supported_diameter description"
+msgid "Maximum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+msgstr "È il diametro massimo nelle direzioni X/Y di una piccola area, che deve essere sostenuta da una torre speciale."
#: fdmprinter.def.json
msgctxt "support_tower_roof_angle label"
@@ -3828,7 +4248,9 @@ msgctxt "skirt_gap description"
msgid ""
"The horizontal distance between the skirt and the first layer of the print.\n"
"This is the minimum distance. Multiple skirt lines will extend outwards from this distance."
-msgstr "Indica la distanza orizzontale tra lo skirt ed il primo strato della stampa.\nQuesta è la distanza minima. Più linee di skirt aumenteranno tale distanza."
+msgstr ""
+"Indica la distanza orizzontale tra lo skirt ed il primo strato della stampa.\n"
+"Questa è la distanza minima. Più linee di skirt aumenteranno tale distanza."
#: fdmprinter.def.json
msgctxt "skirt_brim_minimal_length label"
@@ -4200,16 +4622,6 @@ msgctxt "prime_tower_enable description"
msgid "Print a tower next to the print which serves to prime the material after each nozzle switch."
msgstr "Stampa una torre accanto alla stampa che serve per innescare il materiale dopo ogni cambio ugello."
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular label"
-msgid "Circular Prime Tower"
-msgstr "Torre di innesco circolare"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular description"
-msgid "Make the prime tower as a circular shape."
-msgstr "Conferisce alla torre di innesco una forma circolare."
-
#: fdmprinter.def.json
msgctxt "prime_tower_size label"
msgid "Prime Tower Size"
@@ -4250,16 +4662,6 @@ msgctxt "prime_tower_position_y description"
msgid "The y coordinate of the position of the prime tower."
msgstr "Indica la coordinata Y della posizione della torre di innesco."
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow label"
-msgid "Prime Tower Flow"
-msgstr "Flusso torre di innesco"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow description"
-msgid "Flow compensation: the amount of material extruded is multiplied by this value."
-msgstr "Determina la compensazione del flusso: la quantità di materiale estruso viene moltiplicata per questo valore."
-
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled label"
msgid "Wipe Inactive Nozzle on Prime Tower"
@@ -4270,6 +4672,16 @@ msgctxt "prime_tower_wipe_enabled description"
msgid "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower."
msgstr "Dopo la stampa della torre di innesco con un ugello, pulisce il materiale fuoriuscito dall’altro ugello sulla torre di innesco."
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable label"
+msgid "Prime Tower Brim"
+msgstr "Brim torre di innesco"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable description"
+msgid "Prime-towers might need the extra adhesion afforded by a brim even if the model doesn't. Presently can't be used with the 'Raft' adhesion-type."
+msgstr "Le torri di innesco potrebbero richiedere un'adesione supplementare fornita da un bordo (brim), anche se il modello non lo prevede. Attualmente non può essere utilizzato con il tipo di adesione 'Raft'."
+
#: fdmprinter.def.json
msgctxt "ooze_shield_enabled label"
msgid "Enable Ooze Shield"
@@ -4390,6 +4802,36 @@ msgctxt "remove_empty_first_layers description"
msgid "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle."
msgstr "Rimuovere gli strati vuoti sotto il primo strato stampato, se presenti. La disabilitazione di questa impostazione può provocare la presenza di primi strati vuoti, se l'impostazione di Tolleranza di sezionamento è impostata su Esclusiva o Intermedia."
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution label"
+msgid "Maximum Resolution"
+msgstr "Risoluzione massima"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution description"
+msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
+msgstr "La dimensione minima di un segmento di linea dopo il sezionamento. Se tale dimensione aumenta, la maglia avrà una risoluzione inferiore. Questo può consentire alla stampante di mantenere la velocità per processare il g-code ed aumenterà la velocità di sezionamento eliminando i dettagli della maglia che non è comunque in grado di processare."
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution label"
+msgid "Maximum Travel Resolution"
+msgstr "Risoluzione massima di spostamento"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution description"
+msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
+msgstr "La dimensione minima di un segmento lineare di spostamento dopo il sezionamento. Aumentando tale dimensione, le corse di spostamento avranno meno angoli arrotondati. La stampante può così mantenere la velocità per processare il g-code, ma si può verificare una riduzione della precisione di aggiramento del modello."
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation label"
+msgid "Maximum Deviation"
+msgstr "Deviazione massima"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation description"
+msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution, so if the two conflict the Maximum Deviation will always be held true."
+msgstr "La deviazione massima consentita quando si riduce la risoluzione per l'impostazione Risoluzione massima. Se si aumenta questo parametro, la stampa sarà meno precisa, ma il g-code sarà più piccolo. Deviazione massima rappresenta il limite per Risoluzione massima; pertanto se le due impostazioni sono in conflitto, verrà considerata vera l'impostazione Deviazione massima."
+
#: fdmprinter.def.json
msgctxt "blackmagic label"
msgid "Special Modes"
@@ -4552,8 +4994,8 @@ msgstr "Levigazione dei profili con movimento spiraliforme"
#: fdmprinter.def.json
msgctxt "smooth_spiralized_contours description"
-msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
-msgstr "Leviga i profili con movimento spiraliforme per ridurre la visibilità della giunzione Z (la giunzione Z dovrebbe essere appena visibile sulla stampa, ma rimane visibile nella vista dello strato). Notare che la levigatura tende a rimuovere le bavature fini della superficie."
+msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+msgstr "Leviga i profili con movimento spiraliforme per ridurre la visibilità della giunzione Z (la giunzione Z dovrebbe essere appena visibile sulla stampa, ma rimane visibile nella visualizzazione a strati). Notare che la levigatura tende a rimuovere le bavature fini della superficie."
#: fdmprinter.def.json
msgctxt "relative_extrusion label"
@@ -4765,26 +5207,6 @@ msgctxt "minimum_polygon_circumference description"
msgid "Polygons in sliced layers that have a circumference smaller than this amount will be filtered out. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details."
msgstr "I poligoni in strati sezionati con una circonferenza inferiore a questo valore verranno scartati. I valori inferiori generano una maglia con risoluzione superiore al costo del tempo di sezionamento. È dedicata in particolare alle stampanti SLA ad alta risoluzione e a modelli 3D molto piccoli, ricchi di dettagli."
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution label"
-msgid "Maximum Resolution"
-msgstr "Risoluzione massima"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution description"
-msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
-msgstr "La dimensione minima di un segmento di linea dopo il sezionamento. Se tale dimensione aumenta, la maglia avrà una risoluzione inferiore. Questo può consentire alla stampante di mantenere la velocità per processare il g-code ed aumenterà la velocità di sezionamento eliminando i dettagli della maglia che non è comunque in grado di processare."
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution label"
-msgid "Maximum Travel Resolution"
-msgstr "Risoluzione massima di spostamento"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution description"
-msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
-msgstr "La dimensione minima di un segmento lineare di spostamento dopo il sezionamento. Aumentando tale dimensione, le corse di spostamento avranno meno angoli arrotondati. La stampante può così mantenere la velocità per processare il g-code, ma si può verificare una riduzione della precisione di aggiramento del modello."
-
#: fdmprinter.def.json
msgctxt "support_skip_some_zags label"
msgid "Break Up Support In Chunks"
@@ -4925,16 +5347,6 @@ msgctxt "coasting_speed description"
msgid "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops."
msgstr "È la velocità a cui eseguire lo spostamento durante il Coasting, rispetto alla velocità del percorso di estrusione. Si consiglia di impostare un valore leggermente al di sotto del 100%, poiché durante il Coasting la pressione nel tubo Bowden scende."
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation label"
-msgid "Alternate Skin Rotation"
-msgstr "Rotazione alternata del rivestimento esterno"
-
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation description"
-msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
-msgstr "Alterna la direzione di stampa degli strati superiori/inferiori. Normalmente vengono stampati solo diagonalmente. Questa impostazione aggiunge le direzioni solo X e solo Y."
-
#: fdmprinter.def.json
msgctxt "cross_infill_pocket_size label"
msgid "Cross 3D Pocket Size"
@@ -5042,8 +5454,8 @@ msgstr "Abilitazione del supporto conico"
#: fdmprinter.def.json
msgctxt "support_conical_enabled description"
-msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
-msgstr "Funzione sperimentale: realizza aree di supporto più piccole nella parte inferiore che in corrispondenza dello sbalzo."
+msgid "Make support areas smaller at the bottom than at the overhang."
+msgstr "Realizza aree di supporto più piccole nella parte inferiore che in corrispondenza dello sbalzo."
#: fdmprinter.def.json
msgctxt "support_conical_angle label"
@@ -5107,23 +5519,24 @@ msgstr "Indica la distanza media tra i punti casuali introdotti su ciascun segme
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset label"
-msgid "Flow rate compensation max extrusion offset"
+msgid "Flow Rate Compensation Max Extrusion Offset"
msgstr "Offset massimo dell'estrusione di compensazione del flusso"
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset description"
-msgid "The maximum distance in mm to compensate."
-msgstr "La massima distanza in mm da compensare."
+msgid "The maximum distance in mm to move the filament to compensate for changes in flow rate."
+msgstr "Distanza massima in mm di spostamento del filamento per compensare le modifiche nella velocità di flusso."
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor label"
-msgid "Flow rate compensation factor"
+msgid "Flow Rate Compensation Factor"
msgstr "Fattore di compensazione del flusso"
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor description"
-msgid "The multiplication factor for the flow rate -> distance translation."
-msgstr "Il fattore di moltiplicazione per il flusso -> traslazione distanza."
+msgid "How far to move the filament in order to compensate for changes in flow rate, as a percentage of how far the filament would move in one second of extrusion."
+msgstr "Distanza di spostamento del filamento al fine di compensare le modifiche nella velocità di flusso, come percentuale della distanza di spostamento del filamento"
+" in un secondo di estrusione."
#: fdmprinter.def.json
msgctxt "wireframe_enabled label"
@@ -5275,7 +5688,9 @@ msgctxt "wireframe_up_half_speed description"
msgid ""
"Distance of an upward move which is extruded with half speed.\n"
"This can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing."
-msgstr "Indica la distanza di uno spostamento verso l'alto con estrusione a velocità dimezzata.\nCiò può garantire una migliore adesione agli strati precedenti, senza eccessivo riscaldamento del materiale su questi strati. Applicabile solo alla funzione Wire Printing."
+msgstr ""
+"Indica la distanza di uno spostamento verso l'alto con estrusione a velocità dimezzata.\n"
+"Ciò può garantire una migliore adesione agli strati precedenti, senza eccessivo riscaldamento del materiale su questi strati. Applicabile solo alla funzione Wire Printing."
#: fdmprinter.def.json
msgctxt "wireframe_top_jump label"
@@ -5384,7 +5799,7 @@ msgstr "Indica la distanza tra l'ugello e le linee diagonali verso il basso. Un
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
-msgid "Use adaptive layers"
+msgid "Use Adaptive Layers"
msgstr "Uso di strati adattivi"
#: fdmprinter.def.json
@@ -5394,7 +5809,7 @@ msgstr "Gli strati adattivi calcolano l’altezza degli strati in base alla form
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
-msgid "Adaptive layers maximum variation"
+msgid "Adaptive Layers Maximum Variation"
msgstr "Variazione massima strati adattivi"
#: fdmprinter.def.json
@@ -5404,7 +5819,7 @@ msgstr "La differenza di altezza massima rispetto all’altezza dello strato di
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
-msgid "Adaptive layers variation step size"
+msgid "Adaptive Layers Variation Step Size"
msgstr "Dimensione variazione strati adattivi"
#: fdmprinter.def.json
@@ -5414,13 +5829,14 @@ msgstr "La differenza in altezza dello strato successivo rispetto al precedente.
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
-msgid "Adaptive layers threshold"
-msgstr "Soglia strati adattivi"
+msgid "Adaptive Layers Topography Size"
+msgstr "Dimensione della topografia dei layer adattivi"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
-msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
-msgstr "Soglia per l’utilizzo o meno di uno strato di dimensioni minori. Questo numero è confrontato al valore dell’inclinazione più ripida di uno strato."
+msgid "Target horizontal distance between two adjacent layers. Reducing this setting causes thinner layers to be used to bring the edges of the layers closer together."
+msgstr "Distanza orizzontale target tra due layer adiacenti. Riducendo questa impostazione, i layer più sottili verranno utilizzati per avvicinare i margini dei"
+" layer."
#: fdmprinter.def.json
msgctxt "wall_overhang_angle label"
@@ -5429,8 +5845,9 @@ msgstr "Angolo parete di sbalzo"
#: fdmprinter.def.json
msgctxt "wall_overhang_angle description"
-msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
-msgstr "Le pareti che sbalzano oltre questo angolo verranno stampate utilizzando le impostazioni parete di sbalzo. Quando il valore è 90, nessuna parete sarà trattata come sbalzo."
+msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging. Overhang that gets supported by support will not be treated as overhang either."
+msgstr "Le pareti con uno sbalzo superiore a quest'angolo saranno stampate con le impostazioni per le pareti a sbalzo. Se il valore è 90, nessuna parete sarà trattata"
+" come parete a sbalzo. Nemmeno lo sbalzo supportato dal supporto sarà trattato come tale."
#: fdmprinter.def.json
msgctxt "wall_overhang_speed_factor label"
@@ -5632,6 +6049,198 @@ msgctxt "bridge_fan_speed_3 description"
msgid "Percentage fan speed to use when printing the third bridge skin layer."
msgstr "La velocità della ventola in percentuale da usare per stampare il terzo strato del rivestimento esterno ponte."
+#: fdmprinter.def.json
+msgctxt "clean_between_layers label"
+msgid "Wipe Nozzle Between Layers"
+msgstr "Pulitura ugello tra gli strati"
+
+#: fdmprinter.def.json
+msgctxt "clean_between_layers description"
+msgid "Whether to include nozzle wipe G-Code between layers. Enabling this setting could influence behavior of retract at layer change. Please use Wipe Retraction settings to control retraction at layers where the wipe script will be working."
+msgstr "Se includere il codice G di pulitura ugello tra gli strati. Abilitare questa impostazione potrebbe influire sul comportamento di retrazione al cambio strato. Utilizzare le impostazioni di Retrazione per pulitura per controllare la retrazione in corrispondenza degli strati in cui lo script di pulitura sarà funzionante."
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe label"
+msgid "Material Volume Between Wipes"
+msgstr "Volume di materiale tra le operazioni di pulitura"
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe description"
+msgid "Maximum material, that can be extruded before another nozzle wipe is initiated."
+msgstr "Il massimo volume di materiale, che può essere estruso prima di iniziare la successiva operazione di pulitura ugello."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable label"
+msgid "Wipe Retraction Enable"
+msgstr "Retrazione per pulitura abilitata"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable description"
+msgid "Retract the filament when the nozzle is moving over a non-printed area."
+msgstr "Ritrae il filamento quando l'ugello si sta muovendo su un'area non stampata."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount label"
+msgid "Wipe Retraction Distance"
+msgstr "Distanza di retrazione per pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount description"
+msgid "Amount to retract the filament so it does not ooze during the wipe sequence."
+msgstr "L'entità di retrazione del filamento in modo che non fuoriesca durante la sequenza di pulitura."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount label"
+msgid "Wipe Retraction Extra Prime Amount"
+msgstr "Entità di innesco supplementare dopo retrazione per pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount description"
+msgid "Some material can ooze away during a wipe travel moves, which can be compensated for here."
+msgstr "Qui è possibile compensare l’eventuale trafilamento di materiale che può verificarsi nel corso della pulitura durante il movimento."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed label"
+msgid "Wipe Retraction Speed"
+msgstr "Velocità di retrazione per pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed description"
+msgid "The speed at which the filament is retracted and primed during a wipe retraction move."
+msgstr "Indica la velocità alla quale il filamento viene retratto e preparato durante un movimento di retrazione per pulitura."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed label"
+msgid "Wipe Retraction Retract Speed"
+msgstr "Velocità di retrazione per pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed description"
+msgid "The speed at which the filament is retracted during a wipe retraction move."
+msgstr "Indica la velocità alla quale il filamento viene retratto durante un movimento di retrazione per pulitura."
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed label"
+msgid "Retraction Prime Speed"
+msgstr "Velocità di innesco dopo la retrazione"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed description"
+msgid "The speed at which the filament is primed during a wipe retraction move."
+msgstr "Indica la velocità alla quale il filamento viene preparato durante un movimento di retrazione per pulitura."
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause label"
+msgid "Wipe Pause"
+msgstr "Pausa pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause description"
+msgid "Pause after the unretract."
+msgstr "Pausa dopo ripristino."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable label"
+msgid "Wipe Z Hop When Retracted"
+msgstr "Z Hop pulitura durante retrazione"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable description"
+msgid "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate."
+msgstr "Ogniqualvolta avviene una retrazione, il piano di stampa viene abbassato per creare uno spazio tra l’ugello e la stampa. Questo impedisce l'urto dell'ugello sulla stampa durante gli spostamenti, riducendo la possibilità di far cadere la stampa dal piano."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount label"
+msgid "Wipe Z Hop Height"
+msgstr "Altezza Z Hop pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount description"
+msgid "The height difference when performing a Z Hop."
+msgstr "La differenza di altezza durante l’esecuzione di uno Z Hop."
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed label"
+msgid "Wipe Hop Speed"
+msgstr "Velocità di sollevamento (Hop) per pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed description"
+msgid "Speed to move the z-axis during the hop."
+msgstr "Velocità di spostamento dell'asse z durante il sollevamento (Hop)."
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x label"
+msgid "Wipe Brush X Position"
+msgstr "Posizione X spazzolino di pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x description"
+msgid "X location where wipe script will start."
+msgstr "Posizione X in cui verrà avviato lo script di pulitura."
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count label"
+msgid "Wipe Repeat Count"
+msgstr "Conteggio ripetizioni operazioni di pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count description"
+msgid "Number of times to move the nozzle across the brush."
+msgstr "Numero di passaggi dell'ugello attraverso lo spazzolino."
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance label"
+msgid "Wipe Move Distance"
+msgstr "Distanza spostamento longitudinale di pulitura"
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance description"
+msgid "The distance to move the head back and forth across the brush."
+msgstr "La distanza dello spostamento longitudinale eseguito dalla testina attraverso lo spazzolino."
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size label"
+msgid "Small Hole Max Size"
+msgstr "Dimensione massima foro piccolo"
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size description"
+msgid "Holes and part outlines with a diameter smaller than this will be printed using Small Feature Speed."
+msgstr "I fori e i profili delle parti con un diametro inferiore a quello indicato verranno stampati utilizzando Velocità Dettagli di piccole dimensioni."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length label"
+msgid "Small Feature Max Length"
+msgstr "Lunghezza massima dettagli di piccole dimensioni"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length description"
+msgid "Feature outlines that are shorter than this length will be printed using Small Feature Speed."
+msgstr "Profili di dettagli inferiori a questa lunghezza saranno stampati utilizzando Velocità Dettagli di piccole dimensioni."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor label"
+msgid "Small Feature Speed"
+msgstr "Velocità dettagli piccole dimensioni"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor description"
+msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "I dettagli di piccole dimensioni verranno stampati a questa percentuale della velocità di stampa normale. Una stampa più lenta può aiutare in termini di"
+" adesione e precisione."
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 label"
+msgid "Small Feature Initial Layer Speed"
+msgstr "Velocità layer iniziale per dettagli di piccole dimensioni"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 description"
+msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "I dettagli di piccole dimensioni sul primo layer saranno stampati a questa percentuale della velocità di stampa normale. Una stampa più lenta può aiutare"
+" in termini di adesione e precisione."
+
#: fdmprinter.def.json
msgctxt "command_line_settings label"
msgid "Command Line Settings"
@@ -5692,6 +6301,234 @@ msgctxt "mesh_rotation_matrix description"
msgid "Transformation matrix to be applied to the model when loading it from file."
msgstr "Matrice di rotazione da applicare al modello quando caricato dal file."
+#~ msgctxt "minimum_interface_area description"
+#~ msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Dimensioni minime area per i poligoni di interfaccia del supporto. I poligoni con un’area inferiore a questo valore non verranno generati."
+
+#~ msgctxt "minimum_roof_area description"
+#~ msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Dimensioni minime area per le parti superiori del supporto. I poligoni con un’area inferiore a questo valore non verranno generati."
+
+#~ msgctxt "minimum_bottom_area description"
+#~ msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "Dimensioni minime area per le parti inferiori del supporto. I poligoni con un’area inferiore a questo valore non verranno generati."
+
+#~ msgctxt "skin_alternate_rotation label"
+#~ msgid "Alternate Skin Rotation"
+#~ msgstr "Rotazione alternata del rivestimento esterno"
+
+#~ msgctxt "skin_alternate_rotation description"
+#~ msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
+#~ msgstr "Alterna la direzione di stampa degli strati superiori/inferiori. Normalmente vengono stampati solo diagonalmente. Questa impostazione aggiunge le direzioni solo X e solo Y."
+
+#~ msgctxt "flow_rate_max_extrusion_offset label"
+#~ msgid "Flow rate compensation max extrusion offset"
+#~ msgstr "Offset massimo dell'estrusione di compensazione del flusso"
+
+#~ msgctxt "flow_rate_max_extrusion_offset description"
+#~ msgid "The maximum distance in mm to compensate."
+#~ msgstr "La massima distanza in mm da compensare."
+
+#~ msgctxt "flow_rate_extrusion_offset_factor label"
+#~ msgid "Flow rate compensation factor"
+#~ msgstr "Fattore di compensazione del flusso"
+
+#~ msgctxt "flow_rate_extrusion_offset_factor description"
+#~ msgid "The multiplication factor for the flow rate -> distance translation."
+#~ msgstr "Il fattore di moltiplicazione per il flusso -> traslazione distanza."
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive Layers Threshold"
+#~ msgstr "Soglia strati adattivi"
+
+#~ msgctxt "adaptive_layer_height_threshold description"
+#~ msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
+#~ msgstr "Soglia per l’utilizzo o meno di uno strato di dimensioni minori. Questo numero è confrontato al valore dell’inclinazione più ripida di uno strato."
+
+#~ msgctxt "wall_overhang_angle description"
+#~ msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
+#~ msgstr "Le pareti che sbalzano oltre questo angolo verranno stampate utilizzando le impostazioni parete di sbalzo. Quando il valore è 90, nessuna parete sarà trattata come sbalzo."
+
+#~ msgctxt "small_feature_speed_factor description"
+#~ msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "I dettagli di piccole dimensioni verranno stampati a questa percentuale della velocità di stampa normale. Una stampa più lenta può aiutare in termini di adesione e precisione."
+
+#~ msgctxt "small_feature_speed_factor_0 label"
+#~ msgid "First Layer Speed"
+#~ msgstr "Velocità primo layer"
+
+#~ msgctxt "small_feature_speed_factor_0 description"
+#~ msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "I dettagli di piccole dimensioni sul primo layer saranno stampati a questa percentuale della velocità di stampa normale. Una stampa più lenta può aiutare in termini di adesione e precisione."
+
+#~ msgctxt "ironing_enabled description"
+#~ msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
+#~ msgstr "Ulteriore passaggio sopra la superficie superiore, senza estrusione di materiale. Ha lo scopo di fondere ulteriormente la plastica alla sommità, creando una superficie più uniforme."
+
+#~ msgctxt "start_layers_at_same_position label"
+#~ msgid "Start Layers with the Same Part"
+#~ msgstr "Avvio strati con la stessa parte"
+
+#~ msgctxt "start_layers_at_same_position description"
+#~ msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
+#~ msgstr "In ciascuno strato inizia la stampa dell’oggetto vicino allo stesso punto, in modo che non si inizia un nuovo strato con la stampa del pezzo con cui è terminato lo strato precedente. Questo consente di ottenere migliori sovrapposizioni e parti piccole, ma aumenta il tempo di stampa."
+
+#~ msgctxt "support_infill_angles description"
+#~ msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
+#~ msgstr "Indica l’orientamento della configurazione del riempimento per i supporti. La configurazione del riempimento del supporto viene ruotata sul piano orizzontale."
+
+#~ msgctxt "meshfix_maximum_deviation description"
+#~ msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller."
+#~ msgstr "La deviazione massima consentita quando si riduce la risoluzione per l'impostazione di Risoluzione massima. Se si aumenta questo parametro, la stampa sarà meno precisa, ma il codice g sarà più piccolo."
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code Flavour"
+#~ msgstr "Tipo di codice G"
+
+#~ msgctxt "z_seam_corner description"
+#~ msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
+#~ msgstr "Controlla se gli angoli sul profilo del modello influenzano la posizione della giunzione. Nessuno significa che gli angoli non hanno alcuna influenza sulla posizione della giunzione. Nascondi giunzione favorisce la presenza della giunzione su un angolo interno. Esponi giunzione favorisce la presenza della giunzione su un angolo esterno. Nascondi o esponi giunzione favorisce la presenza della giunzione su un angolo interno o esterno."
+
+#~ msgctxt "skin_no_small_gaps_heuristic label"
+#~ msgid "Ignore Small Z Gaps"
+#~ msgstr "Ignora i piccoli interstizi a Z"
+
+#~ msgctxt "skin_no_small_gaps_heuristic description"
+#~ msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
+#~ msgstr "Quando il modello presenta piccoli spazi vuoti verticali, circa il 5% del tempo di calcolo supplementare può essere utilizzato per la generazione di rivestimenti esterni superiori ed inferiori in questi interstizi. In questo caso disabilitare l’impostazione."
+
+#~ msgctxt "build_volume_temperature description"
+#~ msgid "The temperature used for build volume. If this is 0, the build volume temperature will not be adjusted."
+#~ msgstr "La temperatura utilizzata per il volume di stampa. Se il valore è 0, la temperatura del volume di stampa non verrà regolata."
+
+#~ msgctxt "limit_support_retractions description"
+#~ msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
+#~ msgstr "Omettere la retrazione negli spostamenti da un supporto ad un altro in linea retta. L'abilitazione di questa impostazione riduce il tempo di stampa, ma può comportare un'eccessiva produzione di filamenti all'interno della struttura del supporto."
+
+#~ msgctxt "max_feedrate_z_override label"
+#~ msgid "Maximum Z Speed"
+#~ msgstr "Velocità massima Z"
+
+#~ msgctxt "max_feedrate_z_override description"
+#~ msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
+#~ msgstr "Indica la velocità massima di spostamento del piano di stampa. L’impostazione di questo valore a zero causa l’utilizzo per la stampa dei valori preimpostati in fabbrica per la velocità massima Z."
+
+#~ msgctxt "support_join_distance description"
+#~ msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
+#~ msgstr "Indica la distanza massima tra le strutture di supporto nelle direzioni X/Y. Quando la distanza tra le strutture è inferiore al valore indicato, le strutture convergono in una unica."
+
+#~ msgctxt "support_minimal_diameter label"
+#~ msgid "Minimum Diameter"
+#~ msgstr "Diametro minimo"
+
+#~ msgctxt "support_minimal_diameter description"
+#~ msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+#~ msgstr "È il diametro minimo nelle direzioni X/Y di una piccola area, che deve essere sostenuta da una torre speciale."
+
+#~ msgctxt "prime_tower_circular label"
+#~ msgid "Circular Prime Tower"
+#~ msgstr "Torre di innesco circolare"
+
+#~ msgctxt "prime_tower_circular description"
+#~ msgid "Make the prime tower as a circular shape."
+#~ msgstr "Conferisce alla torre di innesco una forma circolare."
+
+#~ msgctxt "prime_tower_flow description"
+#~ msgid "Flow compensation: the amount of material extruded is multiplied by this value."
+#~ msgstr "Determina la compensazione del flusso: la quantità di materiale estruso viene moltiplicata per questo valore."
+
+#~ msgctxt "smooth_spiralized_contours description"
+#~ msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+#~ msgstr "Leviga i profili con movimento spiraliforme per ridurre la visibilità della giunzione Z (la giunzione Z dovrebbe essere appena visibile sulla stampa, ma rimane visibile nella vista dello strato). Notare che la levigatura tende a rimuovere le bavature fini della superficie."
+
+#~ msgctxt "support_conical_enabled description"
+#~ msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
+#~ msgstr "Funzione sperimentale: realizza aree di supporto più piccole nella parte inferiore che in corrispondenza dello sbalzo."
+
+#~ msgctxt "extruders_enabled_count label"
+#~ msgid "Number of Extruders that are enabled"
+#~ msgstr "Numero di estrusori abilitati"
+
+#~ msgctxt "machine_nozzle_tip_outer_diameter label"
+#~ msgid "Outer nozzle diameter"
+#~ msgstr "Diametro esterno ugello"
+
+#~ msgctxt "machine_nozzle_head_distance label"
+#~ msgid "Nozzle length"
+#~ msgstr "Lunghezza ugello"
+
+#~ msgctxt "machine_nozzle_expansion_angle label"
+#~ msgid "Nozzle angle"
+#~ msgstr "Angolo ugello"
+
+#~ msgctxt "machine_heat_zone_length label"
+#~ msgid "Heat zone length"
+#~ msgstr "Lunghezza della zona di riscaldamento"
+
+#~ msgctxt "machine_nozzle_heat_up_speed label"
+#~ msgid "Heat up speed"
+#~ msgstr "Velocità di riscaldamento"
+
+#~ msgctxt "machine_nozzle_cool_down_speed label"
+#~ msgid "Cool down speed"
+#~ msgstr "Velocità di raffreddamento"
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code flavour"
+#~ msgstr "Tipo di codice G"
+
+#~ msgctxt "machine_disallowed_areas label"
+#~ msgid "Disallowed areas"
+#~ msgstr "Aree non consentite"
+
+#~ msgctxt "machine_head_polygon label"
+#~ msgid "Machine head polygon"
+#~ msgstr "Poligono testina macchina"
+
+#~ msgctxt "machine_head_with_fans_polygon label"
+#~ msgid "Machine head & Fan polygon"
+#~ msgstr "Poligono testina macchina e ventola"
+
+#~ msgctxt "gantry_height label"
+#~ msgid "Gantry height"
+#~ msgstr "Altezza gantry"
+
+#~ msgctxt "machine_use_extruder_offset_to_offset_coords label"
+#~ msgid "Offset With Extruder"
+#~ msgstr "Offset con estrusore"
+
+#~ msgctxt "adaptive_layer_height_enabled label"
+#~ msgid "Use adaptive layers"
+#~ msgstr "Uso di strati adattivi"
+
+#~ msgctxt "adaptive_layer_height_variation label"
+#~ msgid "Adaptive layers maximum variation"
+#~ msgstr "Variazione massima strati adattivi"
+
+#~ msgctxt "adaptive_layer_height_variation_step label"
+#~ msgid "Adaptive layers variation step size"
+#~ msgstr "Dimensione variazione strati adattivi"
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive layers threshold"
+#~ msgstr "Soglia strati adattivi"
+
+#~ msgctxt "skin_overlap description"
+#~ msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
+#~ msgstr "Entità della sovrapposizione tra il rivestimento e le pareti espressa in percentuale della larghezza della linea del rivestimento esterno. Una leggera sovrapposizione consente alle pareti di essere saldamente collegate al rivestimento. È una percentuale delle larghezze medie delle linee del rivestimento e della parete più interna."
+
+#~ msgctxt "skin_overlap_mm description"
+#~ msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
+#~ msgstr "Indica la quantità di sovrapposizione tra il rivestimento esterno e le pareti. Una leggera sovrapposizione consente il saldo collegamento delle pareti al rivestimento esterno."
+
+#~ msgctxt "switch_extruder_retraction_amount description"
+#~ msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+#~ msgstr "Indica il valore di retrazione: impostato a 0 per nessuna retrazione. Questo valore generalmente dovrebbe essere lo stesso della lunghezza della zona di riscaldamento."
+
+#~ msgctxt "retraction_combing description"
+#~ msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
+#~ msgstr "La funzione Combing tiene l’ugello all’interno delle aree già stampate durante lo spostamento. In tal modo le corse di spostamento sono leggermente più lunghe, ma si riduce l’esigenza di effettuare retrazioni. Se questa funzione viene disabilitata, il materiale viene retratto e l’ugello si sposta in linea retta al punto successivo. È anche possibile evitare il combing sopra le aree del rivestimento esterno superiore/inferiore effettuando il combing solo nel riempimento. Si noti che l’opzione ‘Nel riempimento' si comporta esattamente come l’opzione ‘Non nel rivestimento' delle precedenti versioni Cura."
+
#~ msgctxt "connect_skin_polygons description"
#~ msgid "Connect top/bottom skin paths where they run next to each other. For the concentric pattern enabling this setting greatly reduces the travel time, but because the connections can happend midway over infill this feature can reduce the top surface quality."
#~ msgstr "Collega i percorsi del rivestimento esterno superiore/inferiore quando corrono uno accanto all’altro. Per le configurazioni concentriche, l’abilitazione di questa impostazione riduce notevolmente il tempo di spostamento, tuttavia poiché i collegamenti possono aver luogo a metà del riempimento, con questa funzione la qualità della superficie superiore potrebbe risultare inferiore."
diff --git a/resources/i18n/ja_JP/cura.po b/resources/i18n/ja_JP/cura.po
index 13916ef1e2..def6a45abf 100644
--- a/resources/i18n/ja_JP/cura.po
+++ b/resources/i18n/ja_JP/cura.po
@@ -1,24 +1,24 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0100\n"
-"PO-Revision-Date: 2018-11-06 14:58+0100\n"
-"Last-Translator: Bothof \n"
-"Language-Team: Japanese\n"
+"POT-Creation-Date: 2019-11-05 13:13+0100\n"
+"PO-Revision-Date: 2019-09-23 14:15+0200\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: Japanese , Japanese \n"
"Language: ja_JP\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.2.1\n"
-#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:22
+#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:30
msgctxt "@action"
msgid "Machine Settings"
msgstr "プリンターの設定"
@@ -40,23 +40,23 @@ msgctxt "@item:inlistbox"
msgid "G-code File"
msgstr "G-codeファイル"
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:67
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:66
msgctxt "@error:not supported"
msgid "GCodeWriter does not support non-text mode."
msgstr "GCodeWriter は非テキストモードはサポートしていません。"
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:73
-#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:89
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:72
+#: /home/ruben/Projects/Cura/plugins/GCodeWriter/GCodeWriter.py:88
msgctxt "@warning:status"
msgid "Please prepare G-code before exporting."
msgstr "エクスポートする前にG-codeの準備をしてください。"
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:30
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:31
msgctxt "@info:title"
msgid "3D Model Assistant"
msgstr "3Dモデルアシスタント"
-#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:80
+#: /home/ruben/Projects/Cura/plugins/ModelChecker/ModelChecker.py:92
#, python-brace-format
msgctxt "@info:status"
msgid ""
@@ -70,67 +70,50 @@ msgstr ""
"
Print with finegrained control over every last bit of the slicing process."
+#~ msgstr "カスタムプリントセットアップ
スライス処理のきめ細かなコントロールにてプリントする。"
+
+#~ msgctxt "@action:inmenu menubar:help"
+#~ msgid "Show Engine &Log..."
+#~ msgstr "エンジン&ログを表示する…"
+
+#~ msgctxt "@action:menu"
+#~ msgid "Browse packages..."
+#~ msgstr "パッケージを見る…"
+
+#~ msgctxt "@action:inmenu menubar:view"
+#~ msgid "Expand/Collapse Sidebar"
+#~ msgstr "サイドバーを展開する/たたむ"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Please load a 3D model"
+#~ msgstr "3Dモデルをロードしてください"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Ready to slice"
+#~ msgstr "スライスの準備ができました"
+
+#~ msgctxt "@label:PrintjobStatus %1 is target operation"
+#~ msgid "Ready to %1"
+#~ msgstr "%1の準備完了"
+
+#~ msgctxt "@label:PrintjobStatus"
+#~ msgid "Slicing unavailable"
+#~ msgstr "スライスが利用不可能"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Slice current printjob"
+#~ msgstr "現在のプリントジョブをスライスします"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Cancel slicing process"
+#~ msgstr "スライスプロセスをキャンセルします"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Prepare"
+#~ msgstr "準備する"
+
+#~ msgctxt "@label:Printjob"
+#~ msgid "Cancel"
+#~ msgstr "キャンセル"
+
+#~ msgctxt "@info:tooltip"
+#~ msgid "Select the active output device"
+#~ msgstr "アクティブなアウトプットデバイスを選択する"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&View"
+#~ msgstr "&ビュー"
+
+#~ msgctxt "@title:menu"
+#~ msgid "&Settings"
+#~ msgstr "&設定"
+
+#~ msgctxt "@title:menu menubar:toplevel"
+#~ msgid "&Toolbox"
+#~ msgstr "&ツールボックス"
+
+#~ msgctxt "@action:button"
+#~ msgid "Open File"
+#~ msgstr "ファイルを開く"
+
+#~ msgctxt "@tooltip"
+#~ msgid "This quality profile is not available for you current material and nozzle configuration. Please change these to enable this quality profile"
+#~ msgstr "この品質プロファイルは現在の材料およびノズル構成では使用できません。この品質プロファイルを使用できるように変更してください"
+
+#~ msgctxt "@label"
+#~ msgid "Print Speed"
+#~ msgstr "プリントスピード"
+
+#~ msgctxt "@label"
+#~ msgid "Slower"
+#~ msgstr "ゆっくり"
+
+#~ msgctxt "@label"
+#~ msgid "Faster"
+#~ msgstr "早く"
+
+#~ msgctxt "@label"
+#~ msgid "Enable gradual"
+#~ msgstr "グラデュアルを有効にする"
+
+#~ msgctxt "@label"
+#~ msgid "Generate Support"
+#~ msgstr "サポートを生成します"
+
+#~ msgctxt "@label"
+#~ msgid "Build Plate Adhesion"
+#~ msgstr "ビルドプレートの接着"
+
+#~ msgctxt "@label"
+#~ msgid "Need help improving your prints? Read the Ultimaker Troubleshooting Guides"
+#~ msgstr "プリントにヘルプが必要ですか? Ultimakerトラブルシューティングガイドを読んでください"
+
+#~ msgctxt "@title:window"
+#~ msgid "Engine Log"
+#~ msgstr "エンジンログ"
+
+#~ msgctxt "@label"
+#~ msgid "Printer type"
+#~ msgstr "プリンタータイプ"
+
+#~ msgctxt "@label"
+#~ msgid "Use glue with this material combination"
+#~ msgstr "この材料の組み合わせで接着する"
+
+#~ msgctxt "@label"
+#~ msgid "Check compatibility"
+#~ msgstr "互換性の確認"
+
+#~ msgctxt "@tooltip"
+#~ msgid "Click to check the material compatibility on Ultimaker.com."
+#~ msgstr "Ultimaker.comにてマテリアルのコンパティビリティを調べるためにクリック。"
+
+#~ msgctxt "description"
+#~ msgid "Shows changes since latest checked version."
+#~ msgstr "最新の更新バージョンの変更点を表示する。"
+
+#~ msgctxt "name"
+#~ msgid "Changelog"
+#~ msgstr "Changelog"
+
+#~ msgctxt "description"
+#~ msgid "Create a flattend quality changes profile."
+#~ msgstr "プロファイルを変更するフラットエンドクオリティーを作成する。"
+
+#~ msgctxt "name"
+#~ msgid "Profile flatener"
+#~ msgstr "プロファイルフラットナー"
+
+#~ msgctxt "description"
+#~ msgid "Ask the user once if he/she agrees with our license."
+#~ msgstr "ライセンスに同意するかどうかユーザーに1回だけ確認する。"
+
+#~ msgctxt "name"
+#~ msgid "UserAgreement"
+#~ msgstr "UserAgreement"
+
+#~ msgctxt "@warning:status"
+#~ msgid "Please generate G-code before saving."
+#~ msgstr "保存する前に G-code を生成してください。"
+
#~ msgctxt "@action"
#~ msgid "Upgrade Firmware"
#~ msgstr "ファームウェアをアップグレード"
@@ -5021,22 +6517,6 @@ msgstr "Curaプロファイルリーダー"
#~ msgid "Confirm uninstall "
#~ msgstr "アンインストール確認 "
-#~ msgctxt "@label:status"
-#~ msgid "Paused"
-#~ msgstr "一時停止"
-
-#~ msgctxt "@action:button"
-#~ msgid "Previous"
-#~ msgstr "前"
-
-#~ msgctxt "@action:button"
-#~ msgid "Next"
-#~ msgstr "次"
-
-#~ msgctxt "@label"
-#~ msgid "Tip"
-#~ msgstr "ヒント"
-
#~ msgctxt "@label Print estimates: m for meters, g for grams, %4 is currency and %3 is print cost"
#~ msgid "%1m / ~ %2g / ~ %4 %3"
#~ msgstr "%1m / ~ %2g / ~ %4 %3"
@@ -5045,26 +6525,10 @@ msgstr "Curaプロファイルリーダー"
#~ msgid "%1m / ~ %2g"
#~ msgstr "%1m / ~ %2g"
-#~ msgctxt "@label"
-#~ msgid "Print experiment"
-#~ msgstr "試し印刷"
-
-#~ msgctxt "@label"
-#~ msgid "Checklist"
-#~ msgstr "チェックリスト"
-
#~ msgctxt "@title"
#~ msgid "Upgrade Firmware"
#~ msgstr "ファームウェアをアップグレード"
-#~ msgctxt "description"
-#~ msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
-#~ msgstr "材料メーカーがドロップインUIを使用して新しい材料と品質のプロファイルを作成できるようにします。"
-
-#~ msgctxt "name"
-#~ msgid "Print Profile Assistant"
-#~ msgstr "プリントプロファイルアシスタント"
-
#~ msgctxt "@action:button"
#~ msgid "Print with Doodle3D WiFi-Box"
#~ msgstr "Doodle3D WiFi-Boxでプリントする"
@@ -5157,10 +6621,6 @@ msgstr "Curaプロファイルリーダー"
#~ msgid "Lost connection with the printer"
#~ msgstr "プリンターへの接続が切断されました。"
-#~ msgctxt "@label:status"
-#~ msgid "Unavailable"
-#~ msgstr "利用不可"
-
#~ msgctxt "@label:status"
#~ msgid "Unknown"
#~ msgstr "不明"
diff --git a/resources/i18n/ja_JP/fdmextruder.def.json.po b/resources/i18n/ja_JP/fdmextruder.def.json.po
index 95f0382823..d2a33a2db3 100644
--- a/resources/i18n/ja_JP/fdmextruder.def.json.po
+++ b/resources/i18n/ja_JP/fdmextruder.def.json.po
@@ -1,14 +1,14 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 15:24+0200\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-03-13 14:00+0200\n"
"Last-Translator: Bothof \n"
"Language-Team: Japanese\n"
"Language: ja_JP\n"
@@ -84,8 +84,8 @@ msgstr "エクストルーダーがG-Codeを開始する"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_code description"
-msgid "Start g-code to execute whenever turning the extruder on."
-msgstr "エクストルーダーを使う度にGコードを展開します。"
+msgid "Start g-code to execute when switching to this extruder."
+msgstr "このエクストルーダーに切り替えた時に G-Code の開始を実行します。"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_abs label"
@@ -124,8 +124,8 @@ msgstr "エクストルーダーがG-Codeを終了する"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_code description"
-msgid "End g-code to execute whenever turning the extruder off."
-msgstr "エクストルーダーを使用しないときにGコードを終了します。"
+msgid "End g-code to execute when switching away from this extruder."
+msgstr "このエクストルーダーから切り替えた時に G-Code の終了を実行します。"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_abs label"
@@ -226,3 +226,11 @@ msgstr "直径"
msgctxt "material_diameter description"
msgid "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament."
msgstr "使用するフィラメントの太さの調整 この値を使用するフィラメントの太さと一致させてください。"
+
+#~ msgctxt "machine_extruder_start_code description"
+#~ msgid "Start g-code to execute whenever turning the extruder on."
+#~ msgstr "エクストルーダーを使う度にGコードを展開します。"
+
+#~ msgctxt "machine_extruder_end_code description"
+#~ msgid "End g-code to execute whenever turning the extruder off."
+#~ msgstr "エクストルーダーを使用しないときにGコードを終了します。"
diff --git a/resources/i18n/ja_JP/fdmprinter.def.json.po b/resources/i18n/ja_JP/fdmprinter.def.json.po
index 3156e77288..a53f3de7ca 100644
--- a/resources/i18n/ja_JP/fdmprinter.def.json.po
+++ b/resources/i18n/ja_JP/fdmprinter.def.json.po
@@ -1,22 +1,22 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
+"Project-Id-Version: Cura 4.4\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2018-10-29 15:01+0000\n"
-"PO-Revision-Date: 2018-09-28 15:27+0200\n"
-"Last-Translator: Bothof \n"
-"Language-Team: Japanese\n"
+"POT-Creation-Date: 2019-11-05 13:13+0000\n"
+"PO-Revision-Date: 2019-09-23 14:15+0200\n"
+"Last-Translator: Lionbridge \n"
+"Language-Team: Japanese , Japanese \n"
"Language: ja_JP\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.2.1\n"
#: fdmprinter.def.json
msgctxt "machine_settings label"
@@ -61,7 +61,9 @@ msgctxt "machine_start_gcode description"
msgid ""
"G-code commands to be executed at the very start - separated by \n"
"."
-msgstr "最初に実行するG-codeコマンドは、\nで区切ります。"
+msgstr ""
+"最初に実行するG-codeコマンドは、\n"
+"で区切ります。"
#: fdmprinter.def.json
msgctxt "machine_end_gcode label"
@@ -73,7 +75,9 @@ msgctxt "machine_end_gcode description"
msgid ""
"G-code commands to be executed at the very end - separated by \n"
"."
-msgstr "最後に実行するG-codeコマンドは、\nで区切ります。"
+msgstr ""
+"最後に実行するG-codeコマンドは、\n"
+"で区切ります。"
#: fdmprinter.def.json
msgctxt "material_guid label"
@@ -227,6 +231,16 @@ msgctxt "machine_heated_bed description"
msgid "Whether the machine has a heated build plate present."
msgstr "プリンターに加熱式ビルドプレートが付属しているかどうか。"
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume label"
+msgid "Has Build Volume Temperature Stabilization"
+msgstr "造形温度安定化処理有り"
+
+#: fdmprinter.def.json
+msgctxt "machine_heated_build_volume description"
+msgid "Whether the machine is able to stabilize the build volume temperature."
+msgstr "機器が造形温度を安定化処理できるかどうかです。"
+
#: fdmprinter.def.json
msgctxt "machine_center_is_zero label"
msgid "Is Center Origin"
@@ -251,7 +265,7 @@ msgstr "エクストルーダーの数。エクストルーダーの単位は、
#: fdmprinter.def.json
msgctxt "extruders_enabled_count label"
-msgid "Number of Extruders that are enabled"
+msgid "Number of Extruders That Are Enabled"
msgstr "有効なエクストルーダーの数"
#: fdmprinter.def.json
@@ -261,7 +275,7 @@ msgstr "有効なエクストルーダートレインの数(ソフトウェア
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter label"
-msgid "Outer nozzle diameter"
+msgid "Outer Nozzle Diameter"
msgstr "ノズル外径"
# msgstr "ノズル外径"
@@ -272,7 +286,7 @@ msgstr "ノズルの外径。"
#: fdmprinter.def.json
msgctxt "machine_nozzle_head_distance label"
-msgid "Nozzle length"
+msgid "Nozzle Length"
msgstr "ノズル長さ"
# msgstr "ノズルの長さ"
@@ -283,7 +297,7 @@ msgstr "ノズル先端とプリントヘッドの最下部との高さの差。
#: fdmprinter.def.json
msgctxt "machine_nozzle_expansion_angle label"
-msgid "Nozzle angle"
+msgid "Nozzle Angle"
msgstr "ノズル角度"
# msgstr "ノズル角度"
@@ -294,7 +308,7 @@ msgstr "水平面とノズル直上の円錐部分との間の角度。"
#: fdmprinter.def.json
msgctxt "machine_heat_zone_length label"
-msgid "Heat zone length"
+msgid "Heat Zone Length"
msgstr "ノズル加熱長さ"
# msgstr "加熱範囲"
@@ -325,7 +339,7 @@ msgstr "Curaから温度を制御するかどうか。これをオフにして
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed label"
-msgid "Heat up speed"
+msgid "Heat Up Speed"
msgstr "加熱速度"
#: fdmprinter.def.json
@@ -335,7 +349,7 @@ msgstr "ノズルが加熱する速度(℃/ s)は、通常の印刷時温度
#: fdmprinter.def.json
msgctxt "machine_nozzle_cool_down_speed label"
-msgid "Cool down speed"
+msgid "Cool Down Speed"
msgstr "冷却速度"
#: fdmprinter.def.json
@@ -355,7 +369,7 @@ msgstr "ノズルが冷却される前にエクストルーダーが静止しな
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor label"
-msgid "G-code flavour"
+msgid "G-code Flavor"
msgstr "G-codeフレーバー"
#: fdmprinter.def.json
@@ -425,10 +439,9 @@ msgctxt "machine_firmware_retract description"
msgid "Whether to use firmware retract commands (G10/G11) instead of using the E property in G1 commands to retract the material."
msgstr "材料を引き戻すためにG1コマンドのEプロパティーを使用する代わりにファームウェア引き戻しコマンド (G10/G11) を使用するかどうか。"
-# msgstr "Repetier"
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
-msgid "Disallowed areas"
+msgid "Disallowed Areas"
msgstr "拒否エリア"
#: fdmprinter.def.json
@@ -448,7 +461,7 @@ msgstr "ノズルが入ることができない領域を持つポリゴンのリ
#: fdmprinter.def.json
msgctxt "machine_head_polygon label"
-msgid "Machine head polygon"
+msgid "Machine Head Polygon"
msgstr "プリントヘッドポリゴン"
#: fdmprinter.def.json
@@ -458,7 +471,7 @@ msgstr "プリントヘッドの2Dシルエット(ファンキャップは除
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon label"
-msgid "Machine head & Fan polygon"
+msgid "Machine Head & Fan Polygon"
msgstr "プリントヘッドとファンポリゴン"
#: fdmprinter.def.json
@@ -468,8 +481,8 @@ msgstr "プリントヘッドの2Dシルエット(ファンキャップが含
#: fdmprinter.def.json
msgctxt "gantry_height label"
-msgid "Gantry height"
-msgstr "ガントリー高さ"
+msgid "Gantry Height"
+msgstr "ガントリーの高さ"
#: fdmprinter.def.json
msgctxt "gantry_height description"
@@ -499,7 +512,7 @@ msgstr "ノズルの内径。標準以外のノズルを使用する場合は、
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords label"
-msgid "Offset With Extruder"
+msgid "Offset with Extruder"
msgstr "エクストルーダーのオフセット"
#: fdmprinter.def.json
@@ -1060,6 +1073,16 @@ msgctxt "bottom_layers description"
msgid "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number."
msgstr "最底面のレイヤー数。下の厚さで計算すると、この値は整数に変換されます。"
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers label"
+msgid "Initial Bottom Layers"
+msgstr "初期底面レイヤー"
+
+#: fdmprinter.def.json
+msgctxt "initial_bottom_layers description"
+msgid "The number of initial bottom layers, from the build-plate upwards. When calculated by the bottom thickness, this value is rounded to a whole number."
+msgstr "ビルドプレートから上にある初期底面レイヤーの数。下の厚さで計算すると、この値は整数に変換されます。"
+
#: fdmprinter.def.json
msgctxt "top_bottom_pattern label"
msgid "Top/Bottom Pattern"
@@ -1313,6 +1336,56 @@ msgctxt "z_seam_type option sharpest_corner"
msgid "Sharpest Corner"
msgstr "鋭い角"
+#: fdmprinter.def.json
+msgctxt "z_seam_position label"
+msgid "Z Seam Position"
+msgstr "Zシーム位置"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position description"
+msgid "The position near where to start printing each part in a layer."
+msgstr "レイヤー内の各パーツの印刷を開始する場所付近の位置。"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backleft"
+msgid "Back Left"
+msgstr "後方左"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option back"
+msgid "Back"
+msgstr "戻る"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option backright"
+msgid "Back Right"
+msgstr "後方右"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option right"
+msgid "Right"
+msgstr "右"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontright"
+msgid "Front Right"
+msgstr "前方右"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option front"
+msgid "Front"
+msgstr "前"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option frontleft"
+msgid "Front Left"
+msgstr "前左"
+
+#: fdmprinter.def.json
+msgctxt "z_seam_position option left"
+msgid "Left"
+msgstr "左"
+
# msgstr "最も鋭利な角"
#: fdmprinter.def.json
msgctxt "z_seam_x label"
@@ -1322,7 +1395,9 @@ msgstr "ZシームX"
#: fdmprinter.def.json
msgctxt "z_seam_x description"
msgid "The X coordinate of the position near where to start printing each part in a layer."
-msgstr "レイヤー内の各印刷を開始するX座\n標の位置。"
+msgstr ""
+"レイヤー内の各印刷を開始するX座\n"
+"標の位置。"
#: fdmprinter.def.json
msgctxt "z_seam_y label"
@@ -1339,11 +1414,10 @@ msgctxt "z_seam_corner label"
msgid "Seam Corner Preference"
msgstr "シームコーナー設定"
-# msgstr "薄層のプレファレンス"
#: fdmprinter.def.json
msgctxt "z_seam_corner description"
-msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
-msgstr "モデル輪郭のコーナーがシーム(縫い目)の位置に影響するかどうかを制御します。 Noneはコーナーがシームの位置に影響を与えないことを意味します。 Seam(縫い目)を非表示にすると、内側のコーナーでシームが発生しやすくなります。 Seamを表示すると、外側の角にシームが発生する可能性が高くなります。 シームを隠す、または表示するを選択することにより、内側または外側コーナーでシームを発生させる可能性が高くなります。"
+msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner. Smart Hiding allows both inside and outside corners, but chooses inside corners more frequently, if appropriate."
+msgstr "モデル輪郭の角がシームの位置に影響を及ぼすかどうかを制御します。[なし] は、角がシームの位置に影響を及ぼさないことを意味します。シームを隠すにすると、シームが内側の角に生じる可能性が高くなります。シームを外側にすると、シームが外側の角に生じる可能性が高くなります。シームを隠す/外側に出すは、シームが内側または外側の角に生じる可能性が高くなります。スマート・シームを使用すると、内外両側の角を使用できますが、適切な場合には内側の角が選択される頻度が高まります。"
#: fdmprinter.def.json
msgctxt "z_seam_corner option z_seam_corner_none"
@@ -1368,6 +1442,11 @@ msgctxt "z_seam_corner option z_seam_corner_any"
msgid "Hide or Expose Seam"
msgstr "シーム表示/非表示"
+#: fdmprinter.def.json
+msgctxt "z_seam_corner option z_seam_corner_weighted"
+msgid "Smart Hiding"
+msgstr "スマート・シーム"
+
# msgstr "シームを非表示または表示する"
#: fdmprinter.def.json
msgctxt "z_seam_relative label"
@@ -1382,14 +1461,13 @@ msgstr "有効時は、Zシームは各パーツの真ん中に設定されま
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic label"
-msgid "Ignore Small Z Gaps"
-msgstr "小さいZギャップは無視"
+msgid "No Skin in Z Gaps"
+msgstr "Z 軸ギャップにスキンなし"
-# msgstr "小さなZギャップを無視する"
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic description"
-msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
-msgstr "モデルに垂直方向のギャップが小さくある場合、これらの狭いスペースにおいて上部および下部スキンを生成するために、約5%の計算時間が追加されます。そのような場合は、設定を無効にしてください。"
+msgid "When the model has small vertical gaps of only a few layers, there should normally be skin around those layers in the narrow space. Enable this setting to not generate skin if the vertical gap is very small. This improves printing time and slicing time, but technically leaves infill exposed to the air."
+msgstr "モデルの垂直方向に少数層のみの小さなギャップがある場合、通常は、その狭いスペース内にある層の周囲にスキンが存在する必要があります。垂直方向のギャップが非常に小さい場合は、この設定を有効にしてスキンが生成されないようにします。これにより、印刷時間とスライス時間が向上しますが、技術的には空気にさらされたインフィルを残します。"
#: fdmprinter.def.json
msgctxt "skin_outline_count label"
@@ -1407,11 +1485,10 @@ msgctxt "ironing_enabled label"
msgid "Enable Ironing"
msgstr "アイロン有効"
-# msgstr "アイロンを有効にする"
#: fdmprinter.def.json
msgctxt "ironing_enabled description"
-msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
-msgstr "ノズルから吐出せずに上部表面を再度動く機能。表面を溶かしてよりスムースにします。"
+msgid "Go over the top surface one additional time, but this time extruding very little material. This is meant to melt the plastic on top further, creating a smoother surface. The pressure in the nozzle chamber is kept high so that the creases in the surface are filled with material."
+msgstr "微量の材料のみを吐出して、再度上部表面を動きます。これにより上部のプラスティックが溶かされ、よりスムースな表面になります。ノズルチャンバーには高い圧力が保たれるため、表面上のしわが材料で埋められます。"
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer label"
@@ -1513,6 +1590,26 @@ msgctxt "jerk_ironing description"
msgid "The maximum instantaneous velocity change while performing ironing."
msgstr "アイロン時の最大加速度。"
+#: fdmprinter.def.json
+msgctxt "skin_overlap label"
+msgid "Skin Overlap Percentage"
+msgstr "表面公差量"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines, as a percentage of the line widths of the skin lines and the innermost wall. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any percentage over 50% may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "壁とスキンの中央ライン(のエンドポイント)が交差する量(スキンラインのライン幅と壁の最内部に対する割合)を調整します。わずかな交差によって、壁がスキンにしっかりつながります。スキンと壁のライン幅が同じで、割合が50%を超えると、スキンが壁を通過している可能性があります。これは、その時点で、スキン押出機のノズルの位置が、すでに壁の真ん中を過ぎている可能性があるためです。"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm label"
+msgid "Skin Overlap"
+msgstr "表面公差"
+
+#: fdmprinter.def.json
+msgctxt "skin_overlap_mm description"
+msgid "Adjust the amount of overlap between the walls and (the endpoints of) the skin-centerlines. A slight overlap allows the walls to connect firmly to the skin. Note that, given an equal skin and wall line-width, any value over half the width of the wall may already cause any skin to go past the wall, because at that point the position of the nozzle of the skin-extruder may already reach past the middle of the wall."
+msgstr "壁とスキンの中央ライン(のエンドポイント)が交差する量を調整します。わずかな交差によって、壁がスキンにしっかりつながります。スキンと壁のライン幅が同じで、壁の幅が半分以上の値になると、スキンが壁を通過している可能性があります。これは、その時点で、スキン押出機のノズルの位置が、すでに壁の真ん中を過ぎている可能性があるためです。"
+
#: fdmprinter.def.json
msgctxt "infill label"
msgid "Infill"
@@ -1685,6 +1782,16 @@ msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
msgstr "インフィルパターンはY軸に沿ってこの距離を移動します。"
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location label"
+msgid "Randomize Infill Start"
+msgstr "インフィル開始のランダム化"
+
+#: fdmprinter.def.json
+msgctxt "infill_randomize_start_location description"
+msgid "Randomize which infill line is printed first. This prevents one segment becoming the strongest, but it does so at the cost of an additional travel move."
+msgstr "どのインフィルラインが最初に印刷されるかをランダム化します。これによって1つのセグメントが強くなることを回避しますが、追加の移動距離が必要となります。"
+
#: fdmprinter.def.json
msgctxt "infill_multiplier label"
msgid "Infill Line Multiplier"
@@ -1705,7 +1812,9 @@ msgctxt "infill_wall_line_count description"
msgid ""
"Add extra walls around the infill area. Such walls can make top/bottom skin lines sag down less which means you need less top/bottom skin layers for the same quality at the cost of some extra material.\n"
"This feature can combine with the Connect Infill Polygons to connect all the infill into a single extrusion path without the need for travels or retractions if configured right."
-msgstr "インフィルエリア周辺に外壁を追加します。このような壁は、上層/底層ラインにたるみを作ります。つまり、一部の外壁材料の費用で同じ品質を実現するためには、必要な上層/底層スキンが少ないことを意味します。\nこの機能は、インフィルポリゴン接合と組み合わせて、構成が正しい場合、移動または引き戻しが必要なく、すべてのインフィルを1つの押出経路に接続することができます。"
+msgstr ""
+"インフィルエリア周辺に外壁を追加します。このような壁は、上層/底層ラインにたるみを作ります。つまり、一部の外壁材料の費用で同じ品質を実現するためには、必要な上層/底層スキンが少ないことを意味します。\n"
+"この機能は、インフィルポリゴン接合と組み合わせて、構成が正しい場合、移動または引き戻しが必要なく、すべてのインフィルを1つの押出経路に接続することができます。"
#: fdmprinter.def.json
msgctxt "sub_div_rad_add label"
@@ -1738,27 +1847,6 @@ msgctxt "infill_overlap_mm description"
msgid "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill."
msgstr "インフィルと壁が交差する量、わずかな交差によって壁がインフィルにしっかりつながります。"
-#: fdmprinter.def.json
-msgctxt "skin_overlap label"
-msgid "Skin Overlap Percentage"
-msgstr "表面公差量"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap description"
-msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
-msgstr "スキンと壁のオーバーラップ量 (スキンライン幅に対する%)。少しのオーバーラップによって壁がスキンにしっかりつながります。これは、スキンライン幅の平均ライン幅と最内壁の%です。"
-
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm label"
-msgid "Skin Overlap"
-msgstr "表面公差"
-
-# msgstr "スキンオーバーラップ"
-#: fdmprinter.def.json
-msgctxt "skin_overlap_mm description"
-msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
-msgstr "スキンと壁の間の交差した量 わずかなオーバーラップによって壁がスキンにしっかりつながります。"
-
#: fdmprinter.def.json
msgctxt "infill_wipe_dist label"
msgid "Infill Wipe Distance"
@@ -1808,7 +1896,9 @@ msgstr "インフィル優先"
#: fdmprinter.def.json
msgctxt "infill_before_walls description"
msgid "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but overhangs print worse. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface."
-msgstr "壁より前にインフィルをプリントします はじめに壁をプリントするとより精密な壁になりますが、オーバーハングのプリントは悪化します\nはじめにインフィルをプリントすると丈夫な壁になりますが、インフィルの模様が時折表面から透けて表れます。"
+msgstr ""
+"壁より前にインフィルをプリントします はじめに壁をプリントするとより精密な壁になりますが、オーバーハングのプリントは悪化します\n"
+"はじめにインフィルをプリントすると丈夫な壁になりますが、インフィルの模様が時折表面から透けて表れます。"
#: fdmprinter.def.json
msgctxt "min_infill_area label"
@@ -1945,6 +2035,16 @@ msgctxt "default_material_print_temperature description"
msgid "The default temperature used for printing. This should be the \"base\" temperature of a material. All other print temperatures should use offsets based on this value"
msgstr "印刷中のデフォルトの温度。これはマテリアルの基本温度となります。他のすべての造形温度はこの値に基づいてオフセットする必要があります"
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature label"
+msgid "Build Volume Temperature"
+msgstr "造形温度"
+
+#: fdmprinter.def.json
+msgctxt "build_volume_temperature description"
+msgid "The temperature of the environment to print in. If this is 0, the build volume temperature will not be adjusted."
+msgstr "印刷するプリンタ内の温度。これがゼロ (0) の場合、造形温度は調整できません。"
+
#: fdmprinter.def.json
msgctxt "material_print_temperature label"
msgid "Printing Temperature"
@@ -2055,6 +2155,86 @@ msgctxt "material_shrinkage_percentage description"
msgid "Shrinkage ratio in percentage."
msgstr "収縮率をパーセントで示す。"
+#: fdmprinter.def.json
+msgctxt "material_crystallinity label"
+msgid "Crystalline Material"
+msgstr "結晶性材料"
+
+#: fdmprinter.def.json
+msgctxt "material_crystallinity description"
+msgid "Is this material the type that breaks off cleanly when heated (crystalline), or is it the type that produces long intertwined polymer chains (non-crystalline)?"
+msgstr "この材料は加熱時にきれいに分解するタイプ (結晶性) または長く絡み合ったポリマー鎖 (非結晶) を作り出すタイプのいずれですか?"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position label"
+msgid "Anti-ooze Retracted Position"
+msgstr "滲出防止引戻し位置"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retracted_position description"
+msgid "How far the material needs to be retracted before it stops oozing."
+msgstr "滲出を止めるには材料をどこまで引き戻す必要があるか。"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed label"
+msgid "Anti-ooze Retraction Speed"
+msgstr "滲出防止引戻し速度"
+
+#: fdmprinter.def.json
+msgctxt "material_anti_ooze_retraction_speed description"
+msgid "How fast the material needs to be retracted during a filament switch to prevent oozing."
+msgstr "滲出を防止するにはフィラメントスイッチ中に材料をどの程度速く引き戻す必要があるか。"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position label"
+msgid "Break Preparation Retracted Position"
+msgstr "フィラメントの引き出し準備引戻し位置"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_retracted_position description"
+msgid "How far the filament can be stretched before it breaks, while heated."
+msgstr "加熱中にフィラメントの引き出しが生じる距離。"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed label"
+msgid "Break Preparation Retraction Speed"
+msgstr "フィラメント引き出し準備引戻し速度"
+
+#: fdmprinter.def.json
+msgctxt "material_break_preparation_speed description"
+msgid "How fast the filament needs to be retracted just before breaking it off in a retraction."
+msgstr "フィラメントの引き出しが起こるための引き戻しの距離。"
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position label"
+msgid "Break Retracted Position"
+msgstr "フィラメント引き出しの引戻し位置"
+
+#: fdmprinter.def.json
+msgctxt "material_break_retracted_position description"
+msgid "How far to retract the filament in order to break it cleanly."
+msgstr "フィラメントをきれいに引き出すにはフィラメントをどこまで引き戻すか。"
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed label"
+msgid "Break Retraction Speed"
+msgstr "フィラメント引き出しの引戻し速度"
+
+#: fdmprinter.def.json
+msgctxt "material_break_speed description"
+msgid "The speed at which to retract the filament in order to break it cleanly."
+msgstr "フィラメントをきれいに引き出すために維持すべきフィラメントの引戻し速度。"
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature label"
+msgid "Break Temperature"
+msgstr "フィラメント引き出し温度"
+
+#: fdmprinter.def.json
+msgctxt "material_break_temperature description"
+msgid "The temperature at which the filament is broken for a clean break."
+msgstr "フィラメントがきれいに引き出される温度。"
+
#: fdmprinter.def.json
msgctxt "material_flow label"
msgid "Flow"
@@ -2065,6 +2245,126 @@ msgctxt "material_flow description"
msgid "Flow compensation: the amount of material extruded is multiplied by this value."
msgstr "流れの補修: 押出されるマテリアルの量は、この値から乗算されます。"
+#: fdmprinter.def.json
+msgctxt "wall_material_flow label"
+msgid "Wall Flow"
+msgstr "壁のフロー"
+
+#: fdmprinter.def.json
+msgctxt "wall_material_flow description"
+msgid "Flow compensation on wall lines."
+msgstr "壁のフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow label"
+msgid "Outer Wall Flow"
+msgstr "外壁のフロー"
+
+#: fdmprinter.def.json
+msgctxt "wall_0_material_flow description"
+msgid "Flow compensation on the outermost wall line."
+msgstr "最外壁のフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow label"
+msgid "Inner Wall(s) Flow"
+msgstr "内壁のフロー"
+
+#: fdmprinter.def.json
+msgctxt "wall_x_material_flow description"
+msgid "Flow compensation on wall lines for all wall lines except the outermost one."
+msgstr "最外壁以外の壁のフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow label"
+msgid "Top/Bottom Flow"
+msgstr "上面/下面フロー"
+
+#: fdmprinter.def.json
+msgctxt "skin_material_flow description"
+msgid "Flow compensation on top/bottom lines."
+msgstr "上面/下面のフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow label"
+msgid "Top Surface Skin Flow"
+msgstr "上部表面スキンフロー"
+
+#: fdmprinter.def.json
+msgctxt "roofing_material_flow description"
+msgid "Flow compensation on lines of the areas at the top of the print."
+msgstr "印刷物の上部表面のフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow label"
+msgid "Infill Flow"
+msgstr "インフィルフロー"
+
+#: fdmprinter.def.json
+msgctxt "infill_material_flow description"
+msgid "Flow compensation on infill lines."
+msgstr "インフィルのフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow label"
+msgid "Skirt/Brim Flow"
+msgstr "スカート/ブリムのフロー"
+
+#: fdmprinter.def.json
+msgctxt "skirt_brim_material_flow description"
+msgid "Flow compensation on skirt or brim lines."
+msgstr "スカートまたはブリムのフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow label"
+msgid "Support Flow"
+msgstr "支持材のフロー"
+
+#: fdmprinter.def.json
+msgctxt "support_material_flow description"
+msgid "Flow compensation on support structure lines."
+msgstr "支持材のフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow label"
+msgid "Support Interface Flow"
+msgstr "支持材界面フロー"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_material_flow description"
+msgid "Flow compensation on lines of support roof or floor."
+msgstr "支持材の天井面または床面のフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow label"
+msgid "Support Roof Flow"
+msgstr "支持材天井面フロー"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_material_flow description"
+msgid "Flow compensation on support roof lines."
+msgstr "支持材天井面のフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow label"
+msgid "Support Floor Flow"
+msgstr "支持材床面フロー"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_material_flow description"
+msgid "Flow compensation on support floor lines."
+msgstr "支持材床面のフロー補正。"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow label"
+msgid "Prime Tower Flow"
+msgstr "プライムタワーのフロー"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_flow description"
+msgid "Flow compensation on prime tower lines."
+msgstr "プライムタワーのフロー補正。"
+
#: fdmprinter.def.json
msgctxt "material_flow_layer_0 label"
msgid "Initial Layer Flow"
@@ -2182,8 +2482,8 @@ msgstr "サポート引き戻し限界"
#: fdmprinter.def.json
msgctxt "limit_support_retractions description"
-msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
-msgstr "サポートからサポートに直線移動する場合は、引き戻しを省略します。この設定を有効にすると、印刷時間が短縮されますが、サポート構造内部の糸引きが多くなります。"
+msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excessive stringing within the support structure."
+msgstr "支持材から支持材に直線移動する場合は、引戻しを省略します。この設定を有効にすると、印刷時間は節約できますが、支持材内で過剰な糸引きが発生する可能性があります。"
#: fdmprinter.def.json
msgctxt "material_standby_temperature label"
@@ -2202,8 +2502,8 @@ msgstr "ノズルスイッチ引き戻し距離"
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_amount description"
-msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
-msgstr "引き込み量:引き込みを行わない場合は0に設定します。これは通常、ヒートゾーンの長さと同じに設定します。"
+msgid "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+msgstr "エクストルーダー切り替え時の引き込み量。引き込みを行わない場合は0に設定します。これは通常、ヒートゾーンの長さと同じに設定します。"
#: fdmprinter.def.json
msgctxt "switch_extruder_retraction_speeds label"
@@ -2235,6 +2535,16 @@ msgctxt "switch_extruder_prime_speed description"
msgid "The speed at which the filament is pushed back after a nozzle switch retraction."
msgstr "ノズル スイッチ後にフィラメントが押し戻される速度。"
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount label"
+msgid "Nozzle Switch Extra Prime Amount"
+msgstr "ノズル切替え後のプライムに必要な余剰量"
+
+#: fdmprinter.def.json
+msgctxt "switch_extruder_extra_prime_amount description"
+msgid "Extra material to prime after nozzle switching."
+msgstr "ノズル切替え後のプライムに必要な余剰材料。"
+
#: fdmprinter.def.json
msgctxt "speed label"
msgid "Speed"
@@ -2429,14 +2739,14 @@ msgid "The speed at which the skirt and brim are printed. Normally this is done
msgstr "スカートとブリムのプリント速度 通常は一層目のスピードと同じですが、異なる速度でスカートやブリムをプリントしたい場合に設定してください。"
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override label"
-msgid "Maximum Z Speed"
-msgstr "最大Z速度"
+msgctxt "speed_z_hop label"
+msgid "Z Hop Speed"
+msgstr "Z 軸ホップ速度"
#: fdmprinter.def.json
-msgctxt "max_feedrate_z_override description"
-msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
-msgstr "ビルトプレートが移動する最高速度 この値を0に設定すると、ファームウェアのデフォルト値のZの最高速度が適用されます。"
+msgctxt "speed_z_hop description"
+msgid "The speed at which the vertical Z movement is made for Z Hops. This is typically lower than the print speed since the build plate or machine's gantry is harder to move."
+msgstr "Z 軸ホップに対して垂直 Z 軸方向の動きが行われる速度。これは通常、ビルドプレートまたはマシンのガントリーが動きにくいため、印刷速度よりも低くなります。"
#: fdmprinter.def.json
msgctxt "speed_slowdown_layers label"
@@ -2871,8 +3181,8 @@ msgstr "コーミングモード"
#: fdmprinter.def.json
msgctxt "retraction_combing description"
-msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
-msgstr "コーミングは、移動時に印刷済みエリア内にノズルを保持します。この結果、移動距離が長くなりますが、引き戻しの必要性が軽減されます。コーミングがオフの場合は、材料を引き戻して、ノズルを次のポイントまで直線に移動します。コーミングが上層/底層スキンエリアを超えずに、インフィル内のみコーミングするようにできます。「インフィル内」オプションは、Cura の旧版の「スキン内にない」オプションと全く同じ動作をします。"
+msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas or to only comb within the infill."
+msgstr "コーミングは、走行時にすでに印刷された領域内にノズルを保ちます。その結果、移動距離はわずかに長くなりますが、引き込みの必要性は減ります。コーミングがオフの場合、フィラメントの引き戻しを行い、ノズルは次のポイントまで直線移動します。また、インフィルのみにてコーミングすることにより、トップとボトムのスキン領域上での櫛通りを回避できます。"
#: fdmprinter.def.json
msgctxt "retraction_combing option off"
@@ -2944,17 +3254,6 @@ msgctxt "travel_avoid_distance description"
msgid "The distance between the nozzle and already printed parts when avoiding during travel moves."
msgstr "ノズルが既に印刷された部分を移動する際の間隔。"
-#: fdmprinter.def.json
-msgctxt "start_layers_at_same_position label"
-msgid "Start Layers with the Same Part"
-msgstr "同じパーツでレイヤーを開始する"
-
-#: fdmprinter.def.json
-#, fuzzy
-msgctxt "start_layers_at_same_position description"
-msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
-msgstr "各レイヤーの印刷は決まった場所近い距離のポイントにて印刷を始めます。そのため、前のレイヤーが終わった部分から新しいレイヤーのプリントを開始しません。これによりオーバーハングや小さなパーツの印刷改善されますが、その代わり印刷時間が長くなります。"
-
#: fdmprinter.def.json
msgctxt "layer_start_x label"
msgid "Layer Start X"
@@ -3015,6 +3314,16 @@ msgctxt "retraction_hop_after_extruder_switch description"
msgid "After the machine switched from one extruder to the other, the build plate is lowered to create clearance between the nozzle and the print. This prevents the nozzle from leaving oozed material on the outside of a print."
msgstr "マシーンが1つのエクストルーダーからもう一つのエクストルーダーに切り替えられた際、ビルドプレートが下降して、ノズルと印刷物との間に隙間が形成される。これによりノズルが造形物の外側にはみ出たマテリアルを残さないためである。"
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height label"
+msgid "Z Hop After Extruder Switch Height"
+msgstr "エクストルーダースイッチ高さ後のZホップ"
+
+#: fdmprinter.def.json
+msgctxt "retraction_hop_after_extruder_switch_height description"
+msgid "The height difference when performing a Z Hop after extruder switch."
+msgstr "エクストルーダースイッチ後のZホップを実行するときの高さの違い。"
+
#: fdmprinter.def.json
msgctxt "cooling label"
msgid "Cooling"
@@ -3051,7 +3360,6 @@ msgid "Regular Fan Speed"
msgstr "標準ファン速度"
#: fdmprinter.def.json
-#, fuzzy
msgctxt "cool_fan_speed_min description"
msgid "The speed at which the fans spin before hitting the threshold. When a layer prints faster than the threshold, the fan speed gradually inclines towards the maximum fan speed."
msgstr "しきい値に達する前のファンの回転スピード。プリント速度がしきい値より速くなると、ファンの速度は上がっていきます。"
@@ -3082,7 +3390,6 @@ msgid "Initial Fan Speed"
msgstr "初期ファン速度"
#: fdmprinter.def.json
-#, fuzzy
msgctxt "cool_fan_speed_0 description"
msgid "The speed at which the fans spin at the start of the print. In subsequent layers the fan speed is gradually increased up to the layer corresponding to Regular Fan Speed at Height."
msgstr "プリント開始時にファンが回転する速度。後続のレイヤーでは、ファン速度は、高さに応じて早くなります。"
@@ -3290,6 +3597,11 @@ msgctxt "support_pattern option cross"
msgid "Cross"
msgstr "クロス"
+#: fdmprinter.def.json
+msgctxt "support_pattern option gyroid"
+msgid "Gyroid"
+msgstr "ジャイロイド"
+
#: fdmprinter.def.json
msgctxt "support_wall_count label"
msgid "Support Wall Line Count"
@@ -3352,14 +3664,14 @@ msgid "Distance between the printed initial layer support structure lines. This
msgstr "印刷した初期層間の距離が構造ライをサポートします。この設定は、対応濃度で算出されます。"
#: fdmprinter.def.json
-msgctxt "support_infill_angle label"
-msgid "Support Infill Line Direction"
+msgctxt "support_infill_angles label"
+msgid "Support Infill Line Directions"
msgstr "サポートインフィルラインの向き"
#: fdmprinter.def.json
-msgctxt "support_infill_angle description"
-msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
-msgstr "対応するインフィルラインの向きです。サポートインフィルパターンは平面で回転します。"
+msgctxt "support_infill_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angle 0 degrees."
+msgstr "使用する整数線の方向のリスト。リストの要素は、層が進行するにつれて順番に使用され、リストの終わりに達すると、最初から再び開始されます。リスト項目はコンマで区切られ、リスト全体は大括弧で囲まれています。デフォルトは空のリストであり、デフォルト角度の0度を使用します。"
#: fdmprinter.def.json
msgctxt "support_brim_enable label"
@@ -3489,8 +3801,8 @@ msgstr "サポート接合距離"
#: fdmprinter.def.json
msgctxt "support_join_distance description"
-msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
-msgstr "X/Y方向のサポート構造間の最大距離。別の構造がこの値より近づいた場合、構造は 1 つにマージします。"
+msgid "The maximum distance between support structures in the X/Y directions. When separate structures are closer together than this value, the structures merge into one."
+msgstr "支持材間における X/Y 軸方向の最大距離。個別の支持材間の距離がこの値よりも近い場合、支持材は 1 つにマージされます。"
#: fdmprinter.def.json
msgctxt "support_offset label"
@@ -3535,6 +3847,16 @@ msgctxt "gradual_support_infill_step_height description"
msgid "The height of support infill of a given density before switching to half the density."
msgstr "密度が半分に切り替える前の所定のサポートのインフィルの高さ。"
+#: fdmprinter.def.json
+msgctxt "minimum_support_area label"
+msgid "Minimum Support Area"
+msgstr "最小サポート領域"
+
+#: fdmprinter.def.json
+msgctxt "minimum_support_area description"
+msgid "Minimum area size for support polygons. Polygons which have an area smaller than this value will not be generated."
+msgstr "ポリゴンをサポートする最小領域サイズ。この領域よりポリゴンが小さい場合は生成されません。"
+
#: fdmprinter.def.json
msgctxt "support_interface_enable label"
msgid "Enable Support Interface"
@@ -3777,6 +4099,96 @@ msgctxt "support_bottom_pattern option zigzag"
msgid "Zig Zag"
msgstr "ジグザグ"
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area label"
+msgid "Minimum Support Interface Area"
+msgstr "最小サポートインターフェイス領域"
+
+#: fdmprinter.def.json
+msgctxt "minimum_interface_area description"
+msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "サポートインターフェイスポリゴンの最小領域サイズ。この値より小さい領域のポリゴンは通常のサポートとしてプリントされます。"
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area label"
+msgid "Minimum Support Roof Area"
+msgstr "最小サポートルーフ領域"
+
+#: fdmprinter.def.json
+msgctxt "minimum_roof_area description"
+msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "サポートのルーフの最小領域サイズ。この値より小さい領域のポリゴンは通常のサポートとしてプリントされます。"
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area label"
+msgid "Minimum Support Floor Area"
+msgstr "最小サポートフロア領域"
+
+#: fdmprinter.def.json
+msgctxt "minimum_bottom_area description"
+msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will be printed as normal support."
+msgstr "サポートのフロアの最小領域サイズ。この値より小さい領域のポリゴンは通常のサポートとしてプリントされます。"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset label"
+msgid "Support Interface Horizontal Expansion"
+msgstr "サポートインターフェイス水平展開"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_offset description"
+msgid "Amount of offset applied to the support interface polygons."
+msgstr "サポートインターフェイスポリゴンに適用されるオフセット量。"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset label"
+msgid "Support Roof Horizontal Expansion"
+msgstr "サポートルーフ水平展開"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_offset description"
+msgid "Amount of offset applied to the roofs of the support."
+msgstr "サポートのルーフに適用されるオフセット量。"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset label"
+msgid "Support Floor Horizontal Expansion"
+msgstr "サポートフロア水平展開"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_offset description"
+msgid "Amount of offset applied to the floors of the support."
+msgstr "サポートのフロアに適用されるオフセット量。"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles label"
+msgid "Support Interface Line Directions"
+msgstr "サポート面のライン方向"
+
+#: fdmprinter.def.json
+msgctxt "support_interface_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "使用する整数線の方向のリスト。リストの要素は、レイヤの層に合わせて順番に使用され、リストの末尾に達すると、最初から再び開始されます。リスト項目はコンマで区切られ、リスト全体は大括弧で囲まれています。デフォルトは空のリストとなり、デフォルトの角度を使用します(面がかなり厚い場合には45度と135度を交互に使用、それ以外では90度を使用)。"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles label"
+msgid "Support Roof Line Directions"
+msgstr "サポートルーフライン方向"
+
+#: fdmprinter.def.json
+msgctxt "support_roof_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "使用する整数線の方向のリスト。リストの要素は、レイヤの層に合わせて順番に使用され、リストの末尾に達すると、最初から再び開始されます。リスト項目はコンマで区切られ、リスト全体は大括弧で囲まれています。デフォルトは空のリストとなり、デフォルトの角度を使用します(面がかなり厚い場合には45度と135度を交互に使用、それ以外では90度を使用)。"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles label"
+msgid "Support Floor Line Directions"
+msgstr "サポートフロアライン方向"
+
+#: fdmprinter.def.json
+msgctxt "support_bottom_angles description"
+msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees)."
+msgstr "使用する整数線の方向のリスト。リストの要素は、レイヤの層に合わせて順番に使用され、リストの末尾に達すると、最初から再び開始されます。リスト項目はコンマで区切られ、リスト全体は大括弧で囲まれています。デフォルトは空のリストとなり、デフォルトの角度を使用します(面がかなり厚い場合には45度と135度を交互に使用、それ以外では90度を使用)。"
+
#: fdmprinter.def.json
msgctxt "support_fan_enable label"
msgid "Fan Speed Override"
@@ -3819,14 +4231,14 @@ msgid "The diameter of a special tower."
msgstr "特別な塔の直径。"
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter label"
-msgid "Minimum Diameter"
-msgstr "最小直径"
+msgctxt "support_tower_maximum_supported_diameter label"
+msgid "Maximum Tower-Supported Diameter"
+msgstr "最大タワーサポート直径"
#: fdmprinter.def.json
-msgctxt "support_minimal_diameter description"
-msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
-msgstr "特殊なサポート塔によって支持される小さな領域のX / Y方向の最小直径。"
+msgctxt "support_tower_maximum_supported_diameter description"
+msgid "Maximum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+msgstr "特殊なサポートタワーにより支持される小さな領域のX / Y方向の最小直径。"
#: fdmprinter.def.json
msgctxt "support_tower_roof_angle label"
@@ -3954,7 +4366,9 @@ msgctxt "skirt_gap description"
msgid ""
"The horizontal distance between the skirt and the first layer of the print.\n"
"This is the minimum distance. Multiple skirt lines will extend outwards from this distance."
-msgstr "スカートと印刷の最初の層の間の水平距離。\nこれは最小距離です。複数のスカートラインがこの距離から外側に展開されます。"
+msgstr ""
+"スカートと印刷の最初の層の間の水平距離。\n"
+"これは最小距離です。複数のスカートラインがこの距離から外側に展開されます。"
#: fdmprinter.def.json
msgctxt "skirt_brim_minimal_length label"
@@ -4326,16 +4740,6 @@ msgctxt "prime_tower_enable description"
msgid "Print a tower next to the print which serves to prime the material after each nozzle switch."
msgstr "印刷物の横にタワーを造形して、ノズル交換後にフィラメントの調整をします。"
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular label"
-msgid "Circular Prime Tower"
-msgstr "円形プライムタワー"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_circular description"
-msgid "Make the prime tower as a circular shape."
-msgstr "プライムタワーを円形にします。"
-
#: fdmprinter.def.json
msgctxt "prime_tower_size label"
msgid "Prime Tower Size"
@@ -4376,16 +4780,6 @@ msgctxt "prime_tower_position_y description"
msgid "The y coordinate of the position of the prime tower."
msgstr "プライムタワーの位置のy座標。"
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow label"
-msgid "Prime Tower Flow"
-msgstr "プライムタワーのフロー"
-
-#: fdmprinter.def.json
-msgctxt "prime_tower_flow description"
-msgid "Flow compensation: the amount of material extruded is multiplied by this value."
-msgstr "吐出量: マテリアルの吐出量はこの値の乗算で計算されます。"
-
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled label"
msgid "Wipe Inactive Nozzle on Prime Tower"
@@ -4396,6 +4790,16 @@ msgctxt "prime_tower_wipe_enabled description"
msgid "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower."
msgstr "1本のノズルでプライムタワーを印刷した後、もう片方のノズルから滲み出した材料をプライムタワーが拭き取ります。"
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable label"
+msgid "Prime Tower Brim"
+msgstr "プライムタワーブリム"
+
+#: fdmprinter.def.json
+msgctxt "prime_tower_brim_enable description"
+msgid "Prime-towers might need the extra adhesion afforded by a brim even if the model doesn't. Presently can't be used with the 'Raft' adhesion-type."
+msgstr "モデルがない場合でも、プライムタワーには、ブリムによって与えられる追加の付着が必要なことがあります。現在は「ラフト」密着型では使用できません。"
+
#: fdmprinter.def.json
msgctxt "ooze_shield_enabled label"
msgid "Enable Ooze Shield"
@@ -4516,6 +4920,36 @@ msgctxt "remove_empty_first_layers description"
msgid "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle."
msgstr "最初に印刷したレイヤーの下に空のレイヤーがある場合は取り除きます。この設定を無効にすると、スライストレランスが「排他」または「中間」に設定されている場合に最初のレイヤーが空になる原因になります。"
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution label"
+msgid "Maximum Resolution"
+msgstr "最大解像度"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_resolution description"
+msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
+msgstr "スライス後の線分の最小サイズ。これを増やすと、メッシュの解像度が低くなります。これにより、プリンタが g コードの処理速度に追いつくことができ、処理できないメッシュの詳細を取り除いてスライス速度を速めます。"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution label"
+msgid "Maximum Travel Resolution"
+msgstr "最大移動解像度"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_travel_resolution description"
+msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
+msgstr "スライス後の移動線分の最小サイズ。これを増やすと、移動の跡が滑らかでなくなります。これにより、プリンタが g コードの処理速度に追いつくことができますが、精度が低下します。"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation label"
+msgid "Maximum Deviation"
+msgstr "最大偏差"
+
+#: fdmprinter.def.json
+msgctxt "meshfix_maximum_deviation description"
+msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution, so if the two conflict the Maximum Deviation will always be held true."
+msgstr "最大解像度設定の解像度を下げるときに許容される最大偏差です。これを大きくすると印刷の精度は低くなりますが、g-codeは小さくなります。最大偏差は最大解像度の限度であるため、最大偏差でこの2つが競合する場合には常にtrueとなります。"
+
#: fdmprinter.def.json
msgctxt "blackmagic label"
msgid "Special Modes"
@@ -4681,11 +5115,10 @@ msgctxt "smooth_spiralized_contours label"
msgid "Smooth Spiralized Contours"
msgstr "滑らかな輪郭"
-# msgstr "滑らかならせん状の輪郭"
#: fdmprinter.def.json
msgctxt "smooth_spiralized_contours description"
-msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
-msgstr "らせん状の輪郭を滑らかにしてZシームの視認性を低下させます(Zシームは印刷物上でほとんどみえませんが、レイヤービューでは確認できます。)スムージングは細かいサーフェスの詳細をぼかす傾向があることに注意してください。"
+msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+msgstr "らせん状の輪郭を滑らかにしてZシームの視認性を低下させます (Zシームは印刷物上でほとんどみえませんが、層ビューでは確認できます)。スムージングは、細かい表面の詳細をぼかす傾向があることに注意してください。"
#: fdmprinter.def.json
msgctxt "relative_extrusion label"
@@ -4705,7 +5138,7 @@ msgstr "実験"
#: fdmprinter.def.json
msgctxt "experimental description"
msgid "experimental!"
-msgstr "実験的"
+msgstr "実験的!"
#: fdmprinter.def.json
msgctxt "support_tree_enable label"
@@ -4903,26 +5336,6 @@ msgctxt "minimum_polygon_circumference description"
msgid "Polygons in sliced layers that have a circumference smaller than this amount will be filtered out. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details."
msgstr "この量よりも小さい円周を持つスライスレイヤーのポリゴンは、除外されます。値を小さくすると、スライス時間のコストで、メッシュの解像度が高くなります。つまり、ほとんどが高解像 SLA プリンター、極小多機能 3D モデルです。"
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution label"
-msgid "Maximum Resolution"
-msgstr "最大解像度"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_resolution description"
-msgid "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway."
-msgstr "スライス後の線分の最小サイズ。これを増やすと、メッシュの解像度が低くなります。これにより、プリンタが g コードの処理速度に追いつくことができ、処理できないメッシュの詳細を取り除いてスライス速度を速めます。"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution label"
-msgid "Maximum Travel Resolution"
-msgstr "最大移動解像度"
-
-#: fdmprinter.def.json
-msgctxt "meshfix_maximum_travel_resolution description"
-msgid "The minimum size of a travel line segment after slicing. If you increase this, the travel moves will have less smooth corners. This may allow the printer to keep up with the speed it has to process g-code, but it may cause model avoidance to become less accurate."
-msgstr "スライス後の移動線分の最小サイズ。これを増やすと、移動の跡が滑らかでなくなります。これにより、プリンタが g コードの処理速度に追いつくことができますが、精度が低下します。"
-
#: fdmprinter.def.json
msgctxt "support_skip_some_zags label"
msgid "Break Up Support In Chunks"
@@ -5066,16 +5479,6 @@ msgctxt "coasting_speed description"
msgid "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops."
msgstr "コースティング中の移動速度。印刷時の経路の速度設定に比例します。ボーデンチューブの圧力が低下するので、100%よりわずかに低い値が推奨される。"
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation label"
-msgid "Alternate Skin Rotation"
-msgstr "レイヤー回転変更"
-
-#: fdmprinter.def.json
-msgctxt "skin_alternate_rotation description"
-msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
-msgstr "トップ/ボトムのレイヤーが印刷される方向を変更します。通常、それらは斜めに印刷されます。この設定では、X方向のみとY方向のみが追加されます。"
-
#: fdmprinter.def.json
msgctxt "cross_infill_pocket_size label"
msgid "Cross 3D Pocket Size"
@@ -5191,8 +5594,8 @@ msgstr "円錐サポートを有効にする"
#: fdmprinter.def.json
msgctxt "support_conical_enabled description"
-msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
-msgstr "実験的機能:オーバーハング部分よりも底面のサポート領域を小さくする。"
+msgid "Make support areas smaller at the bottom than at the overhang."
+msgstr "オーバーハング部分よりも底面の支持領域を小さくする。"
#: fdmprinter.def.json
msgctxt "support_conical_angle label"
@@ -5256,23 +5659,23 @@ msgstr "各線分に導入されたランダム点間の平均距離。ポリゴ
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset label"
-msgid "Flow rate compensation max extrusion offset"
+msgid "Flow Rate Compensation Max Extrusion Offset"
msgstr "流量補正時の最大抽出オフセット"
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset description"
-msgid "The maximum distance in mm to compensate."
-msgstr "補正の最大距離をミリ単位で指定します。"
+msgid "The maximum distance in mm to move the filament to compensate for changes in flow rate."
+msgstr "流量の変化を補正するためにフィラメントを移動する最大距離(mm)。"
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor label"
-msgid "Flow rate compensation factor"
+msgid "Flow Rate Compensation Factor"
msgstr "流量補正要因"
#: fdmprinter.def.json
msgctxt "flow_rate_extrusion_offset_factor description"
-msgid "The multiplication factor for the flow rate -> distance translation."
-msgstr "流量を距離に変換する際の要因。"
+msgid "How far to move the filament in order to compensate for changes in flow rate, as a percentage of how far the filament would move in one second of extrusion."
+msgstr "流量の変化を補正するためにフィラメントを移動する距離。フィラメントが1秒の押出で移動する距離の割合として指定します。"
#: fdmprinter.def.json
msgctxt "wireframe_enabled label"
@@ -5533,7 +5936,7 @@ msgstr "ノズルと水平方向に下向きの線間の距離。大きな隙間
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
-msgid "Use adaptive layers"
+msgid "Use Adaptive Layers"
msgstr "適応レイヤーの使用"
#: fdmprinter.def.json
@@ -5543,7 +5946,7 @@ msgstr "適応レイヤーは、レイヤーの高さをモデルの形状に合
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
-msgid "Adaptive layers maximum variation"
+msgid "Adaptive Layers Maximum Variation"
msgstr "適応レイヤー最大差分"
#: fdmprinter.def.json
@@ -5553,7 +5956,7 @@ msgstr "基準レイヤー高さと比較して許容される最大の高さ。
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
-msgid "Adaptive layers variation step size"
+msgid "Adaptive Layers Variation Step Size"
msgstr "適応レイヤー差分ステップサイズ"
#: fdmprinter.def.json
@@ -5563,13 +5966,13 @@ msgstr "次のレイヤーの高さを前のレイヤーの高さと比べた差
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
-msgid "Adaptive layers threshold"
-msgstr "適応レイヤー閾値"
+msgid "Adaptive Layers Topography Size"
+msgstr "適応レイヤーのトポグラフィーサイズ"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
-msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
-msgstr "小さいレイヤーを使用するかどうかの閾値。この値が、レイヤー中の最も急な斜面のタンジェントと比較されます。"
+msgid "Target horizontal distance between two adjacent layers. Reducing this setting causes thinner layers to be used to bring the edges of the layers closer together."
+msgstr "隣接する2つのレイヤー間の目標水平距離。この設定を小さくすると、レイヤーのエッジが近づくように薄いレイヤーが使用されます。"
#: fdmprinter.def.json
msgctxt "wall_overhang_angle label"
@@ -5578,8 +5981,8 @@ msgstr "張り出し壁アングル"
#: fdmprinter.def.json
msgctxt "wall_overhang_angle description"
-msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
-msgstr "この角度以上に張り出した壁は、オーバーハング壁設定を使用して印刷されます。値が 90 の場合は、オーバーハング壁として処理されません。"
+msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging. Overhang that gets supported by support will not be treated as overhang either."
+msgstr "この角度以上に張り出した壁は、オーバーハング壁設定を使用してプリントされます。値が90の場合は、オーバーハング壁として処理されません。サポートによってサポートされているオーバーハングも、オーバーハングとして処理されません。"
#: fdmprinter.def.json
msgctxt "wall_overhang_speed_factor label"
@@ -5781,6 +6184,196 @@ msgctxt "bridge_fan_speed_3 description"
msgid "Percentage fan speed to use when printing the third bridge skin layer."
msgstr "サードブリッジのスキンレイヤーを印刷する際に使用するファン速度の割合。"
+#: fdmprinter.def.json
+msgctxt "clean_between_layers label"
+msgid "Wipe Nozzle Between Layers"
+msgstr "レイヤー間のノズル拭き取り"
+
+#: fdmprinter.def.json
+msgctxt "clean_between_layers description"
+msgid "Whether to include nozzle wipe G-Code between layers. Enabling this setting could influence behavior of retract at layer change. Please use Wipe Retraction settings to control retraction at layers where the wipe script will be working."
+msgstr "レイヤー間にノズル拭き取り G-Code を含むかどうか指定します。この設定を有効にすると、レイヤ変更時の引き戻し動作に影響する可能性があります。拭き取りスクリプトが動作するレイヤでの押し戻しを制御するには、ワイプリトラクト設定を使用してください。"
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe label"
+msgid "Material Volume Between Wipes"
+msgstr "ワイプ間の材料の量"
+
+#: fdmprinter.def.json
+msgctxt "max_extrusion_before_wipe description"
+msgid "Maximum material, that can be extruded before another nozzle wipe is initiated."
+msgstr "別のノズル拭き取りを行う前に押し出せる材料の最大量。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable label"
+msgid "Wipe Retraction Enable"
+msgstr "ワイプリトラクト有効"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_enable description"
+msgid "Retract the filament when the nozzle is moving over a non-printed area."
+msgstr "ノズルが印刷しないで良い領域を移動する際にフィラメントを引き戻す。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount label"
+msgid "Wipe Retraction Distance"
+msgstr "ワイプリトラクト無効"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_amount description"
+msgid "Amount to retract the filament so it does not ooze during the wipe sequence."
+msgstr "拭き取りシーケンス中に出ないように押し戻すフィラメントの量。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount label"
+msgid "Wipe Retraction Extra Prime Amount"
+msgstr "ワイプ引き戻し時の余分押し戻し量"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_extra_prime_amount description"
+msgid "Some material can ooze away during a wipe travel moves, which can be compensated for here."
+msgstr "いくつかの材料は、ワイプ移動中ににじみ出るためここで補償することができます。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed label"
+msgid "Wipe Retraction Speed"
+msgstr "ワイプリトラクト速度"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_speed description"
+msgid "The speed at which the filament is retracted and primed during a wipe retraction move."
+msgstr "ワイプ引き戻し中にフィラメントが引き戻される時の速度。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed label"
+msgid "Wipe Retraction Retract Speed"
+msgstr "ワイプ引き戻し速度"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_retract_speed description"
+msgid "The speed at which the filament is retracted during a wipe retraction move."
+msgstr "ワイプ引き戻し移動時にフィラメントが引き戻される速度。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed label"
+msgid "Retraction Prime Speed"
+msgstr "押し戻し速度の取り消し"
+
+#: fdmprinter.def.json
+msgctxt "wipe_retraction_prime_speed description"
+msgid "The speed at which the filament is primed during a wipe retraction move."
+msgstr "ワイプ引き戻し移動時にフィラメントが押し戻されるスピード。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause label"
+msgid "Wipe Pause"
+msgstr "ワイプ一時停止"
+
+#: fdmprinter.def.json
+msgctxt "wipe_pause description"
+msgid "Pause after the unretract."
+msgstr "引き戻し前に一時停止します。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable label"
+msgid "Wipe Z Hop When Retracted"
+msgstr "引き戻し時のワイプZホップ"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_enable description"
+msgid "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate."
+msgstr "引き戻しが完了すると、ビルドプレートが下降してノズルとプリントの間に隙間ができます。ノズルの走行中に造形物に当たるのを防ぎ、造形物をビルドプレートから剥がしてしまう現象を減らします。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount label"
+msgid "Wipe Z Hop Height"
+msgstr "ワイプZホップ高さ"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_amount description"
+msgid "The height difference when performing a Z Hop."
+msgstr "Zホップを実行するときの高さ。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed label"
+msgid "Wipe Hop Speed"
+msgstr "ワイプホップ速度"
+
+#: fdmprinter.def.json
+msgctxt "wipe_hop_speed description"
+msgid "Speed to move the z-axis during the hop."
+msgstr "ホップ中に z 軸を移動する速度。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x label"
+msgid "Wipe Brush X Position"
+msgstr "ワイプブラシXの位置"
+
+#: fdmprinter.def.json
+msgctxt "wipe_brush_pos_x description"
+msgid "X location where wipe script will start."
+msgstr "ワイプスクリプトを開始するX位置。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count label"
+msgid "Wipe Repeat Count"
+msgstr "ワイプ繰り返し回数"
+
+#: fdmprinter.def.json
+msgctxt "wipe_repeat_count description"
+msgid "Number of times to move the nozzle across the brush."
+msgstr "ブラシ全体をノズルが移動する回数。"
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance label"
+msgid "Wipe Move Distance"
+msgstr "ワイプ移動距離"
+
+#: fdmprinter.def.json
+msgctxt "wipe_move_distance description"
+msgid "The distance to move the head back and forth across the brush."
+msgstr "ブラシ全体でヘッド前後に動かす距離。"
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size label"
+msgid "Small Hole Max Size"
+msgstr "小さい穴の最大サイズ"
+
+#: fdmprinter.def.json
+msgctxt "small_hole_max_size description"
+msgid "Holes and part outlines with a diameter smaller than this will be printed using Small Feature Speed."
+msgstr "これより直径が小さな輪郭の穴とパーツは、Small Feature Speedを使用して印刷されます。"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length label"
+msgid "Small Feature Max Length"
+msgstr "小型形体の最大長さ"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_max_length description"
+msgid "Feature outlines that are shorter than this length will be printed using Small Feature Speed."
+msgstr "この長さより短い輪郭の形体は、Small Feature Speedを使用して印刷されます。"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor label"
+msgid "Small Feature Speed"
+msgstr "Small Feature Speed"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor description"
+msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "小型形体は通常のプリント速度に対してこの割合でプリントされます。低速でプリントすると、接着と精度が向上します。"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 label"
+msgid "Small Feature Initial Layer Speed"
+msgstr "小型形体の初期レイヤー速度"
+
+#: fdmprinter.def.json
+msgctxt "small_feature_speed_factor_0 description"
+msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhesion and accuracy."
+msgstr "最初のレイヤーの小型形体は通常のプリント速度に対してこの割合でプリントされます。低速でプリントすると、接着と精度が向上します。"
+
#: fdmprinter.def.json
msgctxt "command_line_settings label"
msgid "Command Line Settings"
@@ -5841,6 +6434,241 @@ msgctxt "mesh_rotation_matrix description"
msgid "Transformation matrix to be applied to the model when loading it from file."
msgstr "ファイルから読み込むときに、モデルに適用するトランスフォーメーションマトリックス。"
+#~ msgctxt "minimum_interface_area description"
+#~ msgid "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "インターフェイスポリゴンをサポートする最小領域サイズ。この領域よりポリゴンが小さい場合は生成されません。"
+
+#~ msgctxt "minimum_roof_area description"
+#~ msgid "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "サポートのルーフに対する最小領域サイズ。この領域よりポリゴンが小さい場合は生成されません。"
+
+#~ msgctxt "minimum_bottom_area description"
+#~ msgid "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will not be generated."
+#~ msgstr "サポートのフロアに対する最小領域サイズ。この領域よりポリゴンが小さい場合は生成されません。"
+
+#~ msgctxt "skin_alternate_rotation label"
+#~ msgid "Alternate Skin Rotation"
+#~ msgstr "レイヤー回転変更"
+
+#~ msgctxt "skin_alternate_rotation description"
+#~ msgid "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions."
+#~ msgstr "トップ/ボトムのレイヤーが印刷される方向を変更します。通常、それらは斜めに印刷されます。この設定では、X方向のみとY方向のみが追加されます。"
+
+#~ msgctxt "flow_rate_max_extrusion_offset label"
+#~ msgid "Flow rate compensation max extrusion offset"
+#~ msgstr "流量補正時の最大抽出オフセット"
+
+#~ msgctxt "flow_rate_max_extrusion_offset description"
+#~ msgid "The maximum distance in mm to compensate."
+#~ msgstr "補正の最大距離をミリ単位で指定します。"
+
+#~ msgctxt "flow_rate_extrusion_offset_factor label"
+#~ msgid "Flow rate compensation factor"
+#~ msgstr "流量補正要因"
+
+#~ msgctxt "flow_rate_extrusion_offset_factor description"
+#~ msgid "The multiplication factor for the flow rate -> distance translation."
+#~ msgstr "流量を距離に変換する際の要因。"
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive Layers Threshold"
+#~ msgstr "適応レイヤーしきい値"
+
+#~ msgctxt "adaptive_layer_height_threshold description"
+#~ msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
+#~ msgstr "小さいレイヤーを使用するかどうかの閾値。この値が、レイヤー中の最も急な斜面のタンジェントと比較されます。"
+
+#~ msgctxt "wall_overhang_angle description"
+#~ msgid "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging."
+#~ msgstr "この角度以上に張り出した壁は、オーバーハング壁設定を使用して印刷されます。値が 90 の場合は、オーバーハング壁として処理されません。"
+
+#~ msgctxt "small_feature_speed_factor description"
+#~ msgid "Small features will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "小型形体は通常の印刷速度よりこの割合で印刷されます。低速の印刷によって、接着と精度が向上します。"
+
+#~ msgctxt "small_feature_speed_factor_0 label"
+#~ msgid "First Layer Speed"
+#~ msgstr "最初のレイヤー速度"
+
+#~ msgctxt "small_feature_speed_factor_0 description"
+#~ msgid "Small features on the first layer will be printed at this percentage of their normal print speed. Slower printing can help with adhestion and accuracy."
+#~ msgstr "小型形体の最初のレイヤーは通常の印刷速度よりこの割合で印刷されます。低速の印刷によって、接着と精度が向上します。"
+
+# msgstr "アイロンを有効にする"
+#~ msgctxt "ironing_enabled description"
+#~ msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
+#~ msgstr "ノズルから吐出せずに上部表面を再度動く機能。表面を溶かしてよりスムースにします。"
+
+#~ msgctxt "start_layers_at_same_position label"
+#~ msgid "Start Layers with the Same Part"
+#~ msgstr "同じパーツでレイヤーを開始する"
+
+#, fuzzy
+#~ msgctxt "start_layers_at_same_position description"
+#~ msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
+#~ msgstr "各レイヤーの印刷は決まった場所近い距離のポイントにて印刷を始めます。そのため、前のレイヤーが終わった部分から新しいレイヤーのプリントを開始しません。これによりオーバーハングや小さなパーツの印刷改善されますが、その代わり印刷時間が長くなります。"
+
+#~ msgctxt "support_infill_angles description"
+#~ msgid "Orientation of the infill pattern for supports. The support infill pattern is rotated in the horizontal plane."
+#~ msgstr "対応するインフィルラインの向きです。サポートインフィルパターンは平面で回転します。"
+
+#~ msgctxt "meshfix_maximum_deviation description"
+#~ msgid "The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this, the print will be less accurate, but the g-code will be smaller."
+#~ msgstr "最大解像度設定の解像度を下げるときに許容される最大偏差です。これを大きくすると、印刷の精度は低くなりますが、g-code は小さくなります。"
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code Flavour"
+#~ msgstr "G-codeフレーバー"
+
+# msgstr "薄層のプレファレンス"
+#~ msgctxt "z_seam_corner description"
+#~ msgid "Control whether corners on the model outline influence the position of the seam. None means that corners have no influence on the seam position. Hide Seam makes the seam more likely to occur on an inside corner. Expose Seam makes the seam more likely to occur on an outside corner. Hide or Expose Seam makes the seam more likely to occur at an inside or outside corner."
+#~ msgstr "モデル輪郭のコーナーがシーム(縫い目)の位置に影響するかどうかを制御します。 Noneはコーナーがシームの位置に影響を与えないことを意味します。 Seam(縫い目)を非表示にすると、内側のコーナーでシームが発生しやすくなります。 Seamを表示すると、外側の角にシームが発生する可能性が高くなります。 シームを隠す、または表示するを選択することにより、内側または外側コーナーでシームを発生させる可能性が高くなります。"
+
+#~ msgctxt "skin_no_small_gaps_heuristic label"
+#~ msgid "Ignore Small Z Gaps"
+#~ msgstr "小さいZギャップは無視"
+
+# msgstr "小さなZギャップを無視する"
+#~ msgctxt "skin_no_small_gaps_heuristic description"
+#~ msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
+#~ msgstr "モデルに垂直方向のギャップが小さくある場合、これらの狭いスペースにおいて上部および下部スキンを生成するために、約5%の計算時間が追加されます。そのような場合は、設定を無効にしてください。"
+
+#~ msgctxt "build_volume_temperature description"
+#~ msgid "The temperature used for build volume. If this is 0, the build volume temperature will not be adjusted."
+#~ msgstr "造形に使用した温度。これがゼロ (0) の場合、造形温度は調整できません。"
+
+#~ msgctxt "limit_support_retractions description"
+#~ msgid "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excesive stringing within the support structure."
+#~ msgstr "サポートからサポートに直線移動する場合は、引き戻しを省略します。この設定を有効にすると、印刷時間が短縮されますが、サポート構造内部の糸引きが多くなります。"
+
+#~ msgctxt "max_feedrate_z_override label"
+#~ msgid "Maximum Z Speed"
+#~ msgstr "最大Z速度"
+
+#~ msgctxt "max_feedrate_z_override description"
+#~ msgid "The maximum speed with which the build plate is moved. Setting this to zero causes the print to use the firmware defaults for the maximum z speed."
+#~ msgstr "ビルトプレートが移動する最高速度 この値を0に設定すると、ファームウェアのデフォルト値のZの最高速度が適用されます。"
+
+#~ msgctxt "support_join_distance description"
+#~ msgid "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one."
+#~ msgstr "X/Y方向のサポート構造間の最大距離。別の構造がこの値より近づいた場合、構造は 1 つにマージします。"
+
+#~ msgctxt "support_minimal_diameter label"
+#~ msgid "Minimum Diameter"
+#~ msgstr "最小直径"
+
+#~ msgctxt "support_minimal_diameter description"
+#~ msgid "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower."
+#~ msgstr "特殊なサポート塔によって支持される小さな領域のX / Y方向の最小直径。"
+
+#~ msgctxt "prime_tower_circular label"
+#~ msgid "Circular Prime Tower"
+#~ msgstr "円形プライムタワー"
+
+#~ msgctxt "prime_tower_circular description"
+#~ msgid "Make the prime tower as a circular shape."
+#~ msgstr "プライムタワーを円形にします。"
+
+#~ msgctxt "prime_tower_flow description"
+#~ msgid "Flow compensation: the amount of material extruded is multiplied by this value."
+#~ msgstr "吐出量: マテリアルの吐出量はこの値の乗算で計算されます。"
+
+# msgstr "滑らかならせん状の輪郭"
+#~ msgctxt "smooth_spiralized_contours description"
+#~ msgid "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details."
+#~ msgstr "らせん状の輪郭を滑らかにしてZシームの視認性を低下させます(Zシームは印刷物上でほとんどみえませんが、レイヤービューでは確認できます。)スムージングは細かいサーフェスの詳細をぼかす傾向があることに注意してください。"
+
+#~ msgctxt "support_conical_enabled description"
+#~ msgid "Experimental feature: Make support areas smaller at the bottom than at the overhang."
+#~ msgstr "実験的機能:オーバーハング部分よりも底面のサポート領域を小さくする。"
+
+#~ msgctxt "extruders_enabled_count label"
+#~ msgid "Number of Extruders that are enabled"
+#~ msgstr "有効なエクストルーダーの数"
+
+#~ msgctxt "machine_nozzle_tip_outer_diameter label"
+#~ msgid "Outer nozzle diameter"
+#~ msgstr "ノズル外径"
+
+#~ msgctxt "machine_nozzle_head_distance label"
+#~ msgid "Nozzle length"
+#~ msgstr "ノズル長さ"
+
+#~ msgctxt "machine_nozzle_expansion_angle label"
+#~ msgid "Nozzle angle"
+#~ msgstr "ノズル角度"
+
+#~ msgctxt "machine_heat_zone_length label"
+#~ msgid "Heat zone length"
+#~ msgstr "ノズル加熱長さ"
+
+#~ msgctxt "machine_nozzle_heat_up_speed label"
+#~ msgid "Heat up speed"
+#~ msgstr "加熱速度"
+
+#~ msgctxt "machine_nozzle_cool_down_speed label"
+#~ msgid "Cool down speed"
+#~ msgstr "冷却速度"
+
+#~ msgctxt "machine_gcode_flavor label"
+#~ msgid "G-code flavour"
+#~ msgstr "G-codeフレーバー"
+
+# msgstr "Repetier"
+#~ msgctxt "machine_disallowed_areas label"
+#~ msgid "Disallowed areas"
+#~ msgstr "拒否エリア"
+
+#~ msgctxt "machine_head_polygon label"
+#~ msgid "Machine head polygon"
+#~ msgstr "プリントヘッドポリゴン"
+
+#~ msgctxt "machine_head_with_fans_polygon label"
+#~ msgid "Machine head & Fan polygon"
+#~ msgstr "プリントヘッドとファンポリゴン"
+
+#~ msgctxt "gantry_height label"
+#~ msgid "Gantry height"
+#~ msgstr "ガントリー高さ"
+
+#~ msgctxt "machine_use_extruder_offset_to_offset_coords label"
+#~ msgid "Offset With Extruder"
+#~ msgstr "エクストルーダーのオフセット"
+
+#~ msgctxt "adaptive_layer_height_enabled label"
+#~ msgid "Use adaptive layers"
+#~ msgstr "適応レイヤーの使用"
+
+#~ msgctxt "adaptive_layer_height_variation label"
+#~ msgid "Adaptive layers maximum variation"
+#~ msgstr "適応レイヤー最大差分"
+
+#~ msgctxt "adaptive_layer_height_variation_step label"
+#~ msgid "Adaptive layers variation step size"
+#~ msgstr "適応レイヤー差分ステップサイズ"
+
+#~ msgctxt "adaptive_layer_height_threshold label"
+#~ msgid "Adaptive layers threshold"
+#~ msgstr "適応レイヤー閾値"
+
+#~ msgctxt "skin_overlap description"
+#~ msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
+#~ msgstr "スキンと壁のオーバーラップ量 (スキンライン幅に対する%)。少しのオーバーラップによって壁がスキンにしっかりつながります。これは、スキンライン幅の平均ライン幅と最内壁の%です。"
+
+# msgstr "スキンオーバーラップ"
+#~ msgctxt "skin_overlap_mm description"
+#~ msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
+#~ msgstr "スキンと壁の間の交差した量 わずかなオーバーラップによって壁がスキンにしっかりつながります。"
+
+#~ msgctxt "switch_extruder_retraction_amount description"
+#~ msgid "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone."
+#~ msgstr "引き込み量:引き込みを行わない場合は0に設定します。これは通常、ヒートゾーンの長さと同じに設定します。"
+
+#~ msgctxt "retraction_combing description"
+#~ msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases."
+#~ msgstr "コーミングは、移動時に印刷済みエリア内にノズルを保持します。この結果、移動距離が長くなりますが、引き戻しの必要性が軽減されます。コーミングがオフの場合は、材料を引き戻して、ノズルを次のポイントまで直線に移動します。コーミングが上層/底層スキンエリアを超えずに、インフィル内のみコーミングするようにできます。「インフィル内」オプションは、Cura の旧版の「スキン内にない」オプションと全く同じ動作をします。"
+
#~ msgctxt "connect_skin_polygons description"
#~ msgid "Connect top/bottom skin paths where they run next to each other. For the concentric pattern enabling this setting greatly reduces the travel time, but because the connections can happend midway over infill this feature can reduce the top surface quality."
#~ msgstr "互いに次に実行する上層/底層スキンパスに接合します。同心円のパターンの場合、この設定を有効にすることにより、移動時間が短縮されますが、インフィルまでの途中で接合があるため、この機能で上層面の品質が損なわれることがあります。"
diff --git a/resources/i18n/ko_KR/cura.po b/resources/i18n/ko_KR/cura.po
index 6f32d46cd7..824cc276e8 100644
--- a/resources/i18n/ko_KR/cura.po
+++ b/resources/i18n/ko_KR/cura.po
@@ -1,24 +1,24 @@
# Cura
-# Copyright (C) 2018 Ultimaker
+# Copyright (C) 2019 Ultimaker B.V.
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2018.
+# Ruben Dulek , 2019.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.6\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-10-29 15:01+0100\n"
-"PO-Revision-Date: 2018-11-06 15:00+0100\n"
-"Last-Translator: Jinbuhm Kim \n"
-"Language-Team: Jinbum Kim