Merge remote-tracking branch 'upstream/master'

This commit is contained in:
NilsRo 2022-05-14 09:26:41 +02:00
commit 2b09e395e2
531 changed files with 144246 additions and 113590 deletions

View File

@ -1,5 +1,8 @@
# Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
project(cura) project(cura)
cmake_minimum_required(VERSION 3.6) cmake_minimum_required(VERSION 3.18)
include(GNUInstallDirs) include(GNUInstallDirs)
@ -8,9 +11,6 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
set(URANIUM_DIR "${CMAKE_SOURCE_DIR}/../Uranium" CACHE PATH "The location of the Uranium repository") set(URANIUM_DIR "${CMAKE_SOURCE_DIR}/../Uranium" CACHE PATH "The location of the Uranium repository")
set(URANIUM_SCRIPTS_DIR "${URANIUM_DIR}/scripts" CACHE PATH "The location of the scripts directory of the Uranium repository") set(URANIUM_SCRIPTS_DIR "${URANIUM_DIR}/scripts" CACHE PATH "The location of the scripts directory of the Uranium repository")
# Tests
include(CuraTests)
option(CURA_DEBUGMODE "Enable debug dialog and other debug features" OFF) option(CURA_DEBUGMODE "Enable debug dialog and other debug features" OFF)
if(CURA_DEBUGMODE) if(CURA_DEBUGMODE)
set(_cura_debugmode "ON") set(_cura_debugmode "ON")
@ -32,17 +32,25 @@ configure_file(${CMAKE_SOURCE_DIR}/com.ultimaker.cura.desktop.in ${CMAKE_BINARY_
configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY) configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY)
if(NOT DEFINED Python_VERSION)
set(Python_VERSION
3.10
CACHE STRING "Python Version" FORCE)
message(STATUS "Setting Python version to ${Python_VERSION}. Set Python_VERSION if you want to compile against an other version.")
endif()
if(APPLE)
set(Python_FIND_FRAMEWORK NEVER)
endif()
find_package(Python ${Python_VERSION} EXACT REQUIRED COMPONENTS Interpreter)
message(STATUS "Linking and building ${project_name} against Python ${Python_VERSION}")
if(NOT DEFINED Python_SITELIB_LOCAL)
set(Python_SITELIB_LOCAL
"${Python_SITELIB}"
CACHE PATH "Local alternative site-package location to install Cura" FORCE)
endif()
# FIXME: The new FindPython3 finds the system's Python3.6 rather than the Python3.5 that we built for Cura's environment. # Tests
# So we're using the old method here, with FindPythonInterp for now. include(CuraTests)
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})
if(NOT ${URANIUM_DIR} STREQUAL "") if(NOT ${URANIUM_DIR} STREQUAL "")
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${URANIUM_DIR}/cmake") set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${URANIUM_DIR}/cmake")
@ -58,30 +66,15 @@ if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "")
endif() endif()
endif() endif()
install(DIRECTORY resources DESTINATION ${CMAKE_INSTALL_DATADIR}/cura)
install(DIRECTORY resources
DESTINATION ${CMAKE_INSTALL_DATADIR}/cura)
include(CuraPluginInstall) include(CuraPluginInstall)
install(FILES cura_app.py DESTINATION ${CMAKE_INSTALL_BINDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(DIRECTORY cura DESTINATION "${Python_SITELIB_LOCAL}")
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py DESTINATION "${Python_SITELIB_LOCAL}/cura/")
if(NOT APPLE AND NOT WIN32) if(NOT APPLE AND NOT WIN32)
install(FILES cura_app.py
DESTINATION ${CMAKE_INSTALL_BINDIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
RENAME cura)
if(EXISTS /etc/debian_version)
install(DIRECTORY cura
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${Python3_VERSION_MAJOR}/dist-packages/cura)
else()
install(DIRECTORY cura
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${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages/cura)
endif()
install(FILES ${CMAKE_BINARY_DIR}/com.ultimaker.cura.desktop install(FILES ${CMAKE_BINARY_DIR}/com.ultimaker.cura.desktop
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES ${CMAKE_SOURCE_DIR}/resources/images/cura-icon.png install(FILES ${CMAKE_SOURCE_DIR}/resources/images/cura-icon.png
@ -91,13 +84,4 @@ if(NOT APPLE AND NOT WIN32)
install(FILES cura.sharedmimeinfo install(FILES cura.sharedmimeinfo
DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages/ DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages/
RENAME cura.xml ) RENAME cura.xml )
else()
install(FILES cura_app.py
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${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages
FILES_MATCHING PATTERN *.py)
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
DESTINATION lib${LIB_SUFFIX}/python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}/site-packages/cura)
endif() endif()

View File

@ -1,4 +1,4 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2022 Ultimaker B.V.
# CuraPluginInstall.cmake is released under the terms of the LGPLv3 or higher. # CuraPluginInstall.cmake is released under the terms of the LGPLv3 or higher.
# #
@ -11,19 +11,6 @@
option(PRINT_PLUGIN_LIST "Should the list of plugins that are installed be printed?" ON) option(PRINT_PLUGIN_LIST "Should the list of plugins that are installed be printed?" ON)
# 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 # Options or configuration variables
set(CURA_NO_INSTALL_PLUGINS "" CACHE STRING "A list of plugins that should not be installed, separated with ';' or ','.") set(CURA_NO_INSTALL_PLUGINS "" CACHE STRING "A list of plugins that should not be installed, separated with ';' or ','.")
@ -97,7 +84,7 @@ foreach(_plugin_json_path ${_plugin_json_list})
if(${PRINT_PLUGIN_LIST}) if(${PRINT_PLUGIN_LIST})
message(STATUS "[-] PLUGIN TO REMOVE : ${_rel_plugin_dir}") message(STATUS "[-] PLUGIN TO REMOVE : ${_rel_plugin_dir}")
endif() endif()
execute_process(COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_bundled_packages_json.py execute_process(COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_bundled_packages_json.py
-d ${CMAKE_CURRENT_SOURCE_DIR}/resources/bundled_packages -d ${CMAKE_CURRENT_SOURCE_DIR}/resources/bundled_packages
${_plugin_dir_name} ${_plugin_dir_name}
RESULT_VARIABLE _mod_json_result) RESULT_VARIABLE _mod_json_result)

View File

@ -1,15 +1,9 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
include(CTest) include(CTest)
include(CMakeParseArguments) include(CMakeParseArguments)
# FIXME: The new FindPython3 finds the system's Python3.6 rather than the Python3.5 that we built for Cura's environment.
# So we're using the old method here, with FindPythonInterp for now.
find_package(PythonInterp 3 REQUIRED)
set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
add_custom_target(test-verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) add_custom_target(test-verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose)
function(cura_add_test) function(cura_add_test)
@ -40,7 +34,7 @@ function(cura_add_test)
if (NOT ${test_exists}) if (NOT ${test_exists})
add_test( add_test(
NAME ${_NAME} NAME ${_NAME}
COMMAND ${Python3_EXECUTABLE} -m pytest --junitxml=${CMAKE_BINARY_DIR}/junit-${_NAME}.xml ${_DIRECTORY} COMMAND ${Python_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 LANG=C)
set_tests_properties(${_NAME} PROPERTIES ENVIRONMENT "PYTHONPATH=${_PYTHONPATH}") set_tests_properties(${_NAME} PROPERTIES ENVIRONMENT "PYTHONPATH=${_PYTHONPATH}")
@ -53,14 +47,14 @@ endfunction()
#Add code style test. #Add code style test.
add_test( add_test(
NAME "code-style" NAME "code-style"
COMMAND ${Python3_EXECUTABLE} run_mypy.py COMMAND ${Python_EXECUTABLE} run_mypy.py
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
) )
#Add test for import statements which are not compatible with all builds #Add test for import statements which are not compatible with all builds
add_test( add_test(
NAME "invalid-imports" NAME "invalid-imports"
COMMAND ${Python3_EXECUTABLE} scripts/check_invalid_imports.py COMMAND ${Python_EXECUTABLE} scripts/check_invalid_imports.py
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
) )
@ -78,6 +72,6 @@ endforeach()
#Add test for whether the shortcut alt-keys are unique in every translation. #Add test for whether the shortcut alt-keys are unique in every translation.
add_test( add_test(
NAME "shortcut-keys" NAME "shortcut-keys"
COMMAND ${Python3_EXECUTABLE} scripts/check_shortcut_keys.py COMMAND ${Python_EXECUTABLE} scripts/check_shortcut_keys.py
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
) )

View File

@ -1,8 +1,8 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2021 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import enum
from datetime import datetime from datetime import datetime
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty, QTimer, Q_ENUMS from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty, QTimer, pyqtEnum
from typing import Any, Optional, Dict, TYPE_CHECKING, Callable from typing import Any, Optional, Dict, TYPE_CHECKING, Callable
from UM.Logger import Logger from UM.Logger import Logger
@ -18,7 +18,7 @@ if TYPE_CHECKING:
i18n_catalog = i18nCatalog("cura") i18n_catalog = i18nCatalog("cura")
class SyncState: class SyncState(enum.IntEnum):
"""QML: Cura.AccountSyncState""" """QML: Cura.AccountSyncState"""
SYNCING = 0 SYNCING = 0
SUCCESS = 1 SUCCESS = 1
@ -41,7 +41,7 @@ class Account(QObject):
# The interval in which sync services are automatically triggered # The interval in which sync services are automatically triggered
SYNC_INTERVAL = 60.0 # seconds SYNC_INTERVAL = 60.0 # seconds
Q_ENUMS(SyncState) pyqtEnum(SyncState)
loginStateChanged = pyqtSignal(bool) loginStateChanged = pyqtSignal(bool)
"""Signal emitted when user logged in or out""" """Signal emitted when user logged in or out"""
@ -269,10 +269,10 @@ class Account(QObject):
return self._authorization_service.getAccessToken() return self._authorization_service.getAccessToken()
@pyqtProperty("QVariantMap", notify = userProfileChanged) @pyqtProperty("QVariantMap", notify = userProfileChanged)
def userProfile(self) -> Optional[Dict[str, Optional[str]]]: def userProfile(self) -> Dict[str, Optional[str]]:
"""None if no user is logged in otherwise the logged in user as a dict containing containing user_id, username and profile_image_url """ """None if no user is logged in otherwise the logged in user as a dict containing containing user_id, username and profile_image_url """
if not self._user_profile: if not self._user_profile:
return None return {}
return self._user_profile.__dict__ return self._user_profile.__dict__
@pyqtProperty(str, notify=lastSyncDateTimeChanged) @pyqtProperty(str, notify=lastSyncDateTimeChanged)

View File

@ -1,6 +1,6 @@
from typing import Optional from typing import Optional
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty
from UM.TaskManagement.HttpRequestManager import HttpRequestManager from UM.TaskManagement.HttpRequestManager import HttpRequestManager

View File

@ -2,7 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional, TYPE_CHECKING from typing import Optional, TYPE_CHECKING
from PyQt5.QtCore import QObject, pyqtProperty from PyQt6.QtCore import QObject, pyqtProperty
from cura.API.Backups import Backups from cura.API.Backups import Backups
from cura.API.ConnectionStatus import ConnectionStatus from cura.API.ConnectionStatus import ConnectionStatus
@ -34,12 +34,13 @@ class CuraAPI(QObject):
raise RuntimeError("Tried to create singleton '{class_name}' more than once.".format(class_name = CuraAPI.__name__)) raise RuntimeError("Tried to create singleton '{class_name}' more than once.".format(class_name = CuraAPI.__name__))
if application is None: if application is None:
raise RuntimeError("Upon first time creation, the application must be set.") raise RuntimeError("Upon first time creation, the application must be set.")
cls.__instance = super(CuraAPI, cls).__new__(cls) instance = super(CuraAPI, cls).__new__(cls)
cls._application = application cls._application = application
return cls.__instance return instance
def __init__(self, application: Optional["CuraApplication"] = None) -> None: def __init__(self, application: Optional["CuraApplication"] = None) -> None:
super().__init__(parent = CuraAPI._application) super().__init__(parent = CuraAPI._application)
CuraAPI.__instance = self
self._account = Account(self._application) self._account = Account(self._application)

View File

@ -1,4 +1,4 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
# --------- # ---------
@ -13,7 +13,7 @@ DEFAULT_CURA_DEBUG_MODE = False
# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for # 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 # 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. # CuraVersion.py.in template.
CuraSDKVersion = "7.9.0" CuraSDKVersion = "8.0.0"
try: try:
from cura.CuraVersion import CuraAppName # type: ignore from cura.CuraVersion import CuraAppName # type: ignore

View File

@ -1,7 +1,7 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2021 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QTimer from PyQt6.QtCore import QTimer
from typing import Any, TYPE_CHECKING from typing import Any, TYPE_CHECKING
from UM.Logger import Logger from UM.Logger import Logger

View File

@ -31,7 +31,7 @@ from cura.Settings.GlobalStack import GlobalStack
from cura.Scene.CuraSceneNode import CuraSceneNode from cura.Scene.CuraSceneNode import CuraSceneNode
from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderManager import ExtruderManager
from PyQt5.QtCore import QTimer from PyQt6.QtCore import QTimer
if TYPE_CHECKING: if TYPE_CHECKING:

View File

@ -2,8 +2,8 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QVariantAnimation, QEasingCurve from PyQt6.QtCore import QVariantAnimation, QEasingCurve
from PyQt5.QtGui import QVector3D from PyQt6.QtGui import QVector3D
from UM.Math.Vector import Vector from UM.Math.Vector import Vector
@ -13,7 +13,7 @@ class CameraAnimation(QVariantAnimation):
super().__init__(parent) super().__init__(parent)
self._camera_tool = None self._camera_tool = None
self.setDuration(300) self.setDuration(300)
self.setEasingCurve(QEasingCurve.OutQuad) self.setEasingCurve(QEasingCurve.Type.OutQuad)
def setCameraTool(self, camera_tool): def setCameraTool(self, camera_tool):
self._camera_tool = camera_tool self._camera_tool = camera_tool

View File

@ -20,9 +20,9 @@ try:
except ImportError: except ImportError:
with_sentry_sdk = False with_sentry_sdk = False
from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QUrl from PyQt6.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QUrl
from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit, QGroupBox, QCheckBox, QPushButton from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit, QGroupBox, QCheckBox, QPushButton
from PyQt5.QtGui import QDesktopServices from PyQt6.QtGui import QDesktopServices
from UM.Application import Application from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger
@ -136,8 +136,8 @@ class CrashHandler:
# "backup and start clean" and "close" buttons # "backup and start clean" and "close" buttons
buttons = QDialogButtonBox() buttons = QDialogButtonBox()
buttons.addButton(QDialogButtonBox.Close) buttons.addButton(QDialogButtonBox.StandardButton.Close)
buttons.addButton(catalog.i18nc("@action:button", "Backup and Reset Configuration"), QDialogButtonBox.AcceptRole) buttons.addButton(catalog.i18nc("@action:button", "Backup and Reset Configuration"), QDialogButtonBox.ButtonRole.AcceptRole)
buttons.rejected.connect(self._closeEarlyCrashDialog) buttons.rejected.connect(self._closeEarlyCrashDialog)
buttons.accepted.connect(self._backupAndStartClean) buttons.accepted.connect(self._backupAndStartClean)
@ -161,7 +161,7 @@ class CrashHandler:
QDesktopServices.openUrl(QUrl.fromLocalFile( path )) QDesktopServices.openUrl(QUrl.fromLocalFile( path ))
def _showDetailedReport(self): def _showDetailedReport(self):
self.dialog.exec_() self.dialog.exec()
def _createDialog(self): def _createDialog(self):
"""Creates a modal dialog.""" """Creates a modal dialog."""
@ -409,12 +409,12 @@ class CrashHandler:
def _buttonsWidget(self): def _buttonsWidget(self):
buttons = QDialogButtonBox() buttons = QDialogButtonBox()
buttons.addButton(QDialogButtonBox.Close) buttons.addButton(QDialogButtonBox.StandardButton.Close)
# Like above, this will be served as a separate detailed report dialog if the application has not yet been # Like above, this will be served as a separate detailed report dialog if the application has not yet been
# fully loaded. In this case, "send report" will be a check box in the early crash dialog, so there is no # fully loaded. In this case, "send report" will be a check box in the early crash dialog, so there is no
# need for this extra button. # need for this extra button.
if self.has_started: if self.has_started:
buttons.addButton(catalog.i18nc("@action:button", "Send report"), QDialogButtonBox.AcceptRole) buttons.addButton(catalog.i18nc("@action:button", "Send report"), QDialogButtonBox.ButtonRole.AcceptRole)
buttons.accepted.connect(self._sendCrashReport) buttons.accepted.connect(self._sendCrashReport)
buttons.rejected.connect(self.dialog.close) buttons.rejected.connect(self.dialog.close)
@ -456,5 +456,5 @@ class CrashHandler:
def _show(self): def _show(self):
# When the exception is in the skip_exception_types list, the dialog is not created, so we don't need to show it # When the exception is in the skip_exception_types list, the dialog is not created, so we don't need to show it
if self.dialog: if self.dialog:
self.dialog.exec_() self.dialog.exec()
os._exit(1) os._exit(1)

View File

@ -1,8 +1,8 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QObject, QUrl from PyQt6.QtCore import QObject, QUrl
from PyQt5.QtGui import QDesktopServices from PyQt6.QtGui import QDesktopServices
from typing import List, cast from typing import List, cast
from UM.Event import CallFunctionEvent from UM.Event import CallFunctionEvent

View File

@ -1,6 +1,6 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import enum
import os import os
import sys import sys
import tempfile import tempfile
@ -8,10 +8,10 @@ import time
from typing import cast, TYPE_CHECKING, Optional, Callable, List, Any, Dict from typing import cast, TYPE_CHECKING, Optional, Callable, List, Any, Dict
import numpy import numpy
from PyQt5.QtCore import QObject, QTimer, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS from PyQt6.QtCore import QObject, QTimer, QUrl, pyqtSignal, pyqtProperty, QEvent, pyqtEnum, QCoreApplication
from PyQt5.QtGui import QColor, QIcon from PyQt6.QtGui import QColor, QIcon
from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType from PyQt6.QtQml import qmlRegisterUncreatableType, qmlRegisterUncreatableMetaObject, qmlRegisterSingletonType, qmlRegisterType
from PyQt5.QtWidgets import QMessageBox from PyQt6.QtWidgets import QMessageBox
import UM.Util import UM.Util
import cura.Settings.cura_empty_instance_containers import cura.Settings.cura_empty_instance_containers
@ -122,7 +122,6 @@ if TYPE_CHECKING:
numpy.seterr(all = "ignore") numpy.seterr(all = "ignore")
class CuraApplication(QtApplication): class CuraApplication(QtApplication):
# SettingVersion represents the set of settings available in the machine/extruder definitions. # 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 # You need to make sure that this version number needs to be increased if there is any non-backwards-compatible
@ -131,7 +130,7 @@ class CuraApplication(QtApplication):
Created = False Created = False
class ResourceTypes: class ResourceTypes(enum.IntEnum):
QmlFiles = Resources.UserType + 1 QmlFiles = Resources.UserType + 1
Firmware = Resources.UserType + 2 Firmware = Resources.UserType + 2
QualityInstanceContainer = Resources.UserType + 3 QualityInstanceContainer = Resources.UserType + 3
@ -145,7 +144,7 @@ class CuraApplication(QtApplication):
SettingVisibilityPreset = Resources.UserType + 11 SettingVisibilityPreset = Resources.UserType + 11
IntentInstanceContainer = Resources.UserType + 12 IntentInstanceContainer = Resources.UserType + 12
Q_ENUMS(ResourceTypes) pyqtEnum(ResourceTypes)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(name = ApplicationMetadata.CuraAppName, super().__init__(name = ApplicationMetadata.CuraAppName,
@ -350,6 +349,7 @@ class CuraApplication(QtApplication):
app_root = os.path.abspath(os.path.join(os.path.dirname(sys.executable))) app_root = os.path.abspath(os.path.join(os.path.dirname(sys.executable)))
Resources.addSearchPath(os.path.join(app_root, "share", "cura", "resources")) Resources.addSearchPath(os.path.join(app_root, "share", "cura", "resources"))
Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "share", "cura", "resources"))
Resources.addSearchPath(os.path.join(self._app_install_dir, "share", "cura", "resources")) Resources.addSearchPath(os.path.join(self._app_install_dir, "share", "cura", "resources"))
if not hasattr(sys, "frozen"): if not hasattr(sys, "frozen"):
@ -622,11 +622,14 @@ class CuraApplication(QtApplication):
# the QML code then gets `null` as the global stack and can deal with that as it deems fit. # the QML code then gets `null` as the global stack and can deal with that as it deems fit.
self.getMachineManager().setActiveMachine(None) self.getMachineManager().setActiveMachine(None)
QtApplication.getInstance().closeAllWindows()
main_window = self.getMainWindow() main_window = self.getMainWindow()
if main_window is not None: if main_window is not None:
main_window.close() main_window.close()
else:
self.exit(0) QtApplication.closeAllWindows()
QCoreApplication.quit()
# This function first performs all upon-exit checks such as USB printing that is in progress. # This function first performs all upon-exit checks such as USB printing that is in progress.
# Use this to close the application. # Use this to close the application.
@ -678,6 +681,22 @@ class CuraApplication(QtApplication):
self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing Active Machine...")) self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing Active Machine..."))
super().setGlobalContainerStack(stack) super().setGlobalContainerStack(stack)
showMessageBox = pyqtSignal(str,str, str, str, int, int,
arguments = ["title", "text", "informativeText", "detailedText","buttons", "icon"])
"""A reusable dialogbox"""
def messageBox(self, title, text,
informativeText = "",
detailedText = "",
buttons = QMessageBox.StandardButton.Ok,
icon = QMessageBox.Icon.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)
showDiscardOrKeepProfileChanges = pyqtSignal() showDiscardOrKeepProfileChanges = pyqtSignal()
def discardOrKeepProfileChanges(self) -> bool: def discardOrKeepProfileChanges(self) -> bool:
@ -858,7 +877,7 @@ class CuraApplication(QtApplication):
self._auto_save = AutoSave(self) self._auto_save = AutoSave(self)
self._auto_save.initialize() self._auto_save.initialize()
self.exec_() self.exec()
def __setUpSingleInstanceServer(self): def __setUpSingleInstanceServer(self):
if self._use_single_instance: if self._use_single_instance:
@ -1075,12 +1094,18 @@ class CuraApplication(QtApplication):
def event(self, event): def event(self, event):
"""Handle Qt events""" """Handle Qt events"""
if event.type() == QEvent.FileOpen: if event.type() == QEvent.Type.FileOpen:
if self._plugins_loaded: if self._plugins_loaded:
self._openFile(event.file()) self._openFile(event.file())
else: else:
self._open_file_queue.append(event.file()) self._open_file_queue.append(event.file())
if int(event.type()) == 20: # 'QEvent.Type.Quit' enum isn't there, even though it should be according to docs.
# Once we're at this point, everything should have been flushed already (past OnExitCallbackManager).
# It's more difficult to call sys.exit(0): That requires that it happens as the result of a pyqtSignal-emit.
# (See https://doc.qt.io/qt-6/qcoreapplication.html#quit)
os._exit(0)
return super().event(event) return super().event(event)
def getAutoSave(self) -> Optional[AutoSave]: def getAutoSave(self) -> Optional[AutoSave]:
@ -1121,16 +1146,16 @@ class CuraApplication(QtApplication):
engine.rootContext().setContextProperty("CuraSDKVersion", ApplicationMetadata.CuraSDKVersion) engine.rootContext().setContextProperty("CuraSDKVersion", ApplicationMetadata.CuraSDKVersion)
self.processEvents() self.processEvents()
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type") qmlRegisterUncreatableMetaObject(CuraApplication.staticMetaObject, "Cura", 1, 0, "ResourceTypes", "ResourceTypes is an enum-only type")
self.processEvents() self.processEvents()
qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 0, "SceneController", self.getCuraSceneController) qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 0, self.getCuraSceneController, "SceneController")
qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, "ExtruderManager", self.getExtruderManager) qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, self.getExtruderManager, "ExtruderManager")
qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager) qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, self.getMachineManager, "MachineManager")
qmlRegisterSingletonType(IntentManager, "Cura", 1, 6, "IntentManager", self.getIntentManager) qmlRegisterSingletonType(IntentManager, "Cura", 1, 6, self.getIntentManager, "IntentManager")
qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager", self.getSettingInheritanceManager) qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, self.getSettingInheritanceManager, "SettingInheritanceManager")
qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager) qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, self.getSimpleModeSettingsManager, "SimpleModeSettingsManager")
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager) qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, self.getMachineActionManager, "MachineActionManager")
self.processEvents() self.processEvents()
qmlRegisterType(NetworkingUtil, "Cura", 1, 5, "NetworkingUtil") qmlRegisterType(NetworkingUtil, "Cura", 1, 5, "NetworkingUtil")
@ -1153,16 +1178,16 @@ class CuraApplication(QtApplication):
qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel") qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel")
qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel")
qmlRegisterType(MaterialBrandsModel, "Cura", 1, 0, "MaterialBrandsModel") qmlRegisterType(MaterialBrandsModel, "Cura", 1, 0, "MaterialBrandsModel")
qmlRegisterSingletonType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel", self.getQualityManagementModel) qmlRegisterSingletonType(QualityManagementModel, "Cura", 1, 0, self.getQualityManagementModel, "QualityManagementModel")
qmlRegisterSingletonType(MaterialManagementModel, "Cura", 1, 5, "MaterialManagementModel", self.getMaterialManagementModel) qmlRegisterSingletonType(MaterialManagementModel, "Cura", 1, 5, self.getMaterialManagementModel, "MaterialManagementModel")
self.processEvents() self.processEvents()
qmlRegisterType(DiscoveredPrintersModel, "Cura", 1, 0, "DiscoveredPrintersModel") qmlRegisterType(DiscoveredPrintersModel, "Cura", 1, 0, "DiscoveredPrintersModel")
qmlRegisterType(DiscoveredCloudPrintersModel, "Cura", 1, 7, "DiscoveredCloudPrintersModel") qmlRegisterType(DiscoveredCloudPrintersModel, "Cura", 1, 7, "DiscoveredCloudPrintersModel")
qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0, qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0,
"QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel) self.getQualityProfilesDropDownMenuModel, "QualityProfilesDropDownMenuModel")
qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0, qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0,
"CustomQualityProfilesDropDownMenuModel", self.getCustomQualityProfilesDropDownMenuModel) self.getCustomQualityProfilesDropDownMenuModel, "CustomQualityProfilesDropDownMenuModel")
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
qmlRegisterType(IntentModel, "Cura", 1, 6, "IntentModel") qmlRegisterType(IntentModel, "Cura", 1, 6, "IntentModel")
qmlRegisterType(IntentCategoryModel, "Cura", 1, 6, "IntentCategoryModel") qmlRegisterType(IntentCategoryModel, "Cura", 1, 6, "IntentCategoryModel")
@ -1174,14 +1199,14 @@ class CuraApplication(QtApplication):
qmlRegisterType(FirstStartMachineActionsModel, "Cura", 1, 0, "FirstStartMachineActionsModel") qmlRegisterType(FirstStartMachineActionsModel, "Cura", 1, 0, "FirstStartMachineActionsModel")
qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator") qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel") qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel")
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.getInstance) qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, ContainerManager.getInstance, "ContainerManager")
qmlRegisterType(SidebarCustomMenuItemsModel, "Cura", 1, 0, "SidebarCustomMenuItemsModel") qmlRegisterType(SidebarCustomMenuItemsModel, "Cura", 1, 0, "SidebarCustomMenuItemsModel")
qmlRegisterType(PrinterOutputDevice, "Cura", 1, 0, "PrinterOutputDevice") qmlRegisterType(PrinterOutputDevice, "Cura", 1, 0, "PrinterOutputDevice")
from cura.API import CuraAPI from cura.API import CuraAPI
qmlRegisterSingletonType(CuraAPI, "Cura", 1, 1, "API", self.getCuraAPI) qmlRegisterSingletonType(CuraAPI, "Cura", 1, 1, self.getCuraAPI, "API")
qmlRegisterUncreatableType(Account, "Cura", 1, 0, "AccountSyncState", "Could not create AccountSyncState") qmlRegisterUncreatableMetaObject(CuraApplication.staticMetaObject, "Cura", 1, 0, "AccountSyncState", "AccountSyncState is an enum-only type")
# As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work. # As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work.
actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml"))) actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")))

View File

@ -13,7 +13,7 @@ catalog = i18nCatalog("cura")
if TYPE_CHECKING: if TYPE_CHECKING:
from UM.Qt.QtApplication import QtApplication from UM.Qt.QtApplication import QtApplication
from PyQt5.QtCore import QObject from PyQt6.QtCore import QObject
class CuraPackageManager(PackageManager): class CuraPackageManager(PackageManager):

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, QUrl from PyQt6.QtCore import pyqtProperty, QUrl
from UM.Resources import Resources from UM.Resources import Resources
from UM.View.View import View from UM.View.View import View

View File

@ -4,7 +4,7 @@
import os import os
from typing import Optional from typing import Optional
from PyQt5.QtCore import QObject, QUrl, pyqtSlot, pyqtProperty, pyqtSignal from PyQt6.QtCore import QObject, QUrl, pyqtSlot, pyqtProperty, pyqtSignal
from UM.Logger import Logger from UM.Logger import Logger
from UM.PluginObject import PluginObject from UM.PluginObject import PluginObject

View File

@ -5,7 +5,7 @@ import time
from collections import deque from collections import deque
from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtProperty from PyQt6.QtCore import QObject, QTimer, pyqtSignal, pyqtProperty
from typing import Optional, Any, Set from typing import Optional, Any, Set
from UM.Logger import Logger from UM.Logger import Logger
@ -53,6 +53,8 @@ class MachineErrorChecker(QObject):
self._keys_to_check = set() # type: Set[str] self._keys_to_check = set() # type: Set[str]
self._num_keys_to_check_per_update = 10
def initialize(self) -> None: def initialize(self) -> None:
self._error_check_timer.timeout.connect(self._rescheduleCheck) self._error_check_timer.timeout.connect(self._rescheduleCheck)
@ -162,37 +164,37 @@ class MachineErrorChecker(QObject):
self._check_in_progress = True self._check_in_progress = True
# If there is nothing to check any more, it means there is no error. for i in range(self._num_keys_to_check_per_update):
if not self._stacks_and_keys_to_check: # If there is nothing to check any more, it means there is no error.
# Finish if not self._stacks_and_keys_to_check:
self._setResult(False) # Finish
return self._setResult(False)
return
# Get the next stack and key to check # Get the next stack and key to check
stack, key = self._stacks_and_keys_to_check.popleft() stack, key = self._stacks_and_keys_to_check.popleft()
enabled = stack.getProperty(key, "enabled") enabled = stack.getProperty(key, "enabled")
if not enabled: if not enabled:
self._application.callLater(self._checkStack) continue
return
validation_state = stack.getProperty(key, "validationState") validation_state = stack.getProperty(key, "validationState")
if validation_state is None: if validation_state is None:
# Setting is not validated. This can happen if there is only a setting definition. # Setting is not validated. This can happen if there is only a setting definition.
# We do need to validate it, because a setting definitions value can be set by a function, which could # We do need to validate it, because a setting definitions value can be set by a function, which could
# be an invalid setting. # be an invalid setting.
definition = stack.getSettingDefinition(key) definition = stack.getSettingDefinition(key)
validator_type = SettingDefinition.getValidatorForType(definition.type) validator_type = SettingDefinition.getValidatorForType(definition.type)
if validator_type: if validator_type:
validator = validator_type(key) validator = validator_type(key)
validation_state = validator(stack) validation_state = validator(stack)
if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError, ValidatorState.Invalid): if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError, ValidatorState.Invalid):
# Since we don't know if any of the settings we didn't check is has an error value, store the list for the # Since we don't know if any of the settings we didn't check is has an error value, store the list for the
# next check. # next check.
keys_to_recheck = {setting_key for stack, setting_key in self._stacks_and_keys_to_check} keys_to_recheck = {setting_key for stack, setting_key in self._stacks_and_keys_to_check}
keys_to_recheck.add(key) keys_to_recheck.add(key)
self._setResult(True, keys_to_recheck = keys_to_recheck) self._setResult(True, keys_to_recheck = keys_to_recheck)
return return
# Schedule the check for the next key # Schedule the check for the next key
self._application.callLater(self._checkStack) self._application.callLater(self._checkStack)

View File

@ -129,7 +129,7 @@ class MachineNode(ContainerNode):
if name not in groups_by_name: if name not in groups_by_name:
# CURA-6599 # CURA-6599
# For some reason, QML will get null or fail to convert type for MachineManager.activeQualityChangesGroup() to # 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 # a QObject. Setting the object ownership to QQmlEngine.ObjectOwnership.CppOwnership doesn't work, but setting the object
# parent to application seems to work. # parent to application seems to work.
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
groups_by_name[name] = QualityChangesGroup(name, quality_type = quality_changes["quality_type"], groups_by_name[name] = QualityChangesGroup(name, quality_type = quality_changes["quality_type"],

View File

@ -3,7 +3,7 @@
from typing import Dict, Set from typing import Dict, Set
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, pyqtProperty from PyQt6.QtCore import Qt, QTimer, pyqtSignal, pyqtProperty
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
from UM.Logger import Logger from UM.Logger import Logger
@ -61,22 +61,22 @@ class BaseMaterialsModel(ListModel):
ContainerTree.getInstance().materialsChanged.connect(self._materialsListChanged) ContainerTree.getInstance().materialsChanged.connect(self._materialsListChanged)
self._application.getMaterialManagementModel().favoritesChanged.connect(self._onChanged) self._application.getMaterialManagementModel().favoritesChanged.connect(self._onChanged)
self.addRoleName(Qt.UserRole + 1, "root_material_id") self.addRoleName(Qt.ItemDataRole.UserRole + 1, "root_material_id")
self.addRoleName(Qt.UserRole + 2, "id") self.addRoleName(Qt.ItemDataRole.UserRole + 2, "id")
self.addRoleName(Qt.UserRole + 3, "GUID") self.addRoleName(Qt.ItemDataRole.UserRole + 3, "GUID")
self.addRoleName(Qt.UserRole + 4, "name") self.addRoleName(Qt.ItemDataRole.UserRole + 4, "name")
self.addRoleName(Qt.UserRole + 5, "brand") self.addRoleName(Qt.ItemDataRole.UserRole + 5, "brand")
self.addRoleName(Qt.UserRole + 6, "description") self.addRoleName(Qt.ItemDataRole.UserRole + 6, "description")
self.addRoleName(Qt.UserRole + 7, "material") self.addRoleName(Qt.ItemDataRole.UserRole + 7, "material")
self.addRoleName(Qt.UserRole + 8, "color_name") self.addRoleName(Qt.ItemDataRole.UserRole + 8, "color_name")
self.addRoleName(Qt.UserRole + 9, "color_code") self.addRoleName(Qt.ItemDataRole.UserRole + 9, "color_code")
self.addRoleName(Qt.UserRole + 10, "density") self.addRoleName(Qt.ItemDataRole.UserRole + 10, "density")
self.addRoleName(Qt.UserRole + 11, "diameter") self.addRoleName(Qt.ItemDataRole.UserRole + 11, "diameter")
self.addRoleName(Qt.UserRole + 12, "approximate_diameter") self.addRoleName(Qt.ItemDataRole.UserRole + 12, "approximate_diameter")
self.addRoleName(Qt.UserRole + 13, "adhesion_info") self.addRoleName(Qt.ItemDataRole.UserRole + 13, "adhesion_info")
self.addRoleName(Qt.UserRole + 14, "is_read_only") self.addRoleName(Qt.ItemDataRole.UserRole + 14, "is_read_only")
self.addRoleName(Qt.UserRole + 15, "container_node") self.addRoleName(Qt.ItemDataRole.UserRole + 15, "container_node")
self.addRoleName(Qt.UserRole + 16, "is_favorite") self.addRoleName(Qt.ItemDataRole.UserRole + 16, "is_favorite")
def _onChanged(self) -> None: def _onChanged(self) -> None:
self._update_timer.start() self._update_timer.start()

View File

@ -1,14 +1,14 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt from PyQt6.QtCore import Qt
from UM.Logger import Logger from UM.Logger import Logger
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
class BuildPlateModel(ListModel): class BuildPlateModel(ListModel):
NameRole = Qt.UserRole + 1 NameRole = Qt.ItemDataRole.UserRole + 1
ContainerNodeRole = Qt.UserRole + 2 ContainerNodeRole = Qt.ItemDataRole.UserRole + 2
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)

View File

@ -10,7 +10,7 @@ from cura.Machines.ContainerTree import ContainerTree
from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel
if TYPE_CHECKING: if TYPE_CHECKING:
from PyQt5.QtCore import QObject from PyQt6.QtCore import QObject
from UM.Settings.Interfaces import ContainerInterface from UM.Settings.Interfaces import ContainerInterface

View File

@ -1,6 +1,6 @@
from typing import Optional, TYPE_CHECKING, List, Dict from typing import Optional, TYPE_CHECKING, List, Dict
from PyQt5.QtCore import QObject, pyqtSlot, Qt, pyqtSignal, pyqtProperty from PyQt6.QtCore import QObject, pyqtSlot, Qt, pyqtSignal, pyqtProperty
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -12,10 +12,10 @@ class DiscoveredCloudPrintersModel(ListModel):
"""Model used to inform the application about newly added cloud printers, which are discovered from the user's """Model used to inform the application about newly added cloud printers, which are discovered from the user's
account """ account """
DeviceKeyRole = Qt.UserRole + 1 DeviceKeyRole = Qt.ItemDataRole.UserRole + 1
DeviceNameRole = Qt.UserRole + 2 DeviceNameRole = Qt.ItemDataRole.UserRole + 2
DeviceTypeRole = Qt.UserRole + 3 DeviceTypeRole = Qt.ItemDataRole.UserRole + 3
DeviceFirmwareVersionRole = Qt.UserRole + 4 DeviceFirmwareVersionRole = Qt.ItemDataRole.UserRole + 4
cloudPrintersDetectedChanged = pyqtSignal(bool) cloudPrintersDetectedChanged = pyqtSignal(bool)

View File

@ -3,7 +3,7 @@
from typing import Callable, Dict, List, Optional, TYPE_CHECKING from typing import Callable, Dict, List, Optional, TYPE_CHECKING
from PyQt5.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject, QTimer from PyQt6.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject, QTimer
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Logger import Logger from UM.Logger import Logger

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer from PyQt6.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer
from typing import Iterable, TYPE_CHECKING from typing import Iterable, TYPE_CHECKING
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
@ -23,43 +23,43 @@ class ExtrudersModel(ListModel):
""" """
# The ID of the container stack for the extruder. # The ID of the container stack for the extruder.
IdRole = Qt.UserRole + 1 IdRole = Qt.ItemDataRole.UserRole + 1
NameRole = Qt.UserRole + 2 NameRole = Qt.ItemDataRole.UserRole + 2
"""Human-readable name of the extruder.""" """Human-readable name of the extruder."""
ColorRole = Qt.UserRole + 3 ColorRole = Qt.ItemDataRole.UserRole + 3
"""Colour of the material loaded in the extruder.""" """Colour of the material loaded in the extruder."""
IndexRole = Qt.UserRole + 4 IndexRole = Qt.ItemDataRole.UserRole + 4
"""Index of the extruder, which is also the value of the setting itself. """Index of the extruder, which is also the value of the setting itself.
An index of 0 indicates the first extruder, an index of 1 the second one, and so on. This is the value that will An index of 0 indicates the first extruder, an index of 1 the second one, and so on. This is the value that will
be saved in instance containers. """ be saved in instance containers. """
# The ID of the definition of the extruder. # The ID of the definition of the extruder.
DefinitionRole = Qt.UserRole + 5 DefinitionRole = Qt.ItemDataRole.UserRole + 5
# The material of the extruder. # The material of the extruder.
MaterialRole = Qt.UserRole + 6 MaterialRole = Qt.ItemDataRole.UserRole + 6
# The variant of the extruder. # The variant of the extruder.
VariantRole = Qt.UserRole + 7 VariantRole = Qt.ItemDataRole.UserRole + 7
StackRole = Qt.UserRole + 8 StackRole = Qt.ItemDataRole.UserRole + 8
MaterialBrandRole = Qt.UserRole + 9 MaterialBrandRole = Qt.ItemDataRole.UserRole + 9
ColorNameRole = Qt.UserRole + 10 ColorNameRole = Qt.ItemDataRole.UserRole + 10
EnabledRole = Qt.UserRole + 11 EnabledRole = Qt.ItemDataRole.UserRole + 11
"""Is the extruder enabled?""" """Is the extruder enabled?"""
MaterialTypeRole = Qt.UserRole + 12 MaterialTypeRole = Qt.ItemDataRole.UserRole + 12
"""The type of the material (e.g. PLA, ABS, PETG, etc.).""" """The type of the material (e.g. PLA, ABS, PETG, etc.)."""
defaultColors = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"] defaultColors = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"]
"""List of colours to display if there is no material or the material has no known colour. """ """List of colours to display if there is no material or the material has no known colour. """
MaterialNameRole = Qt.UserRole + 13 MaterialNameRole = Qt.ItemDataRole.UserRole + 13
def __init__(self, parent = None): def __init__(self, parent = None):
"""Initialises the extruders model, defining the roles and listening for changes in the data. """Initialises the extruders model, defining the roles and listening for changes in the data.

View File

@ -3,7 +3,7 @@
from typing import Optional, Dict, Any, TYPE_CHECKING from typing import Optional, Dict, Any, TYPE_CHECKING
from PyQt5.QtCore import QObject, Qt, pyqtProperty, pyqtSignal, pyqtSlot from PyQt6.QtCore import QObject, Qt, pyqtProperty, pyqtSignal, pyqtSlot
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -19,9 +19,9 @@ class FirstStartMachineActionsModel(ListModel):
- action : the MachineAction object itself - action : the MachineAction object itself
""" """
TitleRole = Qt.UserRole + 1 TitleRole = Qt.ItemDataRole.UserRole + 1
ContentRole = Qt.UserRole + 2 ContentRole = Qt.ItemDataRole.UserRole + 2
ActionRole = Qt.UserRole + 3 ActionRole = Qt.ItemDataRole.UserRole + 3
def __init__(self, application: "CuraApplication", parent: Optional[QObject] = None) -> None: def __init__(self, application: "CuraApplication", parent: Optional[QObject] = None) -> None:
super().__init__(parent) super().__init__(parent)

View File

@ -1,7 +1,7 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2021 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt, QTimer, pyqtProperty, pyqtSignal from PyQt6.QtCore import Qt, QTimer, pyqtProperty, pyqtSignal
from typing import List, Optional from typing import List, Optional
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -15,14 +15,14 @@ from cura.UltimakerCloud.UltimakerCloudConstants import META_CAPABILITIES # To
class GlobalStacksModel(ListModel): class GlobalStacksModel(ListModel):
NameRole = Qt.UserRole + 1 NameRole = Qt.ItemDataRole.UserRole + 1
IdRole = Qt.UserRole + 2 IdRole = Qt.ItemDataRole.UserRole + 2
HasRemoteConnectionRole = Qt.UserRole + 3 HasRemoteConnectionRole = Qt.ItemDataRole.UserRole + 3
ConnectionTypeRole = Qt.UserRole + 4 ConnectionTypeRole = Qt.ItemDataRole.UserRole + 4
MetaDataRole = Qt.UserRole + 5 MetaDataRole = Qt.ItemDataRole.UserRole + 5
DiscoverySourceRole = Qt.UserRole + 6 # For separating local and remote printers in the machine management page DiscoverySourceRole = Qt.ItemDataRole.UserRole + 6 # For separating local and remote printers in the machine management page
RemovalWarningRole = Qt.UserRole + 7 RemovalWarningRole = Qt.ItemDataRole.UserRole + 7
IsOnlineRole = Qt.UserRole + 8 IsOnlineRole = Qt.ItemDataRole.UserRole + 8
def __init__(self, parent = None) -> None: def __init__(self, parent = None) -> None:
super().__init__(parent) super().__init__(parent)
@ -135,7 +135,7 @@ class GlobalStacksModel(ListModel):
continue continue
device_name = container_stack.getMetaDataEntry("group_name", container_stack.getName()) device_name = container_stack.getMetaDataEntry("group_name", container_stack.getName())
section_name = "Connected printers" if has_remote_connection else "Preset printers" section_name = self._catalog.i18nc("@label", "Connected printers") if has_remote_connection else self._catalog.i18nc("@label", "Preset printers")
section_name = self._catalog.i18nc("@info:title", section_name) section_name = self._catalog.i18nc("@info:title", section_name)
default_removal_warning = self._catalog.i18nc( default_removal_warning = self._catalog.i18nc(

View File

@ -2,14 +2,14 @@
#Cura is released under the terms of the LGPLv3 or higher. #Cura is released under the terms of the LGPLv3 or higher.
import collections import collections
from PyQt5.QtCore import Qt, QTimer from PyQt6.QtCore import Qt, QTimer
from typing import TYPE_CHECKING, Optional, Dict from typing import TYPE_CHECKING, Optional, Dict
from cura.Machines.Models.IntentModel import IntentModel from cura.Machines.Models.IntentModel import IntentModel
from cura.Settings.IntentManager import IntentManager from cura.Settings.IntentManager import IntentManager
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
from UM.Settings.ContainerRegistry import ContainerRegistry #To update the list if anything changes. from UM.Settings.ContainerRegistry import ContainerRegistry #To update the list if anything changes.
from PyQt5.QtCore import pyqtSignal from PyQt6.QtCore import pyqtSignal
import cura.CuraApplication import cura.CuraApplication
if TYPE_CHECKING: if TYPE_CHECKING:
from UM.Settings.ContainerRegistry import ContainerInterface from UM.Settings.ContainerRegistry import ContainerInterface
@ -21,11 +21,11 @@ catalog = i18nCatalog("cura")
class IntentCategoryModel(ListModel): class IntentCategoryModel(ListModel):
"""Lists the intent categories that are available for the current printer configuration. """ """Lists the intent categories that are available for the current printer configuration. """
NameRole = Qt.UserRole + 1 NameRole = Qt.ItemDataRole.UserRole + 1
IntentCategoryRole = Qt.UserRole + 2 IntentCategoryRole = Qt.ItemDataRole.UserRole + 2
WeightRole = Qt.UserRole + 3 WeightRole = Qt.ItemDataRole.UserRole + 3
QualitiesRole = Qt.UserRole + 4 QualitiesRole = Qt.ItemDataRole.UserRole + 4
DescriptionRole = Qt.UserRole + 5 DescriptionRole = Qt.ItemDataRole.UserRole + 5
modelUpdated = pyqtSignal() modelUpdated = pyqtSignal()

View File

@ -2,7 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional, Dict, Any, Set, List from typing import Optional, Dict, Any, Set, List
from PyQt5.QtCore import Qt, QObject, pyqtProperty, pyqtSignal, QTimer from PyQt6.QtCore import Qt, QObject, pyqtProperty, pyqtSignal, QTimer
import cura.CuraApplication import cura.CuraApplication
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -15,11 +15,11 @@ from cura.Machines.QualityGroup import QualityGroup
class IntentModel(ListModel): class IntentModel(ListModel):
NameRole = Qt.UserRole + 1 NameRole = Qt.ItemDataRole.UserRole + 1
QualityTypeRole = Qt.UserRole + 2 QualityTypeRole = Qt.ItemDataRole.UserRole + 2
LayerHeightRole = Qt.UserRole + 3 LayerHeightRole = Qt.ItemDataRole.UserRole + 3
AvailableRole = Qt.UserRole + 4 AvailableRole = Qt.ItemDataRole.UserRole + 4
IntentRole = Qt.UserRole + 5 IntentRole = Qt.ItemDataRole.UserRole + 5
def __init__(self, parent: Optional[QObject] = None) -> None: def __init__(self, parent: Optional[QObject] = None) -> None:
super().__init__(parent) super().__init__(parent)

View File

@ -1,7 +1,9 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt, pyqtSignal from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtQml import QQmlEngine
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
@ -9,10 +11,11 @@ class MaterialTypesModel(ListModel):
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
QQmlEngine.setObjectOwnership(self, QQmlEngine.ObjectOwnership.CppOwnership)
self.addRoleName(Qt.UserRole + 1, "name") self.addRoleName(Qt.ItemDataRole.UserRole + 1, "name")
self.addRoleName(Qt.UserRole + 2, "brand") self.addRoleName(Qt.ItemDataRole.UserRole + 2, "brand")
self.addRoleName(Qt.UserRole + 3, "colors") self.addRoleName(Qt.ItemDataRole.UserRole + 3, "colors")
class MaterialBrandsModel(BaseMaterialsModel): class MaterialBrandsModel(BaseMaterialsModel):
@ -20,9 +23,10 @@ class MaterialBrandsModel(BaseMaterialsModel):
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
QQmlEngine.setObjectOwnership(self, QQmlEngine.ObjectOwnership.CppOwnership)
self.addRoleName(Qt.UserRole + 1, "name") self.addRoleName(Qt.ItemDataRole.UserRole + 1, "name")
self.addRoleName(Qt.UserRole + 2, "material_types") self.addRoleName(Qt.ItemDataRole.UserRole + 2, "material_types")
self._update() self._update()
@ -74,16 +78,15 @@ class MaterialBrandsModel(BaseMaterialsModel):
material_type_item_list = [] material_type_item_list = []
brand_item = { brand_item = {
"name": brand, "name": brand,
"material_types": MaterialTypesModel(self) "material_types": MaterialTypesModel()
} }
for material_type, material_list in material_dict.items(): for material_type, material_list in material_dict.items():
material_type_item = { material_type_item = {
"name": material_type, "name": material_type,
"brand": brand, "brand": brand,
"colors": BaseMaterialsModel(self) "colors": BaseMaterialsModel()
} }
material_type_item["colors"].clear()
# Sort materials by name # Sort materials by name
material_list = sorted(material_list, key = lambda x: x["name"].upper()) material_list = sorted(material_list, key = lambda x: x["name"].upper())

View File

@ -2,8 +2,8 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import copy # To duplicate materials. import copy # To duplicate materials.
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl from PyQt6.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl
from PyQt5.QtGui import QDesktopServices from PyQt6.QtGui import QDesktopServices
from typing import Any, Dict, Optional, TYPE_CHECKING from typing import Any, Dict, Optional, TYPE_CHECKING
import uuid # To generate new GUIDs for new materials. import uuid # To generate new GUIDs for new materials.

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QTimer, pyqtSignal, pyqtProperty from PyQt6.QtCore import QTimer, pyqtSignal, pyqtProperty
from UM.Application import Application from UM.Application import Application
from UM.Scene.Camera import Camera from UM.Scene.Camera import Camera

View File

@ -1,7 +1,7 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt from PyQt6.QtCore import Qt
from UM.Logger import Logger from UM.Logger import Logger
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -10,9 +10,9 @@ from cura.Machines.ContainerTree import ContainerTree
class NozzleModel(ListModel): class NozzleModel(ListModel):
IdRole = Qt.UserRole + 1 IdRole = Qt.ItemDataRole.UserRole + 1
HotendNameRole = Qt.UserRole + 2 HotendNameRole = Qt.ItemDataRole.UserRole + 2
ContainerNodeRole = Qt.UserRole + 3 ContainerNodeRole = Qt.ItemDataRole.UserRole + 3
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)

View File

@ -2,7 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Any, cast, Dict, Optional, TYPE_CHECKING from typing import Any, cast, Dict, Optional, TYPE_CHECKING
from PyQt5.QtCore import pyqtSlot, QObject, Qt, QTimer from PyQt6.QtCore import pyqtSlot, QObject, Qt, QTimer
from UM.Logger import Logger from UM.Logger import Logger
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -29,13 +29,13 @@ if TYPE_CHECKING:
class QualityManagementModel(ListModel): class QualityManagementModel(ListModel):
"""This the QML model for the quality management page.""" """This the QML model for the quality management page."""
NameRole = Qt.UserRole + 1 NameRole = Qt.ItemDataRole.UserRole + 1
IsReadOnlyRole = Qt.UserRole + 2 IsReadOnlyRole = Qt.ItemDataRole.UserRole + 2
QualityGroupRole = Qt.UserRole + 3 QualityGroupRole = Qt.ItemDataRole.UserRole + 3
QualityTypeRole = Qt.UserRole + 4 QualityTypeRole = Qt.ItemDataRole.UserRole + 4
QualityChangesGroupRole = Qt.UserRole + 5 QualityChangesGroupRole = Qt.ItemDataRole.UserRole + 5
IntentCategoryRole = Qt.UserRole + 6 IntentCategoryRole = Qt.ItemDataRole.UserRole + 6
SectionNameRole = Qt.UserRole + 7 SectionNameRole = Qt.ItemDataRole.UserRole + 7
def __init__(self, parent: Optional["QObject"] = None) -> None: def __init__(self, parent: Optional["QObject"] = None) -> None:
super().__init__(parent) super().__init__(parent)

View File

@ -1,7 +1,7 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt, QTimer from PyQt6.QtCore import Qt, QTimer
import cura.CuraApplication # Imported this way to prevent circular dependencies. import cura.CuraApplication # Imported this way to prevent circular dependencies.
from UM.Logger import Logger from UM.Logger import Logger
@ -13,14 +13,14 @@ from cura.Machines.Models.MachineModelUtils import fetchLayerHeight
class QualityProfilesDropDownMenuModel(ListModel): class QualityProfilesDropDownMenuModel(ListModel):
"""QML Model for all built-in quality profiles. This model is used for the drop-down quality menu.""" """QML Model for all built-in quality profiles. This model is used for the drop-down quality menu."""
NameRole = Qt.UserRole + 1 NameRole = Qt.ItemDataRole.UserRole + 1
QualityTypeRole = Qt.UserRole + 2 QualityTypeRole = Qt.ItemDataRole.UserRole + 2
LayerHeightRole = Qt.UserRole + 3 LayerHeightRole = Qt.ItemDataRole.UserRole + 3
LayerHeightUnitRole = Qt.UserRole + 4 LayerHeightUnitRole = Qt.ItemDataRole.UserRole + 4
AvailableRole = Qt.UserRole + 5 AvailableRole = Qt.ItemDataRole.UserRole + 5
QualityGroupRole = Qt.UserRole + 6 QualityGroupRole = Qt.ItemDataRole.UserRole + 6
QualityChangesGroupRole = Qt.UserRole + 7 QualityChangesGroupRole = Qt.ItemDataRole.UserRole + 7
IsExperimentalRole = Qt.UserRole + 8 IsExperimentalRole = Qt.ItemDataRole.UserRole + 8
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)

View File

@ -1,7 +1,7 @@
# Copyright (c) 2022 Ultimaker B.V. # Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt from PyQt6.QtCore import pyqtProperty, pyqtSignal, Qt
from typing import Set from typing import Set
import cura.CuraApplication import cura.CuraApplication
@ -17,13 +17,13 @@ import os
class QualitySettingsModel(ListModel): class QualitySettingsModel(ListModel):
"""This model is used to show details settings of the selected quality in the quality management page.""" """This model is used to show details settings of the selected quality in the quality management page."""
KeyRole = Qt.UserRole + 1 KeyRole = Qt.ItemDataRole.UserRole + 1
LabelRole = Qt.UserRole + 2 LabelRole = Qt.ItemDataRole.UserRole + 2
UnitRole = Qt.UserRole + 3 UnitRole = Qt.ItemDataRole.UserRole + 3
ProfileValueRole = Qt.UserRole + 4 ProfileValueRole = Qt.ItemDataRole.UserRole + 4
ProfileValueSourceRole = Qt.UserRole + 5 ProfileValueSourceRole = Qt.ItemDataRole.UserRole + 5
UserValueRole = Qt.UserRole + 6 UserValueRole = Qt.ItemDataRole.UserRole + 6
CategoryRole = Qt.UserRole + 7 CategoryRole = Qt.ItemDataRole.UserRole + 7
GLOBAL_STACK_POSITION = -1 GLOBAL_STACK_POSITION = -1

View File

@ -3,7 +3,7 @@
from typing import Optional, List from typing import Optional, List
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
from UM.Logger import Logger from UM.Logger import Logger
from UM.Preferences import Preferences from UM.Preferences import Preferences

View File

@ -4,7 +4,7 @@
import os import os
from collections import OrderedDict from collections import OrderedDict
from PyQt5.QtCore import pyqtSlot, Qt from PyQt6.QtCore import pyqtSlot, Qt
from UM.Application import Application from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger
@ -15,12 +15,12 @@ from UM.Qt.ListModel import ListModel
class UserChangesModel(ListModel): class UserChangesModel(ListModel):
KeyRole = Qt.UserRole + 1 KeyRole = Qt.ItemDataRole.UserRole + 1
LabelRole = Qt.UserRole + 2 LabelRole = Qt.ItemDataRole.UserRole + 2
ExtruderRole = Qt.UserRole + 3 ExtruderRole = Qt.ItemDataRole.UserRole + 3
OriginalValueRole = Qt.UserRole + 4 OriginalValueRole = Qt.ItemDataRole.UserRole + 4
UserValueRole = Qt.UserRole + 6 UserValueRole = Qt.ItemDataRole.UserRole + 6
CategoryRole = Qt.UserRole + 7 CategoryRole = Qt.ItemDataRole.UserRole + 7
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent = parent) super().__init__(parent = parent)

View File

@ -3,7 +3,7 @@
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal
class QualityChangesGroup(QObject): class QualityChangesGroup(QObject):

View File

@ -4,7 +4,7 @@
from base64 import b64encode from base64 import b64encode
from datetime import datetime from datetime import datetime
from hashlib import sha512 from hashlib import sha512
from PyQt5.QtNetwork import QNetworkReply from PyQt6.QtNetwork import QNetworkReply
import secrets import secrets
from typing import Callable, Optional from typing import Callable, Optional
import urllib.parse import urllib.parse

View File

@ -6,8 +6,8 @@ from datetime import datetime, timedelta
from typing import Callable, Dict, Optional, TYPE_CHECKING, Union from typing import Callable, Dict, Optional, TYPE_CHECKING, Union
from urllib.parse import urlencode, quote_plus from urllib.parse import urlencode, quote_plus
from PyQt5.QtCore import QUrl from PyQt6.QtCore import QUrl
from PyQt5.QtGui import QDesktopServices from PyQt6.QtGui import QDesktopServices
from UM.Logger import Logger from UM.Logger import Logger
from UM.Message import Message from UM.Message import Message

View File

@ -1,7 +1,7 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QTimer from PyQt6.QtCore import QTimer
from UM.Application import Application from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger

View File

@ -1,6 +1,6 @@
from PyQt5.QtGui import QImage from PyQt6.QtGui import QImage
from PyQt5.QtQuick import QQuickImageProvider from PyQt6.QtQuick import QQuickImageProvider
from PyQt5.QtCore import QSize from PyQt6.QtCore import QSize
from UM.Application import Application from UM.Application import Application
from typing import Tuple from typing import Tuple
@ -8,7 +8,7 @@ from typing import Tuple
class PrintJobPreviewImageProvider(QQuickImageProvider): class PrintJobPreviewImageProvider(QQuickImageProvider):
def __init__(self): def __init__(self):
super().__init__(QQuickImageProvider.Image) super().__init__(QQuickImageProvider.ImageType.Image)
def requestImage(self, id: str, size: QSize) -> Tuple[QImage, QSize]: def requestImage(self, id: str, size: QSize) -> Tuple[QImage, QSize]:
"""Request a new image. """Request a new image.

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QObject, QUrl, pyqtSignal, pyqtProperty from PyQt6.QtCore import QObject, QUrl, pyqtSignal, pyqtProperty
from enum import IntEnum from enum import IntEnum
from threading import Thread from threading import Thread

View File

@ -3,7 +3,7 @@
from typing import TYPE_CHECKING, Set, Union, Optional from typing import TYPE_CHECKING, Set, Union, Optional
from PyQt5.QtCore import QTimer from PyQt6.QtCore import QTimer
from .PrinterOutputController import PrinterOutputController from .PrinterOutputController import PrinterOutputController

View File

@ -2,7 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional from typing import Optional
from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal
from .MaterialOutputModel import MaterialOutputModel from .MaterialOutputModel import MaterialOutputModel

View File

@ -3,7 +3,7 @@
from typing import Optional, TYPE_CHECKING from typing import Optional, TYPE_CHECKING
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot
from .ExtruderConfigurationModel import ExtruderConfigurationModel from .ExtruderConfigurationModel import ExtruderConfigurationModel

View File

@ -3,7 +3,7 @@
from typing import Optional from typing import Optional
from PyQt5.QtCore import pyqtProperty, QObject from PyQt6.QtCore import pyqtProperty, QObject
class MaterialOutputModel(QObject): class MaterialOutputModel(QObject):

View File

@ -3,8 +3,8 @@
from typing import Optional, TYPE_CHECKING, List from typing import Optional, TYPE_CHECKING, List
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot, QUrl from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot, QUrl
from PyQt5.QtGui import QImage from PyQt6.QtGui import QImage
if TYPE_CHECKING: if TYPE_CHECKING:
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
@ -58,7 +58,7 @@ class PrintJobOutputModel(QObject):
# requires a QUrl to function, updates correctly we add an increasing number. This causes to see the QUrl # 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. # 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 temp = "image://print_job_preview/" + str(self._preview_image_id) + "/" + self._key
return QUrl(temp, QUrl.TolerantMode) return QUrl(temp, QUrl.ParsingMode.TolerantMode)
def getPreviewImage(self) -> Optional[QImage]: def getPreviewImage(self) -> Optional[QImage]:
return self._preview_image return self._preview_image
@ -119,16 +119,16 @@ class PrintJobOutputModel(QObject):
@pyqtProperty(int, notify = timeTotalChanged) @pyqtProperty(int, notify = timeTotalChanged)
def timeTotal(self) -> int: def timeTotal(self) -> int:
return self._time_total return int(self._time_total)
@pyqtProperty(int, notify = timeElapsedChanged) @pyqtProperty(int, notify = timeElapsedChanged)
def timeElapsed(self) -> int: def timeElapsed(self) -> int:
return self._time_elapsed return int(self._time_elapsed)
@pyqtProperty(int, notify = timeElapsedChanged) @pyqtProperty(int, notify = timeElapsedChanged)
def timeRemaining(self) -> int: def timeRemaining(self) -> int:
# Never get a negative time remaining # Never get a negative time remaining
return max(self.timeTotal - self.timeElapsed, 0) return int(max(self.timeTotal - self.timeElapsed, 0))
@pyqtProperty(float, notify = timeElapsedChanged) @pyqtProperty(float, notify = timeElapsedChanged)
def progress(self) -> float: def progress(self) -> float:

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal
from typing import List from typing import List
MYPY = False MYPY = False

View File

@ -1,7 +1,7 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot, QUrl from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot, QUrl
from typing import List, Dict, Optional, TYPE_CHECKING from typing import List, Dict, Optional, TYPE_CHECKING
from UM.Math.Vector import Vector from UM.Math.Vector import Vector
from cura.PrinterOutput.Peripheral import Peripheral from cura.PrinterOutput.Peripheral import Peripheral

View File

@ -1,10 +1,10 @@
# Copyright (c) 2018 Aldo Hoeben / fieldOfView # Copyright (c) 2018 Aldo Hoeben / fieldOfView
# NetworkMJPGImage is released under the terms of the LGPLv3 or higher. # NetworkMJPGImage is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QUrl, pyqtProperty, pyqtSignal, pyqtSlot, QRect, QByteArray from PyQt6.QtCore import QUrl, pyqtProperty, pyqtSignal, pyqtSlot, QRect, QByteArray
from PyQt5.QtGui import QImage, QPainter from PyQt6.QtGui import QImage, QPainter
from PyQt5.QtQuick import QQuickPaintedItem from PyQt6.QtQuick import QQuickPaintedItem
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager from PyQt6.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager
from UM.Logger import Logger from UM.Logger import Logger

View File

@ -9,8 +9,8 @@ from cura.CuraApplication import CuraApplication
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType
from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator from PyQt6.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication
from time import time from time import time
from typing import Callable, Dict, List, Optional, Union from typing import Callable, Dict, List, Optional, Union
from enum import IntEnum from enum import IntEnum
@ -146,8 +146,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
url = QUrl("http://" + self._address + self._api_prefix + target) url = QUrl("http://" + self._address + self._api_prefix + target)
request = QNetworkRequest(url) request = QNetworkRequest(url)
if content_type is not None: if content_type is not None:
request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) request.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, content_type)
request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) request.setHeader(QNetworkRequest.KnownHeaders.UserAgentHeader, self._user_agent)
return request return request
def createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart: def createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart:
@ -162,10 +162,10 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
if not content_header.startswith("form-data;"): 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) part.setHeader(QNetworkRequest.KnownHeaders.ContentDispositionHeader, content_header)
if content_type is not None: if content_type is not None:
part.setHeader(QNetworkRequest.ContentTypeHeader, content_type) part.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, content_type)
part.setBody(data) part.setBody(data)
return part return part
@ -290,7 +290,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
on_progress: Optional[Callable[[int, int], None]] = None) -> QNetworkReply: on_progress: Optional[Callable[[int, int], None]] = None) -> QNetworkReply:
self._validateManager() self._validateManager()
request = self._createEmptyRequest(target, content_type=None) request = self._createEmptyRequest(target, content_type=None)
multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType) multi_post_part = QHttpMultiPart(QHttpMultiPart.ContentType.FormDataType)
for part in parts: for part in parts:
multi_post_part.append(part) multi_post_part.append(part)
@ -311,7 +311,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
def postForm(self, target: str, header_data: str, body_data: bytes, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None: def postForm(self, target: str, header_data: str, body_data: bytes, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None:
post_part = QHttpPart() post_part = QHttpPart()
post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data) post_part.setHeader(QNetworkRequest.KnownHeaders.ContentDispositionHeader, header_data)
post_part.setBody(body_data) post_part.setBody(body_data)
self.postFormWithParts(target, [post_part], on_finished, on_progress) self.postFormWithParts(target, [post_part], on_finished, on_progress)
@ -357,10 +357,10 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
def _handleOnFinished(self, reply: QNetworkReply) -> None: def _handleOnFinished(self, reply: QNetworkReply) -> None:
# Due to garbage collection, we need to cache certain bits of post operations. # 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. # As we don't want to keep them around forever, delete them if we get a reply.
if reply.operation() == QNetworkAccessManager.PostOperation: if reply.operation() == QNetworkAccessManager.Operation.PostOperation:
self._clearCachedMultiPart(reply) self._clearCachedMultiPart(reply)
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: if reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) is None:
# No status code means it never even reached remote. # No status code means it never even reached remote.
return return

View File

@ -1,11 +1,11 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from enum import IntEnum from enum import IntEnum
from typing import Callable, List, Optional, Union from typing import Callable, List, Optional, Union
from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl from PyQt6.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl
from PyQt5.QtWidgets import QMessageBox from PyQt6.QtWidgets import QMessageBox
import cura.CuraApplication # Imported like this to prevent circular imports. import cura.CuraApplication # Imported like this to prevent circular imports.
from UM.Logger import Logger from UM.Logger import Logger
@ -137,9 +137,11 @@ class PrinterOutputDevice(QObject, OutputDevice):
""" """
if self.connectionState != connection_state: if self.connectionState != connection_state:
self._connection_state = connection_state self._connection_state = connection_state
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack() application = cura.CuraApplication.CuraApplication.getInstance()
if global_stack: if application is not None: # Might happen during the closing of Cura or in a test.
global_stack.setMetaDataEntry("is_online", self.isConnected()) global_stack = application.getGlobalContainerStack()
if global_stack is not None:
global_stack.setMetaDataEntry("is_online", self.isConnected())
self.connectionStateChanged.emit(self._id) self.connectionStateChanged.emit(self._id)
@pyqtProperty(int, constant = True) @pyqtProperty(int, constant = True)

View File

@ -5,7 +5,7 @@ import enum
import functools # For partial methods to use as callbacks with information pre-filled. import functools # For partial methods to use as callbacks with information pre-filled.
import json # To serialise metadata for API calls. import json # To serialise metadata for API calls.
import os # To delete the archive when we're done. import os # To delete the archive when we're done.
from PyQt5.QtCore import QUrl from PyQt6.QtCore import QUrl
import tempfile # To create an archive before we upload it. import tempfile # To create an archive before we upload it.
import cura.CuraApplication # Imported like this to prevent circular imports. import cura.CuraApplication # Imported like this to prevent circular imports.
@ -21,7 +21,7 @@ from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from PyQt5.QtNetwork import QNetworkReply from PyQt6.QtNetwork import QNetworkReply
from cura.UltimakerCloud.CloudMaterialSync import CloudMaterialSync from cura.UltimakerCloud.CloudMaterialSync import CloudMaterialSync
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")

View File

@ -1,7 +1,7 @@
# Copyright (c) 2020 Ultimaker B.V. # Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QTimer from PyQt6.QtCore import QTimer
from UM.Application import Application from UM.Application import Application
from UM.Math.Polygon import Polygon from UM.Math.Polygon import Polygon
@ -383,9 +383,9 @@ class ConvexHullDecorator(SceneNodeDecorator):
# Shrinkage compensation. # Shrinkage compensation.
if not self._global_stack: # Should never happen. if not self._global_stack: # Should never happen.
return convex_hull return convex_hull
scale_factor = self._global_stack.getProperty("material_shrinkage_percentage", "value") / 100.0 scale_factor = self._global_stack.getProperty("material_shrinkage_percentage_xy", "value") / 100.0
result = convex_hull result = convex_hull
if scale_factor != 1.0 and not self.getNode().callDecoration("isGroup"): if scale_factor != 1.0 and scale_factor > 0 and not self.getNode().callDecoration("isGroup"):
center = None center = None
if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time": if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time":
# Find the root node that's placed in the scene; the root of the mesh group. # Find the root node that's placed in the scene; the root of the mesh group.
@ -498,7 +498,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
"adhesion_type", "raft_margin", "print_sequence", "adhesion_type", "raft_margin", "print_sequence",
"skirt_gap", "skirt_line_count", "skirt_brim_line_width", "skirt_distance", "brim_line_count"] "skirt_gap", "skirt_line_count", "skirt_brim_line_width", "skirt_distance", "brim_line_count"]
_influencing_settings = {"xy_offset", "xy_offset_layer_0", "mold_enabled", "mold_width", "anti_overhang_mesh", "infill_mesh", "cutting_mesh", "material_shrinkage_percentage"} _influencing_settings = {"xy_offset", "xy_offset_layer_0", "mold_enabled", "mold_width", "anti_overhang_mesh", "infill_mesh", "cutting_mesh", "material_shrinkage_percentage_xy"}
"""Settings that change the convex hull. """Settings that change the convex hull.
If these settings change, the convex hull should be recalculated. If these settings change, the convex hull should be recalculated.

View File

@ -1,7 +1,7 @@
from UM.Logger import Logger from UM.Logger import Logger
from PyQt5.QtCore import Qt, pyqtSlot, QObject, QTimer from PyQt6.QtCore import Qt, pyqtSlot, QObject, QTimer
from PyQt5.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication
from UM.Scene.Camera import Camera from UM.Scene.Camera import Camera
from cura.UI.ObjectsModel import ObjectsModel from cura.UI.ObjectsModel import ObjectsModel
@ -107,8 +107,8 @@ class CuraSceneController(QObject):
"""Either select or deselect an item""" """Either select or deselect an item"""
modifiers = QApplication.keyboardModifiers() modifiers = QApplication.keyboardModifiers()
ctrl_is_active = modifiers & Qt.ControlModifier ctrl_is_active = modifiers & Qt.KeyboardModifier.ControlModifier
shift_is_active = modifiers & Qt.ShiftModifier shift_is_active = modifiers & Qt.KeyboardModifier.ShiftModifier
if ctrl_is_active: if ctrl_is_active:
item = self._objects_model.getItem(index) item = self._objects_model.getItem(index)

View File

@ -6,8 +6,8 @@ import urllib.parse
import uuid import uuid
from typing import Any, cast, Dict, List, TYPE_CHECKING, Union from typing import Any, cast, Dict, List, TYPE_CHECKING, Union
from PyQt5.QtCore import QObject, QUrl from PyQt6.QtCore import QObject, QUrl
from PyQt5.QtWidgets import QMessageBox from PyQt6.QtWidgets import QMessageBox
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
@ -47,11 +47,11 @@ class ContainerManager(QObject):
def __init__(self, application: "CuraApplication") -> None: def __init__(self, application: "CuraApplication") -> None:
if ContainerManager.__instance is not None: if ContainerManager.__instance is not None:
raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__) raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__)
ContainerManager.__instance = self
try: try:
super().__init__(parent = application) super().__init__(parent = application)
except TypeError: except TypeError:
super().__init__() super().__init__()
ContainerManager.__instance = self
self._container_name_filters = {} # type: Dict[str, Dict[str, Any]] self._container_name_filters = {} # type: Dict[str, Dict[str, Any]]
@ -206,7 +206,7 @@ class ContainerManager(QObject):
if os.path.exists(file_url): if os.path.exists(file_url):
result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"), result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"),
catalog.i18nc("@label Don't translate the XML tag <filename>!", "The file <filename>{0}</filename> already exists. Are you sure you want to overwrite it?").format(file_url)) catalog.i18nc("@label Don't translate the XML tag <filename>!", "The file <filename>{0}</filename> already exists. Are you sure you want to overwrite it?").format(file_url))
if result == QMessageBox.No: if result == QMessageBox.StandardButton.No:
return {"status": "cancelled", "message": "User cancelled"} return {"status": "cancelled", "message": "User cancelled"}
try: try:

View File

@ -6,7 +6,7 @@ import re
import configparser import configparser
from typing import Any, cast, Dict, Optional, List, Union, Tuple from typing import Any, cast, Dict, Optional, List, Union, Tuple
from PyQt5.QtWidgets import QMessageBox from PyQt6.QtWidgets import QMessageBox
from UM.Decorators import override from UM.Decorators import override
from UM.Settings.ContainerFormatError import ContainerFormatError from UM.Settings.ContainerFormatError import ContainerFormatError
@ -139,7 +139,7 @@ class CuraContainerRegistry(ContainerRegistry):
if os.path.exists(file_name): if os.path.exists(file_name):
result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"), result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"),
catalog.i18nc("@label Don't translate the XML tag <filename>!", "The file <filename>{0}</filename> already exists. Are you sure you want to overwrite it?").format(file_name)) catalog.i18nc("@label Don't translate the XML tag <filename>!", "The file <filename>{0}</filename> already exists. Are you sure you want to overwrite it?").format(file_name))
if result == QMessageBox.No: if result == QMessageBox.StandardButton.No:
return False return False
profile_writer = self._findProfileWriter(extension, description) profile_writer = self._findProfileWriter(extension, description)

View File

@ -2,7 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Any, cast, List, Optional, Dict from typing import Any, cast, List, Optional, Dict
from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject from PyQt6.QtCore import pyqtProperty, pyqtSignal, QObject
from UM.Application import Application from UM.Application import Application
from UM.Decorators import override from UM.Decorators import override
@ -75,7 +75,7 @@ class CuraContainerStack(ContainerStack):
self.replaceContainer(_ContainerIndexes.UserChanges, new_user_changes) self.replaceContainer(_ContainerIndexes.UserChanges, new_user_changes)
@pyqtProperty(InstanceContainer, fset = setUserChanges, notify = pyqtContainersChanged) @pyqtProperty(QObject, fset = setUserChanges, notify = pyqtContainersChanged)
def userChanges(self) -> InstanceContainer: def userChanges(self) -> InstanceContainer:
"""Get the user changes container. """Get the user changes container.
@ -92,7 +92,7 @@ class CuraContainerStack(ContainerStack):
self.replaceContainer(_ContainerIndexes.QualityChanges, new_quality_changes, postpone_emit = postpone_emit) self.replaceContainer(_ContainerIndexes.QualityChanges, new_quality_changes, postpone_emit = postpone_emit)
@pyqtProperty(InstanceContainer, fset = setQualityChanges, notify = pyqtContainersChanged) @pyqtProperty(QObject, fset = setQualityChanges, notify = pyqtContainersChanged)
def qualityChanges(self) -> InstanceContainer: def qualityChanges(self) -> InstanceContainer:
"""Get the quality changes container. """Get the quality changes container.
@ -109,7 +109,7 @@ class CuraContainerStack(ContainerStack):
self.replaceContainer(_ContainerIndexes.Intent, new_intent, postpone_emit = postpone_emit) self.replaceContainer(_ContainerIndexes.Intent, new_intent, postpone_emit = postpone_emit)
@pyqtProperty(InstanceContainer, fset = setIntent, notify = pyqtContainersChanged) @pyqtProperty(QObject, fset = setIntent, notify = pyqtContainersChanged)
def intent(self) -> InstanceContainer: def intent(self) -> InstanceContainer:
"""Get the quality container. """Get the quality container.
@ -126,7 +126,7 @@ class CuraContainerStack(ContainerStack):
self.replaceContainer(_ContainerIndexes.Quality, new_quality, postpone_emit = postpone_emit) self.replaceContainer(_ContainerIndexes.Quality, new_quality, postpone_emit = postpone_emit)
@pyqtProperty(InstanceContainer, fset = setQuality, notify = pyqtContainersChanged) @pyqtProperty(QObject, fset = setQuality, notify = pyqtContainersChanged)
def quality(self) -> InstanceContainer: def quality(self) -> InstanceContainer:
"""Get the quality container. """Get the quality container.
@ -143,7 +143,7 @@ class CuraContainerStack(ContainerStack):
self.replaceContainer(_ContainerIndexes.Material, new_material, postpone_emit = postpone_emit) self.replaceContainer(_ContainerIndexes.Material, new_material, postpone_emit = postpone_emit)
@pyqtProperty(InstanceContainer, fset = setMaterial, notify = pyqtContainersChanged) @pyqtProperty(QObject, fset = setMaterial, notify = pyqtContainersChanged)
def material(self) -> InstanceContainer: def material(self) -> InstanceContainer:
"""Get the material container. """Get the material container.
@ -160,7 +160,7 @@ class CuraContainerStack(ContainerStack):
self.replaceContainer(_ContainerIndexes.Variant, new_variant) self.replaceContainer(_ContainerIndexes.Variant, new_variant)
@pyqtProperty(InstanceContainer, fset = setVariant, notify = pyqtContainersChanged) @pyqtProperty(QObject, fset = setVariant, notify = pyqtContainersChanged)
def variant(self) -> InstanceContainer: def variant(self) -> InstanceContainer:
"""Get the variant container. """Get the variant container.
@ -177,7 +177,7 @@ class CuraContainerStack(ContainerStack):
self.replaceContainer(_ContainerIndexes.DefinitionChanges, new_definition_changes) self.replaceContainer(_ContainerIndexes.DefinitionChanges, new_definition_changes)
@pyqtProperty(InstanceContainer, fset = setDefinitionChanges, notify = pyqtContainersChanged) @pyqtProperty(QObject, fset = setDefinitionChanges, notify = pyqtContainersChanged)
def definitionChanges(self) -> InstanceContainer: def definitionChanges(self) -> InstanceContainer:
"""Get the definition changes container. """Get the definition changes container.

View File

@ -17,7 +17,7 @@ class CuraStackBuilder:
"""Contains helper functions to create new machines.""" """Contains helper functions to create new machines."""
@classmethod @classmethod
def createMachine(cls, name: str, definition_id: str, machine_extruder_count: Optional[int] = None) -> Optional[GlobalStack]: def createMachine(cls, name: str, definition_id: str, machine_extruder_count: Optional[int] = None, show_warning_message: bool = True) -> Optional[GlobalStack]:
"""Create a new instance of a machine. """Create a new instance of a machine.
:param name: The name of the new machine. :param name: The name of the new machine.
@ -34,7 +34,8 @@ class CuraStackBuilder:
definitions = registry.findDefinitionContainers(id = definition_id) definitions = registry.findDefinitionContainers(id = definition_id)
if not definitions: if not definitions:
ConfigurationErrorMessage.getInstance().addFaultyContainers(definition_id) if show_warning_message:
ConfigurationErrorMessage.getInstance().addFaultyContainers(definition_id)
Logger.log("w", "Definition {definition} was not found!", definition = definition_id) Logger.log("w", "Definition {definition} was not found!", definition = definition_id)
return None return None

View File

@ -1,7 +1,7 @@
# Copyright (c) 2020 Ultimaker B.V. # Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # 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. from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt.
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
import cura.CuraApplication # To get the global container stack to find the current machine. import cura.CuraApplication # To get the global container stack to find the current machine.
@ -31,9 +31,9 @@ class ExtruderManager(QObject):
if ExtruderManager.__instance is not None: if ExtruderManager.__instance is not None:
raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__) raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__)
ExtruderManager.__instance = self
super().__init__(parent) super().__init__(parent)
ExtruderManager.__instance = self
self._application = cura.CuraApplication.CuraApplication.getInstance() self._application = cura.CuraApplication.CuraApplication.getInstance()

View File

@ -3,7 +3,7 @@
from typing import Any, Dict, TYPE_CHECKING, Optional from typing import Any, Dict, TYPE_CHECKING, Optional
from PyQt5.QtCore import pyqtProperty, pyqtSignal from PyQt6.QtCore import pyqtProperty, pyqtSignal
from UM.Decorators import override from UM.Decorators import override
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase

View File

@ -6,7 +6,7 @@ import threading
from typing import Any, Dict, Optional, Set, TYPE_CHECKING, List from typing import Any, Dict, Optional, Set, TYPE_CHECKING, List
import uuid import uuid
from PyQt5.QtCore import pyqtProperty, pyqtSlot, pyqtSignal from PyQt6.QtCore import pyqtProperty, pyqtSlot, pyqtSignal
from UM.Decorators import deprecated, override from UM.Decorators import deprecated, override
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase

View File

@ -1,7 +1,7 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
from typing import Any, Dict, List, Set, Tuple, TYPE_CHECKING from typing import Any, Dict, List, Set, Tuple, TYPE_CHECKING
from UM.Logger import Logger from UM.Logger import Logger

View File

@ -6,7 +6,7 @@ import re
import unicodedata import unicodedata
from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast, Set from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast, Set
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator

View File

@ -1,8 +1,8 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2021 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtSlot, pyqtProperty, QObject, pyqtSignal, QRegExp from PyQt6.QtCore import pyqtSlot, pyqtProperty, QObject, pyqtSignal
from PyQt5.QtGui import QValidator from PyQt6.QtGui import QValidator
import os #For statvfs. import os #For statvfs.
import urllib #To escape machine names for how they're saved to file. import urllib #To escape machine names for how they're saved to file.
@ -65,6 +65,6 @@ class MachineNameValidator(QObject):
self.validation_regex = "a^" #Never matches (unless you manage to get "a" before the start of the string... good luck). self.validation_regex = "a^" #Never matches (unless you manage to get "a" before the start of the string... good luck).
self.validationChanged.emit() self.validationChanged.emit()
@pyqtProperty("QRegExp", notify=validationChanged) @pyqtProperty(str, notify=validationChanged)
def machineNameRegex(self): def machineNameRegex(self):
return QRegExp(self.machine_name_regex) return str(self.machine_name_regex)

View File

@ -2,7 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import List, Optional, TYPE_CHECKING from typing import List, Optional, TYPE_CHECKING
from PyQt5.QtCore import QObject, QTimer, pyqtProperty, pyqtSignal from PyQt6.QtCore import QObject, QTimer, pyqtProperty, pyqtSignal
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
from UM.Application import Application from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger

View File

@ -3,7 +3,7 @@ import urllib.parse
from configparser import ConfigParser from configparser import ConfigParser
from typing import List from typing import List
from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal
from UM.Logger import Logger from UM.Logger import Logger
from UM.MimeTypeDatabase import MimeTypeDatabase from UM.MimeTypeDatabase import MimeTypeDatabase

View File

@ -4,14 +4,14 @@
from typing import Any from typing import Any
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
from PyQt5.QtCore import pyqtSlot, Qt from PyQt6.QtCore import pyqtSlot, Qt
class SidebarCustomMenuItemsModel(ListModel): class SidebarCustomMenuItemsModel(ListModel):
name_role = Qt.UserRole + 1 name_role = Qt.ItemDataRole.UserRole + 1
actions_role = Qt.UserRole + 2 actions_role = Qt.ItemDataRole.UserRole + 2
menu_item_role = Qt.UserRole + 3 menu_item_role = Qt.ItemDataRole.UserRole + 3
menu_item_icon_name_role = Qt.UserRole + 5 menu_item_icon_name_role = Qt.ItemDataRole.UserRole + 5
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)

View File

@ -1,7 +1,7 @@
# Copyright (c) 2017 Ultimaker B.V. # Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty
from UM.Application import Application from UM.Application import Application

View File

@ -5,7 +5,7 @@ import json
import os import os
from typing import List, Optional from typing import List, Optional
from PyQt5.QtNetwork import QLocalServer, QLocalSocket from PyQt6.QtNetwork import QLocalServer, QLocalSocket
from UM.Qt.QtApplication import QtApplication #For typing. from UM.Qt.QtApplication import QtApplication #For typing.
from UM.Logger import Logger from UM.Logger import Logger
@ -29,7 +29,7 @@ class SingleInstance:
single_instance_socket.connectToServer("ultimaker-cura") single_instance_socket.connectToServer("ultimaker-cura")
single_instance_socket.waitForConnected(msecs = 3000) # wait for 3 seconds single_instance_socket.waitForConnected(msecs = 3000) # wait for 3 seconds
if single_instance_socket.state() != QLocalSocket.ConnectedState: if single_instance_socket.state() != QLocalSocket.LocalSocketState.ConnectedState:
return False return False
# We only send the files that need to be opened. # We only send the files that need to be opened.
@ -37,7 +37,7 @@ class SingleInstance:
Logger.log("i", "No file need to be opened, do nothing.") Logger.log("i", "No file need to be opened, do nothing.")
return True return True
if single_instance_socket.state() == QLocalSocket.ConnectedState: if single_instance_socket.state() == QLocalSocket.LocalSocketState.ConnectedState:
Logger.log("i", "Connection has been made to the single-instance Cura socket.") Logger.log("i", "Connection has been made to the single-instance Cura socket.")
# Protocol is one line of JSON terminated with a carriage return. # Protocol is one line of JSON terminated with a carriage return.

View File

@ -2,10 +2,11 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import numpy import numpy
from PyQt5 import QtCore from PyQt6 import QtCore
from PyQt5.QtCore import QCoreApplication from PyQt6.QtCore import QCoreApplication
from PyQt5.QtGui import QImage from PyQt6.QtGui import QImage
from UM.Logger import Logger
from cura.PreviewPass import PreviewPass from cura.PreviewPass import PreviewPass
from UM.Application import Application from UM.Application import Application
@ -20,7 +21,7 @@ class Snapshot:
def getImageBoundaries(image: QImage): def getImageBoundaries(image: QImage):
# Look at the resulting image to get a good crop. # Look at the resulting image to get a good crop.
# Get the pixels as byte array # Get the pixels as byte array
pixel_array = image.bits().asarray(image.byteCount()) pixel_array = image.bits().asarray(image.sizeInBytes())
width, height = image.width(), image.height() width, height = image.width(), image.height()
# Convert to numpy array, assume it's 32 bit (it should always be) # Convert to numpy array, assume it's 32 bit (it should always be)
pixels = numpy.frombuffer(pixel_array, dtype=numpy.uint8).reshape([height, width, 4]) pixels = numpy.frombuffer(pixel_array, dtype=numpy.uint8).reshape([height, width, 4])
@ -64,6 +65,7 @@ class Snapshot:
bbox = bbox + node.getBoundingBox() bbox = bbox + node.getBoundingBox()
# If there is no bounding box, it means that there is no model in the buildplate # If there is no bounding box, it means that there is no model in the buildplate
if bbox is None: if bbox is None:
Logger.log("w", "Unable to create snapshot as we seem to have an empty buildplate")
return None return None
look_at = bbox.center look_at = bbox.center
@ -96,6 +98,7 @@ class Snapshot:
try: try:
min_x, max_x, min_y, max_y = Snapshot.getImageBoundaries(pixel_output) min_x, max_x, min_y, max_y = Snapshot.getImageBoundaries(pixel_output)
except (ValueError, AttributeError): except (ValueError, AttributeError):
Logger.logException("w", "Failed to crop the snapshot!")
return None return None
size = max((max_x - min_x) / render_width, (max_y - min_y) / render_height) size = max((max_x - min_x) / render_width, (max_y - min_y) / render_height)
@ -117,7 +120,7 @@ class Snapshot:
# Scale it to the correct size # Scale it to the correct size
scaled_image = cropped_image.scaled( scaled_image = cropped_image.scaled(
width, height, width, height,
aspectRatioMode = QtCore.Qt.IgnoreAspectRatio, aspectRatioMode = QtCore.Qt.AspectRatioMode.IgnoreAspectRatio,
transformMode = QtCore.Qt.SmoothTransformation) transformMode = QtCore.Qt.TransformationMode.SmoothTransformation)
return scaled_image return scaled_image

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, QUrl from PyQt6.QtCore import pyqtProperty, QUrl
from UM.Stage import Stage from UM.Stage import Stage

View File

@ -1,9 +1,9 @@
# Copyright (c) 2020 Ultimaker B.V. # Copyright (c) 2020 Ultimaker B.V.
# Uranium is released under the terms of the LGPLv3 or higher. # Uranium is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt, QCoreApplication, QTimer from PyQt6.QtCore import Qt, QCoreApplication, QTimer
from PyQt5.QtGui import QPixmap, QColor, QFont, QPen, QPainter from PyQt6.QtGui import QPixmap, QColor, QFont, QPen, QPainter
from PyQt5.QtWidgets import QSplashScreen from PyQt6.QtWidgets import QSplashScreen
from UM.Resources import Resources from UM.Resources import Resources
from UM.Application import Application from UM.Application import Application
@ -63,8 +63,8 @@ class CuraSplashScreen(QSplashScreen):
painter.save() painter.save()
painter.setPen(QColor(255, 255, 255, 255)) painter.setPen(QColor(255, 255, 255, 255))
painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.RenderHint.Antialiasing)
painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
version = Application.getInstance().getVersion().split("-") version = Application.getInstance().getVersion().split("-")
@ -74,9 +74,9 @@ class CuraSplashScreen(QSplashScreen):
painter.setFont(font) painter.setFont(font)
if len(version) == 1: if len(version) == 1:
painter.drawText(40, 104 + self._version_y_offset, round(330 * self._scale), round(230 * self._scale), Qt.AlignLeft | Qt.AlignTop, version[0] if not ApplicationMetadata.IsAlternateVersion else ApplicationMetadata.CuraBuildType) painter.drawText(40, 104 + self._version_y_offset, round(330 * self._scale), round(230 * self._scale), Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop, version[0] if not ApplicationMetadata.IsAlternateVersion else ApplicationMetadata.CuraBuildType)
elif len(version) > 1: elif len(version) > 1:
painter.drawText(40, 104 + self._version_y_offset, round(330 * self._scale), round(230 * self._scale), Qt.AlignLeft | Qt.AlignTop, version[0] +" "+ version[1] if not ApplicationMetadata.IsAlternateVersion else ApplicationMetadata.CuraBuildType) painter.drawText(40, 104 + self._version_y_offset, round(330 * self._scale), round(230 * self._scale), Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop, f"{version[0]}-{version[1]}" if not ApplicationMetadata.IsAlternateVersion else ApplicationMetadata.CuraBuildType)
# Draw the loading image # Draw the loading image
pen = QPen() pen = QPen()
@ -93,8 +93,8 @@ class CuraSplashScreen(QSplashScreen):
pen.setColor(QColor(255, 255, 255, 255)) pen.setColor(QColor(255, 255, 255, 255))
painter.setPen(pen) painter.setPen(pen)
painter.setFont(font) painter.setFont(font)
painter.drawText(70, 320, 170, 24, painter.drawText(70, 308, 170, 48,
Qt.AlignLeft | Qt.AlignVCenter | Qt.TextWordWrap, Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter | Qt.TextFlag.TextWordWrap,
self._current_message) self._current_message)
painter.restore() painter.restore()
@ -106,7 +106,7 @@ class CuraSplashScreen(QSplashScreen):
self._current_message = message self._current_message = message
self.messageChanged.emit(message) self.messageChanged.emit(message)
QCoreApplication.flush() QCoreApplication.processEvents() # Used to be .flush() -- this might be the closest alternative, but uncertain.
self.repaint() self.repaint()
def close(self): def close(self):

View File

@ -3,7 +3,7 @@
from typing import TYPE_CHECKING, Optional, List, Set, Dict from typing import TYPE_CHECKING, Optional, List, Set, Dict
from PyQt5.QtCore import QObject from PyQt6.QtCore import QObject
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
from UM.Logger import Logger from UM.Logger import Logger

View File

@ -2,7 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional, TYPE_CHECKING from typing import Optional, TYPE_CHECKING
from PyQt5.QtCore import QObject, pyqtSlot from PyQt6.QtCore import QObject, pyqtSlot
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog

View File

@ -4,7 +4,7 @@ from UM.Logger import Logger
import re import re
from typing import Dict, List, Optional, Union from typing import Dict, List, Optional, Union
from PyQt5.QtCore import QTimer, Qt from PyQt6.QtCore import QTimer, Qt
from UM.Application import Application from UM.Application import Application
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -34,14 +34,14 @@ class _NodeInfo:
class ObjectsModel(ListModel): class ObjectsModel(ListModel):
"""Keep track of all objects in the project""" """Keep track of all objects in the project"""
NameRole = Qt.UserRole + 1 NameRole = Qt.ItemDataRole.UserRole + 1
SelectedRole = Qt.UserRole + 2 SelectedRole = Qt.ItemDataRole.UserRole + 2
OutsideAreaRole = Qt.UserRole + 3 OutsideAreaRole = Qt.ItemDataRole.UserRole + 3
BuilplateNumberRole = Qt.UserRole + 4 BuilplateNumberRole = Qt.ItemDataRole.UserRole + 4
NodeRole = Qt.UserRole + 5 NodeRole = Qt.ItemDataRole.UserRole + 5
PerObjectSettingsCountRole = Qt.UserRole + 6 PerObjectSettingsCountRole = Qt.ItemDataRole.UserRole + 6
MeshTypeRole = Qt.UserRole + 7 MeshTypeRole = Qt.ItemDataRole.UserRole + 7
ExtruderNumberRole = Qt.UserRole + 8 ExtruderNumberRole = Qt.ItemDataRole.UserRole + 8
def __init__(self, parent = None) -> None: def __init__(self, parent = None) -> None:
super().__init__(parent) super().__init__(parent)

View File

@ -6,7 +6,7 @@ import math
import os import os
from typing import Dict, List, Optional, TYPE_CHECKING from typing import Dict, List, Optional, TYPE_CHECKING
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot, QTimer from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot, QTimer
from UM.Logger import Logger from UM.Logger import Logger
from UM.Qt.Duration import Duration from UM.Qt.Duration import Duration
@ -132,7 +132,7 @@ class PrintInformation(QObject):
self._updateJobName() self._updateJobName()
self.preSlicedChanged.emit() self.preSlicedChanged.emit()
@pyqtProperty(Duration, notify = currentPrintTimeChanged) @pyqtProperty(QObject, notify = currentPrintTimeChanged)
def currentPrintTime(self) -> Duration: def currentPrintTime(self) -> Duration:
return self._current_print_time[self._active_build_plate] return self._current_print_time[self._active_build_plate]

View File

@ -1,7 +1,7 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import QObject, pyqtSlot from PyQt6.QtCore import QObject, pyqtSlot
from cura import CuraApplication from cura import CuraApplication

View File

@ -4,7 +4,7 @@
import collections import collections
from typing import Optional, Dict, List, cast from typing import Optional, Dict, List, cast
from PyQt5.QtCore import QObject, pyqtSlot from PyQt6.QtCore import QObject, pyqtSlot
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Resources import Resources from UM.Resources import Resources

View File

@ -6,7 +6,7 @@ import os
from collections import deque from collections import deque
from typing import TYPE_CHECKING, Optional, List, Dict, Any from typing import TYPE_CHECKING, Optional, List, Dict, Any
from PyQt5.QtCore import QUrl, Qt, pyqtSlot, pyqtProperty, pyqtSignal from PyQt6.QtCore import QUrl, Qt, pyqtSlot, pyqtProperty, pyqtSignal
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Logger import Logger from UM.Logger import Logger
@ -14,7 +14,7 @@ from UM.Qt.ListModel import ListModel
from UM.Resources import Resources from UM.Resources import Resources
if TYPE_CHECKING: if TYPE_CHECKING:
from PyQt5.QtCore import QObject from PyQt6.QtCore import QObject
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
@ -36,11 +36,11 @@ class WelcomePagesModel(ListModel):
Note that in any case, a page that has its "should_show_function" == False will ALWAYS be skipped. Note that in any case, a page that has its "should_show_function" == False will ALWAYS be skipped.
""" """
IdRole = Qt.UserRole + 1 # Page ID IdRole = Qt.ItemDataRole.UserRole + 1 # Page ID
PageUrlRole = Qt.UserRole + 2 # URL to the page's QML file PageUrlRole = Qt.ItemDataRole.UserRole + 2 # URL to the page's QML file
NextPageIdRole = Qt.UserRole + 3 # The next page ID it should go to NextPageIdRole = Qt.ItemDataRole.UserRole + 3 # The next page ID it should go to
NextPageButtonTextRole = Qt.UserRole + 4 # The text for the next page button NextPageButtonTextRole = Qt.ItemDataRole.UserRole + 4 # The text for the next page button
PreviousPageButtonTextRole = Qt.UserRole + 5 # The text for the previous page button PreviousPageButtonTextRole = Qt.ItemDataRole.UserRole + 5 # The text for the previous page button
def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None: def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
super().__init__(parent) super().__init__(parent)

View File

@ -4,7 +4,7 @@
import os import os
from typing import Optional, Dict, List, Tuple, TYPE_CHECKING from typing import Optional, Dict, List, Tuple, TYPE_CHECKING
from PyQt5.QtCore import pyqtProperty, pyqtSlot from PyQt6.QtCore import pyqtProperty, pyqtSlot
from UM.Logger import Logger from UM.Logger import Logger
from UM.Resources import Resources from UM.Resources import Resources
@ -12,7 +12,7 @@ from UM.Resources import Resources
from cura.UI.WelcomePagesModel import WelcomePagesModel from cura.UI.WelcomePagesModel import WelcomePagesModel
if TYPE_CHECKING: if TYPE_CHECKING:
from PyQt5.QtCore import QObject from PyQt6.QtCore import QObject
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication

View File

@ -1,8 +1,8 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2021 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl
from PyQt5.QtGui import QDesktopServices from PyQt6.QtGui import QDesktopServices
from typing import Dict, Optional, TYPE_CHECKING from typing import Dict, Optional, TYPE_CHECKING
import zipfile # To export all materials in a .zip archive. import zipfile # To export all materials in a .zip archive.

View File

@ -1,7 +1,7 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2021 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtNetwork import QNetworkRequest from PyQt6.QtNetwork import QNetworkRequest
from UM.Logger import Logger from UM.Logger import Logger
from UM.TaskManagement.HttpRequestScope import DefaultUserAgentScope from UM.TaskManagement.HttpRequestScope import DefaultUserAgentScope

View File

@ -4,7 +4,7 @@
import socket import socket
from typing import Optional from typing import Optional
from PyQt5.QtCore import QObject, pyqtSlot from PyQt6.QtCore import QObject, pyqtSlot
# #

View File

@ -19,7 +19,7 @@ if sys.platform != "linux": # Turns out the Linux build _does_ use this, but we
os.environ["QT_PLUGIN_PATH"] = "" # Security workaround: Don't need it, and introduces an attack vector, so set to nul. os.environ["QT_PLUGIN_PATH"] = "" # Security workaround: Don't need it, and introduces an attack vector, so set to nul.
os.environ["QML2_IMPORT_PATH"] = "" # Security workaround: Don't need it, and introduces an attack vector, so set to nul. os.environ["QML2_IMPORT_PATH"] = "" # Security workaround: Don't need it, and introduces an attack vector, so set to nul.
from PyQt5.QtNetwork import QSslConfiguration, QSslSocket from PyQt6.QtNetwork import QSslConfiguration, QSslSocket
from UM.Platform import Platform from UM.Platform import Platform
from cura import ApplicationMetadata from cura import ApplicationMetadata
@ -151,15 +151,15 @@ def exceptHook(hook_type, value, traceback):
# The flag "CuraApplication.Created" is set to True when CuraApplication finishes its constructor call. # The flag "CuraApplication.Created" is set to True when CuraApplication finishes its constructor call.
# #
# Before the "started" flag is set to True, the Qt event loop has not started yet. The event loop is a blocking # Before the "started" flag is set to True, the Qt event loop has not started yet. The event loop is a blocking
# call to the QApplication.exec_(). In this case, we need to: # call to the QApplication.exec(). In this case, we need to:
# 1. Remove all scheduled events so no more unnecessary events will be processed, such as loading the main dialog, # 1. Remove all scheduled events so no more unnecessary events will be processed, such as loading the main dialog,
# loading the machine, etc. # loading the machine, etc.
# 2. Start the Qt event loop with exec_() and show the Crash Dialog. # 2. Start the Qt event loop with exec() and show the Crash Dialog.
# #
# If the application has finished its initialization and was running fine, and then something causes a crash, # If the application has finished its initialization and was running fine, and then something causes a crash,
# we run the old routine to show the Crash Dialog. # we run the old routine to show the Crash Dialog.
# #
from PyQt5.Qt import QApplication from PyQt6.QtWidgets import QApplication
if CuraApplication.Created: if CuraApplication.Created:
_crash_handler = CrashHandler(hook_type, value, traceback, has_started) _crash_handler = CrashHandler(hook_type, value, traceback, has_started)
if CuraApplication.splash is not None: if CuraApplication.splash is not None:
@ -167,7 +167,7 @@ def exceptHook(hook_type, value, traceback):
if not has_started: if not has_started:
CuraApplication.getInstance().removePostedEvents(None) CuraApplication.getInstance().removePostedEvents(None)
_crash_handler.early_crash_dialog.show() _crash_handler.early_crash_dialog.show()
sys.exit(CuraApplication.getInstance().exec_()) sys.exit(CuraApplication.getInstance().exec())
else: else:
_crash_handler.show() _crash_handler.show()
else: else:
@ -178,7 +178,7 @@ def exceptHook(hook_type, value, traceback):
if CuraApplication.splash is not None: if CuraApplication.splash is not None:
CuraApplication.splash.close() CuraApplication.splash.close()
_crash_handler.early_crash_dialog.show() _crash_handler.early_crash_dialog.show()
sys.exit(application.exec_()) sys.exit(application.exec())
# Set exception hook to use the crash dialog handler # Set exception hook to use the crash dialog handler
@ -231,7 +231,7 @@ if Platform.isLinux():
if ApplicationMetadata.CuraDebugMode: if ApplicationMetadata.CuraDebugMode:
ssl_conf = QSslConfiguration.defaultConfiguration() ssl_conf = QSslConfiguration.defaultConfiguration()
ssl_conf.setPeerVerifyMode(QSslSocket.VerifyNone) ssl_conf.setPeerVerifyMode(QSslSocket.PeerVerifyMode.VerifyNone)
QSslConfiguration.setDefaultConfiguration(ssl_conf) QSslConfiguration.setDefaultConfiguration(ssl_conf)
app = CuraApplication() app = CuraApplication()

View File

@ -1,11 +1,11 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2021-2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import os.path import os.path
import zipfile import zipfile
from typing import List, Optional, Union, TYPE_CHECKING, cast from typing import List, Optional, Union, TYPE_CHECKING, cast
import Savitar import pySavitar as Savitar
import numpy import numpy
from UM.Logger import Logger from UM.Logger import Logger
@ -304,4 +304,4 @@ class ThreeMFReader(MeshReader):
unit = "millimeter" unit = "millimeter"
scale = conversion_to_mm[unit] scale = conversion_to_mm[unit]
return Vector(scale, scale, scale) return Vector(scale, scale, scale)

View File

@ -34,7 +34,7 @@ from cura.Settings.CuraContainerStack import _ContainerIndexes
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
from cura.Utils.Threading import call_on_qt_thread from cura.Utils.Threading import call_on_qt_thread
from PyQt5.QtCore import QCoreApplication from PyQt6.QtCore import QCoreApplication
from .WorkspaceDialog import WorkspaceDialog from .WorkspaceDialog import WorkspaceDialog

View File

@ -3,7 +3,7 @@
from typing import Dict, List from typing import Dict, List
from PyQt5.QtCore import Qt from PyQt6.QtCore import Qt
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
from cura.Settings.GlobalStack import GlobalStack from cura.Settings.GlobalStack import GlobalStack
@ -25,10 +25,10 @@ class UpdatableMachinesModel(ListModel):
def __init__(self, parent = None) -> None: def __init__(self, parent = None) -> None:
super().__init__(parent) super().__init__(parent)
self.addRoleName(Qt.UserRole + 1, "id") self.addRoleName(Qt.ItemDataRole.UserRole + 1, "id")
self.addRoleName(Qt.UserRole + 2, "name") self.addRoleName(Qt.ItemDataRole.UserRole + 2, "name")
self.addRoleName(Qt.UserRole + 3, "displayName") self.addRoleName(Qt.ItemDataRole.UserRole + 3, "displayName")
self.addRoleName(Qt.UserRole + 4, "type") # Either "default_option" or "machine" self.addRoleName(Qt.ItemDataRole.UserRole + 4, "type") # Either "default_option" or "machine"
def update(self, machines: List[GlobalStack]) -> None: def update(self, machines: List[GlobalStack]) -> None:
items = [create_new_list_item] # type: List[Dict[str, str]] items = [create_new_list_item] # type: List[Dict[str, str]]

View File

@ -2,7 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import List, Optional, Dict, cast from typing import List, Optional, Dict, cast
from PyQt5.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication from PyQt6.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry
from UM.Application import Application from UM.Application import Application

View File

@ -426,7 +426,7 @@ UM.Dialog
width: parent.width width: parent.width
height: childrenRect.height height: childrenRect.height
visible: manager.hasObjectsOnPlate visible: manager.hasObjectsOnPlate
UM.RecolorImage UM.ColorImage
{ {
width: warningLabel.height width: warningLabel.height
height: width height: width

View File

@ -3,6 +3,6 @@
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.1", "version": "1.0.1",
"description": "Provides support for reading 3MF files.", "description": "Provides support for reading 3MF files.",
"api": 7, "api": 8,
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View File

@ -1,5 +1,5 @@
# Copyright (c) 2015 Ultimaker B.V. # Copyright (c) 2015-2022 Ultimaker B.V.
# Uranium is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional from typing import Optional
from UM.Mesh.MeshWriter import MeshWriter from UM.Mesh.MeshWriter import MeshWriter
@ -13,9 +13,9 @@ from cura.CuraApplication import CuraApplication
from cura.Utils.Threading import call_on_qt_thread from cura.Utils.Threading import call_on_qt_thread
from cura.Snapshot import Snapshot from cura.Snapshot import Snapshot
from PyQt5.QtCore import QBuffer from PyQt6.QtCore import QBuffer
import Savitar import pySavitar as Savitar
import numpy import numpy
import datetime import datetime
@ -157,7 +157,7 @@ class ThreeMFWriter(MeshWriter):
snapshot = self._createSnapshot() snapshot = self._createSnapshot()
if snapshot: if snapshot:
thumbnail_buffer = QBuffer() thumbnail_buffer = QBuffer()
thumbnail_buffer.open(QBuffer.ReadWrite) thumbnail_buffer.open(QBuffer.OpenModeFlag.ReadWrite)
snapshot.save(thumbnail_buffer, "PNG") snapshot.save(thumbnail_buffer, "PNG")
thumbnail_file = zipfile.ZipInfo("Metadata/thumbnail.png") thumbnail_file = zipfile.ZipInfo("Metadata/thumbnail.png")

View File

@ -5,21 +5,23 @@ import sys
from UM.Logger import Logger from UM.Logger import Logger
try: try:
from . import ThreeMFWriter from . import ThreeMFWriter
threemf_writer_was_imported = True
except ImportError: except ImportError:
Logger.log("w", "Could not import ThreeMFWriter; libSavitar may be missing") Logger.log("w", "Could not import ThreeMFWriter; libSavitar may be missing")
from . import ThreeMFWorkspaceWriter threemf_writer_was_imported = False
from . import ThreeMFWorkspaceWriter
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Platform import Platform
i18n_catalog = i18nCatalog("cura") i18n_catalog = i18nCatalog("cura")
def getMetaData(): def getMetaData():
workspace_extension = "3mf" workspace_extension = "3mf"
metaData = {} metaData = {}
if "3MFWriter.ThreeMFWriter" in sys.modules: if threemf_writer_was_imported:
metaData["mesh_writer"] = { metaData["mesh_writer"] = {
"output": [{ "output": [{
"extension": "3mf", "extension": "3mf",
@ -39,6 +41,7 @@ def getMetaData():
return metaData return metaData
def register(app): def register(app):
if "3MFWriter.ThreeMFWriter" in sys.modules: if "3MFWriter.ThreeMFWriter" in sys.modules:
return {"mesh_writer": ThreeMFWriter.ThreeMFWriter(), return {"mesh_writer": ThreeMFWriter.ThreeMFWriter(),

View File

@ -3,6 +3,6 @@
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"version": "1.0.1", "version": "1.0.1",
"description": "Provides support for writing 3MF files.", "description": "Provides support for writing 3MF files.",
"api": 7, "api": 8,
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View File

@ -3,5 +3,5 @@
"author": "fieldOfView", "author": "fieldOfView",
"version": "1.0.0", "version": "1.0.0",
"description": "Provides support for reading AMF files.", "description": "Provides support for reading AMF files.",
"api": 7 "api": 8
} }

View File

@ -3,6 +3,6 @@
"author": "Ultimaker B.V.", "author": "Ultimaker B.V.",
"description": "Backup and restore your configuration.", "description": "Backup and restore your configuration.",
"version": "1.2.0", "version": "1.2.0",
"api": 7, "api": 8,
"i18n-catalog": "cura" "i18n-catalog": "cura"
} }

View File

@ -5,7 +5,7 @@ import threading
from datetime import datetime from datetime import datetime
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from PyQt5.QtNetwork import QNetworkReply from PyQt6.QtNetwork import QNetworkReply
from UM.Job import Job from UM.Job import Job
from UM.Logger import Logger from UM.Logger import Logger

View File

@ -3,7 +3,7 @@
from typing import Any, Optional, List, Dict, Callable from typing import Any, Optional, List, Dict, Callable
from PyQt5.QtNetwork import QNetworkReply from PyQt6.QtNetwork import QNetworkReply
from UM.Logger import Logger from UM.Logger import Logger
from UM.Signal import Signal, signalemitter from UM.Signal import Signal, signalemitter

View File

@ -5,7 +5,7 @@ import os
from datetime import datetime from datetime import datetime
from typing import Any, cast, Dict, List, Optional from typing import Any, cast, Dict, List, Optional
from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from PyQt6.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
from UM.Extension import Extension from UM.Extension import Extension
from UM.Logger import Logger from UM.Logger import Logger

Some files were not shown because too many files have changed in this diff Show More