Browse Source

Merge branch 'main' into improve_oauth

Erwan MATHIEU 1 year ago
parent
commit
eb3b671422

+ 1 - 1
.github/workflows/installers.yml

@@ -58,7 +58,7 @@ jobs:
       enterprise: ${{ github.event.inputs.enterprise == 'true' }}
       staging: ${{ github.event.inputs.staging == 'true' }}
       architecture: X64
-      operating_system: windows-2022
+      operating_system: self-hosted-Windows-X64
     secrets: inherit
 
   linux-installer:

+ 2 - 1
.github/workflows/windows.yml

@@ -34,9 +34,10 @@ on:
       operating_system:
         description: 'OS'
         required: true
-        default: 'windows-2022'
+        default: 'self-hosted-Windows-X64'
         type: choice
         options:
+          - self-hosted-Windows-X64
           - windows-2022
 
 jobs:

+ 0 - 1
conandata.yml

@@ -6,7 +6,6 @@ requirements:
   - "fdm_materials/(latest)@ultimaker/testing"
   - "curaengine_plugin_gradual_flow/(latest)@ultimaker/stable"
   - "dulcificum/latest@ultimaker/testing"
-  - "pyarcus/5.3.0"
   - "pysavitar/5.3.0"
   - "pynest2d/5.3.0"
   - "curaengine_grpc_definitions/(latest)@ultimaker/testing"

+ 6 - 2
conanfile.py

@@ -242,7 +242,7 @@ class CuraConan(ConanFile):
                 self.output.warning(f"Source path for binary {binary['binary']} does not exist")
                 continue
 
-            for bin in Path(src_path).glob(binary["binary"] + "*[.exe|.dll|.so|.dylib|.so.|.pdb]*"):
+            for bin in Path(src_path).glob(binary["binary"] + "*[.exe|.dll|.so|.dylib|.so.]*"):
                 binaries.append((str(bin), binary["dst"]))
             for bin in Path(src_path).glob(binary["binary"]):
                 binaries.append((str(bin), binary["dst"]))
@@ -320,6 +320,8 @@ class CuraConan(ConanFile):
             self.options["openssl"].shared = True
         if self.conf.get("user.curaengine:sentry_url", "", check_type=str) != "":
             self.options["curaengine"].enable_sentry = True
+            self.options["arcus"].enable_sentry = True
+            self.options["clipper"].enable_sentry = True
 
     def validate(self):
         version = self.conf.get("user.cura:version", default = self.version, check_type = str)
@@ -335,6 +337,7 @@ class CuraConan(ConanFile):
             for req in self.conan_data["requirements_internal"]:
                 self.requires(req)
         self.requires("cpython/3.10.4@ultimaker/stable")
+        self.requires("clipper/6.4.2@ultimaker/stable")
         self.requires("openssl/3.2.0")
         self.requires("boost/1.82.0")
         self.requires("spdlog/1.12.0")
@@ -518,7 +521,8 @@ echo "CURA_APP_NAME={{ cura_app_name }}" >> ${{ env_prefix }}GITHUB_ENV
         del self.info.options.cloud_api_version
         del self.info.options.display_name
         del self.info.options.cura_debug_mode
-        self.options.rm_safe("enable_i18n")
+        if self.options.get_safe("enable_i18n", False):
+            del self.info.options.enable_i18n
 
         # TODO: Use the hash of requirements.txt and requirements-ultimaker.txt, Because changing these will actually result in a different
         #  Cura. This is needed because the requirements.txt aren't managed by Conan and therefor not resolved in the package_id. This isn't

+ 25 - 1
cura/CuraActions.py

@@ -3,10 +3,11 @@
 
 from typing import List, cast
 
-from PyQt6.QtCore import QObject, QUrl, QMimeData
+from PyQt6.QtCore import QObject, QUrl, pyqtSignal, pyqtProperty
 from PyQt6.QtGui import QDesktopServices
 from PyQt6.QtWidgets import QApplication
 
+from UM.Application import Application
 from UM.Event import CallFunctionEvent
 from UM.FlameProfiler import pyqtSlot
 from UM.Math.Vector import Vector
@@ -37,6 +38,10 @@ class CuraActions(QObject):
     def __init__(self, parent: QObject = None) -> None:
         super().__init__(parent)
 
+        self._operation_stack = Application.getInstance().getOperationStack()
+        self._operation_stack.changed.connect(self._onUndoStackChanged)
+
+    undoStackChanged = pyqtSignal()
     @pyqtSlot()
     def openDocumentation(self) -> None:
         # Starting a web browser from a signal handler connected to a menu will crash on windows.
@@ -45,6 +50,25 @@ class CuraActions(QObject):
         event = CallFunctionEvent(self._openUrl, [QUrl("https://ultimaker.com/en/resources/manuals/software?utm_source=cura&utm_medium=software&utm_campaign=dropdown-documentation")], {})
         cura.CuraApplication.CuraApplication.getInstance().functionEvent(event)
 
+    @pyqtProperty(bool, notify=undoStackChanged)
+    def canUndo(self):
+        return self._operation_stack.canUndo()
+
+    @pyqtProperty(bool, notify=undoStackChanged)
+    def canRedo(self):
+        return self._operation_stack.canRedo()
+
+    @pyqtSlot()
+    def undo(self):
+        self._operation_stack.undo()
+
+    @pyqtSlot()
+    def redo(self):
+        self._operation_stack.redo()
+
+    def _onUndoStackChanged(self):
+        self.undoStackChanged.emit()
+
     @pyqtSlot()
     def openBugReportPage(self) -> None:
         event = CallFunctionEvent(self._openUrl, [QUrl("https://github.com/Ultimaker/Cura/issues/new/choose")], {})

+ 44 - 14
cura/CuraApplication.py

@@ -15,13 +15,13 @@ import numpy
 from PyQt6.QtCore import QObject, QTimer, QUrl, QUrlQuery, pyqtSignal, pyqtProperty, QEvent, pyqtEnum, QCoreApplication, \
     QByteArray
 from PyQt6.QtGui import QColor, QIcon
-from PyQt6.QtQml import qmlRegisterUncreatableType, qmlRegisterUncreatableMetaObject, qmlRegisterSingletonType, qmlRegisterType
+from PyQt6.QtQml import qmlRegisterUncreatableMetaObject, qmlRegisterSingletonType, qmlRegisterType
 from PyQt6.QtWidgets import QMessageBox
 
 import UM.Util
 import cura.Settings.cura_empty_instance_containers
 from UM.Application import Application
-from UM.Decorators import override
+from UM.Decorators import override, deprecated
 from UM.FlameProfiler import pyqtSlot
 from UM.Logger import Logger
 from UM.Math.AxisAlignedBox import AxisAlignedBox
@@ -191,7 +191,7 @@ class CuraApplication(QtApplication):
         self.empty_container = None  # type: EmptyInstanceContainer
         self.empty_definition_changes_container = None  # type: EmptyInstanceContainer
         self.empty_variant_container = None  # type: EmptyInstanceContainer
-        self.empty_intent_container = None  # type: EmptyInstanceContainer 
+        self.empty_intent_container = None  # type: EmptyInstanceContainer
         self.empty_material_container = None  # type: EmptyInstanceContainer
         self.empty_quality_container = None  # type: EmptyInstanceContainer
         self.empty_quality_changes_container = None  # type: EmptyInstanceContainer
@@ -1138,6 +1138,10 @@ class CuraApplication(QtApplication):
 
         return cast(MachineActionManager.MachineActionManager, self._machine_action_manager)
 
+    @pyqtSlot(result = QObject)
+    def getMachineActionManagerQml(self)-> MachineActionManager.MachineActionManager:
+        return cast(QObject, self._machine_action_manager)
+
     @pyqtSlot(result = QObject)
     def getMaterialManagementModel(self) -> MaterialManagementModel:
         if not self._material_management_model:
@@ -1150,7 +1154,8 @@ class CuraApplication(QtApplication):
             self._quality_management_model = QualityManagementModel(parent = self)
         return self._quality_management_model
 
-    def getSimpleModeSettingsManager(self, *args):
+    @pyqtSlot(result=QObject)
+    def getSimpleModeSettingsManager(self)-> SimpleModeSettingsManager:
         if self._simple_mode_settings_manager is None:
             self._simple_mode_settings_manager = SimpleModeSettingsManager()
         return self._simple_mode_settings_manager
@@ -1193,16 +1198,43 @@ class CuraApplication(QtApplication):
 
         return self._print_information
 
-    def getQualityProfilesDropDownMenuModel(self, *args, **kwargs):
+    @pyqtSlot(result=QObject)
+    def getQualityProfilesDropDownMenuModel(self, *args, **kwargs)-> QualityProfilesDropDownMenuModel:
         if self._quality_profile_drop_down_menu_model is None:
             self._quality_profile_drop_down_menu_model = QualityProfilesDropDownMenuModel(self)
         return self._quality_profile_drop_down_menu_model
 
-    def getCustomQualityProfilesDropDownMenuModel(self, *args, **kwargs):
+    @pyqtSlot(result=QObject)
+    def getCustomQualityProfilesDropDownMenuModel(self, *args, **kwargs)->CustomQualityProfilesDropDownMenuModel:
         if self._custom_quality_profile_drop_down_menu_model is None:
             self._custom_quality_profile_drop_down_menu_model = CustomQualityProfilesDropDownMenuModel(self)
         return self._custom_quality_profile_drop_down_menu_model
 
+    @deprecated("SimpleModeSettingsManager is deprecated and will be removed in major SDK release, Use getSimpleModeSettingsManager() instead", since = "5.7.0")
+    def getSimpleModeSettingsManagerWrapper(self, *args, **kwargs):
+        return self.getSimpleModeSettingsManager()
+
+    @deprecated("MachineActionManager is deprecated and will be removed in major SDK release, Use getMachineActionManager() instead", since="5.7.0")
+    def getMachineActionManagerWrapper(self, *args, **kwargs):
+        return self.getMachineActionManager()
+
+    @deprecated("QualityManagementModel is deprecated and will be removed in major SDK release, Use getQualityManagementModel() instead", since="5.7.0")
+    def getQualityManagementModelWrapper(self, *args, **kwargs):
+        return self.getQualityManagementModel()
+
+    @deprecated("MaterialManagementModel is deprecated and will be removed in major SDK release, Use getMaterialManagementModel() instead", since = "5.7.0")
+    def getMaterialManagementModelWrapper(self, *args, **kwargs):
+        return self.getMaterialManagementModel()
+
+    @deprecated("QualityProfilesDropDownMenuModel is deprecated and will be removed in major SDK release, Use getQualityProfilesDropDownMenuModel() instead", since = "5.7.0")
+    def getQualityProfilesDropDownMenuModelWrapper(self, *args, **kwargs):
+        return self.getQualityProfilesDropDownMenuModel()
+
+    @deprecated("CustomQualityProfilesDropDownMenuModel is deprecated and will be removed in major SDK release, Use getCustomQualityProfilesDropDownMenuModel() instead", since = "5.7.0")
+    def getCustomQualityProfilesDropDownMenuModelWrapper(self,  *args, **kwargs):
+        return self.getCustomQualityProfilesDropDownMenuModel()
+
+
     def getCuraAPI(self, *args, **kwargs) -> "CuraAPI":
         return self._cura_API
 
@@ -1231,8 +1263,8 @@ class CuraApplication(QtApplication):
         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")
+        qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, self.getSimpleModeSettingsManagerWrapper, "SimpleModeSettingsManager")
+        qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, self.getMachineActionManagerWrapper, "MachineActionManager")
 
         self.processEvents()
         qmlRegisterType(NetworkingUtil, "Cura", 1, 5, "NetworkingUtil")
@@ -1257,16 +1289,14 @@ 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, self.getQualityManagementModel, "QualityManagementModel")
-        qmlRegisterSingletonType(MaterialManagementModel, "Cura", 1, 5, self.getMaterialManagementModel, "MaterialManagementModel")
+        qmlRegisterSingletonType(QualityManagementModel, "Cura", 1, 0, self.getQualityManagementModelWrapper,"QualityManagementModel")
+        qmlRegisterSingletonType(MaterialManagementModel, "Cura", 1, 5, self.getMaterialManagementModelWrapper,"MaterialManagementModel")
 
         self.processEvents()
         qmlRegisterType(DiscoveredPrintersModel, "Cura", 1, 0, "DiscoveredPrintersModel")
         qmlRegisterType(DiscoveredCloudPrintersModel, "Cura", 1, 7, "DiscoveredCloudPrintersModel")
-        qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0,
-                                 self.getQualityProfilesDropDownMenuModel, "QualityProfilesDropDownMenuModel")
-        qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0,
-                                 self.getCustomQualityProfilesDropDownMenuModel, "CustomQualityProfilesDropDownMenuModel")
+        qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0, self.getQualityProfilesDropDownMenuModelWrapper, "QualityProfilesDropDownMenuModel")
+        qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0, self.getCustomQualityProfilesDropDownMenuModelWrapper, "CustomQualityProfilesDropDownMenuModel")
         qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
         qmlRegisterType(IntentModel, "Cura", 1, 6, "IntentModel")
         qmlRegisterType(IntentCategoryModel, "Cura", 1, 6, "IntentCategoryModel")

+ 1 - 1
cura/Machines/Models/ExtrudersModel.py

@@ -227,7 +227,7 @@ class ExtrudersModel(ListModel):
                     "material_brand": "",
                     "color_name": "",
                     "material_type": "",
-                    "material_label": ""
+                    "material_name": ""
                 }
                 items.append(item)
             if self._items != items:

+ 4 - 0
cura_app.py

@@ -15,6 +15,10 @@ if "" in sys.path:
 import argparse
 import faulthandler
 import os
+
+# set the environment variable QT_QUICK_FLICKABLE_WHEEL_DECELERATION to 5000 as mentioned in qt6.6 update log to overcome scroll related issues
+os.environ["QT_QUICK_FLICKABLE_WHEEL_DECELERATION"] = str(int(os.environ.get("QT_QUICK_FLICKABLE_WHEEL_DECELERATION", "5000")))
+
 if sys.platform != "linux":  # Turns out the Linux build _does_ use this, but we're not making an Enterprise release for that system anyway.
     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.

+ 2 - 0
plugins/CuraEngineBackend/Cura.proto

@@ -35,6 +35,8 @@ message Slice
     repeated EnginePlugin engine_plugins = 5;
     string sentry_id = 6; // The anonymized Sentry user id that requested the slice
     string cura_version = 7; // The version of Cura that requested the slice
+    optional string project_name = 8; // The name of the project that requested the slice
+    optional string user_name = 9; // The Digital Factory account name of the user that requested the slice
 }
 
 message Extruder

+ 3 - 2
plugins/CuraEngineBackend/CuraEngineBackend.py

@@ -164,6 +164,7 @@ class CuraEngineBackend(QObject, Backend):
 
         application.getPreferences().addPreference("general/auto_slice", False)
         application.getPreferences().addPreference("info/send_engine_crash", True)
+        application.getPreferences().addPreference("info/anonymous_engine_crash_report", True)
 
         self._use_timer: bool = False
 
@@ -1094,14 +1095,14 @@ class CuraEngineBackend(QObject, Backend):
             self._change_timer.timeout.disconnect(self.slice)
 
     def _onPreferencesChanged(self, preference: str) -> None:
-        if preference != "general/auto_slice" and preference != "info/send_engine_crash":
+        if preference != "general/auto_slice" and preference != "info/send_engine_crash" and preference != "info/anonymous_engine_crash_report":
             return
         if preference == "general/auto_slice":
             auto_slice = self.determineAutoSlicing()
             if auto_slice:
                 self._change_timer.start()
         elif preference == "info/send_engine_crash":
-            os.environ["use_sentry"] = "1" if CuraApplication.getInstance().getPreferences().getValue("info/send_engine_crash") else "0"
+            os.environ["USE_SENTRY"] = "1" if CuraApplication.getInstance().getPreferences().getValue("info/send_engine_crash") else "0"
 
     def tickle(self) -> None:
         """Tickle the backend so in case of auto slicing, it starts the timer."""

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