From 04bfd6b820cb5c3f5583a4830b5b4e0ccde27a46 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 30 Apr 2021 12:22:40 +0200 Subject: [PATCH 1/6] Use `UM.Theme` instead of `Theme` This prevents hundreds of QML warning messages logged in some user reports of Cura being slow. ``` 2021-04-30 11:42:01,492 - WARNING - [MainThread] UM.Qt.QtApplication.__onQmlWarning [411]: file:///.../cura/../resources/themes/cura-light/styles.qml:335: TypeError: Cannot read property 'getSize' of null 2021-04-30 11:42:01,492 - WARNING - [MainThread] UM.Qt.QtApplication.__onQmlWarning [411]: file:///.../cura/../resources/themes/cura-light/styles.qml:338: TypeError: Cannot read property 'getColor' of null 2021-04-30 11:42:01,500 - WARNING - [MainThread] UM.Qt.QtApplication.__onQmlWarning [411]: file:///.../cura/../resources/themes/cura-light/styles.qml:327: TypeError: Cannot read property 'getSize' of null 2021-04-30 11:42:01,500 - WARNING - [MainThread] UM.Qt.QtApplication.__onQmlWarning [411]: file:///.../cura/../resources/themes/cura-light/styles.qml:329: TypeError: Cannot read property 'getColor' of null 2021-04-30 11:42:01,500 - WARNING - [MainThread] UM.Qt.QtApplication.__onQmlWarning [411]: file:///.../cura/../resources/themes/cura-light/styles.qml:335: TypeError: Cannot read property 'getSize' of null 2021-04-30 11:42:01,500 - WARNING - [MainThread] UM.Qt.QtApplication.__onQmlWarning [411]: file:///.../cura/../resources/themes/cura-light/styles.qml:338: TypeError: Cannot read property 'getColor' of null 2021-04-30 11:42:01,500 - WARNING - [MainThread] UM.Qt.QtApplication.__onQmlWarning [411]: file:///.../cura/../resources/themes/cura-light/styles.qml:327: TypeError: Cannot read property 'getSize' of null 2021-04-30 11:42:01,500 - WARNING - [MainThread] UM.Qt.QtApplication.__onQmlWarning [411]: file:///.../cura/../resources/themes/cura-light/styles.qml:329: TypeError: Cannot read property 'getColor' of null ``` --- resources/themes/cura-light/styles.qml | 190 ++++++++++++------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index daf06ac6af..6d165df2e1 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -21,49 +21,49 @@ QtObject { if(control.valueError) { - return Theme.getColor("setting_validation_error_background"); + return UM.Theme.getColor("setting_validation_error_background"); } else if(control.valueWarning) { - return Theme.getColor("setting_validation_warning_background"); + return UM.Theme.getColor("setting_validation_warning_background"); } else { - return Theme.getColor("setting_control"); + return UM.Theme.getColor("setting_control"); } } else { - return Theme.getColor("setting_control_disabled"); + return UM.Theme.getColor("setting_control_disabled"); } } radius: UM.Theme.getSize("setting_control_radius").width - border.width: Theme.getSize("default_lining").width + border.width: UM.Theme.getSize("default_lining").width border.color: { if (control.enabled) { if (control.valueError) { - return Theme.getColor("setting_validation_error"); + return UM.Theme.getColor("setting_validation_error"); } else if (control.valueWarning) { - return Theme.getColor("setting_validation_warning"); + return UM.Theme.getColor("setting_validation_warning"); } else if (control.hovered) { - return Theme.getColor("setting_control_border_highlight"); + return UM.Theme.getColor("setting_control_border_highlight"); } else { - return Theme.getColor("setting_control_border"); + return UM.Theme.getColor("setting_control_border"); } } else { - return Theme.getColor("setting_control_disabled_border"); + return UM.Theme.getColor("setting_control_disabled_border"); } } UM.RecolorImage @@ -71,25 +71,25 @@ QtObject id: downArrow anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right - anchors.rightMargin: Theme.getSize("default_margin").width - width: Theme.getSize("standard_arrow").width - height: Theme.getSize("standard_arrow").height + 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: control.enabled ? Theme.getColor("setting_control_button") : Theme.getColor("setting_category_disabled_text") - source: Theme.getIcon("arrow_bottom") + color: control.enabled ? UM.Theme.getColor("setting_control_button") : UM.Theme.getColor("setting_category_disabled_text") + source: UM.Theme.getIcon("arrow_bottom") } Label { id: printSetupComboBoxLabel - color: control.enabled ? Theme.getColor("setting_control_text") : Theme.getColor("setting_control_disabled_text") + color: control.enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") text: control.text; elide: Text.ElideRight; anchors.left: parent.left; - anchors.leftMargin: Theme.getSize("setting_unit_margin").width + anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width anchors.right: downArrow.left; anchors.rightMargin: control.rightMargin; anchors.verticalCenter: parent.verticalCenter; - font: Theme.getFont("default") + font: UM.Theme.getFont("default") } } label: Label{} @@ -175,25 +175,25 @@ QtObject { background: Item { - implicitWidth: Theme.getSize("button").width - implicitHeight: Theme.getSize("button").height + implicitWidth: UM.Theme.getSize("button").width + implicitHeight: UM.Theme.getSize("button").height UM.PointingRectangle { id: button_tooltip anchors.left: parent.right - anchors.leftMargin: Theme.getSize("button_tooltip_arrow").width * 2 + anchors.leftMargin: UM.Theme.getSize("button_tooltip_arrow").width * 2 anchors.verticalCenter: parent.verticalCenter target: Qt.point(parent.x, y + Math.round(height/2)) - arrowSize: Theme.getSize("button_tooltip_arrow").width - color: Theme.getColor("button_tooltip") + arrowSize: UM.Theme.getSize("button_tooltip_arrow").width + color: UM.Theme.getColor("button_tooltip") opacity: control.hovered ? 1.0 : 0.0; visible: control.text != "" - width: control.hovered ? button_tip.width + Theme.getSize("button_tooltip").width : 0 - height: Theme.getSize("button_tooltip").height + width: control.hovered ? button_tip.width + UM.Theme.getSize("button_tooltip").width : 0 + height: UM.Theme.getSize("button_tooltip").height Behavior on width { NumberAnimation { duration: 100; } } Behavior on opacity { NumberAnimation { duration: 100; } } @@ -206,8 +206,8 @@ QtObject anchors.verticalCenter: parent.verticalCenter text: control.text - font: Theme.getFont("default") - color: Theme.getColor("tooltip_text") + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("tooltip_text") } } @@ -226,22 +226,22 @@ QtObject } else if(control.checkable && control.checked && control.hovered) { - return Theme.getColor("toolbar_button_active_hover") + return UM.Theme.getColor("toolbar_button_active_hover") } else if(control.pressed || (control.checkable && control.checked)) { - return Theme.getColor("toolbar_button_active") + return UM.Theme.getColor("toolbar_button_active") } else if(control.hovered) { - return Theme.getColor("toolbar_button_hover") + return UM.Theme.getColor("toolbar_button_hover") } - return Theme.getColor("toolbar_background") + return UM.Theme.getColor("toolbar_background") } Behavior on color { ColorAnimation { duration: 50; } } - border.width: (control.hasOwnProperty("needBorder") && control.needBorder) ? Theme.getSize("default_lining").width : 0 - border.color: control.checked ? Theme.getColor("icon") : Theme.getColor("lining") + border.width: (control.hasOwnProperty("needBorder") && control.needBorder) ? UM.Theme.getSize("default_lining").width : 0 + border.color: control.checked ? UM.Theme.getColor("icon") : UM.Theme.getColor("lining") } } @@ -252,11 +252,11 @@ QtObject anchors.centerIn: parent opacity: control.enabled ? 1.0 : 0.2 source: control.iconSource - width: Theme.getSize("button_icon").width - height: Theme.getSize("button_icon").height - color: Theme.getColor("icon") + width: UM.Theme.getSize("button_icon").width + height: UM.Theme.getSize("button_icon").height + color: UM.Theme.getColor("icon") - sourceSize: Theme.getSize("button_icon") + sourceSize: UM.Theme.getSize("button_icon") } } } @@ -268,10 +268,10 @@ QtObject { background: Rectangle { - implicitWidth: Theme.getSize("message").width - (Theme.getSize("default_margin").width * 2) - implicitHeight: Theme.getSize("progressbar").height - color: control.hasOwnProperty("backgroundColor") ? control.backgroundColor : Theme.getColor("progressbar_background") - radius: Theme.getSize("progressbar_radius").width + implicitWidth: UM.Theme.getSize("message").width - (UM.Theme.getSize("default_margin").width * 2) + implicitHeight: UM.Theme.getSize("progressbar").height + color: control.hasOwnProperty("backgroundColor") ? control.backgroundColor : UM.Theme.getColor("progressbar_background") + radius: UM.Theme.getSize("progressbar_radius").width } progress: Rectangle { @@ -287,22 +287,22 @@ QtObject } else { - return Theme.getColor("progressbar_control"); + return UM.Theme.getColor("progressbar_control"); } } - radius: Theme.getSize("progressbar_radius").width + radius: UM.Theme.getSize("progressbar_radius").width Rectangle { - radius: Theme.getSize("progressbar_radius").width - color: control.hasOwnProperty("controlColor") ? control.controlColor : Theme.getColor("progressbar_control") - width: Theme.getSize("progressbar_control").width - height: Theme.getSize("progressbar_control").height + radius: UM.Theme.getSize("progressbar_radius").width + color: control.hasOwnProperty("controlColor") ? control.controlColor : UM.Theme.getColor("progressbar_control") + width: UM.Theme.getSize("progressbar_control").width + height: UM.Theme.getSize("progressbar_control").height visible: control.indeterminate SequentialAnimation on x { id: xAnim - property int animEndPoint: Theme.getSize("message").width - Math.round((Theme.getSize("default_margin").width * 2.5)) - Theme.getSize("progressbar_control").width + property int animEndPoint: UM.Theme.getSize("message").width - Math.round((UM.Theme.getSize("default_margin").width * 2.5)) - UM.Theme.getSize("progressbar_control").width running: control.indeterminate && control.visible loops: Animation.Infinite NumberAnimation { from: 0; to: xAnim.animEndPoint; duration: 2000;} @@ -324,18 +324,18 @@ QtObject scrollBarBackground: Rectangle { - implicitWidth: Theme.getSize("scrollbar").width + implicitWidth: UM.Theme.getSize("scrollbar").width radius: Math.round(implicitWidth / 2) - color: Theme.getColor("scrollbar_background") + color: UM.Theme.getColor("scrollbar_background") } handle: Rectangle { id: scrollViewHandle - implicitWidth: Theme.getSize("scrollbar").width + implicitWidth: UM.Theme.getSize("scrollbar").width radius: Math.round(implicitWidth / 2) - color: styleData.pressed ? Theme.getColor("scrollbar_handle_down") : styleData.hovered ? Theme.getColor("scrollbar_handle_hover") : Theme.getColor("scrollbar_handle") + color: styleData.pressed ? UM.Theme.getColor("scrollbar_handle_down") : styleData.hovered ? UM.Theme.getColor("scrollbar_handle_hover") : UM.Theme.getColor("scrollbar_handle") Behavior on color { ColorAnimation { duration: 50; } } } } @@ -348,14 +348,14 @@ QtObject background: Rectangle { - implicitHeight: Theme.getSize("setting_control").height; - implicitWidth: Theme.getSize("setting_control").width; + implicitHeight: UM.Theme.getSize("setting_control").height; + implicitWidth: UM.Theme.getSize("setting_control").width; color: control.hovered ? UM.Theme.getColor("setting_control_highlight") : UM.Theme.getColor("setting_control") Behavior on color { ColorAnimation { duration: 50; } } - border.width: Theme.getSize("default_lining").width; - border.color: control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border"); + border.width: UM.Theme.getSize("default_lining").width; + border.color: control.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border"); radius: UM.Theme.getSize("setting_control_radius").width } @@ -364,14 +364,14 @@ QtObject Label { anchors.left: parent.left - anchors.leftMargin: Theme.getSize("default_lining").width + anchors.leftMargin: UM.Theme.getSize("default_lining").width anchors.right: downArrow.left - anchors.rightMargin: Theme.getSize("default_lining").width + anchors.rightMargin: UM.Theme.getSize("default_lining").width anchors.verticalCenter: parent.verticalCenter text: control.currentText - font: Theme.getFont("default"); - color: !enabled ? Theme.getColor("setting_control_disabled_text") : Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default"); + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") elide: Text.ElideRight verticalAlignment: Text.AlignVCenter @@ -381,16 +381,16 @@ QtObject { id: downArrow anchors.right: parent.right - anchors.rightMargin: Theme.getSize("default_lining").width * 2 + anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2 anchors.verticalCenter: parent.verticalCenter - source: Theme.getIcon("arrow_bottom") - width: Theme.getSize("standard_arrow").width - height: Theme.getSize("standard_arrow").height + source: UM.Theme.getIcon("arrow_bottom") + 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: Theme.getColor("setting_control_button"); + color: UM.Theme.getColor("setting_control_button"); } } } @@ -403,16 +403,16 @@ QtObject background: Item { } indicator: Rectangle { - implicitWidth: Theme.getSize("checkbox").width - implicitHeight: Theme.getSize("checkbox").height + implicitWidth: UM.Theme.getSize("checkbox").width + implicitHeight: UM.Theme.getSize("checkbox").height - color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : (control.enabled ? Theme.getColor("checkbox") : Theme.getColor("checkbox_disabled")) + color: (control.hovered || control._hovered) ? UM.Theme.getColor("checkbox_hover") : (control.enabled ? UM.Theme.getColor("checkbox") : UM.Theme.getColor("checkbox_disabled")) Behavior on color { ColorAnimation { duration: 50; } } - radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : Theme.getSize("checkbox_radius").width + radius: control.exclusiveGroup ? Math.round(UM.Theme.getSize("checkbox").width / 2) : UM.Theme.getSize("checkbox_radius").width - border.width: Theme.getSize("default_lining").width - border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border") + border.width: UM.Theme.getSize("default_lining").width + border.color: (control.hovered || control._hovered) ? UM.Theme.getColor("checkbox_border_hover") : UM.Theme.getColor("checkbox_border") UM.RecolorImage { @@ -421,8 +421,8 @@ QtObject width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) sourceSize.height: width - color: Theme.getColor("checkbox_mark") - source: control.exclusiveGroup ? Theme.getIcon("dot") : Theme.getIcon("check") + color: UM.Theme.getColor("checkbox_mark") + source: control.exclusiveGroup ? UM.Theme.getIcon("dot") : UM.Theme.getIcon("check") opacity: control.checked Behavior on opacity { NumberAnimation { duration: 100; } } } @@ -430,8 +430,8 @@ QtObject label: Label { text: control.text - color: Theme.getColor("checkbox_text") - font: Theme.getFont("default") + color: UM.Theme.getColor("checkbox_text") + font: UM.Theme.getFont("default") elide: Text.ElideRight renderType: Text.NativeRendering } @@ -445,16 +445,16 @@ QtObject background: Item { } indicator: Rectangle { - implicitWidth: Theme.getSize("checkbox").width - implicitHeight: Theme.getSize("checkbox").height + implicitWidth: UM.Theme.getSize("checkbox").width + implicitHeight: UM.Theme.getSize("checkbox").height - color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox"); + color: (control.hovered || control._hovered) ? UM.Theme.getColor("checkbox_hover") : UM.Theme.getColor("checkbox"); Behavior on color { ColorAnimation { duration: 50; } } - radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : UM.Theme.getSize("checkbox_radius").width + radius: control.exclusiveGroup ? Math.round(UM.Theme.getSize("checkbox").width / 2) : UM.Theme.getSize("checkbox_radius").width - border.width: Theme.getSize("default_lining").width; - border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border"); + border.width: UM.Theme.getSize("default_lining").width; + border.color: (control.hovered || control._hovered) ? UM.Theme.getColor("checkbox_border_hover") : UM.Theme.getColor("checkbox_border"); UM.RecolorImage { @@ -463,16 +463,16 @@ QtObject width: Math.round(parent.width / 2.5) height: Math.round(parent.height / 2.5) sourceSize.height: width - color: Theme.getColor("checkbox_mark") + color: UM.Theme.getColor("checkbox_mark") source: { if (control.checkbox_state == 2) { - return Theme.getIcon("solid"); + return UM.Theme.getIcon("solid"); } else { - return control.exclusiveGroup ? Theme.getIcon("dot") : Theme.getIcon("check"); + return control.exclusiveGroup ? UM.Theme.getIcon("dot") : UM.Theme.getIcon("check"); } } opacity: control.checked @@ -482,8 +482,8 @@ QtObject label: Label { text: control.text - color: Theme.getColor("checkbox_text") - font: Theme.getFont("default") + color: UM.Theme.getColor("checkbox_text") + font: UM.Theme.getFont("default") } } } @@ -492,30 +492,30 @@ QtObject { TextFieldStyle { - textColor: Theme.getColor("setting_control_text") - placeholderTextColor: Theme.getColor("setting_control_text") - font: Theme.getFont("default") + textColor: UM.Theme.getColor("setting_control_text") + placeholderTextColor: UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default") background: Rectangle { implicitHeight: control.height; implicitWidth: control.width; - border.width: Theme.getSize("default_lining").width; - border.color: control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border"); + border.width: UM.Theme.getSize("default_lining").width; + border.color: control.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border"); radius: UM.Theme.getSize("setting_control_radius").width - color: Theme.getColor("setting_validation_ok"); + color: UM.Theme.getColor("setting_validation_ok"); Label { anchors.right: parent.right; - anchors.rightMargin: Theme.getSize("setting_unit_margin").width; + anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width; anchors.verticalCenter: parent.verticalCenter; text: control.unit ? control.unit : "" - color: Theme.getColor("setting_unit"); - font: Theme.getFont("default"); + color: UM.Theme.getColor("setting_unit"); + font: UM.Theme.getFont("default"); renderType: Text.NativeRendering } } From 4974b74109671917f2c0ca925998d4afedff39d9 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 30 Apr 2021 14:15:31 +0200 Subject: [PATCH 2/6] Update copyright --- resources/themes/cura-light/styles.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 6d165df2e1..aee57b5538 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2021 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 From daa0826190ce7a606e54b944afeed8693f4997d9 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Thu, 22 Apr 2021 15:00:42 +0200 Subject: [PATCH 3/6] Fix mypy issues with the DigitalLibrary plugin --- .../src/DFFileExportAndUploadManager.py | 4 +- plugins/DigitalLibrary/src/DFFileUploader.py | 6 ++- .../src/DigitalFactoryApiClient.py | 8 ++-- .../src/DigitalFactoryController.py | 44 +++++++++---------- .../src/DigitalFactoryFileProvider.py | 5 +++ .../src/DigitalFactoryOutputDevice.py | 4 ++ .../src/DigitalFactoryProjectModel.py | 2 +- 7 files changed, 43 insertions(+), 30 deletions(-) diff --git a/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py b/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py index c991f96633..93e24a0651 100644 --- a/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py +++ b/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py @@ -123,7 +123,7 @@ class DFFileExportAndUploadManager: if isinstance(file_upload_response, DFLibraryFileUploadResponse): file_name = file_upload_response.file_name elif isinstance(file_upload_response, DFPrintJobUploadResponse): - file_name = file_upload_response.job_name + file_name = file_upload_response.job_name if file_upload_response.job_name is not None else "" else: Logger.log("e", "Wrong response type received. Aborting uploading file to the Digital Library") return @@ -273,7 +273,7 @@ class DFFileExportAndUploadManager: if reply_body: reply_dict = json.loads(reply_body) if "errors" in reply_dict and len(reply_dict["errors"]) >= 1 and "title" in reply_dict["errors"][0]: - error_title = reply_dict["errors"][0]["title"] # type: str + error_title = reply_dict["errors"][0]["title"] return error_title def _onUploadError(self, filename: str, reply: "QNetworkReply", error: "QNetworkReply.NetworkError") -> None: diff --git a/plugins/DigitalLibrary/src/DFFileUploader.py b/plugins/DigitalLibrary/src/DFFileUploader.py index 9c5356255e..10fee03c4c 100644 --- a/plugins/DigitalLibrary/src/DFFileUploader.py +++ b/plugins/DigitalLibrary/src/DFFileUploader.py @@ -83,8 +83,10 @@ class DFFileUploader: """ if self._finished: raise ValueError("The upload is already finished") - - Logger.log("i", "Uploading DF file to project '{library_project_id}' via link '{upload_url}'".format(library_project_id = self._df_file.library_project_id, upload_url = self._df_file.upload_url)) + if isinstance(self._df_file, DFLibraryFileUploadResponse): + Logger.log("i", "Uploading Cura project file '{file_name}' via link '{upload_url}'".format(file_name = self._df_file.file_name, upload_url = self._df_file.upload_url)) + elif isinstance(self._df_file, DFPrintJobUploadResponse): + Logger.log("i", "Uploading Cura print file '{file_name}' via link '{upload_url}'".format(file_name = self._df_file.job_name, upload_url = self._df_file.upload_url)) self._http.put( url = cast(str, self._df_file.upload_url), headers_dict = {"Content-Type": cast(str, self._df_file.content_type)}, diff --git a/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py b/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py index 4342d2623e..20bc555831 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py @@ -24,6 +24,7 @@ from .DFLibraryFileUploadResponse import DFLibraryFileUploadResponse from .DFPrintJobUploadRequest import DFPrintJobUploadRequest from .DigitalFactoryFileResponse import DigitalFactoryFileResponse from .DigitalFactoryProjectResponse import DigitalFactoryProjectResponse +from .PaginationLinks import PaginationLinks from .PaginationManager import PaginationManager CloudApiClientModel = TypeVar("CloudApiClientModel", bound=BaseModel) @@ -104,7 +105,7 @@ class DigitalFactoryApiClient: """ if self.hasMoreProjectsToLoad(): - url = self._projects_pagination_mgr.links.next_page + url = cast(PaginationLinks, cast(PaginationManager, self._projects_pagination_mgr).links).next_page self._http.get(url, scope = self._scope, callback = self._parseCallback(on_finished, DigitalFactoryProjectResponse, failed, pagination_manager = self._projects_pagination_mgr), @@ -119,7 +120,7 @@ class DigitalFactoryApiClient: :return: Whether there are more pages in the projects list available to be retrieved from the API. """ - return self._projects_pagination_mgr and self._projects_pagination_mgr.links and self._projects_pagination_mgr.links.next_page is not None + return self._projects_pagination_mgr is not None and self._projects_pagination_mgr.links is not None and self._projects_pagination_mgr.links.next_page is not None def getListOfFilesInProject(self, library_project_id: str, on_finished: Callable[[List[DigitalFactoryFileResponse]], Any], failed: Callable) -> None: """Retrieves the list of files contained in the project with library_project_id from the Digital Factory Library. @@ -314,4 +315,5 @@ class DigitalFactoryApiClient: timeout = self.DEFAULT_REQUEST_TIMEOUT) def clear(self) -> None: - self._projects_pagination_mgr.reset() + if self._projects_pagination_mgr is not None: + self._projects_pagination_mgr.reset() diff --git a/plugins/DigitalLibrary/src/DigitalFactoryController.py b/plugins/DigitalLibrary/src/DigitalFactoryController.py index cd20479611..62f13be64c 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryController.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryController.py @@ -6,7 +6,7 @@ import tempfile import threading from enum import IntEnum from pathlib import Path -from typing import Optional, List, Dict, Any +from typing import Optional, List, Dict, Any, cast from PyQt5.QtCore import pyqtSignal, QObject, pyqtSlot, pyqtProperty, Q_ENUMS, QUrl from PyQt5.QtNetwork import QNetworkReply @@ -97,7 +97,7 @@ class DigitalFactoryController(QObject): self.file_handlers = {} # type: Dict[str, FileHandler] self.nodes = None # type: Optional[List[SceneNode]] - self.file_upload_manager = None + self.file_upload_manager = None # type: Optional[DFFileExportAndUploadManager] self._has_preselected_project = False # type: bool self._api = DigitalFactoryApiClient(self._application, on_error = lambda error: Logger.log("e", str(error)), projects_limit_per_page = 20) @@ -149,7 +149,7 @@ class DigitalFactoryController(QObject): :return: True if the user account has Digital Library access, else False """ - subscriptions = [] # type: Optional[List[Dict[str, Any]]] + subscriptions = [] # type: List[Dict[str, Any]] if self._account.userProfile: subscriptions = self._account.userProfile.get("subscriptions", []) return len(subscriptions) > 0 @@ -340,46 +340,46 @@ class DigitalFactoryController(QObject): Logger.log("e", "Something went wrong while trying to create a new a project. Error: {}".format(reply_string)) # The new_status type is actually "RetrievalStatus" but since the RetrievalStatus cannot be an enum, we leave it as int - def setRetrievingProjectsStatus(self, new_status: int) -> None: + def setRetrievingProjectsStatus(self, new_status: RetrievalStatus) -> None: """ Sets the status of the "retrieving library projects" http call. :param new_status: The new status """ self.retrieving_projects_status = new_status - self.retrievingProjectsStatusChanged.emit(new_status) + self.retrievingProjectsStatusChanged.emit(int(new_status)) @pyqtProperty(int, fset = setRetrievingProjectsStatus, notify = retrievingProjectsStatusChanged) def retrievingProjectsStatus(self) -> int: - return self.retrieving_projects_status + return int(self.retrieving_projects_status) # The new_status type is actually "RetrievalStatus" but since the RetrievalStatus cannot be an enum, we leave it as int - def setRetrievingFilesStatus(self, new_status: int) -> None: + def setRetrievingFilesStatus(self, new_status: RetrievalStatus) -> None: """ Sets the status of the "retrieving files list in the selected library project" http call. :param new_status: The new status """ self.retrieving_files_status = new_status - self.retrievingFilesStatusChanged.emit(new_status) + self.retrievingFilesStatusChanged.emit(int(new_status)) @pyqtProperty(int, fset = setRetrievingFilesStatus, notify = retrievingFilesStatusChanged) def retrievingFilesStatus(self) -> int: - return self.retrieving_files_status + return int(self.retrieving_files_status) # The new_status type is actually "RetrievalStatus" but since the RetrievalStatus cannot be an enum, we leave it as int - def setCreatingNewProjectStatus(self, new_status: int) -> None: + def setCreatingNewProjectStatus(self, new_status: RetrievalStatus) -> None: """ Sets the status of the "creating new library project" http call. :param new_status: The new status """ self.creating_new_project_status = new_status - self.creatingNewProjectStatusChanged.emit(new_status) + self.creatingNewProjectStatusChanged.emit(int(new_status)) @pyqtProperty(int, fset = setCreatingNewProjectStatus, notify = creatingNewProjectStatusChanged) def creatingNewProjectStatus(self) -> int: - return self.creating_new_project_status + return int(self.creating_new_project_status) @staticmethod def _onEngineCreated() -> None: @@ -388,15 +388,15 @@ class DigitalFactoryController(QObject): def _applicationInitializationFinished(self) -> None: self._supported_file_types = self._application.getInstance().getMeshFileHandler().getSupportedFileTypesRead() - @pyqtSlot("QList") - def setSelectedFileIndices(self, file_indices: List[int]) -> None: - """ - Sets the index of the file which is currently selected in the list of files. - - :param file_indices: A list of the indices of the currently selected files - """ - self._selected_file_indices = file_indices - self.selectedFileIndicesChanged.emit(file_indices) + # @pyqtSlot("QList") + # def setSelectedFileIndices(self, file_indices: List[int]) -> None: + # """ + # Sets the index of the file which is currently selected in the list of files. + # + # :param file_indices: A list of the indices of the currently selected files + # """ + # self._selected_file_indices = file_indices + # self.selectedFileIndicesChanged.emit(file_indices) @pyqtSlot() def openSelectedFiles(self) -> None: @@ -546,7 +546,7 @@ class DigitalFactoryController(QObject): library_project_name = self._project_model.items[self._selected_project_idx]["displayName"] # Use the file upload manager to export and upload the 3mf and/or ufp files to the DF Library project - self.file_upload_manager = DFFileExportAndUploadManager(file_handlers = self.file_handlers, nodes = self.nodes, + self.file_upload_manager = DFFileExportAndUploadManager(file_handlers = self.file_handlers, nodes = cast(List[SceneNode], self.nodes), library_project_id = library_project_id, library_project_name = library_project_name, file_name = filename, formats = formats, diff --git a/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py b/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py index c2fe6b969c..c5dc164bda 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py @@ -31,9 +31,14 @@ class DigitalFactoryFileProvider(FileProvider): Function called every time the 'From Digital Factory' option of the 'Open File(s)' submenu is triggered """ self.loadWindow() + print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa") if self._account.isLoggedIn and self._controller.userAccountHasLibraryAccess(): self._controller.initialize() + + if not self._dialog: + Logger.log("e", "Unable to create the Digital Library Open dialog.") + return self._dialog.show() def loadWindow(self) -> None: diff --git a/plugins/DigitalLibrary/src/DigitalFactoryOutputDevice.py b/plugins/DigitalLibrary/src/DigitalFactoryOutputDevice.py index 852c565b5e..202223f9b4 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryOutputDevice.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryOutputDevice.py @@ -72,6 +72,10 @@ class DigitalFactoryOutputDevice(ProjectOutputDevice): df_workspace_information = self._current_workspace_information.getPluginMetadata("digital_factory") self._controller.initialize(preselected_project_id = df_workspace_information.get("library_project_id")) + + if not self._dialog: + Logger.log("e", "Unable to create the Digital Library Save dialog.") + return self._dialog.show() def loadWindow(self) -> None: diff --git a/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py b/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py index b35e760998..57cd0fd27c 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py @@ -47,7 +47,7 @@ class DigitalFactoryProjectModel(ListModel): self._update(df_projects) def sortProjectsBy(self, sort_by: Optional[str]): - if sort_by: + if sort_by is not None: try: self._projects.sort(key = lambda p: getattr(p, sort_by)) except AttributeError: From a6d311a0f2c9fb7ef1d1ec2b0c0960bb5711b621 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Thu, 22 Apr 2021 15:08:07 +0200 Subject: [PATCH 4/6] Fix incompatible mypy type --- plugins/DigitalLibrary/src/DigitalFactoryApiClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py b/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py index 20bc555831..b0e34adaba 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py @@ -294,7 +294,7 @@ class DigitalFactoryApiClient: self._file_uploader = DFFileUploader(self._http, df_file_upload_response, mesh, on_finished, on_success, on_progress, on_error) self._file_uploader.start() - def createNewProject(self, project_name: str, on_finished: Callable[[CloudApiClientModel], Any], on_error: Callable) -> None: + def createNewProject(self, project_name: str, on_finished: Callable[[DigitalFactoryProjectResponse], Any], on_error: Callable) -> None: """ Create a new project in the Digital Factory. :param project_name: Name of the new to be created project. From 1347471fea6cdab04bfc2283ebda513142e6ccdf Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Thu, 22 Apr 2021 15:08:47 +0200 Subject: [PATCH 5/6] Remove unused function --- plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py b/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py index 57cd0fd27c..30c04c7177 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py @@ -46,13 +46,6 @@ class DigitalFactoryProjectModel(ListModel): # self.sortProjectsBy("display_name") self._update(df_projects) - def sortProjectsBy(self, sort_by: Optional[str]): - if sort_by is not None: - try: - self._projects.sort(key = lambda p: getattr(p, sort_by)) - except AttributeError: - Logger.log("e", "The projects cannot be sorted by '{}'. No such attribute exists.".format(sort_by)) - def clearProjects(self) -> None: self.clear() self._projects.clear() From 9b58bf0490dc52853a9008db7ab007f7895d7834 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Thu, 22 Apr 2021 15:16:46 +0200 Subject: [PATCH 6/6] Remove commented out code --- .../DigitalLibrary/src/DigitalFactoryController.py | 13 ------------- .../src/DigitalFactoryFileProvider.py | 1 - 2 files changed, 14 deletions(-) diff --git a/plugins/DigitalLibrary/src/DigitalFactoryController.py b/plugins/DigitalLibrary/src/DigitalFactoryController.py index 62f13be64c..33fcc506e7 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryController.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryController.py @@ -339,7 +339,6 @@ class DigitalFactoryController(QObject): self.setCreatingNewProjectStatus(RetrievalStatus.Failed) Logger.log("e", "Something went wrong while trying to create a new a project. Error: {}".format(reply_string)) - # The new_status type is actually "RetrievalStatus" but since the RetrievalStatus cannot be an enum, we leave it as int def setRetrievingProjectsStatus(self, new_status: RetrievalStatus) -> None: """ Sets the status of the "retrieving library projects" http call. @@ -353,7 +352,6 @@ class DigitalFactoryController(QObject): def retrievingProjectsStatus(self) -> int: return int(self.retrieving_projects_status) - # The new_status type is actually "RetrievalStatus" but since the RetrievalStatus cannot be an enum, we leave it as int def setRetrievingFilesStatus(self, new_status: RetrievalStatus) -> None: """ Sets the status of the "retrieving files list in the selected library project" http call. @@ -367,7 +365,6 @@ class DigitalFactoryController(QObject): def retrievingFilesStatus(self) -> int: return int(self.retrieving_files_status) - # The new_status type is actually "RetrievalStatus" but since the RetrievalStatus cannot be an enum, we leave it as int def setCreatingNewProjectStatus(self, new_status: RetrievalStatus) -> None: """ Sets the status of the "creating new library project" http call. @@ -388,16 +385,6 @@ class DigitalFactoryController(QObject): def _applicationInitializationFinished(self) -> None: self._supported_file_types = self._application.getInstance().getMeshFileHandler().getSupportedFileTypesRead() - # @pyqtSlot("QList") - # def setSelectedFileIndices(self, file_indices: List[int]) -> None: - # """ - # Sets the index of the file which is currently selected in the list of files. - # - # :param file_indices: A list of the indices of the currently selected files - # """ - # self._selected_file_indices = file_indices - # self.selectedFileIndicesChanged.emit(file_indices) - @pyqtSlot() def openSelectedFiles(self) -> None: """ Downloads, then opens all files selected in the Qt frontend open dialog. diff --git a/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py b/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py index c5dc164bda..7a544afaa1 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py @@ -31,7 +31,6 @@ class DigitalFactoryFileProvider(FileProvider): Function called every time the 'From Digital Factory' option of the 'Open File(s)' submenu is triggered """ self.loadWindow() - print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa") if self._account.isLoggedIn and self._controller.userAccountHasLibraryAccess(): self._controller.initialize()