diff --git a/CMakeLists.txt b/CMakeLists.txt index 7846e219e3..f61737fbcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ +# Copyright (c) 2022 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + project(cura) -cmake_minimum_required(VERSION 3.6) +cmake_minimum_required(VERSION 3.18) 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_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) if(CURA_DEBUGMODE) 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) +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. -# So we're using the old method here, with FindPythonInterp for now. -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}) +# Tests +include(CuraTests) if(NOT ${URANIUM_DIR} STREQUAL "") set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${URANIUM_DIR}/cmake") @@ -58,30 +66,15 @@ if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "") endif() endif() - -install(DIRECTORY resources - DESTINATION ${CMAKE_INSTALL_DATADIR}/cura) +install(DIRECTORY resources DESTINATION ${CMAKE_INSTALL_DATADIR}/cura) 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) - 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 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) install(FILES ${CMAKE_SOURCE_DIR}/resources/images/cura-icon.png @@ -91,13 +84,4 @@ if(NOT APPLE AND NOT WIN32) install(FILES cura.sharedmimeinfo DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages/ 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() diff --git a/cmake/CuraPluginInstall.cmake b/cmake/CuraPluginInstall.cmake index 8d9efe1f12..79b86ebdc6 100644 --- a/cmake/CuraPluginInstall.cmake +++ b/cmake/CuraPluginInstall.cmake @@ -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. # @@ -11,19 +11,6 @@ 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 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}) message(STATUS "[-] PLUGIN TO REMOVE : ${_rel_plugin_dir}") 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 ${_plugin_dir_name} RESULT_VARIABLE _mod_json_result) diff --git a/cmake/CuraTests.cmake b/cmake/CuraTests.cmake index b8127a70ec..09e8dadbab 100644 --- a/cmake/CuraTests.cmake +++ b/cmake/CuraTests.cmake @@ -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. include(CTest) 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) function(cura_add_test) @@ -40,7 +34,7 @@ function(cura_add_test) if (NOT ${test_exists}) add_test( 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 "PYTHONPATH=${_PYTHONPATH}") @@ -53,14 +47,14 @@ endfunction() #Add code style test. add_test( NAME "code-style" - COMMAND ${Python3_EXECUTABLE} run_mypy.py + COMMAND ${Python_EXECUTABLE} run_mypy.py WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) #Add test for import statements which are not compatible with all builds add_test( NAME "invalid-imports" - COMMAND ${Python3_EXECUTABLE} scripts/check_invalid_imports.py + COMMAND ${Python_EXECUTABLE} scripts/check_invalid_imports.py 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( NAME "shortcut-keys" - COMMAND ${Python3_EXECUTABLE} scripts/check_shortcut_keys.py + COMMAND ${Python_EXECUTABLE} scripts/check_shortcut_keys.py WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) diff --git a/cura/API/Account.py b/cura/API/Account.py index 9f1184a0a0..b63983e0cc 100644 --- a/cura/API/Account.py +++ b/cura/API/Account.py @@ -1,8 +1,8 @@ # Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. - +import enum 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 UM.Logger import Logger @@ -18,7 +18,7 @@ if TYPE_CHECKING: i18n_catalog = i18nCatalog("cura") -class SyncState: +class SyncState(enum.IntEnum): """QML: Cura.AccountSyncState""" SYNCING = 0 SUCCESS = 1 @@ -41,7 +41,7 @@ class Account(QObject): # The interval in which sync services are automatically triggered SYNC_INTERVAL = 60.0 # seconds - Q_ENUMS(SyncState) + pyqtEnum(SyncState) loginStateChanged = pyqtSignal(bool) """Signal emitted when user logged in or out""" @@ -269,10 +269,10 @@ class Account(QObject): return self._authorization_service.getAccessToken() @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 """ if not self._user_profile: - return None + return {} return self._user_profile.__dict__ @pyqtProperty(str, notify=lastSyncDateTimeChanged) diff --git a/cura/API/ConnectionStatus.py b/cura/API/ConnectionStatus.py index 36f804e3cf..bcdddb717a 100644 --- a/cura/API/ConnectionStatus.py +++ b/cura/API/ConnectionStatus.py @@ -1,6 +1,6 @@ from typing import Optional -from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty +from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty from UM.TaskManagement.HttpRequestManager import HttpRequestManager diff --git a/cura/API/__init__.py b/cura/API/__init__.py index 447be98e4b..f5ffeb92f0 100644 --- a/cura/API/__init__.py +++ b/cura/API/__init__.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. 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.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__)) if application is None: 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 - return cls.__instance + return instance def __init__(self, application: Optional["CuraApplication"] = None) -> None: super().__init__(parent = CuraAPI._application) + CuraAPI.__instance = self self._account = Account(self._application) diff --git a/cura/AutoSave.py b/cura/AutoSave.py index 3205f48af1..c8ea9b756f 100644 --- a/cura/AutoSave.py +++ b/cura/AutoSave.py @@ -1,7 +1,7 @@ # Copyright (c) 2021 Ultimaker B.V. # 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 UM.Logger import Logger diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index fa230866e9..fe607915c1 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -31,7 +31,7 @@ from cura.Settings.GlobalStack import GlobalStack from cura.Scene.CuraSceneNode import CuraSceneNode from cura.Settings.ExtruderManager import ExtruderManager -from PyQt5.QtCore import QTimer +from PyQt6.QtCore import QTimer if TYPE_CHECKING: diff --git a/cura/CameraAnimation.py b/cura/CameraAnimation.py index 37f230a30d..699655a31e 100644 --- a/cura/CameraAnimation.py +++ b/cura/CameraAnimation.py @@ -2,8 +2,8 @@ # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QVariantAnimation, QEasingCurve -from PyQt5.QtGui import QVector3D +from PyQt6.QtCore import QVariantAnimation, QEasingCurve +from PyQt6.QtGui import QVector3D from UM.Math.Vector import Vector @@ -13,7 +13,7 @@ class CameraAnimation(QVariantAnimation): super().__init__(parent) self._camera_tool = None self.setDuration(300) - self.setEasingCurve(QEasingCurve.OutQuad) + self.setEasingCurve(QEasingCurve.Type.OutQuad) def setCameraTool(self, camera_tool): self._camera_tool = camera_tool diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py index 35e9aa832b..bda9568666 100644 --- a/cura/CrashHandler.py +++ b/cura/CrashHandler.py @@ -20,9 +20,9 @@ try: except ImportError: with_sentry_sdk = False -from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QUrl -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit, QGroupBox, QCheckBox, QPushButton -from PyQt5.QtGui import QDesktopServices +from PyQt6.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QUrl +from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit, QGroupBox, QCheckBox, QPushButton +from PyQt6.QtGui import QDesktopServices from UM.Application import Application from UM.Logger import Logger @@ -136,8 +136,8 @@ class CrashHandler: # "backup and start clean" and "close" buttons buttons = QDialogButtonBox() - buttons.addButton(QDialogButtonBox.Close) - buttons.addButton(catalog.i18nc("@action:button", "Backup and Reset Configuration"), QDialogButtonBox.AcceptRole) + buttons.addButton(QDialogButtonBox.StandardButton.Close) + buttons.addButton(catalog.i18nc("@action:button", "Backup and Reset Configuration"), QDialogButtonBox.ButtonRole.AcceptRole) buttons.rejected.connect(self._closeEarlyCrashDialog) buttons.accepted.connect(self._backupAndStartClean) @@ -161,7 +161,7 @@ class CrashHandler: QDesktopServices.openUrl(QUrl.fromLocalFile( path )) def _showDetailedReport(self): - self.dialog.exec_() + self.dialog.exec() def _createDialog(self): """Creates a modal dialog.""" @@ -409,12 +409,12 @@ class CrashHandler: def _buttonsWidget(self): 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 # 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. 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.rejected.connect(self.dialog.close) @@ -456,5 +456,5 @@ class CrashHandler: 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 if self.dialog: - self.dialog.exec_() + self.dialog.exec() os._exit(1) diff --git a/cura/CuraActions.py b/cura/CuraActions.py index 8b232ad1bf..193803325f 100644 --- a/cura/CuraActions.py +++ b/cura/CuraActions.py @@ -1,8 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QObject, QUrl -from PyQt5.QtGui import QDesktopServices +from PyQt6.QtCore import QObject, QUrl +from PyQt6.QtGui import QDesktopServices from typing import List, cast from UM.Event import CallFunctionEvent diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5c94bf73b0..aead7d8a4e 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -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. - +import enum import os import sys import tempfile @@ -8,10 +8,10 @@ import time from typing import cast, TYPE_CHECKING, Optional, Callable, List, Any, Dict import numpy -from PyQt5.QtCore import QObject, QTimer, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS -from PyQt5.QtGui import QColor, QIcon -from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType -from PyQt5.QtWidgets import QMessageBox +from PyQt6.QtCore import QObject, QTimer, QUrl, pyqtSignal, pyqtProperty, QEvent, pyqtEnum +from PyQt6.QtGui import QColor, QIcon +from PyQt6.QtQml import qmlRegisterUncreatableType, qmlRegisterUncreatableMetaObject, qmlRegisterSingletonType, qmlRegisterType +from PyQt6.QtWidgets import QMessageBox import UM.Util import cura.Settings.cura_empty_instance_containers @@ -131,7 +131,7 @@ class CuraApplication(QtApplication): Created = False - class ResourceTypes: + class ResourceTypes(enum.IntEnum): QmlFiles = Resources.UserType + 1 Firmware = Resources.UserType + 2 QualityInstanceContainer = Resources.UserType + 3 @@ -145,7 +145,7 @@ class CuraApplication(QtApplication): SettingVisibilityPreset = Resources.UserType + 11 IntentInstanceContainer = Resources.UserType + 12 - Q_ENUMS(ResourceTypes) + pyqtEnum(ResourceTypes) def __init__(self, *args, **kwargs): super().__init__(name = ApplicationMetadata.CuraAppName, @@ -350,6 +350,7 @@ class CuraApplication(QtApplication): 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(os.path.abspath(os.path.dirname(__file__)), "..", "share", "cura", "resources")) Resources.addSearchPath(os.path.join(self._app_install_dir, "share", "cura", "resources")) if not hasattr(sys, "frozen"): @@ -678,6 +679,22 @@ class CuraApplication(QtApplication): self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing Active Machine...")) 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() def discardOrKeepProfileChanges(self) -> bool: @@ -858,7 +875,7 @@ class CuraApplication(QtApplication): self._auto_save = AutoSave(self) self._auto_save.initialize() - self.exec_() + self.exec() def __setUpSingleInstanceServer(self): if self._use_single_instance: @@ -1075,7 +1092,7 @@ class CuraApplication(QtApplication): def event(self, event): """Handle Qt events""" - if event.type() == QEvent.FileOpen: + if event.type() == QEvent.Type.FileOpen: if self._plugins_loaded: self._openFile(event.file()) else: @@ -1121,16 +1138,16 @@ class CuraApplication(QtApplication): engine.rootContext().setContextProperty("CuraSDKVersion", ApplicationMetadata.CuraSDKVersion) 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() - qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 0, "SceneController", self.getCuraSceneController) - qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, "ExtruderManager", self.getExtruderManager) - qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager) - qmlRegisterSingletonType(IntentManager, "Cura", 1, 6, "IntentManager", self.getIntentManager) - qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager", self.getSettingInheritanceManager) - qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager) - qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager) + qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 0, self.getCuraSceneController, "SceneController") + qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, self.getExtruderManager, "ExtruderManager") + qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, self.getMachineManager, "MachineManager") + qmlRegisterSingletonType(IntentManager, "Cura", 1, 6, self.getIntentManager, "IntentManager") + qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, self.getSettingInheritanceManager, "SettingInheritanceManager") + qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, self.getSimpleModeSettingsManager, "SimpleModeSettingsManager") + qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, self.getMachineActionManager, "MachineActionManager") self.processEvents() qmlRegisterType(NetworkingUtil, "Cura", 1, 5, "NetworkingUtil") @@ -1153,16 +1170,16 @@ class CuraApplication(QtApplication): qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel") qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(MaterialBrandsModel, "Cura", 1, 0, "MaterialBrandsModel") - qmlRegisterSingletonType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel", self.getQualityManagementModel) - qmlRegisterSingletonType(MaterialManagementModel, "Cura", 1, 5, "MaterialManagementModel", self.getMaterialManagementModel) + qmlRegisterSingletonType(QualityManagementModel, "Cura", 1, 0, self.getQualityManagementModel, "QualityManagementModel") + qmlRegisterSingletonType(MaterialManagementModel, "Cura", 1, 5, self.getMaterialManagementModel, "MaterialManagementModel") self.processEvents() qmlRegisterType(DiscoveredPrintersModel, "Cura", 1, 0, "DiscoveredPrintersModel") qmlRegisterType(DiscoveredCloudPrintersModel, "Cura", 1, 7, "DiscoveredCloudPrintersModel") qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0, - "QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel) + self.getQualityProfilesDropDownMenuModel, "QualityProfilesDropDownMenuModel") qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0, - "CustomQualityProfilesDropDownMenuModel", self.getCustomQualityProfilesDropDownMenuModel) + self.getCustomQualityProfilesDropDownMenuModel, "CustomQualityProfilesDropDownMenuModel") qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(IntentModel, "Cura", 1, 6, "IntentModel") qmlRegisterType(IntentCategoryModel, "Cura", 1, 6, "IntentCategoryModel") @@ -1174,14 +1191,14 @@ class CuraApplication(QtApplication): qmlRegisterType(FirstStartMachineActionsModel, "Cura", 1, 0, "FirstStartMachineActionsModel") qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator") qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel") - qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.getInstance) + qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, ContainerManager.getInstance, "ContainerManager") qmlRegisterType(SidebarCustomMenuItemsModel, "Cura", 1, 0, "SidebarCustomMenuItemsModel") qmlRegisterType(PrinterOutputDevice, "Cura", 1, 0, "PrinterOutputDevice") from cura.API import CuraAPI - qmlRegisterSingletonType(CuraAPI, "Cura", 1, 1, "API", self.getCuraAPI) - qmlRegisterUncreatableType(Account, "Cura", 1, 0, "AccountSyncState", "Could not create AccountSyncState") + qmlRegisterSingletonType(CuraAPI, "Cura", 1, 1, self.getCuraAPI, "API") + 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. actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml"))) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index af75aa7b66..17d6832ac6 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -13,7 +13,7 @@ catalog = i18nCatalog("cura") if TYPE_CHECKING: from UM.Qt.QtApplication import QtApplication - from PyQt5.QtCore import QObject + from PyQt6.QtCore import QObject class CuraPackageManager(PackageManager): diff --git a/cura/CuraView.py b/cura/CuraView.py index 86d4254a7d..6b20cf18d3 100644 --- a/cura/CuraView.py +++ b/cura/CuraView.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # 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.View.View import View diff --git a/cura/MachineAction.py b/cura/MachineAction.py index 74b742ef4d..15d9ab1ca1 100644 --- a/cura/MachineAction.py +++ b/cura/MachineAction.py @@ -4,7 +4,7 @@ import os 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.PluginObject import PluginObject diff --git a/cura/Machines/MachineErrorChecker.py b/cura/Machines/MachineErrorChecker.py index 8213734348..bfefe80fa5 100644 --- a/cura/Machines/MachineErrorChecker.py +++ b/cura/Machines/MachineErrorChecker.py @@ -5,7 +5,7 @@ import time 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 UM.Logger import Logger diff --git a/cura/Machines/MachineNode.py b/cura/Machines/MachineNode.py index d4706ae5ef..88736826fd 100644 --- a/cura/Machines/MachineNode.py +++ b/cura/Machines/MachineNode.py @@ -129,7 +129,7 @@ class MachineNode(ContainerNode): if name not in groups_by_name: # CURA-6599 # For some reason, QML will get null or fail to convert type for MachineManager.activeQualityChangesGroup() to - # a QObject. Setting the object ownership to QQmlEngine.CppOwnership doesn't work, but setting the object + # a QObject. Setting the object ownership to QQmlEngine.ObjectOwnership.CppOwnership doesn't work, but setting the object # parent to application seems to work. from cura.CuraApplication import CuraApplication groups_by_name[name] = QualityChangesGroup(name, quality_type = quality_changes["quality_type"], diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py index 776d540867..2521d3686d 100644 --- a/cura/Machines/Models/BaseMaterialsModel.py +++ b/cura/Machines/Models/BaseMaterialsModel.py @@ -3,7 +3,7 @@ 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.Logger import Logger @@ -61,22 +61,22 @@ class BaseMaterialsModel(ListModel): ContainerTree.getInstance().materialsChanged.connect(self._materialsListChanged) self._application.getMaterialManagementModel().favoritesChanged.connect(self._onChanged) - self.addRoleName(Qt.UserRole + 1, "root_material_id") - self.addRoleName(Qt.UserRole + 2, "id") - self.addRoleName(Qt.UserRole + 3, "GUID") - self.addRoleName(Qt.UserRole + 4, "name") - self.addRoleName(Qt.UserRole + 5, "brand") - self.addRoleName(Qt.UserRole + 6, "description") - self.addRoleName(Qt.UserRole + 7, "material") - self.addRoleName(Qt.UserRole + 8, "color_name") - self.addRoleName(Qt.UserRole + 9, "color_code") - self.addRoleName(Qt.UserRole + 10, "density") - self.addRoleName(Qt.UserRole + 11, "diameter") - self.addRoleName(Qt.UserRole + 12, "approximate_diameter") - self.addRoleName(Qt.UserRole + 13, "adhesion_info") - self.addRoleName(Qt.UserRole + 14, "is_read_only") - self.addRoleName(Qt.UserRole + 15, "container_node") - self.addRoleName(Qt.UserRole + 16, "is_favorite") + self.addRoleName(Qt.ItemDataRole.UserRole + 1, "root_material_id") + self.addRoleName(Qt.ItemDataRole.UserRole + 2, "id") + self.addRoleName(Qt.ItemDataRole.UserRole + 3, "GUID") + self.addRoleName(Qt.ItemDataRole.UserRole + 4, "name") + self.addRoleName(Qt.ItemDataRole.UserRole + 5, "brand") + self.addRoleName(Qt.ItemDataRole.UserRole + 6, "description") + self.addRoleName(Qt.ItemDataRole.UserRole + 7, "material") + self.addRoleName(Qt.ItemDataRole.UserRole + 8, "color_name") + self.addRoleName(Qt.ItemDataRole.UserRole + 9, "color_code") + self.addRoleName(Qt.ItemDataRole.UserRole + 10, "density") + self.addRoleName(Qt.ItemDataRole.UserRole + 11, "diameter") + self.addRoleName(Qt.ItemDataRole.UserRole + 12, "approximate_diameter") + self.addRoleName(Qt.ItemDataRole.UserRole + 13, "adhesion_info") + self.addRoleName(Qt.ItemDataRole.UserRole + 14, "is_read_only") + self.addRoleName(Qt.ItemDataRole.UserRole + 15, "container_node") + self.addRoleName(Qt.ItemDataRole.UserRole + 16, "is_favorite") def _onChanged(self) -> None: self._update_timer.start() diff --git a/cura/Machines/Models/BuildPlateModel.py b/cura/Machines/Models/BuildPlateModel.py index 3697dd2762..716792ceb6 100644 --- a/cura/Machines/Models/BuildPlateModel.py +++ b/cura/Machines/Models/BuildPlateModel.py @@ -1,14 +1,14 @@ # Copyright (c) 2019 Ultimaker B.V. # 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.Qt.ListModel import ListModel class BuildPlateModel(ListModel): - NameRole = Qt.UserRole + 1 - ContainerNodeRole = Qt.UserRole + 2 + NameRole = Qt.ItemDataRole.UserRole + 1 + ContainerNodeRole = Qt.ItemDataRole.UserRole + 2 def __init__(self, parent = None): super().__init__(parent) diff --git a/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py index ce4b87da2b..54f0e44a2a 100644 --- a/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py @@ -10,7 +10,7 @@ from cura.Machines.ContainerTree import ContainerTree from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel if TYPE_CHECKING: - from PyQt5.QtCore import QObject + from PyQt6.QtCore import QObject from UM.Settings.Interfaces import ContainerInterface diff --git a/cura/Machines/Models/DiscoveredCloudPrintersModel.py b/cura/Machines/Models/DiscoveredCloudPrintersModel.py index 692ed49593..c6935b2e34 100644 --- a/cura/Machines/Models/DiscoveredCloudPrintersModel.py +++ b/cura/Machines/Models/DiscoveredCloudPrintersModel.py @@ -1,6 +1,6 @@ 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 @@ -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 account """ - DeviceKeyRole = Qt.UserRole + 1 - DeviceNameRole = Qt.UserRole + 2 - DeviceTypeRole = Qt.UserRole + 3 - DeviceFirmwareVersionRole = Qt.UserRole + 4 + DeviceKeyRole = Qt.ItemDataRole.UserRole + 1 + DeviceNameRole = Qt.ItemDataRole.UserRole + 2 + DeviceTypeRole = Qt.ItemDataRole.UserRole + 3 + DeviceFirmwareVersionRole = Qt.ItemDataRole.UserRole + 4 cloudPrintersDetectedChanged = pyqtSignal(bool) diff --git a/cura/Machines/Models/DiscoveredPrintersModel.py b/cura/Machines/Models/DiscoveredPrintersModel.py index 459ec4d795..4c245a927a 100644 --- a/cura/Machines/Models/DiscoveredPrintersModel.py +++ b/cura/Machines/Models/DiscoveredPrintersModel.py @@ -3,7 +3,7 @@ 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.Logger import Logger diff --git a/cura/Machines/Models/ExtrudersModel.py b/cura/Machines/Models/ExtrudersModel.py index 5ae3c19874..2677894bff 100644 --- a/cura/Machines/Models/ExtrudersModel.py +++ b/cura/Machines/Models/ExtrudersModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # 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 UM.i18n import i18nCatalog @@ -23,43 +23,43 @@ class ExtrudersModel(ListModel): """ # 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.""" - ColorRole = Qt.UserRole + 3 + ColorRole = Qt.ItemDataRole.UserRole + 3 """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. 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. """ # The ID of the definition of the extruder. - DefinitionRole = Qt.UserRole + 5 + DefinitionRole = Qt.ItemDataRole.UserRole + 5 # The material of the extruder. - MaterialRole = Qt.UserRole + 6 + MaterialRole = Qt.ItemDataRole.UserRole + 6 # The variant of the extruder. - VariantRole = Qt.UserRole + 7 - StackRole = Qt.UserRole + 8 + VariantRole = Qt.ItemDataRole.UserRole + 7 + StackRole = Qt.ItemDataRole.UserRole + 8 - MaterialBrandRole = Qt.UserRole + 9 - ColorNameRole = Qt.UserRole + 10 + MaterialBrandRole = Qt.ItemDataRole.UserRole + 9 + ColorNameRole = Qt.ItemDataRole.UserRole + 10 - EnabledRole = Qt.UserRole + 11 + EnabledRole = Qt.ItemDataRole.UserRole + 11 """Is the extruder enabled?""" - MaterialTypeRole = Qt.UserRole + 12 + MaterialTypeRole = Qt.ItemDataRole.UserRole + 12 """The type of the material (e.g. PLA, ABS, PETG, etc.).""" defaultColors = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"] """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): """Initialises the extruders model, defining the roles and listening for changes in the data. diff --git a/cura/Machines/Models/FirstStartMachineActionsModel.py b/cura/Machines/Models/FirstStartMachineActionsModel.py index 7d83f0bff2..b9a1a7cf04 100644 --- a/cura/Machines/Models/FirstStartMachineActionsModel.py +++ b/cura/Machines/Models/FirstStartMachineActionsModel.py @@ -3,7 +3,7 @@ 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 @@ -19,9 +19,9 @@ class FirstStartMachineActionsModel(ListModel): - action : the MachineAction object itself """ - TitleRole = Qt.UserRole + 1 - ContentRole = Qt.UserRole + 2 - ActionRole = Qt.UserRole + 3 + TitleRole = Qt.ItemDataRole.UserRole + 1 + ContentRole = Qt.ItemDataRole.UserRole + 2 + ActionRole = Qt.ItemDataRole.UserRole + 3 def __init__(self, application: "CuraApplication", parent: Optional[QObject] = None) -> None: super().__init__(parent) diff --git a/cura/Machines/Models/GlobalStacksModel.py b/cura/Machines/Models/GlobalStacksModel.py index f27a1ec00b..033d89952c 100644 --- a/cura/Machines/Models/GlobalStacksModel.py +++ b/cura/Machines/Models/GlobalStacksModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2021 Ultimaker B.V. # 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 UM.Qt.ListModel import ListModel @@ -15,14 +15,14 @@ from cura.UltimakerCloud.UltimakerCloudConstants import META_CAPABILITIES # To class GlobalStacksModel(ListModel): - NameRole = Qt.UserRole + 1 - IdRole = Qt.UserRole + 2 - HasRemoteConnectionRole = Qt.UserRole + 3 - ConnectionTypeRole = Qt.UserRole + 4 - MetaDataRole = Qt.UserRole + 5 - DiscoverySourceRole = Qt.UserRole + 6 # For separating local and remote printers in the machine management page - RemovalWarningRole = Qt.UserRole + 7 - IsOnlineRole = Qt.UserRole + 8 + NameRole = Qt.ItemDataRole.UserRole + 1 + IdRole = Qt.ItemDataRole.UserRole + 2 + HasRemoteConnectionRole = Qt.ItemDataRole.UserRole + 3 + ConnectionTypeRole = Qt.ItemDataRole.UserRole + 4 + MetaDataRole = Qt.ItemDataRole.UserRole + 5 + DiscoverySourceRole = Qt.ItemDataRole.UserRole + 6 # For separating local and remote printers in the machine management page + RemovalWarningRole = Qt.ItemDataRole.UserRole + 7 + IsOnlineRole = Qt.ItemDataRole.UserRole + 8 def __init__(self, parent = None) -> None: super().__init__(parent) diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py index aeb1f878ca..14e3c4d35e 100644 --- a/cura/Machines/Models/IntentCategoryModel.py +++ b/cura/Machines/Models/IntentCategoryModel.py @@ -2,14 +2,14 @@ #Cura is released under the terms of the LGPLv3 or higher. import collections -from PyQt5.QtCore import Qt, QTimer +from PyQt6.QtCore import Qt, QTimer from typing import TYPE_CHECKING, Optional, Dict from cura.Machines.Models.IntentModel import IntentModel from cura.Settings.IntentManager import IntentManager from UM.Qt.ListModel import ListModel from UM.Settings.ContainerRegistry import ContainerRegistry #To update the list if anything changes. -from PyQt5.QtCore import pyqtSignal +from PyQt6.QtCore import pyqtSignal import cura.CuraApplication if TYPE_CHECKING: from UM.Settings.ContainerRegistry import ContainerInterface @@ -21,11 +21,11 @@ catalog = i18nCatalog("cura") class IntentCategoryModel(ListModel): """Lists the intent categories that are available for the current printer configuration. """ - NameRole = Qt.UserRole + 1 - IntentCategoryRole = Qt.UserRole + 2 - WeightRole = Qt.UserRole + 3 - QualitiesRole = Qt.UserRole + 4 - DescriptionRole = Qt.UserRole + 5 + NameRole = Qt.ItemDataRole.UserRole + 1 + IntentCategoryRole = Qt.ItemDataRole.UserRole + 2 + WeightRole = Qt.ItemDataRole.UserRole + 3 + QualitiesRole = Qt.ItemDataRole.UserRole + 4 + DescriptionRole = Qt.ItemDataRole.UserRole + 5 modelUpdated = pyqtSignal() diff --git a/cura/Machines/Models/IntentModel.py b/cura/Machines/Models/IntentModel.py index 0ec7e268f0..9fb8ff0376 100644 --- a/cura/Machines/Models/IntentModel.py +++ b/cura/Machines/Models/IntentModel.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Optional, Dict, Any, Set, List -from PyQt5.QtCore import Qt, QObject, pyqtProperty, pyqtSignal, QTimer +from PyQt6.QtCore import Qt, QObject, pyqtProperty, pyqtSignal, QTimer import cura.CuraApplication from UM.Qt.ListModel import ListModel @@ -15,11 +15,11 @@ from cura.Machines.QualityGroup import QualityGroup class IntentModel(ListModel): - NameRole = Qt.UserRole + 1 - QualityTypeRole = Qt.UserRole + 2 - LayerHeightRole = Qt.UserRole + 3 - AvailableRole = Qt.UserRole + 4 - IntentRole = Qt.UserRole + 5 + NameRole = Qt.ItemDataRole.UserRole + 1 + QualityTypeRole = Qt.ItemDataRole.UserRole + 2 + LayerHeightRole = Qt.ItemDataRole.UserRole + 3 + AvailableRole = Qt.ItemDataRole.UserRole + 4 + IntentRole = Qt.ItemDataRole.UserRole + 5 def __init__(self, parent: Optional[QObject] = None) -> None: super().__init__(parent) diff --git a/cura/Machines/Models/MaterialBrandsModel.py b/cura/Machines/Models/MaterialBrandsModel.py index b0594cb286..0438fc76fa 100644 --- a/cura/Machines/Models/MaterialBrandsModel.py +++ b/cura/Machines/Models/MaterialBrandsModel.py @@ -1,7 +1,9 @@ # Copyright (c) 2019 Ultimaker B.V. # 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 cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel @@ -9,10 +11,11 @@ class MaterialTypesModel(ListModel): def __init__(self, parent = None): super().__init__(parent) + QQmlEngine.setObjectOwnership(self, QQmlEngine.ObjectOwnership.CppOwnership) - self.addRoleName(Qt.UserRole + 1, "name") - self.addRoleName(Qt.UserRole + 2, "brand") - self.addRoleName(Qt.UserRole + 3, "colors") + self.addRoleName(Qt.ItemDataRole.UserRole + 1, "name") + self.addRoleName(Qt.ItemDataRole.UserRole + 2, "brand") + self.addRoleName(Qt.ItemDataRole.UserRole + 3, "colors") class MaterialBrandsModel(BaseMaterialsModel): @@ -20,9 +23,10 @@ class MaterialBrandsModel(BaseMaterialsModel): def __init__(self, parent = None): super().__init__(parent) + QQmlEngine.setObjectOwnership(self, QQmlEngine.ObjectOwnership.CppOwnership) - self.addRoleName(Qt.UserRole + 1, "name") - self.addRoleName(Qt.UserRole + 2, "material_types") + self.addRoleName(Qt.ItemDataRole.UserRole + 1, "name") + self.addRoleName(Qt.ItemDataRole.UserRole + 2, "material_types") self._update() @@ -74,16 +78,15 @@ class MaterialBrandsModel(BaseMaterialsModel): material_type_item_list = [] brand_item = { "name": brand, - "material_types": MaterialTypesModel(self) + "material_types": MaterialTypesModel() } for material_type, material_list in material_dict.items(): material_type_item = { "name": material_type, "brand": brand, - "colors": BaseMaterialsModel(self) + "colors": BaseMaterialsModel() } - material_type_item["colors"].clear() # Sort materials by name material_list = sorted(material_list, key = lambda x: x["name"].upper()) diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py index ce31193eb8..53d0cca0a2 100644 --- a/cura/Machines/Models/MaterialManagementModel.py +++ b/cura/Machines/Models/MaterialManagementModel.py @@ -2,8 +2,8 @@ # Cura is released under the terms of the LGPLv3 or higher. import copy # To duplicate materials. -from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl -from PyQt5.QtGui import QDesktopServices +from PyQt6.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl +from PyQt6.QtGui import QDesktopServices from typing import Any, Dict, Optional, TYPE_CHECKING import uuid # To generate new GUIDs for new materials. diff --git a/cura/Machines/Models/MultiBuildPlateModel.py b/cura/Machines/Models/MultiBuildPlateModel.py index 8e2f086e3b..300c35754b 100644 --- a/cura/Machines/Models/MultiBuildPlateModel.py +++ b/cura/Machines/Models/MultiBuildPlateModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # 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.Scene.Camera import Camera diff --git a/cura/Machines/Models/NozzleModel.py b/cura/Machines/Models/NozzleModel.py index 5f7f8b02f5..2083866ac5 100644 --- a/cura/Machines/Models/NozzleModel.py +++ b/cura/Machines/Models/NozzleModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2019 Ultimaker B.V. # 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.Qt.ListModel import ListModel @@ -10,9 +10,9 @@ from cura.Machines.ContainerTree import ContainerTree class NozzleModel(ListModel): - IdRole = Qt.UserRole + 1 - HotendNameRole = Qt.UserRole + 2 - ContainerNodeRole = Qt.UserRole + 3 + IdRole = Qt.ItemDataRole.UserRole + 1 + HotendNameRole = Qt.ItemDataRole.UserRole + 2 + ContainerNodeRole = Qt.ItemDataRole.UserRole + 3 def __init__(self, parent = None): super().__init__(parent) diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index 63c1ead29d..8db8719784 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. 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.Qt.ListModel import ListModel @@ -29,13 +29,13 @@ if TYPE_CHECKING: class QualityManagementModel(ListModel): """This the QML model for the quality management page.""" - NameRole = Qt.UserRole + 1 - IsReadOnlyRole = Qt.UserRole + 2 - QualityGroupRole = Qt.UserRole + 3 - QualityTypeRole = Qt.UserRole + 4 - QualityChangesGroupRole = Qt.UserRole + 5 - IntentCategoryRole = Qt.UserRole + 6 - SectionNameRole = Qt.UserRole + 7 + NameRole = Qt.ItemDataRole.UserRole + 1 + IsReadOnlyRole = Qt.ItemDataRole.UserRole + 2 + QualityGroupRole = Qt.ItemDataRole.UserRole + 3 + QualityTypeRole = Qt.ItemDataRole.UserRole + 4 + QualityChangesGroupRole = Qt.ItemDataRole.UserRole + 5 + IntentCategoryRole = Qt.ItemDataRole.UserRole + 6 + SectionNameRole = Qt.ItemDataRole.UserRole + 7 def __init__(self, parent: Optional["QObject"] = None) -> None: super().__init__(parent) diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py index f7316e9c09..b3f92a06f4 100644 --- a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py +++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2019 Ultimaker B.V. # 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. from UM.Logger import Logger @@ -13,14 +13,14 @@ from cura.Machines.Models.MachineModelUtils import fetchLayerHeight class QualityProfilesDropDownMenuModel(ListModel): """QML Model for all built-in quality profiles. This model is used for the drop-down quality menu.""" - NameRole = Qt.UserRole + 1 - QualityTypeRole = Qt.UserRole + 2 - LayerHeightRole = Qt.UserRole + 3 - LayerHeightUnitRole = Qt.UserRole + 4 - AvailableRole = Qt.UserRole + 5 - QualityGroupRole = Qt.UserRole + 6 - QualityChangesGroupRole = Qt.UserRole + 7 - IsExperimentalRole = Qt.UserRole + 8 + NameRole = Qt.ItemDataRole.UserRole + 1 + QualityTypeRole = Qt.ItemDataRole.UserRole + 2 + LayerHeightRole = Qt.ItemDataRole.UserRole + 3 + LayerHeightUnitRole = Qt.ItemDataRole.UserRole + 4 + AvailableRole = Qt.ItemDataRole.UserRole + 5 + QualityGroupRole = Qt.ItemDataRole.UserRole + 6 + QualityChangesGroupRole = Qt.ItemDataRole.UserRole + 7 + IsExperimentalRole = Qt.ItemDataRole.UserRole + 8 def __init__(self, parent = None): super().__init__(parent) diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 2051f1748d..f3808db1fb 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2022 Ultimaker B.V. # 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 import cura.CuraApplication @@ -17,13 +17,13 @@ import os class QualitySettingsModel(ListModel): """This model is used to show details settings of the selected quality in the quality management page.""" - KeyRole = Qt.UserRole + 1 - LabelRole = Qt.UserRole + 2 - UnitRole = Qt.UserRole + 3 - ProfileValueRole = Qt.UserRole + 4 - ProfileValueSourceRole = Qt.UserRole + 5 - UserValueRole = Qt.UserRole + 6 - CategoryRole = Qt.UserRole + 7 + KeyRole = Qt.ItemDataRole.UserRole + 1 + LabelRole = Qt.ItemDataRole.UserRole + 2 + UnitRole = Qt.ItemDataRole.UserRole + 3 + ProfileValueRole = Qt.ItemDataRole.UserRole + 4 + ProfileValueSourceRole = Qt.ItemDataRole.UserRole + 5 + UserValueRole = Qt.ItemDataRole.UserRole + 6 + CategoryRole = Qt.ItemDataRole.UserRole + 7 GLOBAL_STACK_POSITION = -1 diff --git a/cura/Machines/Models/SettingVisibilityPresetsModel.py b/cura/Machines/Models/SettingVisibilityPresetsModel.py index 2ca0960de4..d4c590dc74 100644 --- a/cura/Machines/Models/SettingVisibilityPresetsModel.py +++ b/cura/Machines/Models/SettingVisibilityPresetsModel.py @@ -3,7 +3,7 @@ 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.Preferences import Preferences diff --git a/cura/Machines/Models/UserChangesModel.py b/cura/Machines/Models/UserChangesModel.py index 43bbe8a663..171e910dd8 100644 --- a/cura/Machines/Models/UserChangesModel.py +++ b/cura/Machines/Models/UserChangesModel.py @@ -4,7 +4,7 @@ import os from collections import OrderedDict -from PyQt5.QtCore import pyqtSlot, Qt +from PyQt6.QtCore import pyqtSlot, Qt from UM.Application import Application from UM.Logger import Logger @@ -15,12 +15,12 @@ from UM.Qt.ListModel import ListModel class UserChangesModel(ListModel): - KeyRole = Qt.UserRole + 1 - LabelRole = Qt.UserRole + 2 - ExtruderRole = Qt.UserRole + 3 - OriginalValueRole = Qt.UserRole + 4 - UserValueRole = Qt.UserRole + 6 - CategoryRole = Qt.UserRole + 7 + KeyRole = Qt.ItemDataRole.UserRole + 1 + LabelRole = Qt.ItemDataRole.UserRole + 2 + ExtruderRole = Qt.ItemDataRole.UserRole + 3 + OriginalValueRole = Qt.ItemDataRole.UserRole + 4 + UserValueRole = Qt.ItemDataRole.UserRole + 6 + CategoryRole = Qt.ItemDataRole.UserRole + 7 def __init__(self, parent = None): super().__init__(parent = parent) diff --git a/cura/Machines/QualityChangesGroup.py b/cura/Machines/QualityChangesGroup.py index 668fff785a..f30d04b8a8 100644 --- a/cura/Machines/QualityChangesGroup.py +++ b/cura/Machines/QualityChangesGroup.py @@ -3,7 +3,7 @@ from typing import Any, Dict, Optional -from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal +from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal class QualityChangesGroup(QObject): diff --git a/cura/OAuth2/AuthorizationHelpers.py b/cura/OAuth2/AuthorizationHelpers.py index 77e3c66c11..a654ee4bdb 100644 --- a/cura/OAuth2/AuthorizationHelpers.py +++ b/cura/OAuth2/AuthorizationHelpers.py @@ -4,7 +4,7 @@ from base64 import b64encode from datetime import datetime from hashlib import sha512 -from PyQt5.QtNetwork import QNetworkReply +from PyQt6.QtNetwork import QNetworkReply import secrets from typing import Callable, Optional import urllib.parse diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py index 0343af68a8..f2e6cd27ec 100644 --- a/cura/OAuth2/AuthorizationService.py +++ b/cura/OAuth2/AuthorizationService.py @@ -6,8 +6,8 @@ from datetime import datetime, timedelta from typing import Callable, Dict, Optional, TYPE_CHECKING, Union from urllib.parse import urlencode, quote_plus -from PyQt5.QtCore import QUrl -from PyQt5.QtGui import QDesktopServices +from PyQt6.QtCore import QUrl +from PyQt6.QtGui import QDesktopServices from UM.Logger import Logger from UM.Message import Message diff --git a/cura/PlatformPhysics.py b/cura/PlatformPhysics.py index a2b8a87577..e054528c42 100755 --- a/cura/PlatformPhysics.py +++ b/cura/PlatformPhysics.py @@ -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. -from PyQt5.QtCore import QTimer +from PyQt6.QtCore import QTimer from UM.Application import Application from UM.Logger import Logger diff --git a/cura/PrintJobPreviewImageProvider.py b/cura/PrintJobPreviewImageProvider.py index 321164adeb..90c115a4b4 100644 --- a/cura/PrintJobPreviewImageProvider.py +++ b/cura/PrintJobPreviewImageProvider.py @@ -1,6 +1,6 @@ -from PyQt5.QtGui import QImage -from PyQt5.QtQuick import QQuickImageProvider -from PyQt5.QtCore import QSize +from PyQt6.QtGui import QImage +from PyQt6.QtQuick import QQuickImageProvider +from PyQt6.QtCore import QSize from UM.Application import Application from typing import Tuple @@ -8,7 +8,7 @@ from typing import Tuple class PrintJobPreviewImageProvider(QQuickImageProvider): def __init__(self): - super().__init__(QQuickImageProvider.Image) + super().__init__(QQuickImageProvider.ImageType.Image) def requestImage(self, id: str, size: QSize) -> Tuple[QImage, QSize]: """Request a new image. diff --git a/cura/PrinterOutput/FirmwareUpdater.py b/cura/PrinterOutput/FirmwareUpdater.py index cfcfb2204f..0c1c427ff2 100644 --- a/cura/PrinterOutput/FirmwareUpdater.py +++ b/cura/PrinterOutput/FirmwareUpdater.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # 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 threading import Thread diff --git a/cura/PrinterOutput/GenericOutputController.py b/cura/PrinterOutput/GenericOutputController.py index c160459776..9531a1ab89 100644 --- a/cura/PrinterOutput/GenericOutputController.py +++ b/cura/PrinterOutput/GenericOutputController.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Set, Union, Optional -from PyQt5.QtCore import QTimer +from PyQt6.QtCore import QTimer from .PrinterOutputController import PrinterOutputController diff --git a/cura/PrinterOutput/Models/ExtruderConfigurationModel.py b/cura/PrinterOutput/Models/ExtruderConfigurationModel.py index 4fbf951f45..4cc3e81f56 100644 --- a/cura/PrinterOutput/Models/ExtruderConfigurationModel.py +++ b/cura/PrinterOutput/Models/ExtruderConfigurationModel.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Optional -from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal +from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal from .MaterialOutputModel import MaterialOutputModel diff --git a/cura/PrinterOutput/Models/ExtruderOutputModel.py b/cura/PrinterOutput/Models/ExtruderOutputModel.py index bcd0f579c2..ae1b175f3f 100644 --- a/cura/PrinterOutput/Models/ExtruderOutputModel.py +++ b/cura/PrinterOutput/Models/ExtruderOutputModel.py @@ -3,7 +3,7 @@ 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 diff --git a/cura/PrinterOutput/Models/MaterialOutputModel.py b/cura/PrinterOutput/Models/MaterialOutputModel.py index 3714824a89..89509ace72 100644 --- a/cura/PrinterOutput/Models/MaterialOutputModel.py +++ b/cura/PrinterOutput/Models/MaterialOutputModel.py @@ -3,7 +3,7 @@ from typing import Optional -from PyQt5.QtCore import pyqtProperty, QObject +from PyQt6.QtCore import pyqtProperty, QObject class MaterialOutputModel(QObject): diff --git a/cura/PrinterOutput/Models/PrintJobOutputModel.py b/cura/PrinterOutput/Models/PrintJobOutputModel.py index f7404f71ed..b6a12cb183 100644 --- a/cura/PrinterOutput/Models/PrintJobOutputModel.py +++ b/cura/PrinterOutput/Models/PrintJobOutputModel.py @@ -3,8 +3,8 @@ from typing import Optional, TYPE_CHECKING, List -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot, QUrl -from PyQt5.QtGui import QImage +from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot, QUrl +from PyQt6.QtGui import QImage if TYPE_CHECKING: 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 # as new (instead of relying on cached version and thus forces an update. temp = "image://print_job_preview/" + str(self._preview_image_id) + "/" + self._key - return QUrl(temp, QUrl.TolerantMode) + return QUrl(temp, QUrl.ParsingMode.TolerantMode) def getPreviewImage(self) -> Optional[QImage]: return self._preview_image diff --git a/cura/PrinterOutput/Models/PrinterConfigurationModel.py b/cura/PrinterOutput/Models/PrinterConfigurationModel.py index 54f52134b2..85c69abcd3 100644 --- a/cura/PrinterOutput/Models/PrinterConfigurationModel.py +++ b/cura/PrinterOutput/Models/PrinterConfigurationModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # 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 MYPY = False diff --git a/cura/PrinterOutput/Models/PrinterOutputModel.py b/cura/PrinterOutput/Models/PrinterOutputModel.py index 37464b0b7d..2f7091e014 100644 --- a/cura/PrinterOutput/Models/PrinterOutputModel.py +++ b/cura/PrinterOutput/Models/PrinterOutputModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot, QUrl +from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant, pyqtSlot, QUrl from typing import List, Dict, Optional, TYPE_CHECKING from UM.Math.Vector import Vector from cura.PrinterOutput.Peripheral import Peripheral diff --git a/cura/PrinterOutput/NetworkMJPGImage.py b/cura/PrinterOutput/NetworkMJPGImage.py index 0bfcfab764..a482b40ad8 100644 --- a/cura/PrinterOutput/NetworkMJPGImage.py +++ b/cura/PrinterOutput/NetworkMJPGImage.py @@ -1,10 +1,10 @@ # Copyright (c) 2018 Aldo Hoeben / fieldOfView # NetworkMJPGImage is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QUrl, pyqtProperty, pyqtSignal, pyqtSlot, QRect, QByteArray -from PyQt5.QtGui import QImage, QPainter -from PyQt5.QtQuick import QQuickPaintedItem -from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager +from PyQt6.QtCore import QUrl, pyqtProperty, pyqtSignal, pyqtSlot, QRect, QByteArray +from PyQt6.QtGui import QImage, QPainter +from PyQt6.QtQuick import QQuickPaintedItem +from PyQt6.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager from UM.Logger import Logger diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py index 42c1cd78aa..0fc387a53f 100644 --- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py +++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py @@ -9,8 +9,8 @@ from cura.CuraApplication import CuraApplication from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType -from PyQt5.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication +from PyQt6.QtNetwork import QHttpMultiPart, QHttpPart, QNetworkRequest, QNetworkAccessManager, QNetworkReply, QAuthenticator +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl, QCoreApplication from time import time from typing import Callable, Dict, List, Optional, Union from enum import IntEnum @@ -146,8 +146,8 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): url = QUrl("http://" + self._address + self._api_prefix + target) request = QNetworkRequest(url) if content_type is not None: - request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) - request.setHeader(QNetworkRequest.UserAgentHeader, self._user_agent) + request.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, content_type) + request.setHeader(QNetworkRequest.KnownHeaders.UserAgentHeader, self._user_agent) return request 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;"): 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: - part.setHeader(QNetworkRequest.ContentTypeHeader, content_type) + part.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, content_type) part.setBody(data) return part @@ -290,7 +290,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): on_progress: Optional[Callable[[int, int], None]] = None) -> QNetworkReply: self._validateManager() request = self._createEmptyRequest(target, content_type=None) - multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType) + multi_post_part = QHttpMultiPart(QHttpMultiPart.ContentType.FormDataType) for part in parts: 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: post_part = QHttpPart() - post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data) + post_part.setHeader(QNetworkRequest.KnownHeaders.ContentDispositionHeader, header_data) post_part.setBody(body_data) self.postFormWithParts(target, [post_part], on_finished, on_progress) @@ -357,10 +357,10 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice): def _handleOnFinished(self, reply: QNetworkReply) -> None: # Due to garbage collection, we need to cache certain bits of post operations. # As we don't want to keep them around forever, delete them if we get a reply. - if reply.operation() == QNetworkAccessManager.PostOperation: + if reply.operation() == QNetworkAccessManager.Operation.PostOperation: 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. return diff --git a/cura/PrinterOutput/PrinterOutputDevice.py b/cura/PrinterOutput/PrinterOutputDevice.py index bc7dc4baf4..d3a5e252d3 100644 --- a/cura/PrinterOutput/PrinterOutputDevice.py +++ b/cura/PrinterOutput/PrinterOutputDevice.py @@ -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. from enum import IntEnum from typing import Callable, List, Optional, Union -from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl -from PyQt5.QtWidgets import QMessageBox +from PyQt6.QtCore import pyqtProperty, pyqtSignal, QObject, QTimer, QUrl +from PyQt6.QtWidgets import QMessageBox import cura.CuraApplication # Imported like this to prevent circular imports. from UM.Logger import Logger @@ -137,9 +137,11 @@ class PrinterOutputDevice(QObject, OutputDevice): """ if self.connectionState != connection_state: self._connection_state = connection_state - global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack() - if global_stack: - global_stack.setMetaDataEntry("is_online", self.isConnected()) + application = cura.CuraApplication.CuraApplication.getInstance() + if application is not None: # Might happen during the closing of Cura or in a test. + global_stack = application.getGlobalContainerStack() + if global_stack is not None: + global_stack.setMetaDataEntry("is_online", self.isConnected()) self.connectionStateChanged.emit(self._id) @pyqtProperty(int, constant = True) diff --git a/cura/PrinterOutput/UploadMaterialsJob.py b/cura/PrinterOutput/UploadMaterialsJob.py index 7a08a198c1..b6fbafeb24 100644 --- a/cura/PrinterOutput/UploadMaterialsJob.py +++ b/cura/PrinterOutput/UploadMaterialsJob.py @@ -5,7 +5,7 @@ import enum import functools # For partial methods to use as callbacks with information pre-filled. import json # To serialise metadata for API calls. 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 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 if TYPE_CHECKING: - from PyQt5.QtNetwork import QNetworkReply + from PyQt6.QtNetwork import QNetworkReply from cura.UltimakerCloud.CloudMaterialSync import CloudMaterialSync catalog = i18nCatalog("cura") diff --git a/cura/Scene/ConvexHullDecorator.py b/cura/Scene/ConvexHullDecorator.py index 7d299b1617..b15eaf2ae1 100644 --- a/cura/Scene/ConvexHullDecorator.py +++ b/cura/Scene/ConvexHullDecorator.py @@ -1,7 +1,7 @@ # Copyright (c) 2020 Ultimaker B.V. # 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.Math.Polygon import Polygon diff --git a/cura/Scene/CuraSceneController.py b/cura/Scene/CuraSceneController.py index 99a6eee0e2..1d604b74b6 100644 --- a/cura/Scene/CuraSceneController.py +++ b/cura/Scene/CuraSceneController.py @@ -1,7 +1,7 @@ from UM.Logger import Logger -from PyQt5.QtCore import Qt, pyqtSlot, QObject, QTimer -from PyQt5.QtWidgets import QApplication +from PyQt6.QtCore import Qt, pyqtSlot, QObject, QTimer +from PyQt6.QtWidgets import QApplication from UM.Scene.Camera import Camera from cura.UI.ObjectsModel import ObjectsModel @@ -107,8 +107,8 @@ class CuraSceneController(QObject): """Either select or deselect an item""" modifiers = QApplication.keyboardModifiers() - ctrl_is_active = modifiers & Qt.ControlModifier - shift_is_active = modifiers & Qt.ShiftModifier + ctrl_is_active = modifiers & Qt.KeyboardModifier.ControlModifier + shift_is_active = modifiers & Qt.KeyboardModifier.ShiftModifier if ctrl_is_active: item = self._objects_model.getItem(index) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index 518eaaa8fa..c1b0ceeaae 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -6,8 +6,8 @@ import urllib.parse import uuid from typing import Any, cast, Dict, List, TYPE_CHECKING, Union -from PyQt5.QtCore import QObject, QUrl -from PyQt5.QtWidgets import QMessageBox +from PyQt6.QtCore import QObject, QUrl +from PyQt6.QtWidgets import QMessageBox from UM.i18n import i18nCatalog from UM.FlameProfiler import pyqtSlot @@ -47,11 +47,11 @@ class ContainerManager(QObject): def __init__(self, application: "CuraApplication") -> None: if ContainerManager.__instance is not None: raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__) - ContainerManager.__instance = self try: super().__init__(parent = application) except TypeError: super().__init__() + ContainerManager.__instance = self self._container_name_filters = {} # type: Dict[str, Dict[str, Any]] @@ -206,7 +206,7 @@ class ContainerManager(QObject): if os.path.exists(file_url): result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"), catalog.i18nc("@label Don't translate the XML tag !", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_url)) - if result == QMessageBox.No: + if result == QMessageBox.ButtonRole.NoRole: return {"status": "cancelled", "message": "User cancelled"} try: diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 6130019f4d..a72828708b 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -6,7 +6,7 @@ import re import configparser 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.Settings.ContainerFormatError import ContainerFormatError @@ -139,7 +139,7 @@ class CuraContainerRegistry(ContainerRegistry): if os.path.exists(file_name): result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"), catalog.i18nc("@label Don't translate the XML tag !", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_name)) - if result == QMessageBox.No: + if result == QMessageBox.ButtonRole.NoRole: return False profile_writer = self._findProfileWriter(extension, description) diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index f594ad3d0c..5348deb4bd 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. 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.Decorators import override @@ -75,7 +75,7 @@ class CuraContainerStack(ContainerStack): self.replaceContainer(_ContainerIndexes.UserChanges, new_user_changes) - @pyqtProperty(InstanceContainer, fset = setUserChanges, notify = pyqtContainersChanged) + @pyqtProperty(QObject, fset = setUserChanges, notify = pyqtContainersChanged) def userChanges(self) -> InstanceContainer: """Get the user changes container. @@ -92,7 +92,7 @@ class CuraContainerStack(ContainerStack): 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: """Get the quality changes container. @@ -109,7 +109,7 @@ class CuraContainerStack(ContainerStack): 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: """Get the quality container. @@ -126,7 +126,7 @@ class CuraContainerStack(ContainerStack): 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: """Get the quality container. @@ -143,7 +143,7 @@ class CuraContainerStack(ContainerStack): 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: """Get the material container. @@ -160,7 +160,7 @@ class CuraContainerStack(ContainerStack): self.replaceContainer(_ContainerIndexes.Variant, new_variant) - @pyqtProperty(InstanceContainer, fset = setVariant, notify = pyqtContainersChanged) + @pyqtProperty(QObject, fset = setVariant, notify = pyqtContainersChanged) def variant(self) -> InstanceContainer: """Get the variant container. @@ -177,7 +177,7 @@ class CuraContainerStack(ContainerStack): self.replaceContainer(_ContainerIndexes.DefinitionChanges, new_definition_changes) - @pyqtProperty(InstanceContainer, fset = setDefinitionChanges, notify = pyqtContainersChanged) + @pyqtProperty(QObject, fset = setDefinitionChanges, notify = pyqtContainersChanged) def definitionChanges(self) -> InstanceContainer: """Get the definition changes container. diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 0fdc27ec81..07c074254f 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2020 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt. +from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt. from UM.FlameProfiler import pyqtSlot 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: raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__) - ExtruderManager.__instance = self super().__init__(parent) + ExtruderManager.__instance = self self._application = cura.CuraApplication.CuraApplication.getInstance() diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 2a9838c671..e93193818c 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -3,7 +3,7 @@ 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.MimeTypeDatabase import MimeType, MimeTypeDatabase diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index d40ae08236..f0a6946f88 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -6,7 +6,7 @@ import threading from typing import Any, Dict, Optional, Set, TYPE_CHECKING, List import uuid -from PyQt5.QtCore import pyqtProperty, pyqtSlot, pyqtSignal +from PyQt6.QtCore import pyqtProperty, pyqtSlot, pyqtSignal from UM.Decorators import deprecated, override from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase diff --git a/cura/Settings/IntentManager.py b/cura/Settings/IntentManager.py index a556a86dd8..2dfec02201 100644 --- a/cura/Settings/IntentManager.py +++ b/cura/Settings/IntentManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot from typing import Any, Dict, List, Set, Tuple, TYPE_CHECKING from UM.Logger import Logger diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 648b1e9cae..1c7a8f0e98 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -6,7 +6,7 @@ import re import unicodedata 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.Scene.Iterator.DepthFirstIterator import DepthFirstIterator diff --git a/cura/Settings/MachineNameValidator.py b/cura/Settings/MachineNameValidator.py index 99a5c7da0a..409365ef97 100644 --- a/cura/Settings/MachineNameValidator.py +++ b/cura/Settings/MachineNameValidator.py @@ -1,8 +1,8 @@ # Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtSlot, pyqtProperty, QObject, pyqtSignal, QRegExp -from PyQt5.QtGui import QValidator +from PyQt6.QtCore import pyqtSlot, pyqtProperty, QObject, pyqtSignal +from PyQt6.QtGui import QValidator import os #For statvfs. 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.validationChanged.emit() - @pyqtProperty("QRegExp", notify=validationChanged) + @pyqtProperty(str, notify=validationChanged) def machineNameRegex(self): - return QRegExp(self.machine_name_regex) \ No newline at end of file + return str(self.machine_name_regex) \ No newline at end of file diff --git a/cura/Settings/SettingInheritanceManager.py b/cura/Settings/SettingInheritanceManager.py index 34dfaeb616..5ae00ae271 100644 --- a/cura/Settings/SettingInheritanceManager.py +++ b/cura/Settings/SettingInheritanceManager.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. 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.Application import Application from UM.Logger import Logger diff --git a/cura/Settings/SettingVisibilityPreset.py b/cura/Settings/SettingVisibilityPreset.py index e8a4211d69..f41f38faa3 100644 --- a/cura/Settings/SettingVisibilityPreset.py +++ b/cura/Settings/SettingVisibilityPreset.py @@ -3,7 +3,7 @@ import urllib.parse from configparser import ConfigParser 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.MimeTypeDatabase import MimeTypeDatabase diff --git a/cura/Settings/SidebarCustomMenuItemsModel.py b/cura/Settings/SidebarCustomMenuItemsModel.py index 7177d26923..22b7a9b227 100644 --- a/cura/Settings/SidebarCustomMenuItemsModel.py +++ b/cura/Settings/SidebarCustomMenuItemsModel.py @@ -4,14 +4,14 @@ from typing import Any from UM.Qt.ListModel import ListModel -from PyQt5.QtCore import pyqtSlot, Qt +from PyQt6.QtCore import pyqtSlot, Qt class SidebarCustomMenuItemsModel(ListModel): - name_role = Qt.UserRole + 1 - actions_role = Qt.UserRole + 2 - menu_item_role = Qt.UserRole + 3 - menu_item_icon_name_role = Qt.UserRole + 5 + name_role = Qt.ItemDataRole.UserRole + 1 + actions_role = Qt.ItemDataRole.UserRole + 2 + menu_item_role = Qt.ItemDataRole.UserRole + 3 + menu_item_icon_name_role = Qt.ItemDataRole.UserRole + 5 def __init__(self, parent=None): super().__init__(parent) diff --git a/cura/Settings/SimpleModeSettingsManager.py b/cura/Settings/SimpleModeSettingsManager.py index 6650a9b333..af8707f235 100644 --- a/cura/Settings/SimpleModeSettingsManager.py +++ b/cura/Settings/SimpleModeSettingsManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2017 Ultimaker B.V. # 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 diff --git a/cura/SingleInstance.py b/cura/SingleInstance.py index 597a4d5f32..af98869ad7 100644 --- a/cura/SingleInstance.py +++ b/cura/SingleInstance.py @@ -5,7 +5,7 @@ import json import os 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.Logger import Logger diff --git a/cura/Snapshot.py b/cura/Snapshot.py index a7b813610f..1266d3dcb1 100644 --- a/cura/Snapshot.py +++ b/cura/Snapshot.py @@ -2,10 +2,11 @@ # Cura is released under the terms of the LGPLv3 or higher. import numpy -from PyQt5 import QtCore -from PyQt5.QtCore import QCoreApplication -from PyQt5.QtGui import QImage +from PyQt6 import QtCore +from PyQt6.QtCore import QCoreApplication +from PyQt6.QtGui import QImage +from UM.Logger import Logger from cura.PreviewPass import PreviewPass from UM.Application import Application @@ -20,7 +21,7 @@ class Snapshot: def getImageBoundaries(image: QImage): # Look at the resulting image to get a good crop. # 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() # 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]) @@ -64,6 +65,7 @@ class Snapshot: bbox = bbox + node.getBoundingBox() # If there is no bounding box, it means that there is no model in the buildplate if bbox is None: + Logger.log("w", "Unable to create snapshot as we seem to have an empty buildplate") return None look_at = bbox.center @@ -96,6 +98,7 @@ class Snapshot: try: min_x, max_x, min_y, max_y = Snapshot.getImageBoundaries(pixel_output) except (ValueError, AttributeError): + Logger.logException("w", "Failed to crop the snapshot!") return None 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 scaled_image = cropped_image.scaled( width, height, - aspectRatioMode = QtCore.Qt.IgnoreAspectRatio, - transformMode = QtCore.Qt.SmoothTransformation) + aspectRatioMode = QtCore.Qt.AspectRatioMode.IgnoreAspectRatio, + transformMode = QtCore.Qt.TransformationMode.SmoothTransformation) return scaled_image diff --git a/cura/Stages/CuraStage.py b/cura/Stages/CuraStage.py index 6c4d46dd72..869ed309dc 100644 --- a/cura/Stages/CuraStage.py +++ b/cura/Stages/CuraStage.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # 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 diff --git a/cura/UI/CuraSplashScreen.py b/cura/UI/CuraSplashScreen.py index dfeba843a2..331fb2e880 100644 --- a/cura/UI/CuraSplashScreen.py +++ b/cura/UI/CuraSplashScreen.py @@ -1,9 +1,9 @@ # Copyright (c) 2020 Ultimaker B.V. # Uranium is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import Qt, QCoreApplication, QTimer -from PyQt5.QtGui import QPixmap, QColor, QFont, QPen, QPainter -from PyQt5.QtWidgets import QSplashScreen +from PyQt6.QtCore import Qt, QCoreApplication, QTimer +from PyQt6.QtGui import QPixmap, QColor, QFont, QPen, QPainter +from PyQt6.QtWidgets import QSplashScreen from UM.Resources import Resources from UM.Application import Application @@ -63,8 +63,8 @@ class CuraSplashScreen(QSplashScreen): painter.save() painter.setPen(QColor(255, 255, 255, 255)) - painter.setRenderHint(QPainter.Antialiasing) - painter.setRenderHint(QPainter.Antialiasing, True) + painter.setRenderHint(QPainter.RenderHint.Antialiasing) + painter.setRenderHint(QPainter.RenderHint.Antialiasing, True) version = Application.getInstance().getVersion().split("-") @@ -74,9 +74,9 @@ class CuraSplashScreen(QSplashScreen): painter.setFont(font) 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) - 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, version[0] if not ApplicationMetadata.IsAlternateVersion else ApplicationMetadata.CuraBuildType) + elif len(version) > 1: + 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 pen = QPen() @@ -93,8 +93,8 @@ class CuraSplashScreen(QSplashScreen): pen.setColor(QColor(255, 255, 255, 255)) painter.setPen(pen) painter.setFont(font) - painter.drawText(70, 320, 170, 24, - Qt.AlignLeft | Qt.AlignVCenter | Qt.TextWordWrap, + painter.drawText(70, 308, 170, 48, + Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter | Qt.TextFlag.TextWordWrap, self._current_message) painter.restore() @@ -106,7 +106,7 @@ class CuraSplashScreen(QSplashScreen): self._current_message = message self.messageChanged.emit(message) - QCoreApplication.flush() + QCoreApplication.processEvents() # Used to be .flush() -- this might be the closest alternative, but uncertain. self.repaint() def close(self): diff --git a/cura/UI/MachineActionManager.py b/cura/UI/MachineActionManager.py index 5e31de32c2..7a4ce92de0 100644 --- a/cura/UI/MachineActionManager.py +++ b/cura/UI/MachineActionManager.py @@ -3,7 +3,7 @@ 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.Logger import Logger diff --git a/cura/UI/MachineSettingsManager.py b/cura/UI/MachineSettingsManager.py index 1d2604c3c9..077dc29f6c 100644 --- a/cura/UI/MachineSettingsManager.py +++ b/cura/UI/MachineSettingsManager.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Optional, TYPE_CHECKING -from PyQt5.QtCore import QObject, pyqtSlot +from PyQt6.QtCore import QObject, pyqtSlot from UM.i18n import i18nCatalog diff --git a/cura/UI/ObjectsModel.py b/cura/UI/ObjectsModel.py index 64a6e89054..884d516f08 100644 --- a/cura/UI/ObjectsModel.py +++ b/cura/UI/ObjectsModel.py @@ -4,7 +4,7 @@ from UM.Logger import Logger import re 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.Qt.ListModel import ListModel @@ -34,14 +34,14 @@ class _NodeInfo: class ObjectsModel(ListModel): """Keep track of all objects in the project""" - NameRole = Qt.UserRole + 1 - SelectedRole = Qt.UserRole + 2 - OutsideAreaRole = Qt.UserRole + 3 - BuilplateNumberRole = Qt.UserRole + 4 - NodeRole = Qt.UserRole + 5 - PerObjectSettingsCountRole = Qt.UserRole + 6 - MeshTypeRole = Qt.UserRole + 7 - ExtruderNumberRole = Qt.UserRole + 8 + NameRole = Qt.ItemDataRole.UserRole + 1 + SelectedRole = Qt.ItemDataRole.UserRole + 2 + OutsideAreaRole = Qt.ItemDataRole.UserRole + 3 + BuilplateNumberRole = Qt.ItemDataRole.UserRole + 4 + NodeRole = Qt.ItemDataRole.UserRole + 5 + PerObjectSettingsCountRole = Qt.ItemDataRole.UserRole + 6 + MeshTypeRole = Qt.ItemDataRole.UserRole + 7 + ExtruderNumberRole = Qt.ItemDataRole.UserRole + 8 def __init__(self, parent = None) -> None: super().__init__(parent) diff --git a/cura/UI/PrintInformation.py b/cura/UI/PrintInformation.py index 2135c6fe81..e18fc38247 100644 --- a/cura/UI/PrintInformation.py +++ b/cura/UI/PrintInformation.py @@ -6,7 +6,7 @@ import math import os 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.Qt.Duration import Duration @@ -132,7 +132,7 @@ class PrintInformation(QObject): self._updateJobName() self.preSlicedChanged.emit() - @pyqtProperty(Duration, notify = currentPrintTimeChanged) + @pyqtProperty(QObject, notify = currentPrintTimeChanged) def currentPrintTime(self) -> Duration: return self._current_print_time[self._active_build_plate] diff --git a/cura/UI/RecommendedMode.py b/cura/UI/RecommendedMode.py index 47b617740a..20680c0ca9 100644 --- a/cura/UI/RecommendedMode.py +++ b/cura/UI/RecommendedMode.py @@ -1,7 +1,7 @@ # Copyright (c) 2019 Ultimaker B.V. # 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 diff --git a/cura/UI/TextManager.py b/cura/UI/TextManager.py index 77dadae809..9fb68cc2fd 100644 --- a/cura/UI/TextManager.py +++ b/cura/UI/TextManager.py @@ -4,7 +4,7 @@ import collections 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.Resources import Resources diff --git a/cura/UI/WelcomePagesModel.py b/cura/UI/WelcomePagesModel.py index 890e34a31e..26c27418cf 100644 --- a/cura/UI/WelcomePagesModel.py +++ b/cura/UI/WelcomePagesModel.py @@ -6,7 +6,7 @@ import os from collections import deque 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.Logger import Logger @@ -14,7 +14,7 @@ from UM.Qt.ListModel import ListModel from UM.Resources import Resources if TYPE_CHECKING: - from PyQt5.QtCore import QObject + from PyQt6.QtCore import QObject 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. """ - IdRole = Qt.UserRole + 1 # Page ID - PageUrlRole = Qt.UserRole + 2 # URL to the page's QML file - NextPageIdRole = Qt.UserRole + 3 # The next page ID it should go to - NextPageButtonTextRole = Qt.UserRole + 4 # The text for the next page button - PreviousPageButtonTextRole = Qt.UserRole + 5 # The text for the previous page button + IdRole = Qt.ItemDataRole.UserRole + 1 # Page ID + PageUrlRole = Qt.ItemDataRole.UserRole + 2 # URL to the page's QML file + NextPageIdRole = Qt.ItemDataRole.UserRole + 3 # The next page ID it should go to + NextPageButtonTextRole = Qt.ItemDataRole.UserRole + 4 # The text for the next page button + PreviousPageButtonTextRole = Qt.ItemDataRole.UserRole + 5 # The text for the previous page button def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None: super().__init__(parent) diff --git a/cura/UI/WhatsNewPagesModel.py b/cura/UI/WhatsNewPagesModel.py index b99bdf30f0..4fb7802924 100644 --- a/cura/UI/WhatsNewPagesModel.py +++ b/cura/UI/WhatsNewPagesModel.py @@ -4,7 +4,7 @@ import os 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.Resources import Resources @@ -12,7 +12,7 @@ from UM.Resources import Resources from cura.UI.WelcomePagesModel import WelcomePagesModel if TYPE_CHECKING: - from PyQt5.QtCore import QObject + from PyQt6.QtCore import QObject from cura.CuraApplication import CuraApplication diff --git a/cura/UltimakerCloud/CloudMaterialSync.py b/cura/UltimakerCloud/CloudMaterialSync.py index 8848b9bd60..e2eb50f97e 100644 --- a/cura/UltimakerCloud/CloudMaterialSync.py +++ b/cura/UltimakerCloud/CloudMaterialSync.py @@ -1,8 +1,8 @@ # Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl -from PyQt5.QtGui import QDesktopServices +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QUrl +from PyQt6.QtGui import QDesktopServices from typing import Dict, Optional, TYPE_CHECKING import zipfile # To export all materials in a .zip archive. diff --git a/cura/UltimakerCloud/UltimakerCloudScope.py b/cura/UltimakerCloud/UltimakerCloudScope.py index bbcc8e2aa9..a173c5c758 100644 --- a/cura/UltimakerCloud/UltimakerCloudScope.py +++ b/cura/UltimakerCloud/UltimakerCloudScope.py @@ -1,7 +1,7 @@ # Copyright (c) 2021 Ultimaker B.V. # 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.TaskManagement.HttpRequestScope import DefaultUserAgentScope diff --git a/cura/Utils/NetworkingUtil.py b/cura/Utils/NetworkingUtil.py index b13f7903b9..5e480b28a9 100644 --- a/cura/Utils/NetworkingUtil.py +++ b/cura/Utils/NetworkingUtil.py @@ -4,7 +4,7 @@ import socket from typing import Optional -from PyQt5.QtCore import QObject, pyqtSlot +from PyQt6.QtCore import QObject, pyqtSlot # diff --git a/cura_app.py b/cura_app.py index 1520d2da67..e11e3c4232 100755 --- a/cura_app.py +++ b/cura_app.py @@ -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["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 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. # # 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, # 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, # we run the old routine to show the Crash Dialog. # - from PyQt5.Qt import QApplication + from PyQt6.QtWidgets import QApplication if CuraApplication.Created: _crash_handler = CrashHandler(hook_type, value, traceback, has_started) if CuraApplication.splash is not None: @@ -167,7 +167,7 @@ def exceptHook(hook_type, value, traceback): if not has_started: CuraApplication.getInstance().removePostedEvents(None) _crash_handler.early_crash_dialog.show() - sys.exit(CuraApplication.getInstance().exec_()) + sys.exit(CuraApplication.getInstance().exec()) else: _crash_handler.show() else: @@ -178,7 +178,7 @@ def exceptHook(hook_type, value, traceback): if CuraApplication.splash is not None: CuraApplication.splash.close() _crash_handler.early_crash_dialog.show() - sys.exit(application.exec_()) + sys.exit(application.exec()) # Set exception hook to use the crash dialog handler @@ -231,7 +231,7 @@ if Platform.isLinux(): if ApplicationMetadata.CuraDebugMode: ssl_conf = QSslConfiguration.defaultConfiguration() - ssl_conf.setPeerVerifyMode(QSslSocket.VerifyNone) + ssl_conf.setPeerVerifyMode(QSslSocket.PeerVerifyMode.VerifyNone) QSslConfiguration.setDefaultConfiguration(ssl_conf) app = CuraApplication() diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 37ca1e98aa..e8b6a54e46 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -1,11 +1,11 @@ -# Copyright (c) 2021 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. +# Copyright (c) 2021-2022 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. import os.path import zipfile from typing import List, Optional, Union, TYPE_CHECKING, cast -import Savitar +import pySavitar as Savitar import numpy from UM.Logger import Logger @@ -304,4 +304,4 @@ class ThreeMFReader(MeshReader): unit = "millimeter" scale = conversion_to_mm[unit] - return Vector(scale, scale, scale) \ No newline at end of file + return Vector(scale, scale, scale) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 5f57e49cc6..ddc7922546 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -34,7 +34,7 @@ from cura.Settings.CuraContainerStack import _ContainerIndexes from cura.CuraApplication import CuraApplication from cura.Utils.Threading import call_on_qt_thread -from PyQt5.QtCore import QCoreApplication +from PyQt6.QtCore import QCoreApplication from .WorkspaceDialog import WorkspaceDialog diff --git a/plugins/3MFReader/UpdatableMachinesModel.py b/plugins/3MFReader/UpdatableMachinesModel.py index a332c669e6..9d6eee6c3e 100644 --- a/plugins/3MFReader/UpdatableMachinesModel.py +++ b/plugins/3MFReader/UpdatableMachinesModel.py @@ -3,7 +3,7 @@ from typing import Dict, List -from PyQt5.QtCore import Qt +from PyQt6.QtCore import Qt from UM.Qt.ListModel import ListModel from cura.Settings.GlobalStack import GlobalStack @@ -25,10 +25,10 @@ class UpdatableMachinesModel(ListModel): def __init__(self, parent = None) -> None: super().__init__(parent) - self.addRoleName(Qt.UserRole + 1, "id") - self.addRoleName(Qt.UserRole + 2, "name") - self.addRoleName(Qt.UserRole + 3, "displayName") - self.addRoleName(Qt.UserRole + 4, "type") # Either "default_option" or "machine" + self.addRoleName(Qt.ItemDataRole.UserRole + 1, "id") + self.addRoleName(Qt.ItemDataRole.UserRole + 2, "name") + self.addRoleName(Qt.ItemDataRole.UserRole + 3, "displayName") + self.addRoleName(Qt.ItemDataRole.UserRole + 4, "type") # Either "default_option" or "machine" def update(self, machines: List[GlobalStack]) -> None: items = [create_new_list_item] # type: List[Dict[str, str]] diff --git a/plugins/3MFReader/WorkspaceDialog.py b/plugins/3MFReader/WorkspaceDialog.py index 8d59ec1339..b63d8b6288 100644 --- a/plugins/3MFReader/WorkspaceDialog.py +++ b/plugins/3MFReader/WorkspaceDialog.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. 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.PluginRegistry import PluginRegistry from UM.Application import Application diff --git a/plugins/3MFReader/WorkspaceDialog.qml b/plugins/3MFReader/WorkspaceDialog.qml index e8739dcf64..e69cced221 100644 --- a/plugins/3MFReader/WorkspaceDialog.qml +++ b/plugins/3MFReader/WorkspaceDialog.qml @@ -426,7 +426,7 @@ UM.Dialog width: parent.width height: childrenRect.height visible: manager.hasObjectsOnPlate - UM.RecolorImage + UM.ColorImage { width: warningLabel.height height: width diff --git a/plugins/3MFWriter/ThreeMFWriter.py b/plugins/3MFWriter/ThreeMFWriter.py index 45ba556d65..853aa08513 100644 --- a/plugins/3MFWriter/ThreeMFWriter.py +++ b/plugins/3MFWriter/ThreeMFWriter.py @@ -1,5 +1,5 @@ -# Copyright (c) 2015 Ultimaker B.V. -# Uranium is released under the terms of the LGPLv3 or higher. +# Copyright (c) 2015-2022 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. from typing import Optional 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.Snapshot import Snapshot -from PyQt5.QtCore import QBuffer +from PyQt6.QtCore import QBuffer -import Savitar +import pySavitar as Savitar import numpy import datetime @@ -157,7 +157,7 @@ class ThreeMFWriter(MeshWriter): snapshot = self._createSnapshot() if snapshot: thumbnail_buffer = QBuffer() - thumbnail_buffer.open(QBuffer.ReadWrite) + thumbnail_buffer.open(QBuffer.OpenModeFlag.ReadWrite) snapshot.save(thumbnail_buffer, "PNG") thumbnail_file = zipfile.ZipInfo("Metadata/thumbnail.png") diff --git a/plugins/CuraDrive/src/CreateBackupJob.py b/plugins/CuraDrive/src/CreateBackupJob.py index 12bbc035ac..7d772769ed 100644 --- a/plugins/CuraDrive/src/CreateBackupJob.py +++ b/plugins/CuraDrive/src/CreateBackupJob.py @@ -5,7 +5,7 @@ import threading from datetime import datetime from typing import Any, Dict, Optional -from PyQt5.QtNetwork import QNetworkReply +from PyQt6.QtNetwork import QNetworkReply from UM.Job import Job from UM.Logger import Logger diff --git a/plugins/CuraDrive/src/DriveApiService.py b/plugins/CuraDrive/src/DriveApiService.py index 6dd6f02b97..fde167ec10 100644 --- a/plugins/CuraDrive/src/DriveApiService.py +++ b/plugins/CuraDrive/src/DriveApiService.py @@ -3,7 +3,7 @@ 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.Signal import Signal, signalemitter diff --git a/plugins/CuraDrive/src/DrivePluginExtension.py b/plugins/CuraDrive/src/DrivePluginExtension.py index f42ffea9f7..460284074f 100644 --- a/plugins/CuraDrive/src/DrivePluginExtension.py +++ b/plugins/CuraDrive/src/DrivePluginExtension.py @@ -5,7 +5,7 @@ import os from datetime import datetime 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.Logger import Logger diff --git a/plugins/CuraDrive/src/RestoreBackupJob.py b/plugins/CuraDrive/src/RestoreBackupJob.py index f59acbc8b7..54c94b389e 100644 --- a/plugins/CuraDrive/src/RestoreBackupJob.py +++ b/plugins/CuraDrive/src/RestoreBackupJob.py @@ -7,7 +7,7 @@ import threading from tempfile import NamedTemporaryFile from typing import Optional, Any, Dict -from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest +from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest from UM.Job import Job from UM.Logger import Logger @@ -53,7 +53,7 @@ class RestoreBackupJob(Job): def _onRestoreRequestCompleted(self, reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None) -> None: if not HttpRequestManager.replyIndicatesSuccess(reply, error): Logger.warning("Requesting backup failed, response code %s while trying to connect to %s", - reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url()) + reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute), reply.url()) self.restore_backup_error_message = self.DEFAULT_ERROR_MESSAGE self._job_done.set() return diff --git a/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml index 8ddf8e9d42..b5efc8c41b 100644 --- a/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml +++ b/plugins/CuraDrive/src/qml/components/BackupListItemDetailsRow.qml @@ -17,7 +17,7 @@ RowLayout property alias label: detailName.text property alias value: detailValue.text - UM.RecolorImage + UM.ColorImage { id: icon width: 18 * screenScaleFactor diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 8636c465c0..d7ed5fac21 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -1,15 +1,15 @@ -# Copyright (c) 2021 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. +# Copyright (c) 2021-2022 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. import argparse #To run the engine in debug mode if the front-end is in debug mode. from collections import defaultdict import os -from PyQt5.QtCore import QObject, QTimer, QUrl, pyqtSlot +from PyQt6.QtCore import QObject, QTimer, QUrl, pyqtSlot import sys from time import time from typing import Any, cast, Dict, List, Optional, Set, TYPE_CHECKING -from PyQt5.QtGui import QDesktopServices, QImage +from PyQt6.QtGui import QDesktopServices, QImage from UM.Backend.Backend import Backend, BackendState from UM.Scene.SceneNode import SceneNode @@ -31,7 +31,7 @@ from cura.Utils.Threading import call_on_qt_thread from .ProcessSlicedLayersJob import ProcessSlicedLayersJob from .StartSliceJob import StartSliceJob, StartJobResult -import Arcus +import pyArcus as Arcus if TYPE_CHECKING: from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 74e55ffe2d..be30a9f81c 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -1,5 +1,5 @@ -# Copyright (c) 2021 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. +# Copyright (c) 2021-2022 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. import numpy from string import Formatter @@ -7,8 +7,8 @@ from enum import IntEnum import time from typing import Any, cast, Dict, List, Optional, Set import re -import Arcus #For typing. -from PyQt5.QtCore import QCoreApplication +import pyArcus as Arcus # For typing. +from PyQt6.QtCore import QCoreApplication from UM.Job import Job from UM.Logger import Logger @@ -94,7 +94,7 @@ class StartSliceJob(Job): super().__init__() self._scene = CuraApplication.getInstance().getController().getScene() #type: Scene - self._slice_message = slice_message #type: Arcus.PythonMessage + self._slice_message: Arcus.PythonMessage = slice_message self._is_cancelled = False #type: bool self._build_plate_number = None #type: Optional[int] diff --git a/plugins/DigitalLibrary/resources/qml/CreateNewProjectPopup.qml b/plugins/DigitalLibrary/resources/qml/CreateNewProjectPopup.qml index 74bc52b69e..6846720dda 100644 --- a/plugins/DigitalLibrary/resources/qml/CreateNewProjectPopup.qml +++ b/plugins/DigitalLibrary/resources/qml/CreateNewProjectPopup.qml @@ -1,7 +1,7 @@ //Copyright (C) 2022 Ultimaker B.V. //Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.10 +import QtQuick 2.15 import QtQuick.Window 2.2 import QtQuick.Controls 2.3 @@ -90,9 +90,9 @@ Popup left: parent.left right: parent.right } - validator: RegExpValidator + validator: RegularExpressionValidator { - regExp: /^[^\\\/\*\?\|\[\]]{0,99}$/ + regularExpression: /^[^\\\/\*\?\|\[\]]{0,99}$/ } text: PrintInformation.jobName diff --git a/plugins/DigitalLibrary/resources/qml/LoadMoreProjectsCard.qml b/plugins/DigitalLibrary/resources/qml/LoadMoreProjectsCard.qml index 45a0c6886d..6a0706bd00 100644 --- a/plugins/DigitalLibrary/resources/qml/LoadMoreProjectsCard.qml +++ b/plugins/DigitalLibrary/resources/qml/LoadMoreProjectsCard.qml @@ -30,7 +30,7 @@ Cura.RoundedRectangle anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter - UM.RecolorImage + UM.ColorImage { id: projectImage anchors.verticalCenter: parent.verticalCenter diff --git a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml index 5f594cb79e..3e483b4fef 100644 --- a/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml +++ b/plugins/DigitalLibrary/resources/qml/OpenProjectFilesPage.qml @@ -1,12 +1,11 @@ //Copyright (C) 2022 Ultimaker B.V. //Cura is released under the terms of the LGPLv3 or higher. -import Qt.labs.qmlmodels 1.0 import QtQuick 2.15 import QtQuick.Window 2.2 import QtQuick.Controls 2.3 -import UM 1.2 as UM +import UM 1.6 as UM import Cura 1.6 as Cura import DigitalFactory 1.0 as DF @@ -19,6 +18,7 @@ Item height: parent.height property var fileModel: manager.digitalFactoryFileModel + property var modelRows: manager.digitalFactoryFileModel.items signal openFilePressed() signal selectDifferentProjectPressed() @@ -57,21 +57,19 @@ Item border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - //We can't use Cura's TableView here, since in Cura >= 5.0 this uses QtQuick.TableView, while in Cura < 5.0 this uses QtControls1.TableView. - //So we have to define our own. Once support for 4.13 and earlier is dropped, we can switch to Cura.TableView. - Table + // This is not backwards compatible with Cura < 5.0 due to QT.labs being removed in PyQt6 + Cura.TableView { id: filesTableView anchors.fill: parent anchors.margins: parent.border.width columnHeaders: ["Name", "Uploaded by", "Uploaded at"] - model: TableModel + model: UM.TableModel { - TableModelColumn { display: "fileName" } - TableModelColumn { display: "username" } - TableModelColumn { display: "uploadedAt" } - rows: manager.digitalFactoryFileModel.items + id: tableModel + headers: ["fileName", "username", "uploadedAt"] + rows: modelRows } onCurrentRowChanged: @@ -179,4 +177,10 @@ Item openFilesButton.clicked.connect(base.openFilePressed) selectDifferentProjectButton.clicked.connect(base.selectDifferentProjectPressed) } + + onModelRowsChanged: + { + tableModel.clear() + tableModel.rows = modelRows + } } \ No newline at end of file diff --git a/plugins/DigitalLibrary/resources/qml/SaveProjectFilesPage.qml b/plugins/DigitalLibrary/resources/qml/SaveProjectFilesPage.qml index fa648d8bc2..e7114e3312 100644 --- a/plugins/DigitalLibrary/resources/qml/SaveProjectFilesPage.qml +++ b/plugins/DigitalLibrary/resources/qml/SaveProjectFilesPage.qml @@ -1,12 +1,11 @@ //Copyright (C) 2022 Ultimaker B.V. //Cura is released under the terms of the LGPLv3 or higher. -import Qt.labs.qmlmodels 1.0 -import QtQuick 2.10 +import QtQuick 2.15 import QtQuick.Window 2.2 import QtQuick.Controls 2.3 -import UM 1.5 as UM +import UM 1.6 as UM import Cura 1.6 as Cura import DigitalFactory 1.0 as DF @@ -17,7 +16,9 @@ Item id: base width: parent.width height: parent.height + property var fileModel: manager.digitalFactoryFileModel + property var modelRows: manager.digitalFactoryFileModel.items signal savePressed() signal selectDifferentProjectPressed() @@ -61,9 +62,9 @@ Item anchors.left: parent.left anchors.top: fileNameLabel.bottom anchors.topMargin: UM.Theme.getSize("thin_margin").height - validator: RegExpValidator + validator: RegularExpressionValidator { - regExp: /^[\w\-\. ()]{0,255}$/ + regularExpression: /^[\w\-\. ()]{0,255}$/ } text: PrintInformation.jobName @@ -92,9 +93,8 @@ Item border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - //We can't use Cura's TableView here, since in Cura >= 5.0 this uses QtQuick.TableView, while in Cura < 5.0 this uses QtControls1.TableView. - //So we have to define our own. Once support for 4.13 and earlier is dropped, we can switch to Cura.TableView. - Table + // This is not backwards compatible with Cura < 5.0 due to QT.labs being removed in PyQt6 + Cura.TableView { id: filesTableView anchors.fill: parent @@ -102,11 +102,10 @@ Item allowSelection: false columnHeaders: ["Name", "Uploaded by", "Uploaded at"] - model: TableModel + model: UM.TableModel { - TableModelColumn { display: "fileName" } - TableModelColumn { display: "username" } - TableModelColumn { display: "uploadedAt" } + id: tableModel + headers: ["fileName", "username", "uploadedAt"] rows: manager.digitalFactoryFileModel.items } } @@ -248,4 +247,10 @@ Item saveButton.clicked.connect(base.savePressed) selectDifferentProjectButton.clicked.connect(base.selectDifferentProjectPressed) } + + onModelRowsChanged: + { + tableModel.clear() + tableModel.rows = modelRows + } } diff --git a/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml b/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml index 89ebd0f215..ed632124e5 100644 --- a/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml +++ b/plugins/DigitalLibrary/resources/qml/SelectProjectPage.qml @@ -56,7 +56,7 @@ Item id: createNewProjectButton text: "New Library project" - visible: createNewProjectButtonVisible && manager.userAccountCanCreateNewLibraryProject && (manager.retrievingProjectsStatus == DF.RetrievalStatus.Success || manager.retrievingProjectsStatus == DF.RetrievalStatus.Failed) + visible: createNewProjectButtonVisible && manager.userAccountCanCreateNewLibraryProject && (manager.retrievingProjectsStatus == 2 || manager.retrievingProjectsStatus == 3) // Status is succeeded or failed onClicked: { diff --git a/plugins/DigitalLibrary/resources/qml/Table.qml b/plugins/DigitalLibrary/resources/qml/Table.qml deleted file mode 100644 index c4aafc1ce4..0000000000 --- a/plugins/DigitalLibrary/resources/qml/Table.qml +++ /dev/null @@ -1,203 +0,0 @@ -//Copyright (C) 2022 Ultimaker B.V. -//Cura is released under the terms of the LGPLv3 or higher. - -import Qt.labs.qmlmodels 1.0 -import QtQuick 2.15 -import QtQuick.Controls 2.15 - -import UM 1.2 as UM - -/* - * A re-sizeable table of data. - * - * This table combines a list of headers with a TableView to show certain roles in a table. - * The columns of the table can be resized. - * When the table becomes too big, you can scroll through the table. When a column becomes too small, the contents of - * the table are elided. - * The table gets Cura's themeing. - */ -Item -{ - id: tableBase - - required property var columnHeaders //The text to show in the headers of each column. - property alias model: tableView.model //A TableModel to display in this table. To use a ListModel for the rows, use "rows: listModel.items" - property int currentRow: -1 //The selected row index. - property var onDoubleClicked: function(row) {} //Something to execute when double clicked. Accepts one argument: The index of the row that was clicked on. - property bool allowSelection: true //Whether to allow the user to select items. - - Row - { - id: headerBar - Repeater - { - id: headerRepeater - model: columnHeaders - Rectangle - { - //minimumWidth: Math.max(1, Math.round(tableBase.width / headerRepeater.count)) - width: 300 - height: UM.Theme.getSize("section").height - - color: UM.Theme.getColor("secondary") - - Label - { - id: contentText - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("narrow_margin").width - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("narrow_margin").width - - text: modelData - font: UM.Theme.getFont("medium_bold") - color: UM.Theme.getColor("text") - elide: Text.ElideRight - } - Rectangle //Resize handle. - { - anchors - { - right: parent.right - top: parent.top - bottom: parent.bottom - } - width: UM.Theme.getSize("thick_lining").width - - color: UM.Theme.getColor("thick_lining") - - MouseArea - { - anchors.fill: parent - - cursorShape: Qt.SizeHorCursor - drag - { - target: parent - axis: Drag.XAxis - } - onMouseXChanged: - { - if(drag.active) - { - let new_width = parent.parent.width + mouseX; - let sum_widths = mouseX; - for(let i = 0; i < headerBar.children.length; ++i) - { - sum_widths += headerBar.children[i].width; - } - if(sum_widths > tableBase.width) - { - new_width -= sum_widths - tableBase.width; //Limit the total width to not exceed the view. - } - let width_fraction = new_width / tableBase.width; //Scale with the same fraction along with the total width, if the table is resized. - parent.parent.width = Qt.binding(function() { return Math.max(10, Math.round(tableBase.width * width_fraction)) }); - } - } - } - } - - onWidthChanged: - { - tableView.forceLayout(); //Rescale table cells underneath as well. - } - } - } - } - - TableView - { - id: tableView - anchors - { - top: headerBar.bottom - left: parent.left - right: parent.right - bottom: parent.bottom - } - - flickableDirection: Flickable.AutoFlickIfNeeded - clip: true - ScrollBar.vertical: ScrollBar - { - // Vertical ScrollBar, styled similarly to the scrollBar in the settings panel - id: verticalScrollBar - visible: tableView.contentHeight > tableView.height - - background: Rectangle - { - implicitWidth: UM.Theme.getSize("scrollbar").width - radius: Math.round(implicitWidth / 2) - color: UM.Theme.getColor("scrollbar_background") - } - - contentItem: Rectangle - { - id: scrollViewHandle - implicitWidth: UM.Theme.getSize("scrollbar").width - radius: Math.round(implicitWidth / 2) - - color: verticalScrollBar.pressed ? UM.Theme.getColor("scrollbar_handle_down") : verticalScrollBar.hovered ? UM.Theme.getColor("scrollbar_handle_hover") : UM.Theme.getColor("scrollbar_handle") - Behavior on color { ColorAnimation { duration: 50; } } - } - } - columnWidthProvider: function(column) - { - return headerBar.children[column].width; //Cells get the same width as their column header. - } - - delegate: Rectangle - { - implicitHeight: Math.max(1, cellContent.height) - - color: UM.Theme.getColor((tableBase.currentRow == row) ? "primary" : ((row % 2 == 0) ? "main_background" : "viewport_background")) - - Label - { - id: cellContent - width: parent.width - - text: display - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - } - TextMetrics - { - id: cellTextMetrics - text: cellContent.text - font: cellContent.font - elide: cellContent.elide - elideWidth: cellContent.width - } - UM.TooltipArea - { - anchors.fill: parent - - acceptedButtons: Qt.LeftButton - text: (cellTextMetrics.elidedText == cellContent.text) ? "" : cellContent.text //Show full text in tooltip if it was elided. - onClicked: - { - if(tableBase.allowSelection) - { - tableBase.currentRow = row; //Select this row. - } - } - onDoubleClicked: - { - tableBase.onDoubleClicked(row); - } - } - } - - Connections - { - target: model - function onRowCountChanged() - { - tableView.contentY = 0; //When the number of rows is reduced, make sure to scroll back to the start. - } - } - } -} \ No newline at end of file diff --git a/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py b/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py index a5560f32a8..940711f19c 100644 --- a/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py +++ b/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py @@ -5,9 +5,9 @@ import threading from json import JSONDecodeError from typing import List, Dict, Any, Callable, Union, Optional -from PyQt5.QtCore import QUrl -from PyQt5.QtGui import QDesktopServices -from PyQt5.QtNetwork import QNetworkReply +from PyQt6.QtCore import QUrl +from PyQt6.QtGui import QDesktopServices +from PyQt6.QtNetwork import QNetworkReply from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger diff --git a/plugins/DigitalLibrary/src/DFFileUploader.py b/plugins/DigitalLibrary/src/DFFileUploader.py index 10fee03c4c..6cad7828e2 100644 --- a/plugins/DigitalLibrary/src/DFFileUploader.py +++ b/plugins/DigitalLibrary/src/DFFileUploader.py @@ -1,7 +1,7 @@ # Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply +from PyQt6.QtNetwork import QNetworkRequest, QNetworkReply from typing import Callable, Any, cast, Optional, Union from UM.Logger import Logger @@ -120,9 +120,9 @@ class DFFileUploader: """ Logger.log("i", "Finished callback %s %s", - reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url().toString()) + reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute), reply.url().toString()) - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) # type: Optional[int] + status_code = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) # type: Optional[int] if not status_code: Logger.log("e", "Reply contained no status code.") self._onUploadError(reply, None) diff --git a/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py b/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py index 5301151c5f..3456638ba6 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py @@ -7,7 +7,7 @@ import re from time import time from typing import List, Any, Optional, Union, Type, Tuple, Dict, cast, TypeVar, Callable -from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest +from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest from UM.Logger import Logger from UM.TaskManagement.HttpRequestManager import HttpRequestManager @@ -228,7 +228,7 @@ class DigitalFactoryApiClient: self._anti_gc_callbacks.remove(parse) # Don't try to parse the reply if we didn't get one - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: + if reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) is None: if on_error is not None: on_error() return @@ -250,7 +250,7 @@ class DigitalFactoryApiClient: :return: A tuple with a status code and a dictionary. """ - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + status_code = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) try: response = bytes(reply.readAll()).decode() return status_code, json.loads(response) diff --git a/plugins/DigitalLibrary/src/DigitalFactoryController.py b/plugins/DigitalLibrary/src/DigitalFactoryController.py index ba5ee48888..fa6c63e1dc 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryController.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryController.py @@ -10,9 +10,9 @@ from enum import IntEnum from pathlib import Path from typing import Optional, List, Dict, Any, cast -from PyQt5.QtCore import pyqtSignal, QObject, pyqtSlot, pyqtProperty, Q_ENUMS, QTimer, QUrl -from PyQt5.QtNetwork import QNetworkReply -from PyQt5.QtQml import qmlRegisterType, qmlRegisterUncreatableType +from PyQt6.QtCore import pyqtSignal, QObject, pyqtSlot, pyqtProperty, pyqtEnum, QTimer, QUrl +from PyQt6.QtNetwork import QNetworkReply +from PyQt6.QtQml import qmlRegisterType, qmlRegisterUncreatableMetaObject from UM.FileHandler.FileHandler import FileHandler from UM.Logger import Logger @@ -50,7 +50,7 @@ class DFRetrievalStatus(QObject): be used within QML objects as DigitalFactory.RetrievalStatus. """ - Q_ENUMS(RetrievalStatus) + pyqtEnum(RetrievalStatus) class DigitalFactoryController(QObject): @@ -439,7 +439,7 @@ class DigitalFactoryController(QObject): @staticmethod def _onEngineCreated() -> None: - qmlRegisterUncreatableType(DFRetrievalStatus, "DigitalFactory", 1, 0, "RetrievalStatus", "Could not create RetrievalStatus enum type") + qmlRegisterUncreatableMetaObject(DigitalFactoryController.staticMetaObject, "DigitalFactory", 1, 0, "RetrievalStatus", "RetrievalStatus is an Enum-only type") def _applicationInitializationFinished(self) -> None: self._supported_file_types = self._application.getInstance().getMeshFileHandler().getSupportedFileTypesRead() diff --git a/plugins/DigitalLibrary/src/DigitalFactoryFileModel.py b/plugins/DigitalLibrary/src/DigitalFactoryFileModel.py index 535cce0e8f..5c030ead17 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryFileModel.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryFileModel.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import List, Dict, Callable -from PyQt5.QtCore import Qt, pyqtSignal +from PyQt6.QtCore import Qt, pyqtSignal from UM.Logger import Logger from UM.Qt.ListModel import ListModel @@ -13,13 +13,13 @@ DIGITAL_FACTORY_DISPLAY_DATETIME_FORMAT = "%d-%m-%Y %H:%M" class DigitalFactoryFileModel(ListModel): - FileNameRole = Qt.UserRole + 1 - FileIdRole = Qt.UserRole + 2 - FileSizeRole = Qt.UserRole + 3 - LibraryProjectIdRole = Qt.UserRole + 4 - DownloadUrlRole = Qt.UserRole + 5 - UsernameRole = Qt.UserRole + 6 - UploadedAtRole = Qt.UserRole + 7 + FileNameRole = Qt.ItemDataRole.UserRole + 1 + FileIdRole = Qt.ItemDataRole.UserRole + 2 + FileSizeRole = Qt.ItemDataRole.UserRole + 3 + LibraryProjectIdRole = Qt.ItemDataRole.UserRole + 4 + DownloadUrlRole = Qt.ItemDataRole.UserRole + 5 + UsernameRole = Qt.ItemDataRole.UserRole + 6 + UploadedAtRole = Qt.ItemDataRole.UserRole + 7 dfFileModelChanged = pyqtSignal() diff --git a/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py b/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py index d76774cab1..92aa92ef4c 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import List, Optional -from PyQt5.QtCore import Qt, pyqtSignal +from PyQt6.QtCore import Qt, pyqtSignal from UM.Logger import Logger from UM.Qt.ListModel import ListModel @@ -12,12 +12,12 @@ PROJECT_UPDATED_AT_DATETIME_FORMAT = "%d-%m-%Y" class DigitalFactoryProjectModel(ListModel): - DisplayNameRole = Qt.UserRole + 1 - LibraryProjectIdRole = Qt.UserRole + 2 - DescriptionRole = Qt.UserRole + 3 - ThumbnailUrlRole = Qt.UserRole + 5 - UsernameRole = Qt.UserRole + 6 - LastUpdatedRole = Qt.UserRole + 7 + DisplayNameRole = Qt.ItemDataRole.UserRole + 1 + LibraryProjectIdRole = Qt.ItemDataRole.UserRole + 2 + DescriptionRole = Qt.ItemDataRole.UserRole + 3 + ThumbnailUrlRole = Qt.ItemDataRole.UserRole + 5 + UsernameRole = Qt.ItemDataRole.UserRole + 6 + LastUpdatedRole = Qt.ItemDataRole.UserRole + 7 dfProjectModelChanged = pyqtSignal() diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py index 8d0670c844..e7b1aef6d1 100644 --- a/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py +++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py @@ -1,8 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QUrl -from PyQt5.QtGui import QDesktopServices +from PyQt6.QtCore import QUrl +from PyQt6.QtGui import QDesktopServices from typing import Set diff --git a/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py b/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py index 35f338fb04..154b2951a1 100644 --- a/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py +++ b/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.py @@ -8,7 +8,7 @@ from UM.i18n import i18nCatalog from UM.Settings.ContainerRegistry import ContainerRegistry from cura.PrinterOutput.FirmwareUpdater import FirmwareUpdateState -from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject +from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject from typing import Optional MYPY = False diff --git a/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml b/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml index c679c4328c..0e2fcb7d28 100644 --- a/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml +++ b/plugins/FirmwareUpdater/FirmwareUpdaterMachineAction.qml @@ -5,7 +5,7 @@ import QtQuick 2.2 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.1 -import QtQuick.Dialogs 1.2 // For filedialog +import QtQuick.Dialogs 6.0 // For filedialog import UM 1.5 as UM import Cura 1.0 as Cura @@ -92,7 +92,6 @@ Cura.MachineAction id: customFirmwareDialog title: catalog.i18nc("@title:window", "Select custom firmware") nameFilters: "Firmware image files (*.hex)" - selectExisting: true onAccepted: { updateProgressDialog.visible = true; diff --git a/plugins/ImageReader/ConfigUI.qml b/plugins/ImageReader/ConfigUI.qml index 28fd1f9106..44877fed6c 100644 --- a/plugins/ImageReader/ConfigUI.qml +++ b/plugins/ImageReader/ConfigUI.qml @@ -1,7 +1,7 @@ // Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 +import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.3 import QtQuick.Window 2.1 @@ -31,7 +31,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width text: catalog.i18nc("@action:label", "Height (mm)") - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter MouseArea { id: peak_height_label @@ -47,7 +47,7 @@ UM.Dialog Layout.minimumWidth: UM.Theme.getSize("setting_control").width selectByMouse: true objectName: "Peak_Height" - validator: RegExpValidator { regExp: /^\d{0,3}([\,|\.]\d*)?$/ } + validator: RegularExpressionValidator { regularExpression: /^\d{0,3}([\,|\.]\d*)?$/ } onTextChanged: manager.onPeakHeightChanged(text) } @@ -64,7 +64,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width text: catalog.i18nc("@action:label", "Base (mm)") - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter MouseArea { @@ -81,7 +81,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width objectName: "Base_Height" - validator: RegExpValidator { regExp: /^\d{0,3}([\,|\.]\d*)?$/ } + validator: RegularExpressionValidator { regularExpression: /^\d{0,3}([\,|\.]\d*)?$/ } onTextChanged: manager.onBaseHeightChanged(text) } @@ -98,7 +98,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width text: catalog.i18nc("@action:label", "Width (mm)") - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter MouseArea { id: width_label @@ -115,7 +115,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width focus: true - validator: RegExpValidator { regExp: /^[1-9]\d{0,2}([\,|\.]\d*)?$/ } + validator: RegularExpressionValidator { regularExpression: /^[1-9]\d{0,2}([\,|\.]\d*)?$/ } onTextChanged: manager.onWidthChanged(text) } @@ -132,7 +132,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width text: catalog.i18nc("@action:label", "Depth (mm)") - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter MouseArea { id: depth_label @@ -149,7 +149,7 @@ UM.Dialog selectByMouse: true objectName: "Depth" focus: true - validator: RegExpValidator { regExp: /^[1-9]\d{0,2}([\,|\.]\d*)?$/ } + validator: RegularExpressionValidator { regularExpression: /^[1-9]\d{0,2}([\,|\.]\d*)?$/ } onTextChanged: manager.onDepthChanged(text) } @@ -166,7 +166,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width text: "" - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter MouseArea { id: lighter_is_higher_label @@ -203,7 +203,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width text: catalog.i18nc("@action:label", "Color Model") - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter MouseArea { id: color_model_label @@ -240,7 +240,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width text: catalog.i18nc("@action:label", "1mm Transmittance (%)") - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter MouseArea { id: transmittance_label @@ -255,7 +255,7 @@ UM.Dialog Layout.minimumWidth: UM.Theme.getSize("setting_control").width selectByMouse: true objectName: "Transmittance" - validator: RegExpValidator { regExp: /^[1-9]\d{0,2}([\,|\.]\d*)?$/ } + validator: RegularExpressionValidator { regularExpression: /^[1-9]\d{0,2}([\,|\.]\d*)?$/ } onTextChanged: manager.onTransmittanceChanged(text) UM.ToolTip @@ -272,7 +272,7 @@ UM.Dialog Layout.fillWidth: true Layout.minimumWidth: UM.Theme.getSize("setting_control").width text: catalog.i18nc("@action:label", "Smoothing") - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter MouseArea { diff --git a/plugins/ImageReader/ImageReader.py b/plugins/ImageReader/ImageReader.py index 4a32ed71f1..b6895f5554 100644 --- a/plugins/ImageReader/ImageReader.py +++ b/plugins/ImageReader/ImageReader.py @@ -5,8 +5,8 @@ import numpy import math -from PyQt5.QtGui import QImage, qRed, qGreen, qBlue, qAlpha -from PyQt5.QtCore import Qt +from PyQt6.QtGui import QImage, qRed, qGreen, qBlue, qAlpha +from PyQt6.QtCore import Qt from UM.Mesh.MeshReader import MeshReader from UM.Mesh.MeshBuilder import MeshBuilder @@ -63,7 +63,7 @@ class ImageReader(MeshReader): aspect = height / width if img.width() < 2 or img.height() < 2: - img = img.scaled(width, height, Qt.IgnoreAspectRatio) + img = img.scaled(width, height, Qt.AspectRatioMode.IgnoreAspectRatio) height_from_base = max(height_from_base, 0) base_height = max(base_height, 0) @@ -84,15 +84,15 @@ class ImageReader(MeshReader): width = int(max(round(width * scale_factor), 2)) height = int(max(round(height * scale_factor), 2)) - img = img.scaled(width, height, Qt.IgnoreAspectRatio) + img = img.scaled(width, height, Qt.AspectRatioMode.IgnoreAspectRatio) width_minus_one = width - 1 height_minus_one = height - 1 Job.yieldThread() - texel_width = 1.0 / (width_minus_one) * scale_vector.x - texel_height = 1.0 / (height_minus_one) * scale_vector.z + texel_width = 1.0 / width_minus_one * scale_vector.x + texel_height = 1.0 / height_minus_one * scale_vector.z height_data = numpy.zeros((height, width), dtype = numpy.float32) diff --git a/plugins/ImageReader/ImageReaderUI.py b/plugins/ImageReader/ImageReaderUI.py index 103cd6f7e8..54aa8eadc0 100644 --- a/plugins/ImageReader/ImageReaderUI.py +++ b/plugins/ImageReader/ImageReaderUI.py @@ -4,7 +4,7 @@ import os import threading -from PyQt5.QtCore import Qt, pyqtSignal, QObject +from PyQt6.QtCore import Qt, pyqtSignal, QObject from UM.FlameProfiler import pyqtSlot from UM.Application import Application from UM.PluginRegistry import PluginRegistry @@ -85,7 +85,7 @@ class ImageReaderUI(QObject): Logger.log("d", "Creating ImageReader config UI") path = os.path.join(PluginRegistry.getInstance().getPluginPath("ImageReader"), "ConfigUI.qml") self._ui_view = Application.getInstance().createQmlComponent(path, {"manager": self}) - self._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMinimizeButtonHint & ~Qt.WindowMaximizeButtonHint) + self._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowType.WindowCloseButtonHint & ~Qt.WindowType.WindowMinimizeButtonHint & ~Qt.WindowType.WindowMaximizeButtonHint) self._disable_size_callbacks = False @pyqtSlot() diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py index 96bfa7062b..0f618635af 100755 --- a/plugins/MachineSettingsAction/MachineSettingsAction.py +++ b/plugins/MachineSettingsAction/MachineSettingsAction.py @@ -3,7 +3,7 @@ from typing import Optional, TYPE_CHECKING -from PyQt5.QtCore import pyqtProperty +from PyQt6.QtCore import pyqtProperty import UM.i18n from UM.FlameProfiler import pyqtSlot @@ -18,7 +18,7 @@ from cura.Settings.CuraStackBuilder import CuraStackBuilder from cura.Settings.cura_empty_instance_containers import isEmptyContainer if TYPE_CHECKING: - from PyQt5.QtCore import QObject + from PyQt6.QtCore import QObject catalog = UM.i18n.i18nCatalog("cura") diff --git a/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml b/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml index db581e8cf5..32c8f8df63 100644 --- a/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml +++ b/plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml @@ -47,7 +47,7 @@ Item Column { Layout.fillWidth: true - Layout.alignment: Qt.AlignTop + Layout.alignment: Qt.AlignmentFlag.AlignTop spacing: base.columnSpacing @@ -178,7 +178,7 @@ Item Column { Layout.fillWidth: true - Layout.alignment: Qt.AlignTop + Layout.alignment: Qt.AlignmentFlag.AlignTop spacing: base.columnSpacing diff --git a/plugins/Marketplace/LocalPackageList.py b/plugins/Marketplace/LocalPackageList.py index a609e72d33..ae719b2699 100644 --- a/plugins/Marketplace/LocalPackageList.py +++ b/plugins/Marketplace/LocalPackageList.py @@ -3,7 +3,7 @@ from typing import Any, Dict, List, Optional, TYPE_CHECKING -from PyQt5.QtCore import pyqtSlot, QObject +from PyQt6.QtCore import pyqtSlot, QObject from UM.Version import Version from UM.i18n import i18nCatalog @@ -15,8 +15,8 @@ from .PackageModel import PackageModel from .Constants import PACKAGE_UPDATES_URL if TYPE_CHECKING: - from PyQt5.QtCore import QObject - from PyQt5.QtNetwork import QNetworkReply + from PyQt6.QtCore import QObject + from PyQt6.QtNetwork import QNetworkReply catalog = i18nCatalog("cura") diff --git a/plugins/Marketplace/Marketplace.py b/plugins/Marketplace/Marketplace.py index b9632e5fb0..171e3f915b 100644 --- a/plugins/Marketplace/Marketplace.py +++ b/plugins/Marketplace/Marketplace.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import os.path -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from typing import Optional, cast from cura.CuraApplication import CuraApplication # Creating QML objects and managing packages. diff --git a/plugins/Marketplace/PackageList.py b/plugins/Marketplace/PackageList.py index 04b602002c..30162afe6c 100644 --- a/plugins/Marketplace/PackageList.py +++ b/plugins/Marketplace/PackageList.py @@ -4,7 +4,7 @@ import tempfile import json import os.path -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, Qt +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, Qt from typing import cast, Dict, Optional, Set, TYPE_CHECKING from UM.i18n import i18nCatalog @@ -22,8 +22,8 @@ from .PackageModel import PackageModel from .Constants import USER_PACKAGES_URL, PACKAGES_URL if TYPE_CHECKING: - from PyQt5.QtCore import QObject - from PyQt5.QtNetwork import QNetworkReply + from PyQt6.QtCore import QObject + from PyQt6.QtNetwork import QNetworkReply catalog = i18nCatalog("cura") @@ -32,7 +32,7 @@ class PackageList(ListModel): """ A List model for Packages, this class serves as parent class for more detailed implementations. such as Packages obtained from Remote or Local source """ - PackageRole = Qt.UserRole + 1 + PackageRole = Qt.ItemDataRole.UserRole + 1 DISK_WRITE_BUFFER_SIZE = 256 * 1024 # 256 KB def __init__(self, parent: Optional["QObject"] = None) -> None: diff --git a/plugins/Marketplace/PackageModel.py b/plugins/Marketplace/PackageModel.py index 29c8abe653..bd1b0681fc 100644 --- a/plugins/Marketplace/PackageModel.py +++ b/plugins/Marketplace/PackageModel.py @@ -5,8 +5,8 @@ import re from enum import Enum from typing import Any, cast, Dict, List, Optional -from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal, pyqtSlot -from PyQt5.QtQml import QQmlEngine +from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal, pyqtSlot +from PyQt6.QtQml import QQmlEngine from cura.CuraApplication import CuraApplication from cura.CuraPackageManager import CuraPackageManager @@ -31,7 +31,7 @@ class PackageModel(QObject): :param parent: The parent QML object that controls the lifetime of this model (normally a PackageList). """ super().__init__(parent) - QQmlEngine.setObjectOwnership(self, QQmlEngine.CppOwnership) + QQmlEngine.setObjectOwnership(self, QQmlEngine.ObjectOwnership.CppOwnership) self._package_manager: CuraPackageManager = cast(CuraPackageManager, CuraApplication.getInstance().getPackageManager()) self._plugin_registry: PluginRegistry = CuraApplication.getInstance().getPluginRegistry() diff --git a/plugins/Marketplace/RemotePackageList.py b/plugins/Marketplace/RemotePackageList.py index 4c82f2b29a..67ba8c75da 100644 --- a/plugins/Marketplace/RemotePackageList.py +++ b/plugins/Marketplace/RemotePackageList.py @@ -1,8 +1,8 @@ # Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot -from PyQt5.QtNetwork import QNetworkReply +from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtNetwork import QNetworkReply from typing import Optional, TYPE_CHECKING from UM.i18n import i18nCatalog @@ -14,7 +14,7 @@ from .PackageList import PackageList from .PackageModel import PackageModel # The contents of this list. if TYPE_CHECKING: - from PyQt5.QtCore import QObject + from PyQt6.QtCore import QObject catalog = i18nCatalog("cura") diff --git a/plugins/Marketplace/resources/images/Plugin.svg b/plugins/Marketplace/resources/images/Plugin.svg index 51356d842c..b7616b5876 100644 --- a/plugins/Marketplace/resources/images/Plugin.svg +++ b/plugins/Marketplace/resources/images/Plugin.svg @@ -1,3 +1,3 @@ - - + + diff --git a/plugins/Marketplace/resources/images/Spool.svg b/plugins/Marketplace/resources/images/Spool.svg index dae9b43030..3faffb7a52 100644 --- a/plugins/Marketplace/resources/images/Spool.svg +++ b/plugins/Marketplace/resources/images/Spool.svg @@ -1,3 +1,3 @@ - - + + diff --git a/plugins/Marketplace/resources/qml/LicenseDialog.qml b/plugins/Marketplace/resources/qml/LicenseDialog.qml index 09d7c5b59a..2f3f4ffc12 100644 --- a/plugins/Marketplace/resources/qml/LicenseDialog.qml +++ b/plugins/Marketplace/resources/qml/LicenseDialog.qml @@ -2,7 +2,6 @@ //Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 -import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 @@ -34,7 +33,7 @@ UM.Dialog spacing: UM.Theme.getSize("default_margin").width leftPadding: UM.Theme.getSize("narrow_margin").width - UM.RecolorImage + UM.ColorImage { id: icon width: UM.Theme.getSize("marketplace_large_icon").width @@ -50,7 +49,7 @@ UM.Dialog font: UM.Theme.getFont("large") anchors.verticalCenter: icon.verticalCenter height: UM.Theme.getSize("marketplace_large_icon").height - verticalAlignment: Qt.AlignVCenter + verticalAlignment: Qt.AlignmentFlag.AlignVCenter wrapMode: Text.Wrap renderType: Text.NativeRendering } diff --git a/plugins/Marketplace/resources/qml/ManageButton.qml b/plugins/Marketplace/resources/qml/ManageButton.qml index 36022ffd54..5f4b3dcadd 100644 --- a/plugins/Marketplace/resources/qml/ManageButton.qml +++ b/plugins/Marketplace/resources/qml/ManageButton.qml @@ -46,7 +46,7 @@ Item height: UM.Theme.getSize("action_button").height width: childrenRect.width - UM.RecolorImage + UM.ColorImage { id: busyIndicator visible: parent.visible diff --git a/plugins/Marketplace/resources/qml/ManagePackagesButton.qml b/plugins/Marketplace/resources/qml/ManagePackagesButton.qml index fc9e7d757f..a32de2b809 100644 --- a/plugins/Marketplace/resources/qml/ManagePackagesButton.qml +++ b/plugins/Marketplace/resources/qml/ManagePackagesButton.qml @@ -33,7 +33,7 @@ TabButton visible: root.hovered } - UM.RecolorImage + UM.ColorImage { id: icon diff --git a/plugins/Marketplace/resources/qml/Marketplace.qml b/plugins/Marketplace/resources/qml/Marketplace.qml index 8fcba852bd..887886fd22 100644 --- a/plugins/Marketplace/resources/qml/Marketplace.qml +++ b/plugins/Marketplace/resources/qml/Marketplace.qml @@ -251,7 +251,7 @@ Window margins: UM.Theme.getSize("default_margin").width } spacing: UM.Theme.getSize("default_margin").width - UM.RecolorImage + UM.ColorImage { id: bannerIcon source: UM.Theme.getIcon("Plugin") diff --git a/plugins/Marketplace/resources/qml/OnboardBanner.qml b/plugins/Marketplace/resources/qml/OnboardBanner.qml index 7d973cb74a..278c50ab57 100644 --- a/plugins/Marketplace/resources/qml/OnboardBanner.qml +++ b/plugins/Marketplace/resources/qml/OnboardBanner.qml @@ -20,7 +20,7 @@ Rectangle color: UM.Theme.getColor("action_panel_secondary") // Icon - UM.RecolorImage + UM.ColorImage { id: onboardingIcon anchors @@ -70,7 +70,7 @@ Rectangle wrapMode: Text.Wrap elide: Text.ElideRight - onLineLaidOut: + onLineLaidOut: (line) => { if(line.isLast) { diff --git a/plugins/Marketplace/resources/qml/PackageCardHeader.qml b/plugins/Marketplace/resources/qml/PackageCardHeader.qml index 1c39d4b063..8e25e5c64c 100644 --- a/plugins/Marketplace/resources/qml/PackageCardHeader.qml +++ b/plugins/Marketplace/resources/qml/PackageCardHeader.qml @@ -47,23 +47,21 @@ Item sourceSize.width: width } - UM.RecolorImage + UM.ColorImage { visible: !parent.packageHasIcon anchors.fill: parent - sourceSize.height: height - sourceSize.width: width color: UM.Theme.getColor("text") source: { switch (packageData.packageType) { case "plugin": - return "../images/Plugin.svg"; + return Qt.resolvedUrl("../images/Plugin.svg"); case "material": - return "../images/Spool.svg"; + return Qt.resolvedUrl("../images/Spool.svg"); default: - return "../images/placeholder.svg"; + return Qt.resolvedUrl("../images/placeholder.svg"); } } } @@ -123,7 +121,7 @@ Item Layout.preferredWidth: UM.Theme.getSize("card_tiny_icon").width + 2 * padding Layout.preferredHeight: UM.Theme.getSize("card_tiny_icon").width + 2 * padding - contentItem: UM.RecolorImage + contentItem: UM.ColorImage { source: UM.Theme.getIcon("LinkExternal") color: UM.Theme.getColor("icon") diff --git a/plugins/Marketplace/resources/qml/PackageDetails.qml b/plugins/Marketplace/resources/qml/PackageDetails.qml index 6e5ec0fbf5..218669d81e 100644 --- a/plugins/Marketplace/resources/qml/PackageDetails.qml +++ b/plugins/Marketplace/resources/qml/PackageDetails.qml @@ -31,7 +31,7 @@ Item Cura.SecondaryButton { - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter Layout.preferredHeight: UM.Theme.getSize("action_button").height Layout.preferredWidth: height @@ -47,7 +47,7 @@ Item Label { - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter Layout.fillWidth: true text: detailPage.title @@ -93,4 +93,4 @@ Item } } } -} \ No newline at end of file +} diff --git a/plugins/Marketplace/resources/qml/PackagePage.qml b/plugins/Marketplace/resources/qml/PackagePage.qml index e590ee6091..455b2b8d5d 100644 --- a/plugins/Marketplace/resources/qml/PackagePage.qml +++ b/plugins/Marketplace/resources/qml/PackagePage.qml @@ -46,7 +46,7 @@ Rectangle // But we re-use the package page for the manage plugins as well. The one user that doesn't see // the num downloads is an acceptable "sacrifice" to make this easy to fix. visible: packageData.downloadCount != "0" - UM.RecolorImage + UM.ColorImage { id: downloadsIcon width: UM.Theme.getSize("card_tiny_icon").width diff --git a/plugins/Marketplace/resources/qml/Packages.qml b/plugins/Marketplace/resources/qml/Packages.qml index 56fffe036e..d86536639c 100644 --- a/plugins/Marketplace/resources/qml/Packages.qml +++ b/plugins/Marketplace/resources/qml/Packages.qml @@ -213,7 +213,7 @@ ListView status: UM.StatusIcon.Status.ERROR visible: false } - UM.RecolorImage + UM.ColorImage { id: loadMoreIcon anchors.fill: parent diff --git a/plugins/Marketplace/resources/qml/VerifiedIcon.qml b/plugins/Marketplace/resources/qml/VerifiedIcon.qml index 6b9d7b6017..e701c5a91b 100644 --- a/plugins/Marketplace/resources/qml/VerifiedIcon.qml +++ b/plugins/Marketplace/resources/qml/VerifiedIcon.qml @@ -32,7 +32,7 @@ Control anchors.fill: parent color: UM.Theme.getColor("action_button_hovered") radius: width - UM.RecolorImage + UM.ColorImage { anchors.fill: parent color: UM.Theme.getColor("primary") diff --git a/plugins/ModelChecker/ModelChecker.py b/plugins/ModelChecker/ModelChecker.py index 321ce8d007..b24c40546d 100644 --- a/plugins/ModelChecker/ModelChecker.py +++ b/plugins/ModelChecker/ModelChecker.py @@ -3,7 +3,7 @@ import os -from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, pyqtProperty, QTimer +from PyQt6.QtCore import QObject, pyqtSlot, pyqtSignal, pyqtProperty, QTimer from UM.Application import Application from UM.Extension import Extension diff --git a/plugins/ModelChecker/ModelChecker.qml b/plugins/ModelChecker/ModelChecker.qml index 41c49c9a25..85ee774a8b 100644 --- a/plugins/ModelChecker/ModelChecker.qml +++ b/plugins/ModelChecker/ModelChecker.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import UM 1.2 as UM +import UM 1.5 as UM UM.SimpleButton diff --git a/plugins/MonitorStage/MonitorMain.qml b/plugins/MonitorStage/MonitorMain.qml index aa717ce95c..8992606d90 100644 --- a/plugins/MonitorStage/MonitorMain.qml +++ b/plugins/MonitorStage/MonitorMain.qml @@ -123,7 +123,7 @@ Rectangle visible: !isNetworkConfigured && isNetworkConfigurable width: childrenRect.width - UM.RecolorImage + UM.ColorImage { id: externalLinkIcon anchors.verticalCenter: parent.verticalCenter diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py index 9fca618322..15f37e499d 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py @@ -1,7 +1,7 @@ # Copyright (c) 2020 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtProperty +from PyQt6.QtCore import pyqtProperty from UM.FlameProfiler import pyqtSlot from UM.Application import Application diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index a53f051db8..c6a3817c07 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -79,7 +79,7 @@ Item { id: normalButton text: catalog.i18nc("@label", "Normal model") - toolItem: UM.RecolorImage + toolItem: UM.ColorImage { source: UM.Theme.getIcon("Infill0") color: UM.Theme.getColor("icon") @@ -94,7 +94,7 @@ Item { id: supportMeshButton text: catalog.i18nc("@label", "Print as support") - toolItem: UM.RecolorImage + toolItem: UM.ColorImage { source: UM.Theme.getIcon("MeshTypeSupport") color: UM.Theme.getColor("icon") @@ -109,7 +109,7 @@ Item { id: overlapMeshButton text: catalog.i18nc("@label", "Modify settings for overlaps") - toolItem: UM.RecolorImage + toolItem: UM.ColorImage { source: UM.Theme.getIcon("MeshTypeIntersect") color: UM.Theme.getColor("icon") @@ -124,7 +124,7 @@ Item { id: antiOverhangMeshButton text: catalog.i18nc("@label", "Don't support overlaps") - toolItem: UM.RecolorImage + toolItem: UM.ColorImage { source: UM.Theme.getIcon("BlockSupportOverlaps") color: UM.Theme.getColor("icon") @@ -304,12 +304,11 @@ Item background: Item { - UM.RecolorImage + UM.ColorImage { anchors.verticalCenter: parent.verticalCenter width: parent.width height: width - sourceSize.height: width color: parent.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") source: UM.Theme.getIcon("Minus") } diff --git a/plugins/PerObjectSettingsTool/__init__.py b/plugins/PerObjectSettingsTool/__init__.py index d3c6d236ef..9c3e5f31de 100644 --- a/plugins/PerObjectSettingsTool/__init__.py +++ b/plugins/PerObjectSettingsTool/__init__.py @@ -3,7 +3,7 @@ from . import PerObjectSettingsTool from . import PerObjectSettingVisibilityHandler -from PyQt5.QtQml import qmlRegisterType +from PyQt6.QtQml import qmlRegisterType from UM.i18n import i18nCatalog i18n_catalog = i18nCatalog("cura") diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py index 755d815d0a..845ad45341 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py @@ -9,7 +9,7 @@ import pkgutil import sys from typing import Dict, Type, TYPE_CHECKING, List, Optional, cast -from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot from UM.Application import Application from UM.Extension import Extension diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml index 8ce6e3f94f..d4cba61496 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml @@ -143,14 +143,12 @@ UM.Dialog } } - UM.RecolorImage + UM.ColorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height color: parent.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("text_disabled") source: UM.Theme.getIcon("ChevronSingleDown") } @@ -175,14 +173,12 @@ UM.Dialog } } - UM.RecolorImage + UM.ColorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height color: upButton.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("text_disabled") source: UM.Theme.getIcon("ChevronSingleUp") } @@ -200,14 +196,12 @@ UM.Dialog onClicked: manager.removeScriptByIndex(index) } - UM.RecolorImage + UM.ColorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height color: UM.Theme.getColor("text") source: UM.Theme.getIcon("Cancel") } @@ -237,8 +231,8 @@ UM.Dialog onTriggered: manager.addScriptToList(modelData.toString()) } - onObjectAdded: scriptsMenu.insertItem(index, object) - onObjectRemoved: scriptsMenu.removeItem(object) + onObjectAdded: function(index, object) { scriptsMenu.insertItem(index, object)} + onObjectRemoved: function(object) { scriptsMenu.removeItem(object) } } } @@ -481,7 +475,7 @@ UM.Dialog } toolTipContentAlignment: UM.Enums.ContentAlignment.AlignLeft onClicked: dialog.show() - iconSource: "Script.svg" +// iconSource: "Script.svg" fixedWidthMode: false } diff --git a/plugins/PostProcessingPlugin/scripts/CreateThumbnail.py b/plugins/PostProcessingPlugin/scripts/CreateThumbnail.py index 0ce6ac6eff..fef66915bf 100644 --- a/plugins/PostProcessingPlugin/scripts/CreateThumbnail.py +++ b/plugins/PostProcessingPlugin/scripts/CreateThumbnail.py @@ -2,7 +2,7 @@ import base64 from UM.Logger import Logger from cura.Snapshot import Snapshot -from PyQt5.QtCore import QByteArray, QIODevice, QBuffer +from PyQt6.QtCore import QByteArray, QIODevice, QBuffer from ..Script import Script @@ -22,7 +22,7 @@ class CreateThumbnail(Script): Logger.log("d", "Encoding thumbnail image...") try: thumbnail_buffer = QBuffer() - thumbnail_buffer.open(QBuffer.ReadWrite) + thumbnail_buffer.open(QBuffer.OpenModeFlag.ReadWrite) thumbnail_image = snapshot thumbnail_image.save(thumbnail_buffer, "PNG") base64_bytes = base64.b64encode(thumbnail_buffer.data()) diff --git a/plugins/PrepareStage/PrepareMenu.qml b/plugins/PrepareStage/PrepareMenu.qml index f0779df98f..d6bff1792e 100644 --- a/plugins/PrepareStage/PrepareMenu.qml +++ b/plugins/PrepareStage/PrepareMenu.qml @@ -91,13 +91,11 @@ Item height: parent.height width: visible ? (headerPadding * 3 + UM.Theme.getSize("button_icon").height + iconSize) : 0 - headerItem: UM.RecolorImage + headerItem: UM.ColorImage { id: menuIcon source: UM.Theme.getIcon("Folder", "medium") color: UM.Theme.getColor("icon") - - sourceSize.height: height } contentItem: Item @@ -111,13 +109,13 @@ Item //The column doesn't automatically listen to its children rect if the children change internally, so we need to explicitly update the size. onChildrenRectChanged: { - popup.height = childrenRect.height - popup.width = childrenRect.width + popup.implicitHeight = childrenRect.height + popup.implicitWidth = childrenRect.width } onPositioningComplete: { - popup.height = childrenRect.height - popup.width = childrenRect.width + popup.implicitHeight = childrenRect.height + popup.implicitWidth = childrenRect.width } Repeater @@ -177,7 +175,7 @@ Item contentItem: Item { - UM.RecolorImage + UM.ColorImage { id: buttonIcon source: UM.Theme.getIcon("Folder", "medium") @@ -185,8 +183,6 @@ Item width: UM.Theme.getSize("button_icon").width height: UM.Theme.getSize("button_icon").height color: UM.Theme.getColor("icon") - - sourceSize.height: height } } diff --git a/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py b/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py index d60e4b34f0..873076ea71 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDrivePlugin.py @@ -21,7 +21,7 @@ class RemovableDrivePlugin(OutputDevicePlugin): super().__init__() self._update_thread = threading.Thread(target = self._updateThread) - self._update_thread.setDaemon(True) + self._update_thread.deamon = True self._check_updates = True diff --git a/plugins/SimulationView/LayerSlider.qml b/plugins/SimulationView/LayerSlider.qml index 0a24ca9023..f08c72c1f7 100644 --- a/plugins/SimulationView/LayerSlider.qml +++ b/plugins/SimulationView/LayerSlider.qml @@ -266,7 +266,7 @@ Item anchors.bottom: parent.top anchors.bottomMargin: UM.Theme.getSize("narrow_margin").height anchors.horizontalCenter: parent.horizontalCenter - target: Qt.point(parent.width / 2, parent.top) + target: Qt.point(parent.width / 2, 1) visible: sliderRoot.activeHandle == parent || sliderRoot.activeHandle == rangeHandle // custom properties @@ -376,7 +376,7 @@ Item anchors.top: parent.bottom anchors.topMargin: UM.Theme.getSize("narrow_margin").height anchors.horizontalCenter: parent.horizontalCenter - target: Qt.point(parent.width / 2, parent.bottom) + target: Qt.point(parent.width / 2, -1) visible: sliderRoot.activeHandle == parent || sliderRoot.activeHandle == rangeHandle // custom properties diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index af6b538f26..532ef459c0 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -3,9 +3,9 @@ import sys -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QOpenGLContext -from PyQt5.QtWidgets import QApplication +from PyQt6.QtCore import Qt +from PyQt6.QtGui import QOpenGLContext +from PyQt6.QtWidgets import QApplication from UM.Application import Application from UM.Event import Event, KeyEvent @@ -598,8 +598,8 @@ class SimulationView(CuraView): def event(self, event) -> bool: modifiers = QApplication.keyboardModifiers() - ctrl_is_active = modifiers & Qt.ControlModifier - shift_is_active = modifiers & Qt.ShiftModifier + ctrl_is_active = modifiers & Qt.KeyboardModifier.ControlModifier + shift_is_active = modifiers & Qt.KeyboardModifier.ShiftModifier if event.type == Event.KeyPressEvent and ctrl_is_active: amount = 10 if shift_is_active else 1 if event.key == KeyEvent.UpKey: diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 4fb238f6da..a82d1e3db9 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -75,7 +75,7 @@ Item UM.SimpleButton { id: playButton - iconSource: !isSimulationPlaying ? "./resources/Play.svg": "./resources/Pause.svg" + iconSource: Qt.resolvedUrl(!isSimulationPlaying ? "./resources/Play.svg": "./resources/Pause.svg") width: UM.Theme.getSize("small_button").width height: UM.Theme.getSize("small_button").height hoverColor: UM.Theme.getColor("slider_handle_active") diff --git a/plugins/SimulationView/SimulationViewMenuComponent.qml b/plugins/SimulationView/SimulationViewMenuComponent.qml index ba13a75ea7..a811fea5db 100644 --- a/plugins/SimulationView/SimulationViewMenuComponent.qml +++ b/plugins/SimulationView/SimulationViewMenuComponent.qml @@ -1,10 +1,9 @@ // Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.4 +import QtQuick 2.15 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.1 -import QtGraphicalEffects 1.0 import UM 1.5 as UM import Cura 1.0 as Cura @@ -137,7 +136,7 @@ Cura.ExpandableComponent model: layerViewTypes visible: !UM.SimulationView.compatibilityMode - onActivated: UM.Preferences.setValue("layerview/layer_view_type", index) + onActivated: (index) => {UM.Preferences.setValue("layerview/layer_view_type", index)} Component.onCompleted: { @@ -484,43 +483,28 @@ Cura.ExpandableComponent border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - LinearGradient + gradient: Gradient { - anchors + orientation: Gradient.Horizontal + GradientStop { - left: parent.left - leftMargin: UM.Theme.getSize("default_lining").width - right: parent.right - rightMargin: UM.Theme.getSize("default_lining").width - top: parent.top - topMargin: UM.Theme.getSize("default_lining").width - bottom: parent.bottom - bottomMargin: UM.Theme.getSize("default_lining").width + position: 0.000 + color: Qt.rgba(0, 0, 1, 1) } - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) - gradient: Gradient + GradientStop { - GradientStop - { - position: 0.000 - color: Qt.rgba(0, 0, 1, 1) - } - GradientStop - { - position: 0.25 - color: Qt.rgba(0.25, 1, 0, 1) - } - GradientStop - { - position: 0.375 - color: Qt.rgba(0.375, 0.5, 0, 1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(1, 0.5, 0, 1) - } + position: 0.25 + color: Qt.rgba(0.25, 1, 0, 1) + } + GradientStop + { + position: 0.375 + color: Qt.rgba(0.375, 0.5, 0, 1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(1, 0.5, 0, 1) } } } @@ -538,48 +522,33 @@ Cura.ExpandableComponent border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - LinearGradient + gradient: Gradient { - anchors + orientation: Gradient.Horizontal + GradientStop { - left: parent.left - leftMargin: UM.Theme.getSize("default_lining").width - right: parent.right - rightMargin: UM.Theme.getSize("default_lining").width - top: parent.top - topMargin: UM.Theme.getSize("default_lining").width - bottom: parent.bottom - bottomMargin: UM.Theme.getSize("default_lining").width + position: 0.000 + color: Qt.rgba(0, 0, 0.5, 1) } - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) - gradient: Gradient + GradientStop { - GradientStop - { - position: 0.000 - color: Qt.rgba(0, 0, 0.5, 1) - } - GradientStop - { - position: 0.25 - color: Qt.rgba(0, 0.375, 0.75, 1) - } - GradientStop - { - position: 0.5 - color: Qt.rgba(0, 0.75, 0.5, 1) - } - GradientStop - { - position: 0.75 - color: Qt.rgba(1, 0.75, 0.25, 1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(1, 1, 0, 1) - } + position: 0.25 + color: Qt.rgba(0, 0.375, 0.75, 1) + } + GradientStop + { + position: 0.5 + color: Qt.rgba(0, 0.75, 0.5, 1) + } + GradientStop + { + position: 0.75 + color: Qt.rgba(1, 0.75, 0.25, 1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(1, 1, 0, 1) } } } @@ -597,68 +566,53 @@ Cura.ExpandableComponent border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - LinearGradient + gradient: Gradient { - anchors + orientation: Gradient.Horizontal + GradientStop { - left: parent.left - leftMargin: UM.Theme.getSize("default_lining").width - right: parent.right - rightMargin: UM.Theme.getSize("default_lining").width - top: parent.top - topMargin: UM.Theme.getSize("default_lining").width - bottom: parent.bottom - bottomMargin: UM.Theme.getSize("default_lining").width + position: 0.0 + color: Qt.rgba(0, 0, 0.5, 1) } - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) - gradient: Gradient + GradientStop { - GradientStop - { - position: 0.0 - color: Qt.rgba(0, 0, 0.5, 1) - } - GradientStop - { - position: 0.125 - color: Qt.rgba(0, 0.0, 1.0, 1) - } - GradientStop - { - position: 0.25 - color: Qt.rgba(0, 0.5, 1.0, 1) - } - GradientStop - { - position: 0.375 - color: Qt.rgba(0.0, 1.0, 1.0, 1) - } - GradientStop - { - position: 0.5 - color: Qt.rgba(0.5, 1.0, 0.5, 1) - } - GradientStop - { - position: 0.625 - color: Qt.rgba(1.0, 1.0, 0.0, 1) - } - GradientStop - { - position: 0.75 - color: Qt.rgba(1.0, 0.5, 0, 1) - } - GradientStop - { - position: 0.875 - color: Qt.rgba(1.0, 0.0, 0, 1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(0.5, 0, 0, 1) - } + position: 0.125 + color: Qt.rgba(0, 0.0, 1.0, 1) + } + GradientStop + { + position: 0.25 + color: Qt.rgba(0, 0.5, 1.0, 1) + } + GradientStop + { + position: 0.375 + color: Qt.rgba(0.0, 1.0, 1.0, 1) + } + GradientStop + { + position: 0.5 + color: Qt.rgba(0.5, 1.0, 0.5, 1) + } + GradientStop + { + position: 0.625 + color: Qt.rgba(1.0, 1.0, 0.0, 1) + } + GradientStop + { + position: 0.75 + color: Qt.rgba(1.0, 0.5, 0, 1) + } + GradientStop + { + position: 0.875 + color: Qt.rgba(1.0, 0.0, 0, 1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(0.5, 0, 0, 1) } } } diff --git a/plugins/SimulationView/SimulationViewProxy.py b/plugins/SimulationView/SimulationViewProxy.py index 7d78e93ca5..669f7fdbcc 100644 --- a/plugins/SimulationView/SimulationViewProxy.py +++ b/plugins/SimulationView/SimulationViewProxy.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import TYPE_CHECKING -from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty +from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty from UM.FlameProfiler import pyqtSlot from UM.Application import Application diff --git a/plugins/SimulationView/__init__.py b/plugins/SimulationView/__init__.py index 420ee60660..c3f2b1629c 100644 --- a/plugins/SimulationView/__init__.py +++ b/plugins/SimulationView/__init__.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtQml import qmlRegisterSingletonType +from PyQt6.QtQml import qmlRegisterSingletonType from UM.i18n import i18nCatalog from . import SimulationViewProxy, SimulationView @@ -24,5 +24,5 @@ def createSimulationViewProxy(engine, script_engine): def register(app): simulation_view = SimulationView.SimulationView() - qmlRegisterSingletonType(SimulationViewProxy.SimulationViewProxy, "UM", 1, 0, "SimulationView", simulation_view.getProxy) + qmlRegisterSingletonType(SimulationViewProxy.SimulationViewProxy, "UM", 1, 0, simulation_view.getProxy, "SimulationView") return { "view": simulation_view} diff --git a/plugins/SliceInfoPlugin/MoreInfoWindow.qml b/plugins/SliceInfoPlugin/MoreInfoWindow.qml index 3a6b6c8741..2f60089343 100644 --- a/plugins/SliceInfoPlugin/MoreInfoWindow.qml +++ b/plugins/SliceInfoPlugin/MoreInfoWindow.qml @@ -5,10 +5,9 @@ import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Window 2.2 -import UM 1.3 as UM +import UM 1.5 as UM import Cura 1.1 as Cura - Window { UM.I18nCatalog { id: catalog; name: "cura" } diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 0e8db0f88a..0bf76f8423 100755 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -7,8 +7,8 @@ import platform import time from typing import cast, Optional, Set, TYPE_CHECKING -from PyQt5.QtCore import pyqtSlot, QObject -from PyQt5.QtNetwork import QNetworkRequest +from PyQt6.QtCore import pyqtSlot, QObject +from PyQt6.QtNetwork import QNetworkRequest from UM.Extension import Extension from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator @@ -20,7 +20,7 @@ from UM.Qt.Duration import DurationFormat from cura import ApplicationMetadata if TYPE_CHECKING: - from PyQt5.QtNetwork import QNetworkReply + from PyQt6.QtNetwork import QNetworkReply catalog = i18nCatalog("cura") @@ -289,7 +289,7 @@ class SliceInfo(QObject, Extension): Logger.logException("e", "Exception raised while sending slice info.") # But we should be notified about these problems of course. def _onRequestFinished(self, reply: "QNetworkReply") -> None: - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + status_code = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) if status_code == 200: Logger.log("i", "SliceInfo sent successfully") return diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index f12c1aae01..b7aeb90da4 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -6,8 +6,8 @@ from UM.View.View import View from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Selection import Selection from UM.Resources import Resources -from PyQt5.QtGui import QOpenGLContext, QDesktopServices, QImage -from PyQt5.QtCore import QSize, QUrl +from PyQt6.QtGui import QOpenGLContext, QDesktopServices, QImage +from PyQt6.QtCore import QSize, QUrl import numpy as np import time @@ -296,7 +296,7 @@ class SolidView(View): self._next_xray_checking_time = time.time() + self._xray_checking_update_time xray_img = self._xray_pass.getOutput() - xray_img = xray_img.convertToFormat(QImage.Format_RGB888) + xray_img = xray_img.convertToFormat(QImage.Format.Format_RGB888) # We can't just read the image since the pixels are aligned to internal memory positions. # xray_img.byteCount() != xray_img.width() * xray_img.height() * 3 diff --git a/plugins/SupportEraser/SupportEraser.py b/plugins/SupportEraser/SupportEraser.py index b64a0f4eed..0a714396aa 100644 --- a/plugins/SupportEraser/SupportEraser.py +++ b/plugins/SupportEraser/SupportEraser.py @@ -1,8 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import Qt, QTimer -from PyQt5.QtWidgets import QApplication +from PyQt6.QtCore import Qt, QTimer +from PyQt6.QtWidgets import QApplication from UM.Application import Application from UM.Math.Vector import Vector @@ -31,7 +31,7 @@ import numpy class SupportEraser(Tool): def __init__(self): super().__init__() - self._shortcut_key = Qt.Key_E + self._shortcut_key = Qt.Key.Key_E self._controller = self.getController() self._selection_pass = None @@ -53,7 +53,7 @@ class SupportEraser(Tool): def event(self, event): super().event(event) modifiers = QApplication.keyboardModifiers() - ctrl_is_active = modifiers & Qt.ControlModifier + ctrl_is_active = modifiers & Qt.KeyboardModifier.ControlModifier if event.type == Event.MousePressEvent and MouseEvent.LeftButton in event.buttons and self._controller.getToolsEnabled(): if ctrl_is_active: diff --git a/plugins/TrimeshReader/TrimeshReader.py b/plugins/TrimeshReader/TrimeshReader.py index 6aea321f15..9f13dd7872 100644 --- a/plugins/TrimeshReader/TrimeshReader.py +++ b/plugins/TrimeshReader/TrimeshReader.py @@ -1,5 +1,5 @@ -# Copyright (c) 2019 Ultimaker B.V., fieldOfView -# Cura is released under the terms of the LGPLv3 or higher. +# Copyright (c) 2019-2022 Ultimaker B.V., fieldOfView +# Cura is released under the terms of the LGPLv3 or higher. # The _toMeshData function is taken from the AMFReader class which was built by fieldOfView. @@ -29,14 +29,7 @@ class TrimeshReader(MeshReader): def __init__(self) -> None: super().__init__() - self._supported_extensions = [".ctm", ".dae", ".gltf", ".glb", ".ply", ".zae"] - MimeTypeDatabase.addMimeType( - MimeType( - name = "application/x-ctm", - comment = "Open Compressed Triangle Mesh", - suffixes = ["ctm"] - ) - ) + self._supported_extensions = [".dae", ".gltf", ".glb", ".ply", ".zae"] MimeTypeDatabase.addMimeType( MimeType( name = "model/vnd.collada+xml", @@ -164,4 +157,4 @@ class TrimeshReader(MeshReader): normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count) mesh_data = MeshData(vertices = vertices, indices = indices, normals = normals, file_name = file_name) - return mesh_data \ No newline at end of file + return mesh_data diff --git a/plugins/UFPWriter/UFPWriter.py b/plugins/UFPWriter/UFPWriter.py index 455a7c3c36..52dab1efc7 100644 --- a/plugins/UFPWriter/UFPWriter.py +++ b/plugins/UFPWriter/UFPWriter.py @@ -8,7 +8,7 @@ from Charon.OpenMode import OpenMode # To indicate that we want to write to UFP from Charon.filetypes.OpenPackagingConvention import OPCError from io import StringIO # For converting g-code to bytes. -from PyQt5.QtCore import QBuffer +from PyQt6.QtCore import QBuffer from UM.Logger import Logger from UM.Mesh.MeshWriter import MeshWriter # The writer we need to implement. @@ -83,7 +83,7 @@ class UFPWriter(MeshWriter): thumbnail = archive.getStream("/Metadata/thumbnail.png") thumbnail_buffer = QBuffer() - thumbnail_buffer.open(QBuffer.ReadWrite) + thumbnail_buffer.open(QBuffer.OpenModeFlag.ReadWrite) snapshot.save(thumbnail_buffer, "PNG") thumbnail.write(thumbnail_buffer.data()) diff --git a/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml b/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml index 4458b48996..e95b9d7e0e 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/CameraButton.qml @@ -21,7 +21,7 @@ Button color: parent.enabled ? (parent.hovered ? UM.Theme.getColor("monitor_card_hover") : "transparent") : UM.Theme.getColor("monitor_icon_disabled") } - UM.RecolorImage + UM.ColorImage { id: icon anchors diff --git a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml index e68f552f7b..7d34a182b3 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/DiscoverUM3Action.qml @@ -1,14 +1,14 @@ // Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import UM 1.5 as UM -import Cura 1.5 as Cura - -import QtQuick 2.2 +import QtQuick 2.15 import QtQuick.Controls 2.9 import QtQuick.Layouts 1.1 import QtQuick.Window 2.1 +import UM 1.5 as UM +import Cura 1.5 as Cura + Cura.MachineAction { id: base @@ -302,7 +302,7 @@ Cura.MachineAction { id: addressField width: parent.width - validator: RegExpValidator { regExp: /[a-zA-Z0-9\.\-\_]*/ } + validator: RegularExpressionValidator { regularExpression: /[a-zA-Z0-9\.\-\_]*/ } } } diff --git a/plugins/UM3NetworkPrinting/resources/qml/GenericPopUp.qml b/plugins/UM3NetworkPrinting/resources/qml/GenericPopUp.qml index 580338ae0c..47660fc7f3 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/GenericPopUp.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/GenericPopUp.qml @@ -3,7 +3,6 @@ import QtQuick 2.2 import QtQuick.Controls 2.0 -import QtGraphicalEffects 1.0 import UM 1.3 as UM /** @@ -60,16 +59,6 @@ Popup { anchors.fill: parent - DropShadow - { - anchors.fill: pointedRectangle - color: UM.Theme.getColor("monitor_shadow") - radius: UM.Theme.getSize("monitor_shadow_radius").width - source: pointedRectangle - transparentBorder: true - verticalOffset: 2 * screenScaleFactor - } - Item { id: pointedRectangle diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml index 60e3726a32..0bd57e76d8 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorBuildplateConfiguration.qml @@ -45,7 +45,7 @@ Item radius: Math.floor(height / 2) } - UM.RecolorImage + UM.ColorImage { id: buildplateIcon anchors.centerIn: parent diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml index a42dc0d12a..89c2edd9b5 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorCarousel.qml @@ -3,7 +3,6 @@ import QtQuick 2.3 import QtQuick.Controls 2.0 -import QtGraphicalEffects 1.0 import UM 1.3 as UM Item @@ -39,24 +38,10 @@ Item } height: parent.height z: 10 - LinearGradient + Rectangle { anchors.fill: parent - start: Qt.point(0, 0) - end: Qt.point(leftHint.width, 0) - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: UM.Theme.getColor("monitor_stage_background") - } - GradientStop - { - position: 1.0 - color: UM.Theme.getColor("monitor_stage_background_fade") - } - } + color: UM.Theme.getColor("monitor_stage_background") } MouseArea { @@ -90,13 +75,11 @@ Item contentItem: Item { anchors.fill: parent - UM.RecolorImage + UM.ColorImage { anchors.centerIn: parent width: 18 // TODO: Theme! height: width // TODO: Theme! - sourceSize.width: width // TODO: Theme! - sourceSize.height: width // TODO: Theme! color: UM.Theme.getColor("text") source: UM.Theme.getIcon("ChevronSingleLeft") } @@ -169,13 +152,11 @@ Item contentItem: Item { anchors.fill: parent - UM.RecolorImage + UM.ColorImage { anchors.centerIn: parent width: 18 // TODO: Theme! height: width // TODO: Theme! - sourceSize.width: width // TODO: Theme! - sourceSize.height: width // TODO: Theme! color: UM.Theme.getColor("text") source: UM.Theme.getIcon("ChevronSingleRight") } @@ -194,24 +175,11 @@ Item height: centerSection.height z: 10 - LinearGradient + Rectangle { anchors.fill: parent - start: Qt.point(0, 0) - end: Qt.point(rightHint.width, 0) - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: UM.Theme.getColor("monitor_stage_background_fade") - } - GradientStop - { - position: 1.0 - color: UM.Theme.getColor("monitor_stage_background") - } - } + color: UM.Theme.getColor("monitor_stage_background_fade") + } MouseArea { diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml index f22ac53298..4b1a7df607 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorIconExtruder.qml @@ -27,7 +27,7 @@ Item height: size width: size - UM.RecolorImage + UM.ColorImage { id: icon anchors.fill: parent diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml index cf2239201f..4b4b7a2a3a 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrintJobPreview.qml @@ -38,7 +38,7 @@ Item } - UM.RecolorImage + UM.ColorImage { id: ultiBotImage @@ -46,18 +46,13 @@ Item color: UM.Theme.getColor("monitor_placeholder_image") height: printJobPreview.height source: "../svg/ultibot.svg" - sourceSize - { - height: height - width: width - } /* Since print jobs ALWAYS have an image url, we have to check if that image URL errors or not in order to determine if we show the placeholder (ultibot) image instead. */ visible: printJob && previewImage.status == Image.Error width: printJobPreview.width } - UM.RecolorImage + UM.ColorImage { id: overlayIcon anchors.centerIn: printJobPreview @@ -90,11 +85,6 @@ Item } return "" } - sourceSize - { - height: height - width: width - } visible: source != "" width: 0.5 * printJobPreview.width } diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml index df701b1d1f..2bc20ae462 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorPrinterCard.qml @@ -147,7 +147,7 @@ Item color: UM.Theme.getColor("text_link") text: catalog.i18nc("@label link to Connect and Cloud interfaces", "Manage printer") } - UM.RecolorImage + UM.ColorImage { id: externalLinkIcon anchors diff --git a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml index 87b7cab83e..3fd500cfca 100644 --- a/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml +++ b/plugins/UM3NetworkPrinting/resources/qml/MonitorQueue.qml @@ -40,7 +40,7 @@ Item height: 18 * screenScaleFactor // TODO: Theme! width: childrenRect.width - UM.RecolorImage + UM.ColorImage { id: externalLinkIcon anchors.verticalCenter: manageQueueLabel.verticalCenter diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 7b8be4b2c2..470e57947e 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -5,8 +5,8 @@ from json import JSONDecodeError from time import time from typing import Callable, List, Type, TypeVar, Union, Optional, Tuple, Dict, Any, cast -from PyQt5.QtCore import QUrl -from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply +from PyQt6.QtCore import QUrl +from PyQt6.QtNetwork import QNetworkRequest, QNetworkReply from UM.Logger import Logger from UM.TaskManagement.HttpRequestManager import HttpRequestManager @@ -165,7 +165,7 @@ class CloudApiClient: request = QNetworkRequest(QUrl(path)) if content_type: - request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) + request.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, content_type) access_token = self._account.accessToken if access_token: request.setRawHeader(b"Authorization", "Bearer {}".format(access_token).encode()) @@ -179,7 +179,7 @@ class CloudApiClient: :return: A tuple with a status code and a dictionary. """ - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + status_code = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) try: response = bytes(reply.readAll()).decode() return status_code, json.loads(response) @@ -233,7 +233,7 @@ class CloudApiClient: self._anti_gc_callbacks.remove(parse) # Don't try to parse the reply if we didn't get one - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: + if reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) is None: if on_error is not None: on_error() return diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 85e802215c..8c45ce537f 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -5,9 +5,9 @@ from time import time import os from typing import cast, List, Optional, TYPE_CHECKING -from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot -from PyQt5.QtGui import QDesktopServices -from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest # Parse errors specific to print job uploading. +from PyQt6.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot +from PyQt6.QtGui import QDesktopServices +from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest # Parse errors specific to print job uploading. from UM import i18nCatalog from UM.Backend.Backend import BackendState @@ -272,7 +272,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): """ Displays a message when an error occurs specific to uploading print job (i.e. queue is full). """ - error_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + error_code = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) if error_code == 409: PrintJobUploadQueueFullMessage().show() else: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 8eecafd49c..004c9bc656 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -4,8 +4,8 @@ import os from typing import Dict, List, Optional, Set -from PyQt5.QtNetwork import QNetworkReply -from PyQt5.QtWidgets import QMessageBox +from PyQt6.QtNetwork import QNetworkReply +from PyQt6.QtWidgets import QMessageBox from UM import i18nCatalog from UM.Logger import Logger # To log errors talking to the API. @@ -480,7 +480,7 @@ class CloudOutputDeviceManager: if remove_printers_ids == all_ids: question_content = self.i18n_catalog.i18nc("@label", "You are about to remove all printers from Cura. This action cannot be undone.\nAre you sure you want to continue?") result = QMessageBox.question(None, question_title, question_content) - if result == QMessageBox.No: + if result == QMessageBox.ButtonRole.NoRole: return for machine_cloud_id in self.reported_device_ids: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py index 5a3e2474a8..1881d90923 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py @@ -1,7 +1,7 @@ # Copyright (c) 2019 Ultimaker B.V. # !/usr/bin/env python # -*- coding: utf-8 -*- -from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply +from PyQt6.QtNetwork import QNetworkRequest, QNetworkReply from typing import Callable, Any, Tuple, cast, Dict, Optional from UM.Logger import Logger @@ -106,9 +106,9 @@ class ToolPathUploader: """Checks whether a chunk of data was uploaded successfully, starting the next chunk if needed.""" Logger.log("i", "Finished callback %s %s", - reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url().toString()) + reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute), reply.url().toString()) - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) # type: Optional[int] + status_code = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) # type: Optional[int] if not status_code: Logger.log("e", "Reply contained no status code.") self._errorCallback(reply, None) diff --git a/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py b/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py index 34687339a9..05609070a2 100644 --- a/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py +++ b/plugins/UM3NetworkPrinting/src/Messages/CloudFlowMessage.py @@ -2,8 +2,8 @@ # Cura is released under the terms of the LGPLv3 or higher. import os -from PyQt5.QtCore import QUrl -from PyQt5.QtGui import QDesktopServices +from PyQt6.QtCore import QUrl +from PyQt6.QtGui import QDesktopServices from UM import i18nCatalog from UM.Message import Message diff --git a/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py b/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py index 059b81b39e..3b00f24672 100644 --- a/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py +++ b/plugins/UM3NetworkPrinting/src/Messages/NotClusterHostMessage.py @@ -2,8 +2,8 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import TYPE_CHECKING -from PyQt5.QtCore import QUrl -from PyQt5.QtGui import QDesktopServices +from PyQt6.QtCore import QUrl +from PyQt6.QtGui import QDesktopServices from UM import i18nCatalog from UM.Message import Message diff --git a/plugins/UM3NetworkPrinting/src/Models/ConfigurationChangeModel.py b/plugins/UM3NetworkPrinting/src/Models/ConfigurationChangeModel.py index 58fae03679..6de08afb65 100644 --- a/plugins/UM3NetworkPrinting/src/Models/ConfigurationChangeModel.py +++ b/plugins/UM3NetworkPrinting/src/Models/ConfigurationChangeModel.py @@ -1,6 +1,6 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import pyqtProperty, QObject +from PyQt6.QtCore import pyqtProperty, QObject BLOCKING_CHANGE_TYPES = [ diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterStatus.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterStatus.py index b5fae5d9c7..16b4b6d656 100644 --- a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterStatus.py +++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterStatus.py @@ -3,7 +3,7 @@ from itertools import product from typing import List, Union, Dict, Optional, Any -from PyQt5.QtCore import QUrl +from PyQt6.QtCore import QUrl from cura.PrinterOutput.Models.PrinterConfigurationModel import PrinterConfigurationModel from cura.PrinterOutput.PrinterOutputController import PrinterOutputController diff --git a/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py b/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py index b063a2bf5b..85651244f9 100644 --- a/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py +++ b/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py @@ -2,9 +2,9 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import List, Optional -from PyQt5.QtCore import pyqtProperty, pyqtSignal -from PyQt5.QtGui import QImage -from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest +from PyQt6.QtCore import pyqtProperty, pyqtSignal +from PyQt6.QtGui import QImage +from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest from UM.Logger import Logger from UM.TaskManagement.HttpRequestManager import HttpRequestManager @@ -42,6 +42,6 @@ class UM3PrintJobOutputModel(PrintJobOutputModel): def _onImageLoaded(self, reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None) -> None: if not HttpRequestManager.replyIndicatesSuccess(reply, error): Logger.warning("Requesting preview image failed, response code {0} while trying to connect to {1}".format( - reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url())) + reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute), reply.url())) return self.updatePreviewImageData(reply.readAll()) diff --git a/plugins/UM3NetworkPrinting/src/Network/ClusterApiClient.py b/plugins/UM3NetworkPrinting/src/Network/ClusterApiClient.py index d1840bf90c..e0b156dc08 100644 --- a/plugins/UM3NetworkPrinting/src/Network/ClusterApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Network/ClusterApiClient.py @@ -4,8 +4,8 @@ import json from json import JSONDecodeError from typing import Callable, List, Optional, Dict, Union, Any, Type, cast, TypeVar, Tuple -from PyQt5.QtCore import QUrl -from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply +from PyQt6.QtCore import QUrl +from PyQt6.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply from UM.Logger import Logger @@ -118,9 +118,8 @@ class ClusterApiClient: """ url = QUrl("http://" + self._address + path) request = QNetworkRequest(url) - request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) if content_type: - request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) + request.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, content_type) return request @staticmethod @@ -130,7 +129,7 @@ class ClusterApiClient: :param reply: The reply from the server. :return: A tuple with a status code and a dictionary. """ - status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) + status_code = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) try: response = bytes(reply.readAll()).decode() return status_code, json.loads(response) @@ -173,10 +172,10 @@ class ClusterApiClient: self._anti_gc_callbacks.remove(parse) # Don't try to parse the reply if we didn't get one - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: + if reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) is None: return - if reply.error() > 0: + if reply.error() != QNetworkReply.NetworkError.NoError: self._on_error(reply.errorString()) return diff --git a/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py index 9288b4c4b0..2d27b7c3be 100644 --- a/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Network/LocalClusterOutputDevice.py @@ -3,9 +3,9 @@ import os from typing import Optional, Dict, List, Callable, Any -from PyQt5.QtGui import QDesktopServices -from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject -from PyQt5.QtNetwork import QNetworkReply +from PyQt6.QtGui import QDesktopServices +from PyQt6.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject +from PyQt6.QtNetwork import QNetworkReply from UM.FileHandler.FileHandler import FileHandler from UM.i18n import i18nCatalog diff --git a/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py index 877eaebcb7..32e20892ac 100644 --- a/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py +++ b/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import os from typing import Dict, TYPE_CHECKING, Set, List -from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest +from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest from UM.Job import Job from UM.Logger import Logger @@ -152,7 +152,7 @@ class SendMaterialJob(Job): def _sendingFinished(self, reply: QNetworkReply) -> None: """Check a reply from an upload to the printer and log an error when the call failed""" - if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200: + if reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) != 200: Logger.log("w", "Error while syncing material: %s", reply.errorString()) return body = reply.readAll().data().decode('utf8') diff --git a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py index 772a9d1973..12b0fa56bf 100644 --- a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py +++ b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterAction.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Optional, cast -from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty, QObject +from PyQt6.QtCore import pyqtSlot, pyqtSignal, pyqtProperty, QObject from UM import i18nCatalog from cura.CuraApplication import CuraApplication diff --git a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py index c9231d71ee..769e92610a 100644 --- a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py @@ -4,7 +4,7 @@ import os from time import time from typing import List, Optional, Dict -from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject, pyqtSlot, QUrl +from PyQt6.QtCore import pyqtProperty, pyqtSignal, QObject, pyqtSlot, QUrl from UM.Logger import Logger from UM.Qt.Duration import Duration, DurationFormat diff --git a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py index 1e9b46cb1c..02e3cc137d 100644 --- a/plugins/USBPrinting/USBPrinterOutputDeviceManager.py +++ b/plugins/USBPrinting/USBPrinterOutputDeviceManager.py @@ -7,7 +7,7 @@ import serial.tools.list_ports from os import environ from re import search -from PyQt5.QtCore import QObject, pyqtSignal +from PyQt6.QtCore import QObject, pyqtSignal from UM.Signal import Signal, signalemitter from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin @@ -30,16 +30,17 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin): def __init__(self, application, parent = None): if USBPrinterOutputDeviceManager.__instance is not None: raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__) - USBPrinterOutputDeviceManager.__instance = self super().__init__(parent = parent) + USBPrinterOutputDeviceManager.__instance = self + self._application = application self._serial_port_list = [] self._usb_output_devices = {} self._usb_output_devices_model = None self._update_thread = threading.Thread(target = self._updateThread) - self._update_thread.setDaemon(True) + self._update_thread.daemon = True self._check_updates = True diff --git a/plugins/UltimakerMachineActions/UMOUpgradeSelection.py b/plugins/UltimakerMachineActions/UMOUpgradeSelection.py index 62eab75986..0703731d64 100644 --- a/plugins/UltimakerMachineActions/UMOUpgradeSelection.py +++ b/plugins/UltimakerMachineActions/UMOUpgradeSelection.py @@ -3,7 +3,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry from cura.MachineAction import MachineAction -from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty +from PyQt6.QtCore import pyqtSlot, pyqtSignal, pyqtProperty from UM.i18n import i18nCatalog from UM.Application import Application diff --git a/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py b/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py index 00faa216eb..bc372c1428 100644 --- a/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py +++ b/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Ultimaker B.V. +# Copyright (c) 2022 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import configparser @@ -33,18 +33,20 @@ class VersionUpgrade44to45(VersionUpgrade): In this case the plug-in will also check for stacks that need to be deleted. """ + super().__init__() # Only delete hidden stacks when upgrading from version 4.4. Not 4.3 or 4.5, just when you're starting out from 4.4. # If you're starting from an earlier version, you can't have had the bug that produces too many hidden stacks (https://github.com/Ultimaker/Cura/issues/6731). # If you're starting from a later version, the bug was already fixed. data_storage_root = os.path.dirname(Resources.getDataStoragePath()) - folders = set(os.listdir(data_storage_root)) # All version folders. - folders = set(filter(lambda p: re.fullmatch(r"\d+\.\d+", p), folders)) # Only folders with a correct version number as name. - folders.difference_update({os.path.basename(Resources.getDataStoragePath())}) # Remove current version from candidates (since the folder was just copied). - if folders: - latest_version = max(folders, key = Version) # Sort them by semantic version numbering. - if latest_version == "4.4": - self.removeHiddenStacks() + if os.path.exists(data_storage_root): + folders = set(os.listdir(data_storage_root)) # All version folders. + folders = set(filter(lambda p: re.fullmatch(r"\d+\.\d+", p), folders)) # Only folders with a correct version number as name. + folders.difference_update({os.path.basename(Resources.getDataStoragePath())}) # Remove current version from candidates (since the folder was just copied). + if folders: + latest_version = max(folders, key = Version) # Sort them by semantic version numbering. + if latest_version == "4.4": + self.removeHiddenStacks() def removeHiddenStacks(self) -> None: """ diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py index be4fe5ea76..5af7b17652 100644 --- a/plugins/XRayView/XRayView.py +++ b/plugins/XRayView/XRayView.py @@ -2,7 +2,7 @@ # Cura is released under the terms of the LGPLv3 or higher. import os.path -from PyQt5.QtGui import QOpenGLContext, QImage +from PyQt6.QtGui import QOpenGLContext, QImage from UM.Application import Application from UM.Logger import Logger diff --git a/plugins/XmlMaterialProfile/PluginInfo.py b/plugins/XmlMaterialProfile/PluginInfo.py index 4b78a47a5e..b88bea21eb 100644 --- a/plugins/XmlMaterialProfile/PluginInfo.py +++ b/plugins/XmlMaterialProfile/PluginInfo.py @@ -5,9 +5,9 @@ class PluginInfo(PluginObject): __instance = None # type: PluginInfo def __init__(self, *args, **kwags): - super().__init__(*args, **kwags) if PluginInfo.__instance is not None: raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__) + super().__init__(*args, **kwags) PluginInfo.__instance = self @classmethod diff --git a/resources/qml/Account/AccountWidget.qml b/resources/qml/Account/AccountWidget.qml index d738c5c474..84a0caede1 100644 --- a/resources/qml/Account/AccountWidget.qml +++ b/resources/qml/Account/AccountWidget.qml @@ -10,7 +10,7 @@ import Cura 1.1 as Cura Item { property var profile: Cura.API.account.userProfile - property var loggedIn: Cura.API.account.isLoggedIn + property bool loggedIn: Cura.API.account.isLoggedIn height: signInButton.visible ? signInButton.height : accountWidget.height width: signInButton.visible ? signInButton.width : accountWidget.width @@ -81,6 +81,7 @@ Item source: (loggedIn && profile["profile_image_url"]) ? profile["profile_image_url"] : "" outlineColor: loggedIn ? UM.Theme.getColor("account_widget_outline_active") : UM.Theme.getColor("lining") + maskColor: UM.Theme.getColor("main_window_header_background") } contentItem: Item diff --git a/resources/qml/Account/AvatarImage.qml b/resources/qml/Account/AvatarImage.qml index 58c39e5065..6a60e993d8 100644 --- a/resources/qml/Account/AvatarImage.qml +++ b/resources/qml/Account/AvatarImage.qml @@ -3,7 +3,6 @@ import QtQuick 2.10 import QtQuick.Controls 2.3 -import QtGraphicalEffects 1.0 import UM 1.4 as UM @@ -16,44 +15,46 @@ Item property alias source: profileImage.source property alias outlineColor: profileImageOutline.color + + // This should be set to the color behind the image + // It fills the space around a rectangular avatar to make the image under it look circular + property alias maskColor: profileImageMask.color property bool hasAvatar: source != "" + Rectangle + { + id: profileImageBackground + anchors.fill: parent + radius: width + color: "white" + } + Image { id: profileImage anchors.fill: parent fillMode: Image.PreserveAspectCrop - visible: false + visible: hasAvatar mipmap: true } - Rectangle + UM.ColorImage { + // This image is a rectangle with a hole in the middle. + // Since we don't have access to proper masking in QT6 yet this is used as a primitive masking replacement id: profileImageMask anchors.fill: parent - radius: width - color: hasAvatar ? "white" : "transparent" + source: UM.Theme.getIcon("CircleMask") } - OpacityMask - { - anchors.fill: parent - source: profileImage - maskSource: profileImageMask - visible: hasAvatar - cached: true - } - - UM.RecolorImage + UM.ColorImage { + // This creates the circle outline around the image id: profileImageOutline - anchors.centerIn: parent - // Make it a bit bigger than it has to, otherwise it sometimes shows a white border. - width: parent.width + 2 - height: parent.height + 2 + anchors.fill: parent + anchors.margins: .25 visible: hasAvatar source: UM.Theme.getIcon("CircleOutline") - sourceSize: Qt.size(parent.width, parent.height) color: UM.Theme.getColor("account_widget_outline_active") } } diff --git a/resources/qml/Account/SyncState.qml b/resources/qml/Account/SyncState.qml index e5731ff9d7..9c978b4607 100644 --- a/resources/qml/Account/SyncState.qml +++ b/resources/qml/Account/SyncState.qml @@ -43,7 +43,7 @@ Row // Sync state icon + message } ] - UM.RecolorImage + UM.ColorImage { id: icon width: 20 * screenScaleFactor diff --git a/resources/qml/Account/UserOperations.qml b/resources/qml/Account/UserOperations.qml index be858df993..d7677264fb 100644 --- a/resources/qml/Account/UserOperations.qml +++ b/resources/qml/Account/UserOperations.qml @@ -30,6 +30,7 @@ Column height: UM.Theme.getSize("main_window_header").height source: profile["profile_image_url"] ? profile["profile_image_url"] : "" + maskColor: UM.Theme.getColor("main_background") outlineColor: UM.Theme.getColor("main_background") } Rectangle diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml index fece44d287..187da07cb6 100644 --- a/resources/qml/ActionButton.qml +++ b/resources/qml/ActionButton.qml @@ -3,7 +3,6 @@ import QtQuick 2.7 import QtQuick.Controls 2.1 -import QtGraphicalEffects 1.0 // For the dropshadow import UM 1.5 as UM import Cura 1.0 as Cura @@ -47,7 +46,7 @@ Button leftPadding: UM.Theme.getSize("default_margin").width rightPadding: UM.Theme.getSize("default_margin").width - height: UM.Theme.getSize("action_button").height + implicitHeight: UM.Theme.getSize("action_button").height hoverEnabled: true onHoveredChanged: @@ -63,14 +62,12 @@ Button spacing: UM.Theme.getSize("narrow_margin").width height: button.height //Left side icon. Only displayed if !isIconOnRightSide. - UM.RecolorImage + UM.ColorImage { id: buttonIconLeft source: "" height: visible ? button.iconSize : 0 width: visible ? height : 0 - sourceSize.width: width - sourceSize.height: height color: button.enabled ? (button.hovered ? button.textHoverColor : button.textColor) : button.textDisabledColor visible: source != "" && !button.isIconOnRightSide anchors.verticalCenter: parent.verticalCenter @@ -110,14 +107,12 @@ Button } //Right side icon. Only displayed if isIconOnRightSide. - UM.RecolorImage + UM.ColorImage { id: buttonIconRight source: buttonIconLeft.source height: visible ? button.iconSize : 0 width: visible ? height : 0 - sourceSize.width: width - sourceSize.height: height color: buttonIconLeft.color visible: source != "" && button.isIconOnRightSide anchors.verticalCenter: buttonIconLeft.verticalCenter diff --git a/resources/qml/ActionPanel/PrintInformationWidget.qml b/resources/qml/ActionPanel/PrintInformationWidget.qml index d9923ce4e8..377bc3e979 100644 --- a/resources/qml/ActionPanel/PrintInformationWidget.qml +++ b/resources/qml/ActionPanel/PrintInformationWidget.qml @@ -7,7 +7,7 @@ import QtQuick.Controls 2.1 import UM 1.1 as UM import Cura 1.0 as Cura -UM.RecolorImage +UM.ColorImage { id: widget @@ -17,6 +17,8 @@ UM.RecolorImage color: UM.Theme.getColor("icon") + property var printMaterialCosts: PrintInformation.materialCosts + MouseArea { anchors.fill: parent @@ -37,8 +39,6 @@ UM.RecolorImage opacity: opened ? 1 : 0 Behavior on opacity { NumberAnimation { duration: 100 } } - contentWidth: printJobInformation.width - contentHeight: printJobInformation.implicitHeight contentItem: PrintJobInformation { diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml index 868f23d242..58bf736575 100644 --- a/resources/qml/ActionPanel/SliceProcessWidget.qml +++ b/resources/qml/ActionPanel/SliceProcessWidget.qml @@ -119,6 +119,7 @@ Column text: widget.waitingForSliceToStart ? catalog.i18nc("@button", "Processing"): catalog.i18nc("@button", "Slice") tooltip: catalog.i18nc("@label", "Start the slicing process") + hoverEnabled: !widget.waitingForSliceToStart enabled: widget.backendState != UM.Backend.Error && !widget.waitingForSliceToStart visible: widget.backendState == UM.Backend.NotStarted || widget.backendState == UM.Backend.Error onClicked: { diff --git a/resources/qml/ApplicationSwitcher/ApplicationButton.qml b/resources/qml/ApplicationSwitcher/ApplicationButton.qml index 182b80811b..3d67889220 100644 --- a/resources/qml/ApplicationSwitcher/ApplicationButton.qml +++ b/resources/qml/ApplicationSwitcher/ApplicationButton.qml @@ -45,7 +45,7 @@ Button anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - UM.RecolorImage + UM.ColorImage { id: applicationIcon anchors.horizontalCenter: parent.horizontalCenter @@ -54,7 +54,7 @@ Button width: UM.Theme.getSize("application_switcher_icon").width height: width - UM.RecolorImage + UM.ColorImage { id: externalLinkIndicatorIcon visible: base.isExternalLink diff --git a/resources/qml/ApplicationSwitcher/ApplicationSwitcher.qml b/resources/qml/ApplicationSwitcher/ApplicationSwitcher.qml index a8ea2312a5..69852270c1 100644 --- a/resources/qml/ApplicationSwitcher/ApplicationSwitcher.qml +++ b/resources/qml/ApplicationSwitcher/ApplicationSwitcher.qml @@ -31,7 +31,7 @@ Item Behavior on opacity { NumberAnimation { duration: 100; } } } - UM.RecolorImage + UM.ColorImage { anchors.fill: parent color: UM.Theme.getColor("primary_text") diff --git a/resources/qml/CategoryButton.qml b/resources/qml/CategoryButton.qml index b5d8bb2b2d..049ca032f0 100644 --- a/resources/qml/CategoryButton.qml +++ b/resources/qml/CategoryButton.qml @@ -78,7 +78,7 @@ Button id: content //spacing: UM.Theme.getSize("narrow_margin").width - UM.RecolorImage + UM.ColorImage { id: icon source: "" @@ -88,8 +88,6 @@ Button width: visible ? UM.Theme.getSize("section_icon").width: 0 height: UM.Theme.getSize("section_icon").height anchors.leftMargin: base.indented ? UM.Theme.getSize("default_margin").width: 0 - sourceSize.width: width - sourceSize.height: width } UM.Label @@ -106,15 +104,13 @@ Button color: UM.Theme.getColor("setting_category_text") } - UM.RecolorImage + UM.ColorImage { id: categoryArrow anchors.right: parent.right width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height anchors.verticalCenter: parent.verticalCenter - sourceSize.width: width - sourceSize.height: height color: UM.Theme.getColor("setting_control_button") source: expanded ? UM.Theme.getIcon("ChevronSingleDown") : UM.Theme.getIcon("ChevronSingleLeft") } diff --git a/resources/qml/ColorDialog.qml b/resources/qml/ColorDialog.qml index 6877ef34b6..49adcf0cca 100644 --- a/resources/qml/ColorDialog.qml +++ b/resources/qml/ColorDialog.qml @@ -1,4 +1,7 @@ -import QtQuick 2.10 +// Copyright (c) 2022 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.15 import QtQuick.Controls 2.2 import QtQuick.Window 2.1 import QtQuick.Layouts 1.1 @@ -26,7 +29,7 @@ UM.Dialog // the size of the dialog ourselves. // Ugly workaround for windows having overlapping elements due to incorrect dialog width minimumWidth: content.width + (Qt.platform.os == "windows" ? 4 * margin : 2 * margin) - minimumHeight: content.height + buttonRow.height + (Qt.platform.os == "windows" ? 5 * margin : 3 * margin) + minimumHeight: content.height + buttonArea.height + (Qt.platform.os == "windows" ? 5 * margin : 3 * margin) property alias color: colorInput.text property var swatchColors: [ @@ -77,7 +80,7 @@ UM.Dialog implicitHeight: UM.Theme.getSize("medium_button_icon").height radius: width / 2 - UM.RecolorImage + UM.ColorImage { anchors.fill: parent visible: swatchColor == base.color @@ -104,7 +107,7 @@ UM.Dialog text: catalog.i18nc("@label", "Hex") } - TextField + Cura.TextField { id: colorInput Layout.fillWidth: true @@ -116,7 +119,7 @@ UM.Dialog text = `#${text}`; } } - validator: RegExpValidator { regExp: /^#([a-fA-F0-9]{0,6})$/ } + validator: RegularExpressionValidator { regularExpression: /^#([a-fA-F0-9]{0,6})$/ } } Rectangle diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 371754e9e0..bd9979335b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -3,8 +3,8 @@ import QtQuick 2.7 import QtQuick.Controls 2.15 -import QtQuick.Dialogs 1.2 -import QtGraphicalEffects 1.0 +import QtQuick.Dialogs + import UM 1.5 as UM import Cura 1.1 as Cura @@ -49,6 +49,22 @@ UM.MainWindow tooltip.hide(); } + MouseArea + { + // Hack introduced when switching to qt6 + // We used to be able to let the main window's default handlers control this, but something seems to be changed + // for qt6 in the ordering. TODO; We should find out what changed and have a less hacky fix for that. + enabled: parent.visible + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.AllButtons + onPositionChanged: (mouse) => {base.mouseMoved(mouse);} + onPressed: (mouse) => { base.mousePressed(mouse);} + onReleased: (mouse) => { base.mouseReleased(mouse);} + onWheel: (wheel) => {base.wheel(wheel)} + + } + Rectangle { id: greyOutBackground @@ -147,7 +163,7 @@ UM.MainWindow anchors.fill: parent //DeleteSelection on the keypress backspace event - Keys.onPressed: + Keys.onPressed: (event) => { if (event.key == Qt.Key_Backspace) { @@ -171,29 +187,10 @@ UM.MainWindow } height: stageMenu.source != "" ? Math.round(mainWindowHeader.height + stageMenu.height / 2) : mainWindowHeader.height - LinearGradient + Rectangle { anchors.fill: parent - start: Qt.point(0, 0) - end: Qt.point(parent.width, 0) - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: UM.Theme.getColor("main_window_header_background") - } - GradientStop - { - position: 0.5 - color: UM.Theme.getColor("main_window_header_background_gradient") - } - GradientStop - { - position: 1.0 - color: UM.Theme.getColor("main_window_header_background") - } - } + color: UM.Theme.getColor("main_window_header_background") } // This is a placeholder for adding a pattern in the header @@ -237,7 +234,7 @@ UM.MainWindow { // The drop area is here to handle files being dropped onto Cura. anchors.fill: parent - onDropped: + onDropped: (drop) => { if (drop.urls.length > 0) { @@ -246,7 +243,7 @@ UM.MainWindow for (var i = 0; i < drop.urls.length; i++) { var filename = drop.urls[i]; - if (filename.toLowerCase().endsWith(".curapackage")) + if (filename.toString().toLowerCase().endsWith(".curapackage")) { // Try to install plugin & close. CuraApplication.installPackageViaDragAndDrop(filename); @@ -636,24 +633,19 @@ UM.MainWindow //: File open dialog title title: catalog.i18nc("@title:window","Open file(s)") modality: Qt.WindowModal - selectMultiple: true + fileMode: FileDialog.OpenFiles nameFilters: UM.MeshFileHandler.supportedReadFileTypes; - folder: - { - //Because several implementations of the file dialog only update the folder when it is explicitly set. - folder = CuraApplication.getDefaultPath("dialog_load_path"); - return CuraApplication.getDefaultPath("dialog_load_path"); - } + currentFolder: CuraApplication.getDefaultPath("dialog_load_path") onAccepted: { // Because several implementations of the file dialog only update the folder // when it is explicitly set. - var f = folder; - folder = f; + var f = currentFolder; + currentFolder = f; - CuraApplication.setDefaultPath("dialog_load_path", folder); + CuraApplication.setDefaultPath("dialog_load_path", currentFolder); - handleOpenFileUrls(fileUrls); + handleOpenFileUrls(selectedFiles); } // Yeah... I know... it is a mess to put all those things here. @@ -745,7 +737,7 @@ UM.MainWindow { id: packageInstallDialog title: catalog.i18nc("@window:title", "Install Package") - standardButtons: StandardButton.Ok + standardButtons: Dialog.Ok } Cura.MessageDialog diff --git a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml index bcace5a8b1..0579cb3c30 100644 --- a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml +++ b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml @@ -1,11 +1,10 @@ //Copyright (c) 2022 Ultimaker B.V. //Cura is released under the terms of the LGPLv3 or higher. -import Qt.labs.qmlmodels 1.0 import QtQuick 2.1 import QtQuick.Controls 2.15 -import UM 1.5 as UM +import UM 1.6 as UM import Cura 1.6 as Cura UM.Dialog @@ -77,11 +76,9 @@ UM.Dialog Cura.MachineManager.activeQualityDisplayNameMap["main"], catalog.i18nc("@title:column", "Current changes") ] - model: TableModel + model: UM.TableModel { - TableModelColumn { display: "label" } - TableModelColumn { display: "original_value" } - TableModelColumn { display: "user_value" } + headers: ["label", "original_value", "user_value"] rows: userChangesModel.items } sectionRole: "category" diff --git a/resources/qml/EmptyViewMenuComponent.qml b/resources/qml/EmptyViewMenuComponent.qml index 10a50ea023..61d821ccb6 100644 --- a/resources/qml/EmptyViewMenuComponent.qml +++ b/resources/qml/EmptyViewMenuComponent.qml @@ -3,7 +3,7 @@ import QtQuick 2.10 import QtQuick.Controls 2.3 -import QtGraphicalEffects 1.0 // For the dropshadow + import UM 1.2 as UM @@ -12,6 +12,8 @@ Rectangle { color: UM.Theme.getColor("disabled") + /* + TODO: Reimplement later DropShadow { id: shadow @@ -24,5 +26,5 @@ Rectangle color: UM.Theme.getColor("action_button_shadow") // Should always be drawn behind the background. z: parent.z - 1 - } + }*/ } diff --git a/resources/qml/ExpandableComponent.qml b/resources/qml/ExpandableComponent.qml index e5eab3bd93..471fed5850 100644 --- a/resources/qml/ExpandableComponent.qml +++ b/resources/qml/ExpandableComponent.qml @@ -155,7 +155,7 @@ Item } } - UM.RecolorImage + UM.ColorImage { id: collapseButton anchors @@ -249,13 +249,13 @@ Item } property var clickPos: Qt.point(0, 0) property bool dragging: false - onPressed: + onPressed: (mouse) => { clickPos = Qt.point(mouse.x, mouse.y); dragging = true } - onPositionChanged: + onPositionChanged: (mouse) => { if(dragging) { @@ -305,14 +305,6 @@ Item padding: UM.Theme.getSize("default_margin").width contentItem: Item {} - - onContentItemChanged: - { - // Since we want the size of the content to be set by the size of the content, - // we need to do it like this. - content.width = contentItem.width + 2 * content.padding - content.height = contentItem.height + 2 * content.padding - } } } @@ -322,10 +314,8 @@ Item { // Since it could be that the content is dynamically populated, we should also take these changes into account. target: content.contentItem - function onWidthChanged() { content.width = content.contentItem.width + 2 * content.padding } function onHeightChanged() { - content.height = content.contentItem.height + 2 * content.padding contentContainer.height = contentHeader.height + content.height } } diff --git a/resources/qml/ExpandableComponentHeader.qml b/resources/qml/ExpandableComponentHeader.qml index 7176f0978b..de60faba2f 100644 --- a/resources/qml/ExpandableComponentHeader.qml +++ b/resources/qml/ExpandableComponentHeader.qml @@ -51,10 +51,9 @@ Cura.RoundedRectangle verticalCenter: parent.verticalCenter } - contentItem: UM.RecolorImage + contentItem: UM.ColorImage { anchors.fill: parent - sourceSize.width: width color: closeButton.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text") source: UM.Theme.getIcon("Cancel") } diff --git a/resources/qml/ExpandablePopup.qml b/resources/qml/ExpandablePopup.qml index 219608a762..967ef09767 100644 --- a/resources/qml/ExpandablePopup.qml +++ b/resources/qml/ExpandablePopup.qml @@ -27,6 +27,12 @@ Item // The contentItem holds the QML item that is shown when the "open" button is pressed property alias contentItem: content.contentItem + // If the contentItem is a Layout (eg Column) you must use these to set the popup size otherwise you end up with a + // binding loop between the popup and the contentItem + // ImplicitWidth/ImplicitHeight can be used instead in the contentItem if it is not a Layout. + property alias contentWidth: content.width + property alias contentHeight: content.height + property color contentBackgroundColor: UM.Theme.getColor("action_button") property color headerBackgroundColor: UM.Theme.getColor("action_button") @@ -168,7 +174,7 @@ Item anchors.bottom: parent.bottom } - UM.RecolorImage + UM.ColorImage { id: collapseButton anchors @@ -211,23 +217,5 @@ Item } contentItem: Item {} - - onContentItemChanged: - { - // Since we want the size of the content to be set by the size of the content, - // we need to do it like this. - content.width = contentItem.width + 2 * content.padding - content.height = contentItem.height + 2 * content.padding - } - } - - // DO NOT MOVE UP IN THE CODE: This connection has to be here, after the definition of the content item. - // Apparently the order in which these are handled matters and so the height is correctly updated if this is here. - Connections - { - // Since it could be that the content is dynamically populated, we should also take these changes into account. - target: content.contentItem - function onWidthChanged() { content.width = content.contentItem.width + 2 * content.padding } - function onHeightChanged() { content.height = content.contentItem.height + 2 * content.padding } } } diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index b9141a449a..fb3269ca78 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -15,7 +15,7 @@ Item property color materialColor property alias textColor: extruderNumberText.color property bool extruderEnabled: true - property alias iconSize: mainIcon.sourceSize + property var iconSize property string iconVariant: "medium" Item @@ -24,19 +24,21 @@ Item anchors.fill: parent layer.enabled: true // Prevent weird opacity effects. - UM.RecolorImage + UM.ColorImage { anchors.fill: parent - sourceSize: mainIcon.sourceSize + width: mainIcon.width + height: mainIcon.height source: UM.Theme.getIcon("ExtruderColor", iconVariant) color: materialColor } - UM.RecolorImage + UM.ColorImage { id: mainIcon anchors.fill: parent - sourceSize: UM.Theme.getSize("extruder_icon") + width: UM.Theme.getSize("extruder_icon").width + height: UM.Theme.getSize("extruder_icon").height source: UM.Theme.getIcon("Extruder", iconVariant) color: extruderNumberText.color diff --git a/resources/qml/IconWithText.qml b/resources/qml/IconWithText.qml index d7b4adfa8c..cc0834d7ea 100644 --- a/resources/qml/IconWithText.qml +++ b/resources/qml/IconWithText.qml @@ -35,7 +35,7 @@ Item implicitWidth: icon.width + 100 implicitHeight: icon.height - UM.RecolorImage + UM.ColorImage { id: icon width: UM.Theme.getSize("section_icon").width diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 1a5f40466a..d2ca855e8b 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -1,7 +1,7 @@ // Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.15 import QtQuick.Controls 2.1 import QtQuick.Layouts 1.1 @@ -97,8 +97,8 @@ Item cursorPosition = 0 } - validator: RegExpValidator { - regExp: /^[^\\\/\*\?\|\[\]]*$/ + validator: RegularExpressionValidator { + regularExpression: /^[^\\\/\*\?\|\[\]]*$/ } color: UM.Theme.getColor("text_scene") background: Item {} diff --git a/resources/qml/MachineSettings/NumericTextFieldWithUnit.qml b/resources/qml/MachineSettings/NumericTextFieldWithUnit.qml index 51c9730052..b5147d63db 100644 --- a/resources/qml/MachineSettings/NumericTextFieldWithUnit.qml +++ b/resources/qml/MachineSettings/NumericTextFieldWithUnit.qml @@ -1,7 +1,7 @@ // Copyright (c) 2020 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.10 +import QtQuick 2.15 import QtQuick.Controls 2.3 import UM 1.5 as UM @@ -172,9 +172,9 @@ UM.TooltipArea return "^%0\\d{0,%1}[.,]?\\d{0,%2}$".arg(minus).arg(digits).arg(numericTextFieldWithUnit.decimals) } } - validator: RegExpValidator + validator: RegularExpressionValidator { - regExp: new RegExp(textFieldWithUnit.validatorString) + regularExpression: new RegExp(textFieldWithUnit.validatorString) } //Enforce actual minimum and maximum values. diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index 49d6710606..e8917517dd 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -88,7 +88,7 @@ Button visible: !configurationItem.isValidMaterial - UM.RecolorImage + UM.ColorImage { id: icon anchors.verticalCenter: unknownMaterialMessage.verticalCenter diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index 58d96f8028..8d4fc9c2b5 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -57,7 +57,7 @@ Cura.ExpandablePopup property var extruderStack: activeMachine ? activeMachine.extruderList[model.index]: null property bool valueWarning: !Cura.ExtruderManager.getExtruderHasQualityForMaterial(extruderStack) - property bool valueError: activeMachine ? Cura.ContainerManager.getContainerMetaDataEntry(extruderStack.material.id, "compatible", "") != "True" : false + property bool valueError: activeMachine ? Cura.ContainerManager.getContainerMetaDataEntry(extruderStack.material.id, "compatible") != "True" : false // Extruder icon. Shows extruder index and has the same color as the active material. Cura.ExtruderIcon @@ -109,7 +109,7 @@ Cura.ExpandablePopup } // Warning icon that indicates if no qualities are available for the variant/material combination for this extruder - UM.RecolorImage + UM.ColorImage { id: badge anchors @@ -257,11 +257,10 @@ Cura.ExpandablePopup } } + contentWidth: UM.Theme.getSize("configuration_selector").width contentItem: Column { id: popupItem - width: UM.Theme.getSize("configuration_selector").width - height: implicitHeight // Required because ExpandableComponent will try to use this to determine the size of the background of the pop-up. padding: UM.Theme.getSize("default_margin").height spacing: UM.Theme.getSize("default_margin").height diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 4b2b84d39e..7223706e63 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -202,7 +202,7 @@ Item return paddedWidth - textWidth - UM.Theme.getSize("print_setup_big_item").height * 0.5 - UM.Theme.getSize("default_margin").width } } - property string instructionLink: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "instruction_link", ""): "" + property string instructionLink: Cura.MachineManager.activeStack != null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "instruction_link"): "" Row { @@ -269,7 +269,7 @@ Item { id: materialSelection - property bool valueError: Cura.MachineManager.activeStack !== null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible", "") !== "True" : true + property bool valueError: Cura.MachineManager.activeStack !== null ? Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeStack.material.id, "compatible") !== "True" : true property bool valueWarning: !Cura.MachineManager.isActiveQualitySupported text: Cura.MachineManager.activeStack !== null ? Cura.MachineManager.activeStack.material.name : "" @@ -304,7 +304,7 @@ Item height: UM.Theme.getSize("small_button").height width: UM.Theme.getSize("small_button").width anchors.centerIn: parent - background: UM.RecolorImage + background: UM.ColorImage { source: UM.Theme.getIcon("Guide") color: instructionButton.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("icon") @@ -369,15 +369,13 @@ Item width: selectors.controlWidth height: childrenRect.height - UM.RecolorImage + UM.ColorImage { id: warningImage anchors.left: parent.left source: UM.Theme.getIcon("Warning") width: UM.Theme.getSize("section_icon").width height: UM.Theme.getSize("section_icon").height - sourceSize.width: width - sourceSize.height: height color: UM.Theme.getColor("material_compatibility_warning") visible: !Cura.MachineManager.isCurrentSetupSupported || warnings.buildplateCompatibilityError || warnings.buildplateCompatibilityWarning } diff --git a/resources/qml/Menus/ContextMenu.qml b/resources/qml/Menus/ContextMenu.qml index 1bba79e2c1..cbae92efba 100644 --- a/resources/qml/Menus/ContextMenu.qml +++ b/resources/qml/Menus/ContextMenu.qml @@ -45,8 +45,8 @@ Cura.Menu shortcut: "Ctrl+" + (model.index + 1) } // Add it to the fifth position (and above) as we want it to be added after the extruder header. - onObjectAdded: base.insertItem(index + 5, object) - onObjectRemoved: base.removeItem(object) + onObjectAdded: function(index, object) { base.insertItem(index + 5, object) } + onObjectRemoved: function(object) { base.removeItem(object) } } // Global actions diff --git a/resources/qml/Menus/ExtensionMenu.qml b/resources/qml/Menus/ExtensionMenu.qml index 3c2d1a79c7..4ba36bbb40 100644 --- a/resources/qml/Menus/ExtensionMenu.qml +++ b/resources/qml/Menus/ExtensionMenu.qml @@ -53,12 +53,12 @@ Cura.Menu sourceComponent: modelText.trim() == "" ? extensionsMenuSeparator : extensionsMenuItem } - onObjectAdded: sub_menu.insertItem(index, object.item) - onObjectRemoved: sub_menu.removeItem(object.item) + onObjectAdded: function(index, object) { sub_menu.insertItem(index, object.item)} + onObjectRemoved: function(object) { sub_menu.removeItem(object.item)} } } - onObjectAdded: extensionMenu.insertMenu(index, object) - onObjectRemoved: extensionMenu.removeMenu(object) + onObjectAdded: function(index, object) { extensionMenu.insertMenu(index, object) } + onObjectRemoved: function(object) { extensionMenu.removeMenu(object)} } } \ No newline at end of file diff --git a/resources/qml/Menus/MaterialBrandMenu.qml b/resources/qml/Menus/MaterialBrandMenu.qml new file mode 100644 index 0000000000..04d780b5c3 --- /dev/null +++ b/resources/qml/Menus/MaterialBrandMenu.qml @@ -0,0 +1,322 @@ +// Copyright (c) 2022 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.4 +import QtQuick.Layouts 2.7 + +import UM 1.5 as UM +import Cura 1.7 as Cura + +/* This element is a workaround for MacOS, where it can crash in Qt6 when nested menus are closed. +Instead we'll use a pop-up which doesn't seem to have that problem. */ + +Cura.MenuItem +{ + id: materialBrandMenu + overrideShowArrow: true + + property var materialTypesModel + text: materialTypesModel.name + + contentItem: MouseArea + { + hoverEnabled: true + + RowLayout + { + spacing: 0 + opacity: materialBrandMenu.enabled ? 1 : 0.5 + + Item + { + // Spacer + width: UM.Theme.getSize("default_margin").width + } + + UM.Label + { + text: replaceText(materialBrandMenu.text) + Layout.fillWidth: true + Layout.fillHeight:true + elide: Label.ElideRight + wrapMode: Text.NoWrap + } + + Item + { + Layout.fillWidth: true + } + + Item + { + // Right side margin + width: UM.Theme.getSize("default_margin").width + } + } + + onEntered: showTimer.restartTimer() + onExited: hideTimer.restartTimer() + } + + Timer + { + id: showTimer + interval: 250 + function restartTimer() + { + restart(); + running = Qt.binding(function() { return materialBrandMenu.enabled && materialBrandMenu.contentItem.containsMouse; }); + hideTimer.running = false; + } + onTriggered: menuPopup.open() + } + Timer + { + id: hideTimer + interval: 250 + function restartTimer() //Restart but re-evaluate the running property then. + { + restart(); + running = Qt.binding(function() { return materialBrandMenu.enabled && !materialBrandMenu.contentItem.containsMouse && !menuPopup.itemHovered > 0; }); + showTimer.running = false; + } + onTriggered: menuPopup.close() + } + + Popup + { + id: menuPopup + x: parent.width - UM.Theme.getSize("default_lining").width + y: -UM.Theme.getSize("default_lining").width + width: materialTypesList.width + padding * 2 + height: materialTypesList.height + padding * 2 + + padding: background.border.width + // Nasty hack to ensure that we can keep track if the popup contains the mouse. + // Since we also want a hover for the sub items (and these events are sent async) + // We have to keep a count of itemHovered (instead of just a bool) + property int itemHovered: 0 + MouseArea + { + id: submenuArea + anchors.fill: parent + + hoverEnabled: true + onEntered: hideTimer.restartTimer() + } + + background: Rectangle + { + color: UM.Theme.getColor("main_background") + border.color: UM.Theme.getColor("lining") + border.width: UM.Theme.getSize("default_lining").width + } + + Column + { + id: materialTypesList + spacing: 0 + + property var brandMaterials: materialTypesModel.material_types + + Repeater + { + model: parent.brandMaterials + + //Use a MouseArea and Rectangle, not a button, because the button grabs mouse events which makes the parent pop-up think it's no longer being hovered. + //With a custom MouseArea, we can prevent the events from being accepted. + delegate: Rectangle + { + height: UM.Theme.getSize("menu").height + width: UM.Theme.getSize("menu").width + + color: materialTypeButton.containsMouse ? UM.Theme.getColor("background_2") : UM.Theme.getColor("background_1") + + RowLayout + { + spacing: 0 + opacity: materialBrandMenu.enabled ? 1 : 0.5 + height: parent.height + width: parent.width + + Item + { + // Spacer + width: UM.Theme.getSize("default_margin").width + } + + UM.Label + { + text: model.name + Layout.fillWidth: true + Layout.fillHeight: true + elide: Label.ElideRight + wrapMode: Text.NoWrap + } + + Item + { + Layout.fillWidth: true + } + + UM.ColorImage + { + height: UM.Theme.getSize("default_arrow").height + width: UM.Theme.getSize("default_arrow").width + color: UM.Theme.getColor("setting_control_text") + source: UM.Theme.getIcon("ChevronSingleRight") + } + + Item + { + // Right side margin + width: UM.Theme.getSize("default_margin").width + } + } + + MouseArea + { + id: materialTypeButton + anchors.fill: parent + + hoverEnabled: true + acceptedButtons: Qt.NoButton + + onEntered: + { + menuPopup.itemHovered += 1; + showSubTimer.restartTimer(); + } + onExited: + { + menuPopup.itemHovered -= 1; + hideSubTimer.restartTimer(); + } + } + Timer + { + id: showSubTimer + interval: 250 + function restartTimer() + { + restart(); + running = Qt.binding(function() { return materialTypeButton.containsMouse; }); + hideSubTimer.running = false; + } + onTriggered: colorPopup.open() + } + Timer + { + id: hideSubTimer + interval: 250 + function restartTimer() //Restart but re-evaluate the running property then. + { + restart(); + running = Qt.binding(function() { return !materialTypeButton.containsMouse && !colorPopup.itemHovered > 0; }); + showSubTimer.running = false; + } + onTriggered: colorPopup.close() + } + + Popup + { + id: colorPopup + width: materialColorsList.width + padding * 2 + height: materialColorsList.height + padding * 2 + x: parent.width + y: -UM.Theme.getSize("default_lining").width + + property int itemHovered: 0 + padding: background.border.width + + background: Rectangle + { + color: UM.Theme.getColor("main_background") + border.color: UM.Theme.getColor("lining") + border.width: UM.Theme.getSize("default_lining").width + } + + Column + { + id: materialColorsList + property var brandColors: model.colors + spacing: 0 + + Repeater + { + model: parent.brandColors + + delegate: Rectangle + { + height: UM.Theme.getSize("menu").height + width: UM.Theme.getSize("menu").width + + color: materialColorButton.containsMouse ? UM.Theme.getColor("background_2") : UM.Theme.getColor("background_1") + + Item + { + opacity: materialBrandMenu.enabled ? 1 : 0.5 + anchors.fill: parent + + //Checkmark, if the material is selected. + UM.ColorImage + { + id: checkmark + visible: model.id === materialMenu.activeMaterialId + height: UM.Theme.getSize("default_arrow").height + width: height + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + anchors.verticalCenter: parent.verticalCenter + source: UM.Theme.getIcon("Check", "low") + color: UM.Theme.getColor("setting_control_text") + } + + UM.Label + { + text: model.name + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + UM.Theme.getSize("default_arrow").height + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_margin").width + + elide: Label.ElideRight + wrapMode: Text.NoWrap + } + } + + MouseArea + { + id: materialColorButton + anchors.fill: parent + + hoverEnabled: true + onClicked: + { + Cura.MachineManager.setMaterial(extruderIndex, model.container_node); + menuPopup.close(); + colorPopup.close(); + materialMenu.close(); + } + onEntered: + { + menuPopup.itemHovered += 1; + colorPopup.itemHovered += 1; + } + onExited: + { + menuPopup.itemHovered -= 1; + colorPopup.itemHovered -= 1; + } + } + } + } + } + } + } + } + } + } +} diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index e6d7fbc3e9..c4ae4113f9 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -66,8 +66,8 @@ Cura.Menu checked: model.root_material_id === materialMenu.currentRootMaterialId onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) } - onObjectAdded: materialMenu.insertItem(index + 1, object) - onObjectRemoved: materialMenu.removeItem(index) + onObjectAdded: function(index, object) { materialMenu.insertItem(index + 1, object) } + onObjectRemoved: function(object) { materialMenu.removeItem(index) } } Cura.MenuSeparator { visible: favoriteMaterialsModel.items.length > 0} @@ -88,8 +88,8 @@ Cura.Menu checked: model.root_material_id === materialMenu.currentRootMaterialId onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) } - onObjectAdded: genericMenu.insertItem(index, object) - onObjectRemoved: genericMenu.removeItem(index) + onObjectAdded: function(index, object) { genericMenu.insertItem(index, object)} + onObjectRemoved: function(object) {genericMenu.removeItem(index) } } } @@ -98,45 +98,12 @@ Cura.Menu Instantiator { model: brandModel - Cura.Menu + delegate: Cura.MaterialBrandMenu { - id: brandMenu - title: brandName - property string brandName: model.name - property var brandMaterials: model.material_types - - Instantiator - { - model: brandMaterials - delegate: Cura.Menu - { - id: brandMaterialsMenu - title: materialName - property string materialName: model.name - property var brandMaterialColors: model.colors - - Instantiator - { - model: brandMaterialColors - delegate: Cura.MenuItem - { - text: model.name - checkable: true - enabled: isActiveExtruderEnabled - checked: model.id === materialMenu.activeMaterialId - - onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) - } - onObjectAdded: brandMaterialsMenu.insertItem(index, object) - onObjectRemoved: brandMaterialsMenu.removeItem(object) - } - } - onObjectAdded: brandMenu.insertMenu(index, object) - onObjectRemoved: brandMenu.removeMenu(object) - } + materialTypesModel: model } - onObjectAdded: materialMenu.insertMenu(index + 4, object) - onObjectRemoved: materialMenu.removeMenu(object) + onObjectAdded: function(index, object) { materialMenu.insertItem(index + 4, object)} + onObjectRemoved: function(object) { materialMenu.removeItem(index) } } Cura.MenuSeparator {} diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index b320a02a5e..896866e82f 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -49,8 +49,8 @@ Cura.Menu onTriggered: Cura.MachineManager.setVariant(nozzleMenu.extruderIndex, model.container_node) } - onObjectAdded: nozzleMenu.insertItem(index, object) - onObjectRemoved: nozzleMenu.removeItem(object) + onObjectAdded: function(index, object) { nozzleMenu.insertItem(index, object) } + onObjectRemoved: function(object) {nozzleMenu.removeItem(object)} } } diff --git a/resources/qml/Menus/OpenFilesMenu.qml b/resources/qml/Menus/OpenFilesMenu.qml index de5ab00c76..1cc98d2285 100644 --- a/resources/qml/Menus/OpenFilesMenu.qml +++ b/resources/qml/Menus/OpenFilesMenu.qml @@ -34,8 +34,8 @@ Cura.Menu } shortcut: model.shortcut } - onObjectAdded: openFilesMenu.insertItem(index, object) + onObjectAdded: function(index, object) { openFilesMenu.insertItem(index, object)} - onObjectRemoved: openFilesMenu.removeItem(object) + onObjectRemoved: function(object) { openFilesMenu.removeItem(object) } } } diff --git a/resources/qml/Menus/PrinterMenu.qml b/resources/qml/Menus/PrinterMenu.qml index 9f0e0575b0..6a9a36b17d 100644 --- a/resources/qml/Menus/PrinterMenu.qml +++ b/resources/qml/Menus/PrinterMenu.qml @@ -38,8 +38,8 @@ Cura.Menu checked: Cura.MachineManager.activeMachineNetworkGroupName == connectGroupName onTriggered: Cura.MachineManager.setActiveMachine(model.id) } - onObjectAdded: menu.insertItem(2, object) - onObjectRemoved: menu.removeItem(object) + onObjectAdded: function(index, object) { menu.insertItem(2, object)} + onObjectRemoved: function(object) { menu.removeItem(object)} } Cura.MenuSeparator { visible: networKPrinterInstantiator.count > 0 } @@ -66,8 +66,8 @@ Cura.Menu onTriggered: Cura.MachineManager.setActiveMachine(model.id) } // A bit hackish, but we have 2 items at the end, put them before that - onObjectAdded: menu.insertItem(menu.count - 2, object) - onObjectRemoved: menu.removeItem(object) + onObjectAdded: function(index, object) { menu.insertItem(menu.count - 2, object) } + onObjectRemoved: function(object) { menu.removeItem(object) } } Cura.MenuSeparator { visible: localPrinterInstantiator.count > 0 } diff --git a/resources/qml/Menus/RecentFilesMenu.qml b/resources/qml/Menus/RecentFilesMenu.qml index 8f4f328927..19ff681219 100644 --- a/resources/qml/Menus/RecentFilesMenu.qml +++ b/resources/qml/Menus/RecentFilesMenu.qml @@ -29,7 +29,7 @@ Cura.Menu } onTriggered: CuraApplication.readLocalFile(modelData) } - onObjectAdded: menu.insertItem(index, object) - onObjectRemoved: menu.removeItem(object) + onObjectAdded: (index, object) => menu.insertItem(index, object) + onObjectRemoved: (object) => menu.removeItem(object) } } diff --git a/resources/qml/Menus/SaveProjectMenu.qml b/resources/qml/Menus/SaveProjectMenu.qml index 16d54382d1..ac40f4b598 100644 --- a/resources/qml/Menus/SaveProjectMenu.qml +++ b/resources/qml/Menus/SaveProjectMenu.qml @@ -43,8 +43,8 @@ Cura.Menu shortcut: model.shortcut enabled: saveProjectMenu.shouldBeVisible } - onObjectAdded: saveProjectMenu.insertItem(index, object) - onObjectRemoved: saveProjectMenu.removeItem(object) + onObjectAdded: function(index, object) { saveProjectMenu.insertItem(index, object)} + onObjectRemoved: function(object) { saveProjectMenu.removeItem(object)} } WorkspaceSummaryDialog diff --git a/resources/qml/Menus/SettingVisibilityPresetsMenu.qml b/resources/qml/Menus/SettingVisibilityPresetsMenu.qml index 08d74a74ce..8518f4e93c 100644 --- a/resources/qml/Menus/SettingVisibilityPresetsMenu.qml +++ b/resources/qml/Menus/SettingVisibilityPresetsMenu.qml @@ -29,14 +29,11 @@ Cura.Menu checkable: true checked: modelData.presetId == settingVisibilityPresetsModel.activePreset ActionGroup.group: group - onTriggered: - { - settingVisibilityPresetsModel.setActivePreset(modelData.presetId); - } + onTriggered: settingVisibilityPresetsModel.setActivePreset(modelData.presetId) } - onObjectAdded: menu.insertItem(index, object) - onObjectRemoved: menu.removeItem(object) + onObjectAdded: function(index, object) { menu.insertItem(index, object) } + onObjectRemoved: function(object) { menu.removeItem(object)} } Cura.MenuSeparator {} diff --git a/resources/qml/Menus/SettingsMenu.qml b/resources/qml/Menus/SettingsMenu.qml index 25bee871f5..c93ee0bb09 100644 --- a/resources/qml/Menus/SettingsMenu.qml +++ b/resources/qml/Menus/SettingsMenu.qml @@ -67,8 +67,8 @@ Cura.Menu height: visible ? implicitHeight: 0 } } - onObjectAdded: base.insertMenu(index, object) - onObjectRemoved: base.removeMenu(object) + onObjectAdded: function(index, object) { base.insertMenu(index, object) } + onObjectRemoved:function(object) { base.removeMenu(object)} } Cura.MenuSeparator { } diff --git a/resources/qml/ObjectItemButton.qml b/resources/qml/ObjectItemButton.qml index c3066b800d..407a0298f4 100644 --- a/resources/qml/ObjectItemButton.qml +++ b/resources/qml/ObjectItemButton.qml @@ -146,7 +146,7 @@ Button labelText: perObjectSettingsCount.toString() } - UM.RecolorImage + UM.ColorImage { id: meshTypeIcon anchors diff --git a/resources/qml/ObjectSelector.qml b/resources/qml/ObjectSelector.qml index db68ff6c03..fdb4697a7e 100644 --- a/resources/qml/ObjectSelector.qml +++ b/resources/qml/ObjectSelector.qml @@ -1,3 +1,4 @@ + // Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. @@ -40,12 +41,11 @@ Item width: parent.width height: label.height - UM.RecolorImage + UM.ColorImage { id: openCloseIcon width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width anchors.left: parent.left color: openCloseButton.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text") source: objectSelector.opened ? UM.Theme.getIcon("ChevronSingleDown") : UM.Theme.getIcon("ChevronSingleUp") diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index c4200e2351..ca8019ea75 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -224,7 +224,7 @@ UM.PreferencesPage textRole: "text" model: languageList implicitWidth: UM.Theme.getSize("combobox").width - implicitHeight: currencyField.height + height: currencyField.height function setCurrentIndex() { var code = UM.Preferences.getValue("general/language"); @@ -264,6 +264,7 @@ UM.PreferencesPage selectByMouse: true text: UM.Preferences.getValue("cura/currency") implicitWidth: UM.Theme.getSize("combobox").width + implicitHeight: UM.Theme.getSize("setting_control").height onTextChanged: UM.Preferences.setValue("cura/currency", text) } @@ -293,7 +294,7 @@ UM.PreferencesPage model: themeList textRole: "text" implicitWidth: UM.Theme.getSize("combobox").width - implicitHeight: currencyField.height + height: currencyField.height currentIndex: { diff --git a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml index 9f7eeccc54..6f404ad738 100644 --- a/resources/qml/Preferences/Materials/MaterialsBrandSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsBrandSection.qml @@ -2,7 +2,7 @@ // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.1 import QtQuick.Layouts 1.3 import UM 1.5 as UM diff --git a/resources/qml/Preferences/Materials/MaterialsList.qml b/resources/qml/Preferences/Materials/MaterialsList.qml index bb40187825..913e213dae 100644 --- a/resources/qml/Preferences/Materials/MaterialsList.qml +++ b/resources/qml/Preferences/Materials/MaterialsList.qml @@ -2,8 +2,8 @@ // Uranium is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 +import QtQuick.Dialogs import UM 1.2 as UM import Cura 1.0 as Cura diff --git a/resources/qml/Preferences/Materials/MaterialsPage.qml b/resources/qml/Preferences/Materials/MaterialsPage.qml index 2774c2a204..48c86255d2 100644 --- a/resources/qml/Preferences/Materials/MaterialsPage.qml +++ b/resources/qml/Preferences/Materials/MaterialsPage.qml @@ -3,7 +3,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.15 -import QtQuick.Dialogs 1.2 +import QtQuick.Dialogs import UM 1.5 as UM import Cura 1.5 as Cura @@ -226,9 +226,9 @@ UM.ManagementPage { id: importMaterialDialog title: catalog.i18nc("@title:window", "Import Material") - selectExisting: true + fileMode: FileDialog.OpenFile nameFilters: Cura.ContainerManager.getContainerNameFilters("material") - folder: CuraApplication.getDefaultPath("dialog_material_path") + currentFolder: CuraApplication.getDefaultPath("dialog_material_path") onAccepted: { const result = Cura.ContainerManager.importMaterialContainer(fileUrl); @@ -254,9 +254,9 @@ UM.ManagementPage { id: exportMaterialDialog title: catalog.i18nc("@title:window", "Export Material") - selectExisting: false + fileMode: FileDialog.SaveFile nameFilters: Cura.ContainerManager.getContainerNameFilters("material") - folder: CuraApplication.getDefaultPath("dialog_material_path") + currentFolder: CuraApplication.getDefaultPath("dialog_material_path") onAccepted: { const result = Cura.ContainerManager.exportContainer(base.currentItem.root_material_id, selectedNameFilter, fileUrl); diff --git a/resources/qml/Preferences/Materials/MaterialsSlot.qml b/resources/qml/Preferences/Materials/MaterialsSlot.qml index f124736fd0..8292fbe6da 100644 --- a/resources/qml/Preferences/Materials/MaterialsSlot.qml +++ b/resources/qml/Preferences/Materials/MaterialsSlot.qml @@ -106,7 +106,7 @@ Rectangle anchors.right: materialSlot.right visible: false - UM.RecolorImage + UM.ColorImage { id: favoriteIndicator anchors.centerIn: parent diff --git a/resources/qml/Preferences/Materials/MaterialsSyncDialog.qml b/resources/qml/Preferences/Materials/MaterialsSyncDialog.qml index e592be6d5d..4fb8d78b2f 100644 --- a/resources/qml/Preferences/Materials/MaterialsSyncDialog.qml +++ b/resources/qml/Preferences/Materials/MaterialsSyncDialog.qml @@ -3,9 +3,10 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 -import QtQuick.Dialogs 1.2 +import QtQuick.Dialogs import QtQuick.Layouts 1.15 import QtQuick.Window 2.1 + import Cura 1.1 as Cura import UM 1.5 as UM @@ -297,7 +298,7 @@ Window iconSize: UM.Theme.getSize("machine_selector_icon").width //Printer status badge (always cloud, but whether it's online or offline). - UM.RecolorImage + UM.ColorImage { width: UM.Theme.getSize("printer_status_icon").width height: UM.Theme.getSize("printer_status_icon").height @@ -325,7 +326,7 @@ Window } } - UM.RecolorImage + UM.ColorImage { id: printerSpinner width: UM.Theme.getSize("section_icon").width @@ -402,7 +403,7 @@ Window UM.Label { Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter text: catalog.i18nc("@text Asking the user whether printers are missing in a list.", "Printers missing?") + "\n" + catalog.i18nc("@text", "Make sure all your printers are turned ON and connected to Digital Factory.") @@ -413,7 +414,7 @@ Window Cura.SecondaryButton { id: refreshListButton - Layout.alignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignmentFlag.AlignVCenter text: catalog.i18nc("@button", "Refresh List") iconSource: UM.Theme.getIcon("ArrowDoubleCircleRight") onClicked: Cura.API.account.sync(true) @@ -490,7 +491,7 @@ Window visible: !syncButton.visible - UM.RecolorImage + UM.ColorImage { id: syncingIcon height: UM.Theme.getSize("action_button_icon").height @@ -731,7 +732,6 @@ Window property variant exportUsbDialog: FileDialog { title: catalog.i18nc("@title:window", "Export All Materials") - selectExisting: false nameFilters: ["Material archives (*.umm)", "All files (*)"] onAccepted: { @@ -740,4 +740,4 @@ Window materialsSyncDialog.hasExportedUsb = true; } } -} \ No newline at end of file +} diff --git a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml index d781218027..2e6a255014 100644 --- a/resources/qml/Preferences/Materials/MaterialsTypeSection.qml +++ b/resources/qml/Preferences/Materials/MaterialsTypeSection.qml @@ -2,7 +2,7 @@ // Uranium is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Controls 1.4 +import QtQuick.Controls 2.4 import QtQuick.Layouts 1.3 import UM 1.5 as UM diff --git a/resources/qml/Preferences/Materials/MaterialsView.qml b/resources/qml/Preferences/Materials/MaterialsView.qml index 2cbadc6bd6..b033f755cf 100644 --- a/resources/qml/Preferences/Materials/MaterialsView.qml +++ b/resources/qml/Preferences/Materials/MaterialsView.qml @@ -3,8 +3,8 @@ import QtQuick 2.7 import QtQuick.Controls 2.15 -import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.3 +import QtQuick.Dialogs import UM 1.5 as UM import Cura 1.0 as Cura @@ -206,7 +206,8 @@ Item { height: informationPage.rowHeight width: informationPage.columnWidth - verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") + verticalAlignment: Qt.AlignVCenter + text: catalog.i18nc("@label", "Color") } Row diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 9ea23194e7..5d8f5499a4 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -4,7 +4,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.3 -import QtQuick.Dialogs 1.2 +import QtQuick.Dialogs import UM 1.5 as UM import Cura 1.6 as Cura @@ -349,9 +349,9 @@ UM.ManagementPage { id: exportDialog title: catalog.i18nc("@title:window", "Export Profile") - selectExisting: false + fileMode: FileDialog.SaveFile nameFilters: base.qualityManagementModel.getFileNameFilters("profile_writer") - folder: CuraApplication.getDefaultPath("dialog_profile_path") + currentFolder: CuraApplication.getDefaultPath("dialog_profile_path") onAccepted: { var result = Cura.ContainerManager.exportQualityChangesGroup(base.currentItem.quality_changes_group, @@ -414,9 +414,9 @@ UM.ManagementPage { id: importDialog title: catalog.i18nc("@title:window", "Import Profile") - selectExisting: true + fileMode: FileDialog.OpenFile nameFilters: base.qualityManagementModel.getFileNameFilters("profile_reader") - folder: CuraApplication.getDefaultPath("dialog_profile_path") + currentFolder: CuraApplication.getDefaultPath("dialog_profile_path") onAccepted: { var result = Cura.ContainerManager.importProfile(fileUrl); diff --git a/resources/qml/Preferences/SettingVisibilityItem.qml b/resources/qml/Preferences/SettingVisibilityItem.qml index b7edd54c35..8905c15124 100644 --- a/resources/qml/Preferences/SettingVisibilityItem.qml +++ b/resources/qml/Preferences/SettingVisibilityItem.qml @@ -74,7 +74,7 @@ Item } } - UM.RecolorImage + UM.ColorImage { anchors.centerIn: parent width: Math.round(check.height * 0.75) | 0 diff --git a/resources/qml/PrintSetupHeaderButton.qml b/resources/qml/PrintSetupHeaderButton.qml index a4f95148da..0a6c5c363a 100644 --- a/resources/qml/PrintSetupHeaderButton.qml +++ b/resources/qml/PrintSetupHeaderButton.qml @@ -89,7 +89,7 @@ ToolButton { id: background - UM.RecolorImage + UM.ColorImage { id: downArrow anchors.verticalCenter: parent.verticalCenter @@ -97,7 +97,6 @@ ToolButton anchors.rightMargin: UM.Theme.getSize("default_margin").width width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.height: width color: base.enabled ? UM.Theme.getColor("setting_control_button") : UM.Theme.getColor("setting_category_disabled_text") source: UM.Theme.getIcon("ChevronSingleDown") } diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index 2ca4a9f9bf..41bf28be15 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -159,7 +159,7 @@ Item } onExited: base.hideTooltip() } - UM.RecolorImage + UM.ColorImage { id: downArrow diff --git a/resources/qml/PrintSetupSelector/Custom/MenuButton.qml b/resources/qml/PrintSetupSelector/Custom/MenuButton.qml index 112edbbf77..6663ff9991 100644 --- a/resources/qml/PrintSetupSelector/Custom/MenuButton.qml +++ b/resources/qml/PrintSetupSelector/Custom/MenuButton.qml @@ -44,7 +44,7 @@ Button { height: button.height width: button.width - UM.RecolorImage + UM.ColorImage { id: check height: UM.Theme.getSize("default_arrow").height diff --git a/resources/qml/PrintSetupSelector/NoIntentIcon.qml b/resources/qml/PrintSetupSelector/NoIntentIcon.qml index 6fc883fdef..2dc422f6d6 100644 --- a/resources/qml/PrintSetupSelector/NoIntentIcon.qml +++ b/resources/qml/PrintSetupSelector/NoIntentIcon.qml @@ -16,7 +16,7 @@ Item implicitWidth: UM.Theme.getSize("section_icon").width implicitHeight: UM.Theme.getSize("section_icon").height - UM.RecolorImage + UM.ColorImage { source: UM.Theme.getIcon("Information") color: UM.Theme.getColor("icon") diff --git a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml index 046efe8b5b..5a3cc63c62 100644 --- a/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml +++ b/resources/qml/PrintSetupSelector/PrintSetupSelectorContents.qml @@ -15,9 +15,8 @@ Item id: content property int absoluteMinimumHeight: 200 * screenScaleFactor - - width: UM.Theme.getSize("print_setup_widget").width - 2 * UM.Theme.getSize("default_margin").width - height: contents.height + buttonRow.height + implicitWidth: UM.Theme.getSize("print_setup_widget").width - 2 * UM.Theme.getSize("default_margin").width + implicitHeight: contents.height + buttonRow.height enum Mode { @@ -227,7 +226,7 @@ Item color: UM.Theme.getColor("lining") } - UM.RecolorImage + UM.ColorImage { width: UM.Theme.getSize("drag_icon").width height: UM.Theme.getSize("drag_icon").height diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml index 49be0fae1c..0b683f0ddf 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedSupportSelector.qml @@ -154,7 +154,7 @@ Item when: supportExtruderCombobox.model.count > 0 } - indicator: UM.RecolorImage + indicator: UM.ColorImage { id: downArrow x: supportExtruderCombobox.width - width - supportExtruderCombobox.rightPadding @@ -163,8 +163,6 @@ Item source: UM.Theme.getIcon("ChevronSingleDown") width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width + 5 * screenScaleFactor - sourceSize.height: width + 5 * screenScaleFactor color: UM.Theme.getColor("setting_control_button") } diff --git a/resources/qml/PrinterOutput/ExtruderBox.qml b/resources/qml/PrinterOutput/ExtruderBox.qml index bea7c3bdd8..e567d5d4cb 100644 --- a/resources/qml/PrinterOutput/ExtruderBox.qml +++ b/resources/qml/PrinterOutput/ExtruderBox.qml @@ -1,7 +1,7 @@ //Copyright (c) 2022 Ultimaker B.V. //Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.15 import QtQuick.Controls 2.1 import UM 1.5 as UM @@ -206,7 +206,7 @@ Item selectByMouse: true maximumLength: 5 enabled: parent.enabled - validator: RegExpValidator { regExp: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex. + validator: RegularExpressionValidator { regularExpression: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex. anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width anchors.right: unit.left diff --git a/resources/qml/PrinterOutput/HeatedBedBox.qml b/resources/qml/PrinterOutput/HeatedBedBox.qml index 288e9cab3f..8a1d13524f 100644 --- a/resources/qml/PrinterOutput/HeatedBedBox.qml +++ b/resources/qml/PrinterOutput/HeatedBedBox.qml @@ -1,7 +1,7 @@ // Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.10 +import QtQuick 2.15 import QtQuick.Controls 2.4 import UM 1.5 as UM @@ -186,7 +186,7 @@ Item selectByMouse: true maximumLength: 5 enabled: parent.enabled - validator: RegExpValidator { regExp: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex. + validator: RegularExpressionValidator { regularExpression: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex. anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width anchors.right: unit.left diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index 12f495f7a8..77cd2be409 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -108,7 +108,7 @@ Cura.ExpandablePopup iconColor: UM.Theme.getColor("machine_selector_printer_icon") iconSize: source != "" ? UM.Theme.getSize("machine_selector_icon").width: 0 - UM.RecolorImage + UM.ColorImage { id: connectionStatusImage anchors @@ -192,9 +192,8 @@ Cura.ExpandablePopup contentItem: Item { id: popup - width: UM.Theme.getSize("machine_selector_widget_content").width - height: Math.min(machineSelectorList.contentHeight + separator.height + buttonRow.height, UM.Theme.getSize("machine_selector_widget_content").height) //Maximum height is the theme entry. - + implicitWidth: UM.Theme.getSize("machine_selector_widget_content").width + implicitHeight: Math.min(machineSelectorList.contentHeight + separator.height + buttonRow.height, UM.Theme.getSize("machine_selector_widget_content").height) //Maximum height is the theme entry. MachineSelectorList { id: machineSelectorList diff --git a/resources/qml/ProfileOverview.qml b/resources/qml/ProfileOverview.qml index e1009cd010..3508a85193 100644 --- a/resources/qml/ProfileOverview.qml +++ b/resources/qml/ProfileOverview.qml @@ -1,11 +1,10 @@ //Copyright (c) 2022 Ultimaker B.V. //Cura is released under the terms of the LGPLv3 or higher. -import Qt.labs.qmlmodels 1.0 import QtQuick 2.7 import QtQuick.Controls 2.15 -import UM 1.5 as UM +import UM 1.6 as UM import Cura 1.6 as Cura Cura.TableView @@ -39,13 +38,11 @@ Cura.TableView catalog.i18nc("@title:column", "Current"), catalog.i18nc("@title:column Unit of measurement", "Unit") ] - model: TableModel + + model: UM.TableModel { id: tableModel - TableModelColumn { display: "label" } - TableModelColumn { display: "profile_value" } - TableModelColumn { display: "user_value" } - TableModelColumn { display: "unit" } + headers: ["label", "profile_value", "user_value", "unit"] rows: modelRows } sectionRole: "category" diff --git a/resources/qml/SearchBar.qml b/resources/qml/SearchBar.qml index 4d9c003653..af5ad7cc35 100644 --- a/resources/qml/SearchBar.qml +++ b/resources/qml/SearchBar.qml @@ -17,7 +17,7 @@ Cura.TextField placeholderText: catalog.i18nc("@placeholder", "Search") font.italic: true - UM.RecolorImage + UM.ColorImage { id: searchIcon diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index 4987eedb83..215d2be1be 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -143,13 +143,12 @@ SettingItem return UM.Theme.getColor("checkbox") } - UM.RecolorImage + UM.ColorImage { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter height: UM.Theme.getSize("checkbox_mark").height width: UM.Theme.getSize("checkbox_mark").width - sourceSize.height: width color: !enabled ? UM.Theme.getColor("checkbox_mark_disabled") : UM.Theme.getColor("checkbox_mark"); source: UM.Theme.getIcon("Check", "low") opacity: control.checked ? 1 : 0 diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index c3bc472fbe..3072161c59 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -98,7 +98,7 @@ SettingItem when: control.model.items.length > 0 } - indicator: UM.RecolorImage + indicator: UM.ColorImage { id: downArrow x: control.width - width - control.rightPadding @@ -107,8 +107,6 @@ SettingItem source: UM.Theme.getIcon("ChevronSingleDown") width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width + 5 * screenScaleFactor - sourceSize.height: width + 5 * screenScaleFactor color: UM.Theme.getColor("setting_control_button"); } diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index 2a4db2ab31..e02fe88e34 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -99,7 +99,7 @@ SettingItem value: control.currentText != "" ? control.model.getItem(control.currentIndex).color : "transparent" } - indicator: UM.RecolorImage + indicator: UM.ColorImage { id: downArrow x: control.width - width - control.rightPadding @@ -108,8 +108,6 @@ SettingItem source: UM.Theme.getIcon("ChevronSingleDown") width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width + 5 * screenScaleFactor - sourceSize.height: width + 5 * screenScaleFactor color: UM.Theme.getColor("setting_control_button") } @@ -159,7 +157,7 @@ SettingItem background: Rectangle { id: swatch - height: Math.round(parent.height / 2) + height: UM.Theme.getSize("standard_arrow").width width: height radius: Math.round(width / 2) anchors.right: parent.right diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index 95976ad58e..5b051178b1 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -1,8 +1,8 @@ // Copyright (c) 2021 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 -import QtQuick.Controls 2.0 +import QtQuick 2.15 +import QtQuick.Controls 2.15 import UM 1.5 as UM @@ -154,7 +154,7 @@ SettingItem // should be done as little as possible) clip: definition.type == "str" || definition.type == "[int]" - validator: RegExpValidator { regExp: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,3}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry + validator: RegularExpressionValidator { regularExpression: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,3}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry Binding { @@ -162,6 +162,13 @@ SettingItem property: "text" value: { + if (input.activeFocus) + { + // In QT6 using "when: !activeFocus" causes the value to be null when activeFocus becomes True + // Since we want the value to stay the same when giving focus to the TextInput this is being used + // in place of "when: !activeFocus" + return input.text + } // Stacklevels // 0: user -> unsaved change // 1: quality changes -> saved change @@ -181,7 +188,6 @@ SettingItem return propertyProvider.properties.value } } - when: !input.activeFocus } MouseArea diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 40e9e19b01..28787acb27 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -43,6 +43,7 @@ Item height: parent.height anchors.left: parent.left anchors.right: parent.right + topPadding: height / 4 leftPadding: searchIcon.width + UM.Theme.getSize("default_margin").width * 2 placeholderText: catalog.i18nc("@label:textbox", "Search settings") font.italic: true @@ -50,7 +51,7 @@ Item property var expandedCategories property bool lastFindingSettings: false - UM.RecolorImage + UM.ColorImage { id: searchIcon @@ -171,7 +172,7 @@ Item { anchors.fill: contents acceptedButtons: Qt.AllButtons - onWheel: wheel.accepted = true + onWheel: (wheel) => { wheel.accepted = true } } ListView diff --git a/resources/qml/SpinBox.qml b/resources/qml/SpinBox.qml index 5f809a434a..038125111c 100644 --- a/resources/qml/SpinBox.qml +++ b/resources/qml/SpinBox.qml @@ -1,7 +1,7 @@ // Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.15 import QtQuick.Controls 2.15 import UM 1.5 as UM @@ -28,14 +28,13 @@ Item property bool editable: true - property var validator: RegExpValidator + property var validator: RegularExpressionValidator { - regExp: new RegExp("^" + prefix + "([0-9]+[.|,]?[0-9]*)?" + suffix + "$") + regularExpression: new RegExp("^" + prefix + "([0-9]+[.|,]?[0-9]*)?" + suffix + "$") } signal editingFinished() - implicitWidth: spinBox.implicitWidth - implicitHeight: spinBox.implicitHeight + height: UM.Theme.getSize("setting_control").height SpinBox { @@ -44,8 +43,8 @@ Item editable: base.editable topPadding: 0 bottomPadding: 0 - padding: UM.Theme.getSize("narrow_margin").width - + leftPadding: down.indicator.width + UM.Theme.getSize("narrow_margin").width + rightPadding: up.indicator.width + UM.Theme.getSize("narrow_margin").width // The stepSize of the SpinBox is intentionally set to be always `1` // As SpinBoxes can only contain integer values the `base.stepSize` is concidered the precision/resolution // increasing the spinBox.value by one increases the actual/real value of the component by `base.stepSize` @@ -110,7 +109,7 @@ Item color: spinBox.down.pressed ? spinBox.palette.mid : UM.Theme.getColor("detail_background") } - UM.RecolorImage + UM.ColorImage { anchors.centerIn: parent height: parent.height / 2.5 @@ -130,7 +129,7 @@ Item color: spinBox.up.pressed ? spinBox.palette.mid : UM.Theme.getColor("detail_background") } - UM.RecolorImage + UM.ColorImage { anchors.centerIn: parent height: parent.height / 2.5 diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index 5e0b863f5a..444d310511 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -1,7 +1,6 @@ //Copyright (C) 2022 Ultimaker B.V. //Cura is released under the terms of the LGPLv3 or higher. -import Qt.labs.qmlmodels 1.0 import QtQuick 2.15 import QtQuick.Controls 2.15 @@ -56,8 +55,9 @@ Item font: UM.Theme.getFont("medium_bold") elide: Text.ElideRight } - Item //Resize handle. + Item { + //Resize handle. anchors { right: parent.right diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 32de5b76ca..9c1abd31b7 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -63,13 +63,10 @@ Item isTopElement: toolsModel.getItem(0).id == model.id isBottomElement: toolsModel.getItem(toolsModel.count - 1).id == model.id - toolItem: UM.RecolorImage + toolItem: UM.ColorImage { source: UM.Theme.getIcon(model.icon) != "" ? UM.Theme.getIcon(model.icon) : "file:///" + model.location + "/" + model.icon color: UM.Theme.getColor("icon") - - sourceSize.height: Math.round(UM.Theme.getSize("button").height / 2) - sourceSize.width: Math.round(UM.Theme.getSize("button").width / 2) } onCheckedChanged: @@ -160,7 +157,7 @@ Item anchors.topMargin: base.activeY z: buttons.z - 1 - target: Qt.point(parent.right, base.activeY + Math.round(UM.Theme.getSize("button").height/2)) + target: Qt.point(-1, base.activeY + Math.round(UM.Theme.getSize("button").height / 2)) arrowSize: UM.Theme.getSize("default_arrow").width width: diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index 452cc5a09a..e76e5dbb67 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -69,17 +69,10 @@ Cura.ExpandablePopup } } + contentWidth: viewSelector.width - 2 * viewSelector.contentPadding contentItem: Column { id: viewSelectorPopup - width: viewSelector.width - 2 * viewSelector.contentPadding - - // For some reason the height/width of the column gets set to 0 if this is not set... - Component.onCompleted: - { - height = implicitHeight - width = viewSelector.width - 2 * viewSelector.contentPadding - } Repeater { diff --git a/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml b/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml index d2d48267de..127fca5fa6 100644 --- a/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml +++ b/resources/qml/WelcomePages/AddLocalPrinterScrollView.qml @@ -1,8 +1,8 @@ // Copyright (c) 2022 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.10 -import QtQuick.Controls 2.3 +import QtQuick 2.15 +import QtQuick.Controls 2.14 import UM 1.5 as UM import Cura 1.1 as Cura @@ -115,14 +115,12 @@ Item width: childrenRect.width height: UM.Theme.getSize("action_button").height - UM.RecolorImage + UM.ColorImage { id: arrow anchors.left: parent.left width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height color: UM.Theme.getColor("text") source: base.currentSection == section ? UM.Theme.getIcon("ChevronSingleDown") : UM.Theme.getIcon("ChevronSingleRight") } @@ -235,9 +233,9 @@ Item placeholderText: catalog.i18nc("@text", "Please name your printer") maximumLength: 40 width: parent.width - (printerNameLabel.width + (3 * UM.Theme.getSize("default_margin").width)) - validator: RegExpValidator + validator: RegularExpressionValidator { - regExp: printerNameTextField.machineNameValidator.machineNameRegex + regularExpression: printerNameTextField.machineNameValidator.machineNameRegex } property var machineNameValidator: Cura.MachineNameValidator { } } diff --git a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml index 64f194dd56..badd87326b 100644 --- a/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml +++ b/resources/qml/WelcomePages/AddNetworkPrinterScrollView.qml @@ -200,7 +200,7 @@ Item height: troubleshootingLinkIcon.height width: troubleshootingLinkIcon.width + troubleshootingLabel.width + UM.Theme.getSize("thin_margin").width - UM.RecolorImage + UM.ColorImage { id: troubleshootingLinkIcon anchors.right: troubleshootingLabel.left @@ -208,7 +208,6 @@ Item anchors.verticalCenter: parent.verticalCenter height: troubleshootingLabel.height width: height - sourceSize.height: width color: UM.Theme.getColor("text_link") source: UM.Theme.getIcon("LinkExternal") } diff --git a/resources/qml/WelcomePages/AddPrinterByIpContent.qml b/resources/qml/WelcomePages/AddPrinterByIpContent.qml index 2207bd1708..1adaa09a49 100644 --- a/resources/qml/WelcomePages/AddPrinterByIpContent.qml +++ b/resources/qml/WelcomePages/AddPrinterByIpContent.qml @@ -1,7 +1,7 @@ // Copyright (c) 2019 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.10 +import QtQuick 2.15 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 @@ -123,9 +123,9 @@ Item onInvalidInputDetected: invalidInputLabel.visible = true - validator: RegExpValidator + validator: RegularExpressionValidator { - regExp: /([a-fA-F0-9.:]+)?/ + regularExpression: /([a-fA-F0-9.:]+)?/ } onTextEdited: invalidInputLabel.visible = false diff --git a/resources/qml/WelcomePages/DropDownHeader.qml b/resources/qml/WelcomePages/DropDownHeader.qml index a4b416b093..b91f3383be 100644 --- a/resources/qml/WelcomePages/DropDownHeader.qml +++ b/resources/qml/WelcomePages/DropDownHeader.qml @@ -57,7 +57,7 @@ Cura.RoundedRectangle color: base.hovered ? UM.Theme.getColor("small_button_text_hover") : UM.Theme.getColor("small_button_text") } - UM.RecolorImage + UM.ColorImage { id: rightIcon anchors.right: parent.right diff --git a/resources/qml/WelcomePages/WelcomeDialogItem.qml b/resources/qml/WelcomePages/WelcomeDialogItem.qml index 2d01642ada..d98610d7d8 100644 --- a/resources/qml/WelcomePages/WelcomeDialogItem.qml +++ b/resources/qml/WelcomePages/WelcomeDialogItem.qml @@ -4,7 +4,6 @@ import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Window 2.2 -import QtGraphicalEffects 1.0 // For the DropShadow import UM 1.3 as UM import Cura 1.1 as Cura @@ -45,7 +44,8 @@ Item } // Drop shadow around the panel - DropShadow + // TODO: Maybe re-implement this some other way. + /*DropShadow { id: shadow radius: UM.Theme.getSize("first_run_shadow_radius").width @@ -55,7 +55,7 @@ Item verticalOffset: shadowOffset color: UM.Theme.getColor("first_run_shadow") transparentBorder: true - } + }*/ // Close this dialog when there's no more page to show Connections diff --git a/resources/qml/WelcomePages/WhatsNewContent.qml b/resources/qml/WelcomePages/WhatsNewContent.qml index c56f8880ed..2ac3935ece 100644 --- a/resources/qml/WelcomePages/WhatsNewContent.qml +++ b/resources/qml/WelcomePages/WhatsNewContent.qml @@ -4,7 +4,6 @@ import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 -import QtGraphicalEffects 1.12 // For the DropShadow import UM 1.3 as UM import Cura 1.1 as Cura @@ -67,7 +66,7 @@ Item Rectangle { - Layout.alignment: Qt.AlignHCenter + Layout.alignment: Qt.AlignmentFlag.AlignHCenter color: UM.Theme.getColor("viewport_overlay") width: whatsNewViewport.width height: whatsNewViewport.height @@ -92,13 +91,6 @@ Item source: manager.getSubpageImageSource(index) } - DropShadow { - anchors.fill: subpageImage - radius: UM.Theme.getSize("monitor_shadow_radius").width - color: UM.Theme.getColor("first_run_shadow") - source: subpageImage - } - Cura.ScrollableTextArea { id: subpageText diff --git a/resources/qml/Widgets/ComboBox.qml b/resources/qml/Widgets/ComboBox.qml index 698eb4ec10..2a3716c3af 100644 --- a/resources/qml/Widgets/ComboBox.qml +++ b/resources/qml/Widgets/ComboBox.qml @@ -39,7 +39,7 @@ ComboBox background: UM.UnderlineBackground{} - indicator: UM.RecolorImage + indicator: UM.ColorImage { id: downArrow x: control.width - width - control.rightPadding @@ -48,8 +48,6 @@ ComboBox source: UM.Theme.getIcon("ChevronSingleDown") width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width + 5 * screenScaleFactor - sourceSize.height: width + 5 * screenScaleFactor color: UM.Theme.getColor("setting_control_button") } diff --git a/resources/qml/Widgets/MenuItem.qml b/resources/qml/Widgets/MenuItem.qml index 36098e1197..c2929e512e 100644 --- a/resources/qml/Widgets/MenuItem.qml +++ b/resources/qml/Widgets/MenuItem.qml @@ -15,11 +15,12 @@ UM.MenuItem implicitHeight: UM.Theme.getSize("menu").height + UM.Theme.getSize("narrow_margin").height implicitWidth: UM.Theme.getSize("menu").width - opacity: enabled ? 1.0 : 0.5 - arrow: UM.RecolorImage + property bool overrideShowArrow: false + + arrow: UM.ColorImage { - visible: menuItem.subMenu + visible: menuItem.subMenu || overrideShowArrow height: UM.Theme.getSize("default_arrow").height width: height anchors.verticalCenter: parent.verticalCenter @@ -29,7 +30,7 @@ UM.MenuItem color: UM.Theme.getColor("setting_control_text") } - indicator: UM.RecolorImage + indicator: UM.ColorImage { id: check visible: menuItem.checkable && menuItem.checked diff --git a/resources/qml/Widgets/TextField.qml b/resources/qml/Widgets/TextField.qml index b708446d65..5e19f65149 100644 --- a/resources/qml/Widgets/TextField.qml +++ b/resources/qml/Widgets/TextField.qml @@ -53,7 +53,7 @@ TextField { id: backgroundRectangle //Optional icon added on the left hand side. - UM.RecolorImage + UM.ColorImage { id: iconLeft diff --git a/resources/themes/cura-light/icons/default/BlockGrid.svg b/resources/themes/cura-light/icons/default/BlockGrid.svg index 207171b8f7..3fb368e7c8 100644 --- a/resources/themes/cura-light/icons/default/BlockGrid.svg +++ b/resources/themes/cura-light/icons/default/BlockGrid.svg @@ -1,3 +1,3 @@ - - + + diff --git a/resources/themes/cura-light/icons/default/CircleMask.svg b/resources/themes/cura-light/icons/default/CircleMask.svg new file mode 100644 index 0000000000..d3a2e9a81c --- /dev/null +++ b/resources/themes/cura-light/icons/default/CircleMask.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/themes/cura-light/icons/default/ExtruderColor.svg b/resources/themes/cura-light/icons/default/ExtruderColor.svg index ff202e7296..8c6063ce13 100644 --- a/resources/themes/cura-light/icons/default/ExtruderColor.svg +++ b/resources/themes/cura-light/icons/default/ExtruderColor.svg @@ -2,9 +2,6 @@ - diff --git a/resources/themes/cura-light/icons/default/Settings.svg b/resources/themes/cura-light/icons/default/Settings.svg index feb0ab0cc8..204f2a5b6f 100644 --- a/resources/themes/cura-light/icons/default/Settings.svg +++ b/resources/themes/cura-light/icons/default/Settings.svg @@ -1,3 +1,3 @@ - + diff --git a/resources/themes/cura-light/icons/low/Check.svg b/resources/themes/cura-light/icons/low/Check.svg index 9630b70052..022df8c696 100644 --- a/resources/themes/cura-light/icons/low/Check.svg +++ b/resources/themes/cura-light/icons/low/Check.svg @@ -1,3 +1,3 @@ - - + + diff --git a/resources/themes/cura-light/icons/low/CheckBoxFill.svg b/resources/themes/cura-light/icons/low/CheckBoxFill.svg index bfbb6d87f2..acaf3ed5aa 100644 --- a/resources/themes/cura-light/icons/low/CheckBoxFill.svg +++ b/resources/themes/cura-light/icons/low/CheckBoxFill.svg @@ -1,4 +1,4 @@ - - - + + + diff --git a/resources/themes/cura-light/icons/medium/ExtruderColor.svg b/resources/themes/cura-light/icons/medium/ExtruderColor.svg index cd4452b246..b438cf805b 100644 --- a/resources/themes/cura-light/icons/medium/ExtruderColor.svg +++ b/resources/themes/cura-light/icons/medium/ExtruderColor.svg @@ -2,9 +2,7 @@ - + diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 94372d415e..86d9766d1b 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -6,166 +6,166 @@ "fonts": { "large": { "size": 1.35, - "weight": 40, + "weight": 400, "family": "Noto Sans" }, "large_ja_JP": { "size": 1.35, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "large_zh_CN": { "size": 1.35, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "large_zh_TW": { "size": 1.35, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "large_bold": { "size": 1.35, - "weight": 63, + "weight": 600, "family": "Noto Sans" }, "huge": { "size": 1.8, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "huge_bold": { "size": 1.8, - "weight": 63, + "weight": 600, "family": "Noto Sans" }, "medium": { "size": 1.16, - "weight": 40, + "weight": 400, "family": "Noto Sans" }, "medium_ja_JP": { "size": 1.16, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "medium_zh_CN": { "size": 1.16, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "medium_zh_TW": { "size": 1.16, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "medium_bold": { "size": 1.16, - "weight": 63, + "weight": 600, "family": "Noto Sans" }, "default": { "size": 0.95, - "weight": 40, + "weight": 400, "family": "Noto Sans" }, "default_ja_JP": { "size": 1.0, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "default_zh_CN": { "size": 1.0, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "default_zh_TW": { "size": 1.0, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "default_bold": { "size": 0.95, - "weight": 63, + "weight": 600, "family": "Noto Sans" }, "default_bold_ja_JP": { "size": 1.0, - "weight": 63, + "weight": 600, "family": "Noto Sans" }, "default_bold_zh_CN": { "size": 1.0, - "weight": 63, + "weight": 600, "family": "Noto Sans" }, "default_bold_zh_TW": { "size": 1.0, - "weight": 63, + "weight": 600, "family": "Noto Sans" }, "default_italic": { "size": 0.95, - "weight": 40, + "weight": 400, "italic": true, "family": "Noto Sans" }, "default_italic_ja_JP": { "size": 1.0, - "weight": 50, + "weight": 400, "italic": true, "family": "Noto Sans" }, "default_italic_zh_CN": { "size": 1.0, - "weight": 50, + "weight": 400, "italic": true, "family": "Noto Sans" }, "default_italic_zh_TW": { "size": 1.0, - "weight": 50, + "weight": 400, "italic": true, "family": "Noto Sans" }, "small": { "size": 0.9, - "weight": 40, + "weight": 400, "family": "Noto Sans" }, "small_ja_JP": { "size": 0.9, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "small_zh_CN": { "size": 0.9, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "small_zh_TW": { "size": 0.9, - "weight": 50, + "weight": 400, "family": "Noto Sans" }, "small_emphasis": { "size": 0.9, - "weight": 100, + "weight": 700, "family": "Noto Sans" }, "small_emphasis_ja_JP": { "size": 0.9, - "weight": 100, + "weight": 700, "family": "Noto Sans" }, "small_emphasis_zh_CN": { "size": 0.9, - "weight": 100, + "weight": 700, "family": "Noto Sans" }, "small_emphasis_zh_TW": { "size": 0.9, - "weight": 100, + "weight": 700, "family": "Noto Sans" } }, diff --git a/tests/PrinterOutput/TestNetworkedPrinterOutputDevice.py b/tests/PrinterOutput/TestNetworkedPrinterOutputDevice.py index 2a5cc8a2d5..984051d589 100644 --- a/tests/PrinterOutput/TestNetworkedPrinterOutputDevice.py +++ b/tests/PrinterOutput/TestNetworkedPrinterOutputDevice.py @@ -4,8 +4,8 @@ import time from unittest.mock import MagicMock, patch -from PyQt5.QtNetwork import QNetworkAccessManager -from PyQt5.QtCore import QUrl +from PyQt6.QtNetwork import QNetworkAccessManager +from PyQt6.QtCore import QUrl from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState from cura.PrinterOutput.PrinterOutputDevice import ConnectionState @@ -43,7 +43,7 @@ def test_post(): # Create a fake reply (we can't use a QReply, since those are abstract C++) reply = MagicMock() - reply.operation = MagicMock(return_value=QNetworkAccessManager.PostOperation) + reply.operation = MagicMock(return_value=QNetworkAccessManager.Operation.PostOperation) reply.url = MagicMock(return_value=QUrl("127.0.0.1")) mocked_network_manager.post = MagicMock(return_value = reply) @@ -65,7 +65,7 @@ def test_get(): # Create a fake reply (we can't use a QReply, since those are abstract C++) reply = MagicMock() - reply.operation = MagicMock(return_value=QNetworkAccessManager.PostOperation) + reply.operation = MagicMock(return_value=QNetworkAccessManager.Operation.PostOperation) reply.url = MagicMock(return_value=QUrl("127.0.0.1")) mocked_network_manager.get = MagicMock(return_value=reply) @@ -87,7 +87,7 @@ def test_delete(): # Create a fake reply (we can't use a QReply, since those are abstract C++) reply = MagicMock() - reply.operation = MagicMock(return_value=QNetworkAccessManager.PostOperation) + reply.operation = MagicMock(return_value=QNetworkAccessManager.Operation.PostOperation) reply.url = MagicMock(return_value=QUrl("127.0.0.1")) mocked_network_manager.deleteResource = MagicMock(return_value=reply) @@ -109,7 +109,7 @@ def test_put(): # Create a fake reply (we can't use a QReply, since those are abstract C++) reply = MagicMock() - reply.operation = MagicMock(return_value=QNetworkAccessManager.PostOperation) + reply.operation = MagicMock(return_value=QNetworkAccessManager.Operation.PostOperation) reply.url = MagicMock(return_value=QUrl("127.0.0.1")) mocked_network_manager.put = MagicMock(return_value = reply) diff --git a/tests/Settings/TestContainerManager.py b/tests/Settings/TestContainerManager.py index 19ade68f68..36409ba414 100644 --- a/tests/Settings/TestContainerManager.py +++ b/tests/Settings/TestContainerManager.py @@ -1,7 +1,7 @@ from unittest import TestCase from unittest.mock import MagicMock -from PyQt5.QtCore import QUrl +from PyQt6.QtCore import QUrl from unittest.mock import patch from UM.MimeTypeDatabase import MimeTypeDatabase from cura.Settings.ContainerManager import ContainerManager diff --git a/tests/TestOAuth2.py b/tests/TestOAuth2.py index 7d0a4bc5c4..09fa555af4 100644 --- a/tests/TestOAuth2.py +++ b/tests/TestOAuth2.py @@ -4,8 +4,8 @@ from datetime import datetime from unittest.mock import MagicMock, Mock, patch -from PyQt5.QtGui import QDesktopServices -from PyQt5.QtNetwork import QNetworkReply +from PyQt6.QtGui import QDesktopServices +from PyQt6.QtNetwork import QNetworkReply from UM.Preferences import Preferences from cura.OAuth2.AuthorizationHelpers import AuthorizationHelpers, TOKEN_TIMESTAMP_FORMAT