diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 59dbe23ea4..88495e3f63 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -24,7 +24,8 @@ Item ToolboxTabButton { text: catalog.i18nc("@title:tab", "Plugins") - active: toolbox.viewCategory == "plugin" + active: toolbox.viewCategory == "plugin" && enabled + enabled: toolbox.viewPage != "loading" && toolbox.viewPage != "errored" onClicked: { toolbox.filterModelByProp("packages", "type", "plugin") @@ -35,7 +36,8 @@ Item ToolboxTabButton { text: catalog.i18nc("@title:tab", "Materials") - active: toolbox.viewCategory == "material" + active: toolbox.viewCategory == "material" && enabled + enabled: toolbox.viewPage != "loading" && toolbox.viewPage != "errored" onClicked: { toolbox.filterModelByProp("authors", "package_types", "material") diff --git a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml index 0f759c75fb..22fb6d73ca 100644 --- a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml @@ -43,7 +43,7 @@ Button return UM.Theme.getColor("topbar_button_text_inactive"); } } - font: control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium") + font: control.enabled ? (control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")) : UM.Theme.getFont("default_italic") verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 492439f860..f64e1cd1b9 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -333,8 +333,8 @@ class Toolbox(QObject, Extension): # Handlers for Network Events # -------------------------------------------------------------------------- - def _onNetworkAccessibleChanged(self, accessible: int) -> None: - if accessible == 0: + def _onNetworkAccessibleChanged(self, network_accessibility: QNetworkAccessManager.NetworkAccessibility) -> None: + if network_accessibility == QNetworkAccessManager.NotAccessible: self.resetDownload() def _onRequestFinished(self, reply: QNetworkReply) -> None: @@ -354,50 +354,55 @@ class Toolbox(QObject, Extension): if reply.operation() == QNetworkAccessManager.GetOperation: for type, url in self._request_urls.items(): if reply.url() == url: - try: - json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) + if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200: + try: + json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) + + # Check for errors: + if "errors" in json_data: + for error in json_data["errors"]: + Logger.log("e", "%s", error["title"]) + return + + # Create model and apply metadata: + if not self._models[type]: + Logger.log("e", "Could not find the %s model.", type) + break + + # HACK: Eventually get rid of the code from here... + if type is "plugins_showcase" or type is "materials_showcase": + self._metadata["plugins_showcase"] = json_data["data"]["plugin"]["packages"] + self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"]) + self._metadata["materials_showcase"] = json_data["data"]["material"]["authors"] + self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"]) + else: + # ...until here. + # This hack arises for multiple reasons but the main + # one is because there are not separate API calls + # for different kinds of showcases. + self._metadata[type] = json_data["data"] + self._models[type].setMetadata(self._metadata[type]) + + # Do some auto filtering + # TODO: Make multiple API calls in the future to handle this + if type is "packages": + self._models[type].setFilter({"type": "plugin"}) + if type is "authors": + self._models[type].setFilter({"package_types": "material"}) + + self.metadataChanged.emit() + + if self.loadingComplete() is True: + self.setViewPage("overview") - # Check for errors: - if "errors" in json_data: - for error in json_data["errors"]: - Logger.log("e", "%s", error["title"]) return - - # Create model and apply metadata: - if not self._models[type]: - Logger.log("e", "Could not find the %s model.", type) + except json.decoder.JSONDecodeError: + Logger.log("w", "Toolbox: Received invalid JSON for %s.", type) break - - # HACK: Eventually get rid of the code from here... - if type is "plugins_showcase" or type is "materials_showcase": - self._metadata["plugins_showcase"] = json_data["data"]["plugin"]["packages"] - self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"]) - self._metadata["materials_showcase"] = json_data["data"]["material"]["authors"] - self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"]) - else: - # ...until here. - # This hack arises for multiple reasons but the main - # one is because there are not separate API calls - # for different kinds of showcases. - self._metadata[type] = json_data["data"] - self._models[type].setMetadata(self._metadata[type]) - - # Do some auto filtering - # TODO: Make multiple API calls in the future to handle this - if type is "packages": - self._models[type].setFilter({"type": "plugin"}) - if type is "authors": - self._models[type].setFilter({"package_types": "material"}) - - self.metadataChanged.emit() - - if self.loadingComplete() is True: - self.setViewPage("overview") - + else: + self.setViewPage("errored") + self.resetDownload() return - except json.decoder.JSONDecodeError: - Logger.log("w", "Toolbox: Received invalid JSON for %s.", type) - break else: # Ignore any operation that is not a get operation