From 138fc668a74d02da4200989eca3188b720592cb0 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 28 Mar 2018 17:10:22 +0200 Subject: [PATCH 01/83] CURA-5035 First draft --- plugins/PluginBrowser/PluginBrowser.py | 10 +- plugins/PluginBrowser/PluginBrowser.qml | 368 ------------------ .../resources/qml/PluginBrowser.qml | 136 +++++++ .../{ => resources/qml}/PluginEntry.qml | 4 +- .../resources/qml/ToolboxFooter.qml | 82 ++++ .../resources/qml/ToolboxGridTile.qml | 61 +++ .../resources/qml/ToolboxHeader.qml | 113 ++++++ .../resources/qml/ToolboxItemGrid.qml | 50 +++ .../resources/qml/ToolboxLicenseDialog.qml | 76 ++++ .../resources/qml/ToolboxRestartDialog.qml | 91 +++++ .../resources/qml/ToolboxShowcase.qml | 54 +++ .../resources/qml/ToolboxShowcaseTile.qml | 48 +++ .../resources/qml/ToolboxViewDownloads.qml | 40 ++ .../resources/qml/ToolboxViewInstalled.qml | 33 ++ resources/themes/cura-light/theme.json | 5 + 15 files changed, 799 insertions(+), 372 deletions(-) delete mode 100644 plugins/PluginBrowser/PluginBrowser.qml create mode 100644 plugins/PluginBrowser/resources/qml/PluginBrowser.qml rename plugins/PluginBrowser/{ => resources/qml}/PluginEntry.qml (99%) create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxFooter.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxHeader.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxItemGrid.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxLicenseDialog.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxRestartDialog.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxShowcase.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxViewInstalled.qml diff --git a/plugins/PluginBrowser/PluginBrowser.py b/plugins/PluginBrowser/PluginBrowser.py index 8912a7a202..68056786ab 100644 --- a/plugins/PluginBrowser/PluginBrowser.py +++ b/plugins/PluginBrowser/PluginBrowser.py @@ -44,6 +44,7 @@ class PluginBrowser(QObject, Extension): # Can be 'installed' or 'available' self._view = "available" + self._detail_view = None self._restart_required = False @@ -135,7 +136,7 @@ class PluginBrowser(QObject, Extension): def _createDialog(self, qml_name): Logger.log("d", "Creating dialog [%s]", qml_name) - path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), qml_name) + path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) dialog = Application.getInstance().createQmlComponent(path, {"manager": self}) return dialog @@ -283,6 +284,13 @@ class PluginBrowser(QObject, Extension): self.viewChanged.emit() self.pluginsMetadataChanged.emit() + @pyqtSlot(str) + def setDetailView(self, item): + self._detail_view = item if item else None + print("Now looking at", self._detail_view) + self.viewChanged.emit() + self.pluginsMetadataChanged.emit() + @pyqtProperty(QObject, notify=pluginsMetadataChanged) def pluginsModel(self): self._plugins_model = PluginsModel(None, self._view) diff --git a/plugins/PluginBrowser/PluginBrowser.qml b/plugins/PluginBrowser/PluginBrowser.qml deleted file mode 100644 index ec4c2a9135..0000000000 --- a/plugins/PluginBrowser/PluginBrowser.qml +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright (c) 2017 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - -import UM 1.1 as UM - -Window { - id: base - - title: catalog.i18nc("@title:tab", "Plugins"); - width: 800 * screenScaleFactor - height: 640 * screenScaleFactor - minimumWidth: 350 * screenScaleFactor - minimumHeight: 350 * screenScaleFactor - color: UM.Theme.getColor("sidebar") - - Item { - id: view - anchors { - fill: parent - leftMargin: UM.Theme.getSize("default_margin").width - rightMargin: UM.Theme.getSize("default_margin").width - topMargin: UM.Theme.getSize("default_margin").height - bottomMargin: UM.Theme.getSize("default_margin").height - } - - Rectangle { - id: topBar - width: parent.width - color: "transparent" - height: childrenRect.height - - Row { - spacing: 12 - height: childrenRect.height - width: childrenRect.width - anchors.horizontalCenter: parent.horizontalCenter - - Button { - text: "Install" - style: ButtonStyle { - background: Rectangle { - color: "transparent" - implicitWidth: 96 - implicitHeight: 48 - Rectangle { - visible: manager.viewing == "available" ? true : false - color: UM.Theme.getColor("primary") - anchors.bottom: parent.bottom - width: parent.width - height: 3 - } - } - label: Text { - text: control.text - color: UM.Theme.getColor("text") - font { - pixelSize: 15 - } - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - } - onClicked: manager.setView("available") - } - - Button { - text: "Manage" - style: ButtonStyle { - background: Rectangle { - color: "transparent" - implicitWidth: 96 - implicitHeight: 48 - Rectangle { - visible: manager.viewing == "installed" ? true : false - color: UM.Theme.getColor("primary") - anchors.bottom: parent.bottom - width: parent.width - height: 3 - } - } - label: Text { - text: control.text - color: UM.Theme.getColor("text") - font { - pixelSize: 15 - } - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - } - onClicked: manager.setView("installed") - } - } - } - - // Scroll view breaks in QtQuick.Controls 2.x - ScrollView { - id: installedPluginList - width: parent.width - height: 400 - - anchors { - top: topBar.bottom - topMargin: UM.Theme.getSize("default_margin").height - bottom: bottomBar.top - bottomMargin: UM.Theme.getSize("default_margin").height - } - - frameVisible: true - - ListView { - id: pluginList - property var activePlugin - property var filter: "installed" - - anchors.fill: parent - - model: manager.pluginsModel - delegate: PluginEntry {} - } - } - - Rectangle { - id: bottomBar - width: parent.width - height: childrenRect.height - color: "transparent" - anchors.bottom: parent.bottom - - Label { - visible: manager.restartRequired - text: "You will need to restart Cura before changes in plugins have effect." - height: 30 - verticalAlignment: Text.AlignVCenter - } - Button { - id: restartChangedButton - text: "Quit Cura" - anchors.right: closeButton.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - visible: manager.restartRequired - iconName: "dialog-restart" - onClicked: manager.restart() - style: ButtonStyle { - background: Rectangle { - implicitWidth: 96 - implicitHeight: 30 - color: UM.Theme.getColor("primary") - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("button_text") - font { - pixelSize: 13 - bold: true - } - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - } - - Button { - id: closeButton - text: catalog.i18nc("@action:button", "Close") - iconName: "dialog-close" - onClicked: { - if ( manager.isDownloading ) { - manager.cancelDownload() - } - base.close(); - } - anchors.right: parent.right - style: ButtonStyle { - background: Rectangle { - color: "transparent" - implicitWidth: 96 - implicitHeight: 30 - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("text") - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - } - } - - UM.I18nCatalog { id: catalog; name: "cura" } - - Connections { - target: manager - onShowLicenseDialog: { - licenseDialog.pluginName = manager.getLicenseDialogPluginName(); - licenseDialog.licenseContent = manager.getLicenseDialogLicenseContent(); - licenseDialog.pluginFileLocation = manager.getLicenseDialogPluginFileLocation(); - licenseDialog.show(); - } - } - - UM.Dialog { - id: licenseDialog - title: catalog.i18nc("@title:window", "Plugin License Agreement") - - minimumWidth: UM.Theme.getSize("license_window_minimum").width - minimumHeight: UM.Theme.getSize("license_window_minimum").height - width: minimumWidth - height: minimumHeight - - property var pluginName; - property var licenseContent; - property var pluginFileLocation; - - Item - { - anchors.fill: parent - - Label - { - id: licenseTitle - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - text: licenseDialog.pluginName + catalog.i18nc("@label", "This plugin contains a license.\nYou need to accept this license to install this plugin.\nDo you agree with the terms below?") - wrapMode: Text.Wrap - } - - TextArea - { - id: licenseText - anchors.top: licenseTitle.bottom - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.topMargin: UM.Theme.getSize("default_margin").height - readOnly: true - text: licenseDialog.licenseContent != null ? licenseDialog.licenseContent : "" - } - } - - rightButtons: [ - Button - { - id: acceptButton - anchors.margins: UM.Theme.getSize("default_margin").width - text: catalog.i18nc("@action:button", "Accept") - onClicked: - { - licenseDialog.close(); - manager.installPlugin(licenseDialog.pluginFileLocation); - } - }, - Button - { - id: declineButton - anchors.margins: UM.Theme.getSize("default_margin").width - text: catalog.i18nc("@action:button", "Decline") - onClicked: - { - licenseDialog.close(); - } - } - ] - } - - Connections { - target: manager - onShowRestartDialog: { - restartDialog.message = manager.getRestartDialogMessage(); - restartDialog.show(); - } - } - - Window { - id: restartDialog - // title: catalog.i18nc("@title:tab", "Plugins"); - width: 360 * screenScaleFactor - height: 120 * screenScaleFactor - minimumWidth: 360 * screenScaleFactor - minimumHeight: 120 * screenScaleFactor - color: UM.Theme.getColor("sidebar") - property var message; - - Text { - id: message - anchors { - left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - top: parent.top - topMargin: UM.Theme.getSize("default_margin").height - } - text: restartDialog.message != null ? restartDialog.message : "" - } - Button { - id: laterButton - text: "Later" - onClicked: restartDialog.close(); - anchors { - left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - bottom: parent.bottom - bottomMargin: UM.Theme.getSize("default_margin").height - } - style: ButtonStyle { - background: Rectangle { - color: "transparent" - implicitWidth: 96 - implicitHeight: 30 - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("text") - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - } - - - Button { - id: restartButton - text: "Quit Cura" - anchors { - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - bottom: parent.bottom - bottomMargin: UM.Theme.getSize("default_margin").height - } - onClicked: manager.restart() - style: ButtonStyle { - background: Rectangle { - implicitWidth: 96 - implicitHeight: 30 - color: UM.Theme.getColor("primary") - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("button_text") - font { - pixelSize: 13 - bold: true - } - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - } - } - - } -} diff --git a/plugins/PluginBrowser/resources/qml/PluginBrowser.qml b/plugins/PluginBrowser/resources/qml/PluginBrowser.qml new file mode 100644 index 0000000000..ee27a3cc31 --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/PluginBrowser.qml @@ -0,0 +1,136 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +import UM 1.1 as UM + +Window + { + id: base + title: catalog.i18nc("@title:tab", "Plugins"); + width: 800 * screenScaleFactor + height: 640 * screenScaleFactor + minimumWidth: 800 * screenScaleFactor + maximumWidth: 800 * screenScaleFactor + minimumHeight: 350 * screenScaleFactor + color: UM.Theme.getColor("sidebar") + Item + { + id: view + anchors.fill: parent + ToolboxHeader + { + id: topBar + } + Rectangle + { + id: mainView + width: parent.width + anchors + { + top: topBar.bottom + bottom: bottomBar.top + } + ToolboxViewDownloads + { + id: viewDownloads + visible: manager.viewing == "available" ? true : false + } + ToolboxViewInstalled + { + id: installedPluginList + visible: manager.viewing == "installed" ? true : false + } + } + Rectangle + { + anchors + { + top: topBar.bottom + } + width: parent.width + height: 8 + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: Qt.rgba(0,0,0,0.1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(0,0,0,0) + } + } + } + ToolboxFooter + { + id: bottomBar + } + Rectangle + { + anchors + { + top: bottomBar.top + } + width: parent.width + height: 8 + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: Qt.rgba(0,0,0,0.1) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(0,0,0,0) + } + } + } + + + + + UM.I18nCatalog { id: catalog; name: "cura" } + + Connections + { + target: manager + onShowLicenseDialog: + { + licenseDialog.pluginName = manager.getLicenseDialogPluginName(); + licenseDialog.licenseContent = manager.getLicenseDialogLicenseContent(); + licenseDialog.pluginFileLocation = manager.getLicenseDialogPluginFileLocation(); + licenseDialog.show(); + } + } + Connections + { + target: manager + onShowRestartDialog: + { + restartDialog.message = manager.getRestartDialogMessage(); + restartDialog.show(); + } + } + ToolboxLicenseDialog + { + id: licenseDialog + } + + ToolboxRestartDialog + { + id: restartDialog + } + } +} diff --git a/plugins/PluginBrowser/PluginEntry.qml b/plugins/PluginBrowser/resources/qml/PluginEntry.qml similarity index 99% rename from plugins/PluginBrowser/PluginEntry.qml rename to plugins/PluginBrowser/resources/qml/PluginEntry.qml index 9dbcb96e79..5ab4d1b2bf 100644 --- a/plugins/PluginBrowser/PluginEntry.qml +++ b/plugins/PluginBrowser/resources/qml/PluginEntry.qml @@ -19,12 +19,10 @@ Component { // Don't show required plugins as they can't be managed anyway: height: !model.required ? 84 : 0 visible: !model.required ? true : false - color: "transparent" + color: Qt.rgba(1.0, 0.0, 0.0, 0.1) anchors { left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width } diff --git a/plugins/PluginBrowser/resources/qml/ToolboxFooter.qml b/plugins/PluginBrowser/resources/qml/ToolboxFooter.qml new file mode 100644 index 0000000000..5ff336320f --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxFooter.qml @@ -0,0 +1,82 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +import UM 1.1 as UM + +Rectangle { + width: parent.width + height: UM.Theme.getSize("base_unit").height * 4 + color: "transparent" + anchors.bottom: parent.bottom + + Label { + visible: manager.restartRequired + text: "You will need to restart Cura before changes in plugins have effect." + height: 30 + verticalAlignment: Text.AlignVCenter + } + Button { + id: restartChangedButton + text: "Quit Cura" + anchors.right: closeButton.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + visible: manager.restartRequired + iconName: "dialog-restart" + onClicked: manager.restart() + style: ButtonStyle { + background: Rectangle { + implicitWidth: 96 + implicitHeight: 30 + color: UM.Theme.getColor("primary") + } + label: Text { + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("button_text") + font { + pixelSize: 13 + bold: true + } + text: control.text + horizontalAlignment: Text.AlignHCenter + } + } + } + + Button { + id: closeButton + text: catalog.i18nc("@action:button", "Close") + iconName: "dialog-close" + onClicked: { + if ( manager.isDownloading ) { + manager.cancelDownload() + } + base.close(); + } + anchors.right: parent.right + style: ButtonStyle { + background: Rectangle { + color: "transparent" + implicitWidth: 96 + implicitHeight: 30 + border { + width: 1 + color: UM.Theme.getColor("lining") + } + } + label: Text { + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("text") + text: control.text + horizontalAlignment: Text.AlignHCenter + } + } + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml b/plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml new file mode 100644 index 0000000000..bf2d4827bc --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml @@ -0,0 +1,61 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +Item +{ + id: base + width: parent.columnSize + height: childrenRect.height + Row + { + width: parent.width + height: childrenRect.height + spacing: Math.floor(UM.Theme.getSize("base_unit").width / 2) + Rectangle + { + id: thumbnail + width: UM.Theme.getSize("base_unit").width * 6 + height: UM.Theme.getSize("base_unit").height * 6 + color: "white" + border.width: 1 + } + Column + { + width: UM.Theme.getSize("base_unit").width * 12 + Label + { + id: name + text: "Auto Orientation" + width: parent.width + wrapMode: Text.WordWrap + height: UM.Theme.getSize("base_unit").height * 2 + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default_bold") + } + Label + { + id: info + text: "Automatically orientate your model." + width: parent.width + wrapMode: Text.WordWrap + color: UM.Theme.getColor("text_medium") + font: UM.Theme.getFont("very_small") + } + } + } + MouseArea + { + anchors.fill: parent + onClicked: { + manager.setDetailView("thingy") + } + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxHeader.qml b/plugins/PluginBrowser/resources/qml/ToolboxHeader.qml new file mode 100644 index 0000000000..cce078035d --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxHeader.qml @@ -0,0 +1,113 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +import UM 1.1 as UM + +Rectangle { + + width: parent.width + color: "transparent" + height: childrenRect.height + + Row { + spacing: 12 + height: childrenRect.height + width: childrenRect.width + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + + Button { + text: "Plugins" + style: ButtonStyle { + background: Rectangle { + color: "transparent" + implicitWidth: 96 + implicitHeight: 48 + Rectangle { + visible: manager.viewing == "available" ? true : false + color: UM.Theme.getColor("primary") + anchors.bottom: parent.bottom + width: parent.width + height: 3 + } + } + label: Text { + text: control.text + color: UM.Theme.getColor("text") + font { + pixelSize: 15 + } + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + } + onClicked: manager.setView("available") + } + + Button { + text: "Materials" + style: ButtonStyle { + background: Rectangle { + color: "transparent" + implicitWidth: 96 + implicitHeight: 48 + Rectangle { + visible: manager.viewing == "available" ? true : false + color: UM.Theme.getColor("primary") + anchors.bottom: parent.bottom + width: parent.width + height: 3 + } + } + label: Text { + text: control.text + color: UM.Theme.getColor("text") + font { + pixelSize: 15 + } + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + } + onClicked: manager.setView("available") + } + } + + Button { + text: "Installed" + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_margin").width + style: ButtonStyle { + background: Rectangle { + color: "transparent" + implicitWidth: 96 + implicitHeight: 48 + Rectangle { + visible: manager.viewing == "installed" ? true : false + color: UM.Theme.getColor("primary") + anchors.bottom: parent.bottom + width: parent.width + height: 3 + } + } + label: Text { + text: control.text + color: UM.Theme.getColor("text") + font { + pixelSize: 15 + } + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + } + onClicked: manager.setView("installed") + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxItemGrid.qml b/plugins/PluginBrowser/resources/qml/ToolboxItemGrid.qml new file mode 100644 index 0000000000..6d642dc165 --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxItemGrid.qml @@ -0,0 +1,50 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 +import UM 1.1 as UM + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +Rectangle +{ + id: base + width: parent.width + height: 1200 + color: "transparent" + Label + { + id: heading + text: "Community Plugins" + width: parent.width + height: UM.Theme.getSize("base_unit").width * 4 + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("text_medium") + font: UM.Theme.getFont("medium") + } + GridLayout + { + id: grid + width: base.width + anchors + { + top: heading.bottom + } + columns: 3 + columnSpacing: UM.Theme.getSize("base_unit").width + rowSpacing: UM.Theme.getSize("base_unit").height + ToolboxGridTile {} + ToolboxGridTile {} + ToolboxGridTile {} + ToolboxGridTile {} + ToolboxGridTile {} + ToolboxGridTile {} + ToolboxGridTile {} + ToolboxGridTile {} + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxLicenseDialog.qml b/plugins/PluginBrowser/resources/qml/ToolboxLicenseDialog.qml new file mode 100644 index 0000000000..eb9f7fb5e7 --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxLicenseDialog.qml @@ -0,0 +1,76 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +import UM 1.1 as UM + +UM.Dialog { + title: catalog.i18nc("@title:window", "Plugin License Agreement") + + minimumWidth: UM.Theme.getSize("license_window_minimum").width + minimumHeight: UM.Theme.getSize("license_window_minimum").height + width: minimumWidth + height: minimumHeight + + property var pluginName; + property var licenseContent; + property var pluginFileLocation; + + Item + { + anchors.fill: parent + + Label + { + id: licenseTitle + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + text: licenseDialog.pluginName + catalog.i18nc("@label", "This plugin contains a license.\nYou need to accept this license to install this plugin.\nDo you agree with the terms below?") + wrapMode: Text.Wrap + } + + TextArea + { + id: licenseText + anchors.top: licenseTitle.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.topMargin: UM.Theme.getSize("default_margin").height + readOnly: true + text: licenseDialog.licenseContent != null ? licenseDialog.licenseContent : "" + } + } + + rightButtons: [ + Button + { + id: acceptButton + anchors.margins: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@action:button", "Accept") + onClicked: + { + licenseDialog.close(); + manager.installPlugin(licenseDialog.pluginFileLocation); + } + }, + Button + { + id: declineButton + anchors.margins: UM.Theme.getSize("default_margin").width + text: catalog.i18nc("@action:button", "Decline") + onClicked: + { + licenseDialog.close(); + } + } + ] +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxRestartDialog.qml b/plugins/PluginBrowser/resources/qml/ToolboxRestartDialog.qml new file mode 100644 index 0000000000..08c5e759b8 --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxRestartDialog.qml @@ -0,0 +1,91 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +import UM 1.1 as UM + +Window { + // title: catalog.i18nc("@title:tab", "Plugins"); + width: 360 * screenScaleFactor + height: 120 * screenScaleFactor + minimumWidth: 360 * screenScaleFactor + minimumHeight: 120 * screenScaleFactor + color: UM.Theme.getColor("sidebar") + property var message; + + Text { + id: message + anchors { + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + top: parent.top + topMargin: UM.Theme.getSize("default_margin").height + } + text: restartDialog.message != null ? restartDialog.message : "" + } + Button { + id: laterButton + text: "Later" + onClicked: restartDialog.close(); + anchors { + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + bottom: parent.bottom + bottomMargin: UM.Theme.getSize("default_margin").height + } + style: ButtonStyle { + background: Rectangle { + color: "transparent" + implicitWidth: 96 + implicitHeight: 30 + border { + width: 1 + color: UM.Theme.getColor("lining") + } + } + label: Text { + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("text") + text: control.text + horizontalAlignment: Text.AlignHCenter + } + } + } + + + Button { + id: restartButton + text: "Quit Cura" + anchors { + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + bottom: parent.bottom + bottomMargin: UM.Theme.getSize("default_margin").height + } + onClicked: manager.restart() + style: ButtonStyle { + background: Rectangle { + implicitWidth: 96 + implicitHeight: 30 + color: UM.Theme.getColor("primary") + } + label: Text { + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("button_text") + font { + pixelSize: 13 + bold: true + } + text: control.text + horizontalAlignment: Text.AlignHCenter + } + } + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxShowcase.qml b/plugins/PluginBrowser/resources/qml/ToolboxShowcase.qml new file mode 100644 index 0000000000..f5aec67e09 --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxShowcase.qml @@ -0,0 +1,54 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +Rectangle +{ + id: base + width: parent.width + height: childrenRect.height + color: "transparent" + Label + { + id: heading + text: "Top Downloads" + width: parent.width + height: UM.Theme.getSize("base_unit").width * 4 + verticalAlignment: Text.AlignVCenter + color: UM.Theme.getColor("text_medium") + font: UM.Theme.getFont("medium") + } + Row + { + height: childrenRect.height + width: childrenRect.width + spacing: UM.Theme.getSize("base_unit").width * 2 + anchors + { + horizontalCenter: parent.horizontalCenter + top: heading.bottom + } + + ToolboxShowcaseTile {} + ToolboxShowcaseTile {} + ToolboxShowcaseTile {} + } + Rectangle + { + color: UM.Theme.getColor("text_medium") + width: parent.width + height: UM.Theme.getSize("base_unit").height / 6 + anchors + { + bottom: parent.bottom + } + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml b/plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml new file mode 100644 index 0000000000..dbcd4c4ade --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml @@ -0,0 +1,48 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +/* NOTE: This file uses the UM.Theme's "base_unit" size. It's commonly agreed +that good design is consistent design, and since the UM.Theme's JSON file does +not provide a method for interiting base units across the interface, adding more +properties for severy single UI element is undesirable for both developers and +theme makers/modfiers. Thus, "base_unit" is used wherever it can be. */ + +Item +{ + width: UM.Theme.getSize("base_unit").width * 12 + height: UM.Theme.getSize("base_unit").width * 12 + Rectangle + { + color: "white" + width: UM.Theme.getSize("base_unit").width * 8 + height: UM.Theme.getSize("base_unit").width * 8 + border.width: 1 + anchors + { + top: parent.top + horizontalCenter: parent.horizontalCenter + } + } + Label + { + text: "Solidworks Integration" + anchors + { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + } + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + height: UM.Theme.getSize("base_unit").width * 4 + width: parent.width + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("medium_bold") + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml b/plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml new file mode 100644 index 0000000000..a2349d5c8c --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml @@ -0,0 +1,40 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +ScrollView +{ + id: base + frameVisible: false + anchors.fill: parent + style: UM.Theme.styles.scrollview + Column + { + width: base.width + spacing: UM.Theme.getSize("base_unit").height + height: childrenRect.height + anchors + { + fill: parent + topMargin: UM.Theme.getSize("base_unit").height + bottomMargin: UM.Theme.getSize("base_unit").height + leftMargin: UM.Theme.getSize("base_unit").width * 2 + rightMargin: UM.Theme.getSize("base_unit").width * 2 + } + ToolboxShowcase + { + id: showcase + } + ToolboxItemGrid + { + id: allPlugins + } + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewInstalled.qml b/plugins/PluginBrowser/resources/qml/ToolboxViewInstalled.qml new file mode 100644 index 0000000000..7db50f6a24 --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxViewInstalled.qml @@ -0,0 +1,33 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Window 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +import UM 1.1 as UM + +ScrollView +{ + anchors.fill: parent + ListView + { + id: pluginList + property var activePlugin + property var filter: "installed" + anchors + { + fill: parent + topMargin: UM.Theme.getSize("default_margin").height + bottomMargin: UM.Theme.getSize("default_margin").height + leftMargin: UM.Theme.getSize("default_margin").width + rightMargin: UM.Theme.getSize("default_margin").width + } + model: manager.pluginsModel + delegate: PluginEntry {} + } +} diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 0fde7f3bc9..0c3980f0ea 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -68,6 +68,9 @@ }, "colors": { + + + "sidebar": [255, 255, 255, 255], "lining": [192, 193, 194, 255], "viewport_overlay": [0, 0, 0, 192], @@ -92,6 +95,7 @@ "text_hover": [70, 84, 113, 255], "text_pressed": [12, 169, 227, 255], "text_subtext": [0, 0, 0, 255], + "text_medium": [128, 128, 128, 255], "text_emphasis": [255, 255, 255, 255], "text_scene": [31, 36, 39, 255], "text_scene_hover": [70, 84, 113, 255], @@ -317,6 +321,7 @@ }, "sizes": { + "base_unit": [1.0, 1.0], "window_minimum_size": [70, 50], "window_margin": [1.0, 1.0], "default_margin": [1.0, 1.0], From f63e67dc22ebd7ff3cb4f240cc0d2cdadac53e53 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 29 Mar 2018 16:52:28 +0200 Subject: [PATCH 02/83] CURA-5035 UI pretty much built --- plugins/PluginBrowser/PluginBrowser.py | 26 +++-- .../resources/qml/PluginBrowser.qml | 42 ++----- .../resources/qml/SectionShadow.qml | 23 ++++ .../resources/qml/ToolboxDetailBlock.qml | 108 ++++++++++++++++++ .../{ToolboxItemGrid.qml => ToolboxGrid.qml} | 3 +- .../resources/qml/ToolboxGridTile.qml | 7 +- .../resources/qml/ToolboxShowcaseTile.qml | 4 +- .../resources/qml/ToolboxViewDetail.qml | 84 ++++++++++++++ .../resources/qml/ToolboxViewDownloads.qml | 2 +- resources/themes/cura-light/theme.json | 7 +- 10 files changed, 254 insertions(+), 52 deletions(-) create mode 100644 plugins/PluginBrowser/resources/qml/SectionShadow.qml create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxDetailBlock.qml rename plugins/PluginBrowser/resources/qml/{ToolboxItemGrid.qml => ToolboxGrid.qml} (93%) create mode 100644 plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml diff --git a/plugins/PluginBrowser/PluginBrowser.py b/plugins/PluginBrowser/PluginBrowser.py index 68056786ab..917502efa0 100644 --- a/plugins/PluginBrowser/PluginBrowser.py +++ b/plugins/PluginBrowser/PluginBrowser.py @@ -44,7 +44,7 @@ class PluginBrowser(QObject, Extension): # Can be 'installed' or 'available' self._view = "available" - self._detail_view = None + self._detail_view = "" self._restart_required = False @@ -86,6 +86,7 @@ class PluginBrowser(QObject, Extension): onIsDownloadingChanged = pyqtSignal() restartRequiredChanged = pyqtSignal() viewChanged = pyqtSignal() + detailViewChanged = pyqtSignal() @pyqtSlot(result = str) def getLicenseDialogPluginName(self): @@ -279,19 +280,26 @@ class PluginBrowser(QObject, Extension): self.setIsDownloading(False) @pyqtSlot(str) - def setView(self, view): + def setView(self, view = "available"): self._view = view self.viewChanged.emit() self.pluginsMetadataChanged.emit() + @pyqtProperty(str, notify = viewChanged) + def viewing(self): + return self._view + @pyqtSlot(str) - def setDetailView(self, item): - self._detail_view = item if item else None - print("Now looking at", self._detail_view) - self.viewChanged.emit() + def setDetailView(self, item = ""): + self._detail_view = item + self.detailViewChanged.emit() self.pluginsMetadataChanged.emit() - @pyqtProperty(QObject, notify=pluginsMetadataChanged) + @pyqtProperty(str, notify = detailViewChanged) + def detailView(self): + return self._detail_view + + @pyqtProperty(QObject, notify = pluginsMetadataChanged) def pluginsModel(self): self._plugins_model = PluginsModel(None, self._view) # self._plugins_model.update() @@ -403,10 +411,6 @@ class PluginBrowser(QObject, Extension): def restartRequired(self): return self._restart_required - @pyqtProperty(str, notify = viewChanged) - def viewing(self): - return self._view - @pyqtSlot() def restart(self): CuraApplication.getInstance().windowClosed() diff --git a/plugins/PluginBrowser/resources/qml/PluginBrowser.qml b/plugins/PluginBrowser/resources/qml/PluginBrowser.qml index ee27a3cc31..dbe7011f8a 100644 --- a/plugins/PluginBrowser/resources/qml/PluginBrowser.qml +++ b/plugins/PluginBrowser/resources/qml/PluginBrowser.qml @@ -41,7 +41,13 @@ Window ToolboxViewDownloads { id: viewDownloads - visible: manager.viewing == "available" ? true : false + visible: manager.viewing == "available" && manager.detailView == "" ? true : false + } + + ToolboxViewDetail + { + id: viewDetail + visible: manager.viewing == "available" && manager.detailView != "" ? true : false } ToolboxViewInstalled { @@ -49,53 +55,23 @@ Window visible: manager.viewing == "installed" ? true : false } } - Rectangle + SectionShadow { anchors { top: topBar.bottom } - width: parent.width - height: 8 - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: Qt.rgba(0,0,0,0.1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(0,0,0,0) - } - } } ToolboxFooter { id: bottomBar } - Rectangle + SectionShadow { anchors { top: bottomBar.top } - width: parent.width - height: 8 - gradient: Gradient - { - GradientStop - { - position: 0.0 - color: Qt.rgba(0,0,0,0.1) - } - GradientStop - { - position: 1.0 - color: Qt.rgba(0,0,0,0) - } - } } diff --git a/plugins/PluginBrowser/resources/qml/SectionShadow.qml b/plugins/PluginBrowser/resources/qml/SectionShadow.qml new file mode 100644 index 0000000000..362c88575d --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/SectionShadow.qml @@ -0,0 +1,23 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 + +Rectangle +{ + width: parent.width + height: 8 + gradient: Gradient + { + GradientStop + { + position: 0.0 + color: Qt.rgba(0,0,0,0.2) + } + GradientStop + { + position: 1.0 + color: Qt.rgba(0,0,0,0) + } + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxDetailBlock.qml b/plugins/PluginBrowser/resources/qml/ToolboxDetailBlock.qml new file mode 100644 index 0000000000..abe2cdf450 --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxDetailBlock.qml @@ -0,0 +1,108 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +Rectangle +{ + width: parent.width + height: childrenRect.height + color: "transparent" + Column + { + anchors + { + left: parent.left + right: controls.left + rightMargin: UM.Theme.getSize("default_margin").width + top: parent.top + leftMargin: UM.Theme.getSize("default_margin").width + topMargin: UM.Theme.getSize("default_margin").height + } + Label + { + width: parent.width + height: UM.Theme.getSize("base_unit").height * 2 + text: "DSM Abrasive" + wrapMode: Text.WordWrap + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default_bold") + } + Label + { + width: parent.width + text: "DSM abrasive material provides extra stiffness. It’s suitable for printing \"Functional prototypes\" and \"End parts\"." + wrapMode: Text.WordWrap + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("normal") + } + } + Rectangle + { + id: controls + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: UM.Theme.getSize("default_margin").height + width: childrenRect.width + Button { + id: installButton + text: catalog.i18nc("@action:button", "Install") + enabled: + { + if ( manager.isDownloading ) + { + return pluginList.activePlugin == model ? true : false + } + else + { + return true + } + } + opacity: enabled ? 1.0 : 0.5 + style: ButtonStyle { + background: Rectangle + { + implicitWidth: 96 + implicitHeight: 30 + color: UM.Theme.getColor("primary") + } + label: Label + { + text: control.text + color: "white" + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + } + onClicked: + { + if ( manager.isDownloading && pluginList.activePlugin == model ) + { + manager.cancelDownload(); + } + else + { + pluginList.activePlugin = model; + if ( model.can_upgrade ) + { + manager.downloadAndInstallPlugin( model.update_url ); + } + else { + manager.downloadAndInstallPlugin( model.file_location ); + } + } + } + } + } + Rectangle + { + color: UM.Theme.getColor("text_medium") + width: parent.width + height: UM.Theme.getSize("default_lining").height + anchors.top: parent.top + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxItemGrid.qml b/plugins/PluginBrowser/resources/qml/ToolboxGrid.qml similarity index 93% rename from plugins/PluginBrowser/resources/qml/ToolboxItemGrid.qml rename to plugins/PluginBrowser/resources/qml/ToolboxGrid.qml index 6d642dc165..53c4443493 100644 --- a/plugins/PluginBrowser/resources/qml/ToolboxItemGrid.qml +++ b/plugins/PluginBrowser/resources/qml/ToolboxGrid.qml @@ -15,7 +15,7 @@ Rectangle { id: base width: parent.width - height: 1200 + height: childrenRect.height + UM.Theme.getSize("double_margin").height * 8 color: "transparent" Label { @@ -38,6 +38,7 @@ Rectangle columns: 3 columnSpacing: UM.Theme.getSize("base_unit").width rowSpacing: UM.Theme.getSize("base_unit").height + ToolboxGridTile {} ToolboxGridTile {} ToolboxGridTile {} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml b/plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml index bf2d4827bc..160e59bf15 100644 --- a/plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml +++ b/plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml @@ -6,13 +6,14 @@ import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 import UM 1.1 as UM Item { id: base - width: parent.columnSize height: childrenRect.height + Layout.fillWidth: true Row { width: parent.width @@ -21,8 +22,8 @@ Item Rectangle { id: thumbnail - width: UM.Theme.getSize("base_unit").width * 6 - height: UM.Theme.getSize("base_unit").height * 6 + width: UM.Theme.getSize("toolbox_thumbnail_small").width + height: UM.Theme.getSize("toolbox_thumbnail_small").height color: "white" border.width: 1 } diff --git a/plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml b/plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml index dbcd4c4ade..29a9054b2d 100644 --- a/plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml +++ b/plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml @@ -16,8 +16,8 @@ theme makers/modfiers. Thus, "base_unit" is used wherever it can be. */ Item { - width: UM.Theme.getSize("base_unit").width * 12 - height: UM.Theme.getSize("base_unit").width * 12 + width: UM.Theme.getSize("toolbox_thumbnail_large").width + height: UM.Theme.getSize("toolbox_thumbnail_large").width Rectangle { color: "white" diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml b/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml new file mode 100644 index 0000000000..9198452ed9 --- /dev/null +++ b/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml @@ -0,0 +1,84 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +Item +{ + id: base + anchors.fill: parent + Rectangle + { + id: backMargin + height: parent.height + width: UM.Theme.getSize("base_unit").width * 6 + anchors + { + top: parent.top + left: parent.left + topMargin: UM.Theme.getSize("double_margin").height + leftMargin: UM.Theme.getSize("default_margin").width + rightMargin: UM.Theme.getSize("default_margin").width + } + Button + { + text: "Back" + onClicked: { + manager.setDetailView("") + } + } + color: "transparent" + } + ScrollView + { + id: scroll + frameVisible: false + anchors.right: base.right + anchors.left: backMargin.right + height: parent.height + style: UM.Theme.styles.scrollview + Column + { + width: scroll.width + spacing: UM.Theme.getSize("base_unit").height + height: childrenRect.height + (UM.Theme.getSize("double_margin").height * 2) + anchors + { + fill: parent + topMargin: UM.Theme.getSize("double_margin").height + bottomMargin: UM.Theme.getSize("double_margin").height + leftMargin: UM.Theme.getSize("double_margin").width + rightMargin: UM.Theme.getSize("double_margin").width + } + Rectangle + { + width: parent.width + height: UM.Theme.getSize("base_unit").height * 12 + color: "transparent" + Rectangle + { + id: thumbnail + width: UM.Theme.getSize("toolbox_thumbnail_medium").width + height: UM.Theme.getSize("toolbox_thumbnail_medium").height + color: "white" + border.width: 1 + } + } + ToolboxDetailBlock {} + ToolboxDetailBlock {} + ToolboxDetailBlock {} + ToolboxDetailBlock {} + ToolboxDetailBlock {} + ToolboxDetailBlock {} + ToolboxDetailBlock {} + ToolboxDetailBlock {} + ToolboxDetailBlock {} + ToolboxDetailBlock {} + ToolboxDetailBlock {} + } + } +} diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml b/plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml index a2349d5c8c..55e3650488 100644 --- a/plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml +++ b/plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml @@ -32,7 +32,7 @@ ScrollView { id: showcase } - ToolboxItemGrid + ToolboxGrid { id: allPlugins } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 0c3980f0ea..7706b8081d 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -325,6 +325,7 @@ "window_minimum_size": [70, 50], "window_margin": [1.0, 1.0], "default_margin": [1.0, 1.0], + "double_margin": [2.0, 2.0], "default_lining": [0.08, 0.08], "default_arrow": [0.8, 0.8], "logo": [7.6, 1.6], @@ -438,6 +439,10 @@ "objects_menu_size": [20, 40], "objects_menu_size_collapsed": [20, 17], "build_plate_selection_size": [15, 5], - "objects_menu_button": [0.3, 2.7] + "objects_menu_button": [0.3, 2.7], + + "toolbox_thumbnail_small": [6.0, 6.0], + "toolbox_thumbnail_medium": [9.0, 9.0], + "toolbox_thumbnail_large": [12.0, 12.0] } } From 322fe7d61f6210cd3ca2e5b4abc848c0620b46ba Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 30 Mar 2018 14:15:00 +0200 Subject: [PATCH 03/83] CURA-5137 Rename Plugin Browser into Toolbox --- cura/CuraApplication.py | 2 +- plugins/PluginBrowser/__init__.py | 12 ------------ plugins/PluginBrowser/plugin.json | 7 ------- .../PluginBrowser.py => Toolbox/Toolbox/Toolbox.py} | 7 ++++--- plugins/Toolbox/__init__.py | 12 ++++++++++++ plugins/Toolbox/plugin.json | 7 +++++++ .../resources/qml/PluginBrowser.qml | 0 .../resources/qml/PluginEntry.qml | 0 .../resources/qml/SectionShadow.qml | 0 .../resources/qml/ToolboxDetailBlock.qml | 0 .../resources/qml/ToolboxFooter.qml | 0 .../resources/qml/ToolboxGrid.qml | 0 .../resources/qml/ToolboxGridTile.qml | 0 .../resources/qml/ToolboxHeader.qml | 0 .../resources/qml/ToolboxLicenseDialog.qml | 0 .../resources/qml/ToolboxRestartDialog.qml | 0 .../resources/qml/ToolboxShowcase.qml | 0 .../resources/qml/ToolboxShowcaseTile.qml | 0 .../resources/qml/ToolboxViewDetail.qml | 0 .../resources/qml/ToolboxViewDownloads.qml | 0 .../resources/qml/ToolboxViewInstalled.qml | 0 resources/qml/Actions.qml | 2 +- resources/qml/Cura.qml | 4 ++-- 23 files changed, 27 insertions(+), 26 deletions(-) delete mode 100644 plugins/PluginBrowser/__init__.py delete mode 100644 plugins/PluginBrowser/plugin.json rename plugins/{PluginBrowser/PluginBrowser.py => Toolbox/Toolbox/Toolbox.py} (98%) create mode 100644 plugins/Toolbox/__init__.py create mode 100644 plugins/Toolbox/plugin.json rename plugins/{PluginBrowser => Toolbox}/resources/qml/PluginBrowser.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/PluginEntry.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/SectionShadow.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxDetailBlock.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxFooter.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxGrid.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxGridTile.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxHeader.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxLicenseDialog.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxRestartDialog.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxShowcase.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxShowcaseTile.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxViewDetail.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxViewDownloads.qml (100%) rename plugins/{PluginBrowser => Toolbox}/resources/qml/ToolboxViewInstalled.qml (100%) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5ac0f03b2e..d3ea3f134c 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -261,7 +261,7 @@ class CuraApplication(QtApplication): "TranslateTool", "FileLogger", "XmlMaterialProfile", - "PluginBrowser", + "Toolbox", "PrepareStage", "MonitorStage" ]) diff --git a/plugins/PluginBrowser/__init__.py b/plugins/PluginBrowser/__init__.py deleted file mode 100644 index d414c36a99..0000000000 --- a/plugins/PluginBrowser/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2017 Ultimaker B.V. -# PluginBrowser is released under the terms of the LGPLv3 or higher. - -from . import PluginBrowser - - -def getMetaData(): - return {} - - -def register(app): - return {"extension": PluginBrowser.PluginBrowser()} diff --git a/plugins/PluginBrowser/plugin.json b/plugins/PluginBrowser/plugin.json deleted file mode 100644 index 491e21f506..0000000000 --- a/plugins/PluginBrowser/plugin.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "Plugin Browser", - "author": "Ultimaker B.V.", - "version": "1.0.0", - "api": 4, - "description": "Find, manage and install new plugins." -} \ No newline at end of file diff --git a/plugins/PluginBrowser/PluginBrowser.py b/plugins/Toolbox/Toolbox/Toolbox.py similarity index 98% rename from plugins/PluginBrowser/PluginBrowser.py rename to plugins/Toolbox/Toolbox/Toolbox.py index 917502efa0..9c64efc9fa 100644 --- a/plugins/PluginBrowser/PluginBrowser.py +++ b/plugins/Toolbox/Toolbox/Toolbox.py @@ -1,5 +1,5 @@ -# Copyright (c) 2017 Ultimaker B.V. -# PluginBrowser is released under the terms of the LGPLv3 or higher. +# Copyright (c) 2018 Ultimaker B.V. +# Toolbox is released under the terms of the LGPLv3 or higher. from PyQt5.QtCore import QUrl, QObject, pyqtProperty, pyqtSignal, pyqtSlot from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply @@ -24,7 +24,7 @@ from cura.CuraApplication import CuraApplication i18n_catalog = i18nCatalog("cura") -class PluginBrowser(QObject, Extension): +class Toolbox(QObject, Extension): def __init__(self, parent=None): super().__init__(parent) @@ -138,6 +138,7 @@ class PluginBrowser(QObject, Extension): def _createDialog(self, qml_name): Logger.log("d", "Creating dialog [%s]", qml_name) path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) + Logger.log("d", "Creating dialog [%s]", path) dialog = Application.getInstance().createQmlComponent(path, {"manager": self}) return dialog diff --git a/plugins/Toolbox/__init__.py b/plugins/Toolbox/__init__.py new file mode 100644 index 0000000000..dc2d6c9c23 --- /dev/null +++ b/plugins/Toolbox/__init__.py @@ -0,0 +1,12 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Toolbox is released under the terms of the LGPLv3 or higher. + +from .Toolbox import Toolbox + + +def getMetaData(): + return {} + + +def register(app): + return {"extension": Toolbox.Toolbox()} diff --git a/plugins/Toolbox/plugin.json b/plugins/Toolbox/plugin.json new file mode 100644 index 0000000000..7c85851df7 --- /dev/null +++ b/plugins/Toolbox/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "Toolbox", + "author": "Ultimaker B.V.", + "version": "1.0.0", + "api": 4, + "description": "Find, manage and install new cura packages." +} \ No newline at end of file diff --git a/plugins/PluginBrowser/resources/qml/PluginBrowser.qml b/plugins/Toolbox/resources/qml/PluginBrowser.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/PluginBrowser.qml rename to plugins/Toolbox/resources/qml/PluginBrowser.qml diff --git a/plugins/PluginBrowser/resources/qml/PluginEntry.qml b/plugins/Toolbox/resources/qml/PluginEntry.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/PluginEntry.qml rename to plugins/Toolbox/resources/qml/PluginEntry.qml diff --git a/plugins/PluginBrowser/resources/qml/SectionShadow.qml b/plugins/Toolbox/resources/qml/SectionShadow.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/SectionShadow.qml rename to plugins/Toolbox/resources/qml/SectionShadow.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxDetailBlock.qml b/plugins/Toolbox/resources/qml/ToolboxDetailBlock.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxDetailBlock.qml rename to plugins/Toolbox/resources/qml/ToolboxDetailBlock.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxFooter.qml rename to plugins/Toolbox/resources/qml/ToolboxFooter.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxGrid.qml b/plugins/Toolbox/resources/qml/ToolboxGrid.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxGrid.qml rename to plugins/Toolbox/resources/qml/ToolboxGrid.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxGridTile.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxGridTile.qml rename to plugins/Toolbox/resources/qml/ToolboxGridTile.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxHeader.qml rename to plugins/Toolbox/resources/qml/ToolboxHeader.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxLicenseDialog.qml b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxLicenseDialog.qml rename to plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxRestartDialog.qml b/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxRestartDialog.qml rename to plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxShowcase.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxShowcase.qml rename to plugins/Toolbox/resources/qml/ToolboxShowcase.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxShowcaseTile.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxShowcaseTile.qml rename to plugins/Toolbox/resources/qml/ToolboxShowcaseTile.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml b/plugins/Toolbox/resources/qml/ToolboxViewDetail.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml rename to plugins/Toolbox/resources/qml/ToolboxViewDetail.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml b/plugins/Toolbox/resources/qml/ToolboxViewDownloads.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxViewDownloads.qml rename to plugins/Toolbox/resources/qml/ToolboxViewDownloads.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewInstalled.qml b/plugins/Toolbox/resources/qml/ToolboxViewInstalled.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxViewInstalled.qml rename to plugins/Toolbox/resources/qml/ToolboxViewInstalled.qml diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 7002711614..cb9299e69c 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -430,7 +430,7 @@ Item Action { id: browsePluginsAction - text: catalog.i18nc("@action:menu", "Browse plugins...") + text: catalog.i18nc("@action:menu", "Browse packages...") iconName: "plugins_browse" } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index c4ebb790e8..db5be5ea25 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -270,7 +270,7 @@ UM.MainWindow Menu { id: plugin_menu - title: catalog.i18nc("@title:menu menubar:toplevel", "P&lugins") + title: catalog.i18nc("@title:menu menubar:toplevel", "&Toolbox") MenuItem { action: Cura.Actions.browsePlugins } } @@ -670,7 +670,7 @@ UM.MainWindow { target: Cura.Actions.browsePlugins onTriggered: { - curaExtensions.callExtensionMethod("Plugin Browser", "browsePlugins") + curaExtensions.callExtensionMethod("Toolbox", "browsePlugins") } } From 0416ba95ae8e70cb336755ef03a76acada8ab6c0 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 30 Mar 2018 14:16:51 +0200 Subject: [PATCH 04/83] CURA-5137 Add init file --- plugins/Toolbox/Toolbox/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugins/Toolbox/Toolbox/__init__.py diff --git a/plugins/Toolbox/Toolbox/__init__.py b/plugins/Toolbox/Toolbox/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 89c27ae7f4f6b6ad85f4e15d2a7517996f87a274 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Fri, 30 Mar 2018 15:13:10 +0200 Subject: [PATCH 05/83] CURA-5137 Get the list of packages from the server --- plugins/Toolbox/Toolbox/Toolbox.py | 19 +++++++++---------- resources/qml/Actions.qml | 4 ++-- resources/qml/Cura.qml | 6 +++--- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/plugins/Toolbox/Toolbox/Toolbox.py b/plugins/Toolbox/Toolbox/Toolbox.py index 9c64efc9fa..f1efcc6684 100644 --- a/plugins/Toolbox/Toolbox/Toolbox.py +++ b/plugins/Toolbox/Toolbox/Toolbox.py @@ -24,12 +24,13 @@ from cura.CuraApplication import CuraApplication i18n_catalog = i18nCatalog("cura") +## The Toolbox class is responsible of communicating with the server through the API class Toolbox(QObject, Extension): def __init__(self, parent=None): super().__init__(parent) - self._api_version = 4 - self._api_url = "http://software.ultimaker.com/cura/v%s/" % self._api_version + self._api_version = 1 + self._api_url = "https://api-staging.ultimaker.com/cura-packages/v%s/" % self._api_version self._plugin_list_request = None self._download_plugin_request = None @@ -119,18 +120,18 @@ class Toolbox(QObject, Extension): return self._is_downloading @pyqtSlot() - def browsePlugins(self): + def browsePackages(self): self._createNetworkManager() - self.requestPluginList() + self.requestPackageList() if not self._dialog: self._dialog = self._createDialog("PluginBrowser.qml") self._dialog.show() - @pyqtSlot() - def requestPluginList(self): - Logger.log("i", "Requesting plugin list") - url = QUrl(self._api_url + "plugins") + def requestPackageList(self): + cura_version = 4 + Logger.log("i", "Requesting package list") + url = QUrl(self._api_url + "packages?cura_version={version}".format(version = cura_version)) self._plugin_list_request = QNetworkRequest(url) self._plugin_list_request.setRawHeader(*self._request_header) self._network_manager.get(self._plugin_list_request) @@ -138,7 +139,6 @@ class Toolbox(QObject, Extension): def _createDialog(self, qml_name): Logger.log("d", "Creating dialog [%s]", qml_name) path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) - Logger.log("d", "Creating dialog [%s]", path) dialog = Application.getInstance().createQmlComponent(path, {"manager": self}) return dialog @@ -223,7 +223,6 @@ class Toolbox(QObject, Extension): self.openRestartDialog(result["message"]) self._restart_required = True self.restartRequiredChanged.emit() - # Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Plugin browser"), result["message"]) @pyqtSlot(str) def removePlugin(self, plugin_id): diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index cb9299e69c..21e6eebf58 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -68,7 +68,7 @@ Item property alias configureSettingVisibility: configureSettingVisibilityAction - property alias browsePlugins: browsePluginsAction + property alias browsePackages: browsePackagesAction UM.I18nCatalog{id: catalog; name:"cura"} @@ -429,7 +429,7 @@ Item Action { - id: browsePluginsAction + id: browsePackagesAction text: catalog.i18nc("@action:menu", "Browse packages...") iconName: "plugins_browse" } diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index db5be5ea25..e20a29fe16 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -272,7 +272,7 @@ UM.MainWindow id: plugin_menu title: catalog.i18nc("@title:menu menubar:toplevel", "&Toolbox") - MenuItem { action: Cura.Actions.browsePlugins } + MenuItem { action: Cura.Actions.browsePackages } } Menu @@ -668,9 +668,9 @@ UM.MainWindow // show the plugin browser dialog Connections { - target: Cura.Actions.browsePlugins + target: Cura.Actions.browsePackages onTriggered: { - curaExtensions.callExtensionMethod("Toolbox", "browsePlugins") + curaExtensions.callExtensionMethod("Toolbox", "browsePackages") } } From 3d452d334b45afd43b23503eeaf7531df7d84c50 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 3 Apr 2018 11:21:15 +0200 Subject: [PATCH 06/83] CURA-5137 Create the Cura Packages Model for the Toolbox. Fetch the data from the new server and create the model for show in the toolbox. --- plugins/Toolbox/Toolbox/CuraPackageModel.py | 71 +++++++++++++++++++++ plugins/Toolbox/Toolbox/Toolbox.py | 53 ++++++++------- 2 files changed, 101 insertions(+), 23 deletions(-) create mode 100644 plugins/Toolbox/Toolbox/CuraPackageModel.py diff --git a/plugins/Toolbox/Toolbox/CuraPackageModel.py b/plugins/Toolbox/Toolbox/CuraPackageModel.py new file mode 100644 index 0000000000..f8d6174d66 --- /dev/null +++ b/plugins/Toolbox/Toolbox/CuraPackageModel.py @@ -0,0 +1,71 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from typing import Dict + +from PyQt5.QtCore import Qt, pyqtProperty, pyqtSignal + +from UM.Qt.ListModel import ListModel + +## Model that holds cura packages. By setting the filter property the instances held by this model can be changed. +class CuraPackageModel(ListModel): + IdRole = Qt.UserRole + 1 + TypeRole = Qt.UserRole + 2 + NameRole = Qt.UserRole + 3 + VersionRole = Qt.UserRole + 4 + AuthorRole = Qt.UserRole + 5 + DescriptionRole = Qt.UserRole + 6 + IconURLRole = Qt.UserRole + 7 + ImageURLsRole = Qt.UserRole + 8 + + def __init__(self, parent = None): + super().__init__(parent) + + self._packages_metadata = None + + self.addRoleName(CuraPackageModel.IdRole, "id") + self.addRoleName(CuraPackageModel.TypeRole, "type") + self.addRoleName(CuraPackageModel.NameRole, "name") + self.addRoleName(CuraPackageModel.VersionRole, "version") + self.addRoleName(CuraPackageModel.AuthorRole, "author") + self.addRoleName(CuraPackageModel.DescriptionRole, "description") + self.addRoleName(CuraPackageModel.IconURLRole, "icon_url") + self.addRoleName(CuraPackageModel.ImageURLsRole, "image_urls") + + # List of filters for queries. The result is the union of the each list of results. + self._filter = None # type: Dict[str,str] + + def setPackagesMetaData(self, data): + self._packages_metadata = data + self._update() + + def _update(self): + items = [] + + for package in self._packages_metadata: + items.append({ + "id": package["package_id"], + "type": package["package_type"], + "name": package["display_name"], + "version": package["package_version"], + "author": package["author"], + "description": package["description"], + "icon_url": package["icon_url"] if "icon_url" in package else None, + "image_urls": package["image_urls"] + }) + + items.sort(key = lambda k: k["name"]) + self.setItems(items) + + filterChanged = pyqtSignal() + + ## Set the filter of this model based on a string. + # \param filter_dict \type{Dict} Dictionary to do the filtering by. + def setFilter(self, filter_dict: Dict[str, str]) -> None: + if filter_dict != self._filter: + self._filter = filter_dict + self.filterChanged.emit() + + @pyqtProperty("QVariantMap", fset = setFilter, notify = filterChanged) + def filter(self) -> Dict[str, str]: + return self._filter diff --git a/plugins/Toolbox/Toolbox/Toolbox.py b/plugins/Toolbox/Toolbox/Toolbox.py index f1efcc6684..858a21d18a 100644 --- a/plugins/Toolbox/Toolbox/Toolbox.py +++ b/plugins/Toolbox/Toolbox/Toolbox.py @@ -1,5 +1,6 @@ # Copyright (c) 2018 Ultimaker B.V. # Toolbox is released under the terms of the LGPLv3 or higher. +from typing import Dict from PyQt5.QtCore import QUrl, QObject, pyqtProperty, pyqtSignal, pyqtSlot from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply @@ -21,6 +22,7 @@ import platform import zipfile from cura.CuraApplication import CuraApplication +from .CuraPackageModel import CuraPackageModel i18n_catalog = i18nCatalog("cura") @@ -32,16 +34,17 @@ class Toolbox(QObject, Extension): self._api_version = 1 self._api_url = "https://api-staging.ultimaker.com/cura-packages/v%s/" % self._api_version - self._plugin_list_request = None + self._package_list_request = None self._download_plugin_request = None self._download_plugin_reply = None self._network_manager = None self._plugin_registry = Application.getInstance().getPluginRegistry() + self._packages_version_number = self._plugin_registry.APIVersion - self._plugins_metadata = [] - self._plugins_model = None + self._packages_metadata = [] + self._packages_model = None # Can be 'installed' or 'available' self._view = "available" @@ -82,7 +85,7 @@ class Toolbox(QObject, Extension): showLicenseDialog = pyqtSignal() showRestartDialog = pyqtSignal() - pluginsMetadataChanged = pyqtSignal() + packagesMetadataChanged = pyqtSignal() onDownloadProgressChanged = pyqtSignal() onIsDownloadingChanged = pyqtSignal() restartRequiredChanged = pyqtSignal() @@ -129,12 +132,11 @@ class Toolbox(QObject, Extension): self._dialog.show() def requestPackageList(self): - cura_version = 4 Logger.log("i", "Requesting package list") - url = QUrl(self._api_url + "packages?cura_version={version}".format(version = cura_version)) - self._plugin_list_request = QNetworkRequest(url) - self._plugin_list_request.setRawHeader(*self._request_header) - self._network_manager.get(self._plugin_list_request) + url = QUrl("{base_url}packages?cura_version={version}".format(base_url = self._api_url, version = self._packages_version_number)) + self._package_list_request = QNetworkRequest(url) + self._package_list_request.setRawHeader(*self._request_header) + self._network_manager.get(self._package_list_request) def _createDialog(self, qml_name): Logger.log("d", "Creating dialog [%s]", qml_name) @@ -218,7 +220,7 @@ class Toolbox(QObject, Extension): result = PluginRegistry.getInstance().installPlugin("file://" + location) self._newly_installed_plugin_ids.append(result["id"]) - self.pluginsMetadataChanged.emit() + self.packagesMetadataChanged.emit() self.openRestartDialog(result["message"]) self._restart_required = True @@ -229,7 +231,7 @@ class Toolbox(QObject, Extension): result = PluginRegistry.getInstance().uninstallPlugin(plugin_id) self._newly_uninstalled_plugin_ids.append(result["id"]) - self.pluginsMetadataChanged.emit() + self.packagesMetadataChanged.emit() self._restart_required = True self.restartRequiredChanged.emit() @@ -239,13 +241,13 @@ class Toolbox(QObject, Extension): @pyqtSlot(str) def enablePlugin(self, plugin_id): self._plugin_registry.enablePlugin(plugin_id) - self.pluginsMetadataChanged.emit() + self.packagesMetadataChanged.emit() Logger.log("i", "%s was set as 'active'", id) @pyqtSlot(str) def disablePlugin(self, plugin_id): self._plugin_registry.disablePlugin(plugin_id) - self.pluginsMetadataChanged.emit() + self.packagesMetadataChanged.emit() Logger.log("i", "%s was set as 'deactive'", id) @pyqtProperty(int, notify = onDownloadProgressChanged) @@ -283,7 +285,7 @@ class Toolbox(QObject, Extension): def setView(self, view = "available"): self._view = view self.viewChanged.emit() - self.pluginsMetadataChanged.emit() + self.packagesMetadataChanged.emit() @pyqtProperty(str, notify = viewChanged) def viewing(self): @@ -293,13 +295,13 @@ class Toolbox(QObject, Extension): def setDetailView(self, item = ""): self._detail_view = item self.detailViewChanged.emit() - self.pluginsMetadataChanged.emit() + self.packagesMetadataChanged.emit() @pyqtProperty(str, notify = detailViewChanged) def detailView(self): return self._detail_view - @pyqtProperty(QObject, notify = pluginsMetadataChanged) + @pyqtProperty(QObject, notify = packagesMetadataChanged) def pluginsModel(self): self._plugins_model = PluginsModel(None, self._view) # self._plugins_model.update() @@ -311,20 +313,22 @@ class Toolbox(QObject, Extension): if self._checkCanUpgrade(plugin["id"], plugin["version"]): plugin["can_upgrade"] = True - for item in self._plugins_metadata: + for item in self._packages_metadata: if item["id"] == plugin["id"]: plugin["update_url"] = item["file_location"] return self._plugins_model - + @pyqtProperty(QObject, notify = packagesMetadataChanged) + def packagesModel(self): + return self._packages_model def _checkCanUpgrade(self, id, version): # TODO: This could maybe be done more efficiently using a dictionary... # Scan plugin server data for plugin with the given id: - for plugin in self._plugins_metadata: + for plugin in self._packages_metadata: if id == plugin["id"]: reg_version = Version(version) new_version = Version(plugin["version"]) @@ -374,14 +378,17 @@ class Toolbox(QObject, Extension): return if reply.operation() == QNetworkAccessManager.GetOperation: - if reply_url == self._api_url + "plugins": + if reply_url == "{base_url}packages?cura_version={version}".format(base_url = self._api_url, version = self._packages_version_number): try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) # Add metadata to the manager: - self._plugins_metadata = json_data - self._plugin_registry.addExternalPlugins(self._plugins_metadata) - self.pluginsMetadataChanged.emit() + self._packages_metadata = json_data + if not self._packages_model: + self._packages_model = CuraPackageModel() + self._packages_model.setPackagesMetaData(self._packages_metadata["data"]) + # self._plugin_registry.addExternalPlugins(self._packages_metadata) + self.packagesMetadataChanged.emit() except json.decoder.JSONDecodeError: Logger.log("w", "Received an invalid print job state message: Not valid JSON.") return From 229512e730cb69aba972cf860b7f517faf0546c7 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 3 Apr 2018 11:33:58 +0200 Subject: [PATCH 07/83] CURA-5035 More progress --- plugins/PluginBrowser/resources/qml/PluginBrowser.qml | 1 + .../qml/{ToolboxDetailBlock.qml => ToolboxDetailTile.qml} | 0 plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml | 5 +++-- 3 files changed, 4 insertions(+), 2 deletions(-) rename plugins/PluginBrowser/resources/qml/{ToolboxDetailBlock.qml => ToolboxDetailTile.qml} (100%) diff --git a/plugins/PluginBrowser/resources/qml/PluginBrowser.qml b/plugins/PluginBrowser/resources/qml/PluginBrowser.qml index dbe7011f8a..643d26bfbe 100644 --- a/plugins/PluginBrowser/resources/qml/PluginBrowser.qml +++ b/plugins/PluginBrowser/resources/qml/PluginBrowser.qml @@ -33,6 +33,7 @@ Window { id: mainView width: parent.width + color: "red" anchors { top: topBar.bottom diff --git a/plugins/PluginBrowser/resources/qml/ToolboxDetailBlock.qml b/plugins/PluginBrowser/resources/qml/ToolboxDetailTile.qml similarity index 100% rename from plugins/PluginBrowser/resources/qml/ToolboxDetailBlock.qml rename to plugins/PluginBrowser/resources/qml/ToolboxDetailTile.qml diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml b/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml index 9198452ed9..3ef4c74463 100644 --- a/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml +++ b/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml @@ -7,11 +7,13 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + Item { id: base anchors.fill: parent - Rectangle + Item { id: backMargin height: parent.height @@ -31,7 +33,6 @@ Item manager.setDetailView("") } } - color: "transparent" } ScrollView { From 32eab053978fad1ee8d112074138d7a541e414ae Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 3 Apr 2018 11:36:21 +0200 Subject: [PATCH 08/83] CURA-5035 Rename ToolboxDetailTile --- .../resources/qml/ToolboxViewDetail.qml | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml b/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml index 3ef4c74463..10ad984bdc 100644 --- a/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml +++ b/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml @@ -69,17 +69,17 @@ Item border.width: 1 } } - ToolboxDetailBlock {} - ToolboxDetailBlock {} - ToolboxDetailBlock {} - ToolboxDetailBlock {} - ToolboxDetailBlock {} - ToolboxDetailBlock {} - ToolboxDetailBlock {} - ToolboxDetailBlock {} - ToolboxDetailBlock {} - ToolboxDetailBlock {} - ToolboxDetailBlock {} + ToolboxDetailTile {} + ToolboxDetailTile {} + ToolboxDetailTile {} + ToolboxDetailTile {} + ToolboxDetailTile {} + ToolboxDetailTile {} + ToolboxDetailTile {} + ToolboxDetailTile {} + ToolboxDetailTile {} + ToolboxDetailTile {} + ToolboxDetailTile {} } } } From 8a7f9027c5fcf728437e5462fccf28a1947c80ca Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 3 Apr 2018 16:57:31 +0200 Subject: [PATCH 09/83] CURA-5035 Finished layout --- .../resources/qml/PluginBrowser.qml | 2 +- .../resources/qml/ToolboxFooter.qml | 8 +- .../resources/qml/ToolboxViewDetail.qml | 132 +++++++++++++++--- resources/themes/cura-light/theme.json | 2 +- 4 files changed, 119 insertions(+), 25 deletions(-) diff --git a/plugins/PluginBrowser/resources/qml/PluginBrowser.qml b/plugins/PluginBrowser/resources/qml/PluginBrowser.qml index 643d26bfbe..d0e150eaf5 100644 --- a/plugins/PluginBrowser/resources/qml/PluginBrowser.qml +++ b/plugins/PluginBrowser/resources/qml/PluginBrowser.qml @@ -33,7 +33,7 @@ Window { id: mainView width: parent.width - color: "red" + color: "transparent" anchors { top: topBar.bottom diff --git a/plugins/PluginBrowser/resources/qml/ToolboxFooter.qml b/plugins/PluginBrowser/resources/qml/ToolboxFooter.qml index 5ff336320f..b1ef00f313 100644 --- a/plugins/PluginBrowser/resources/qml/ToolboxFooter.qml +++ b/plugins/PluginBrowser/resources/qml/ToolboxFooter.qml @@ -60,7 +60,13 @@ Rectangle { } base.close(); } - anchors.right: parent.right + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("default_margin").height + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").height + } style: ButtonStyle { background: Rectangle { color: "transparent" diff --git a/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml b/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml index 10ad984bdc..84175b118c 100644 --- a/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml +++ b/plugins/PluginBrowser/resources/qml/ToolboxViewDetail.qml @@ -15,7 +15,7 @@ Item anchors.fill: parent Item { - id: backMargin + id: sidebar height: parent.height width: UM.Theme.getSize("base_unit").width * 6 anchors @@ -29,46 +29,133 @@ Item Button { text: "Back" - onClicked: { + UM.RecolorImage + { + id: backArrow + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + 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("arrow_left") + } + width: UM.Theme.getSize("base_unit").width * 4 + height: UM.Theme.getSize("base_unit").height * 2 + onClicked: + { manager.setDetailView("") } + style: ButtonStyle + { + background: Rectangle + { + color: "transparent" + } + label: Label + { + text: control.text + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default_bold") + horizontalAlignment: Text.AlignRight + width: control.width + } + } } } + + Rectangle + { + id: header + anchors + { + left: sidebar.right + right: parent.right + } + height: UM.Theme.getSize("base_unit").height * 12 + Rectangle + { + id: thumbnail + width: UM.Theme.getSize("toolbox_thumbnail_medium").width + height: UM.Theme.getSize("toolbox_thumbnail_medium").height + color: "grey" + anchors + { + top: parent.top + left: parent.left + leftMargin: UM.Theme.getSize("double_margin").width + topMargin: UM.Theme.getSize("double_margin").height + } + } + Column + { + anchors + { + top: thumbnail.top + left: thumbnail.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("double_margin").width + } + spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) + Label + { + text: "DSM" + font: UM.Theme.getFont("large") + wrapMode: Text.WordWrap + width: parent.width + } + Label + { + text: "Sets the horizontal and vertical alignment of the text within the Text items width and height. By default, the text is vertically aligned to the top." + font: UM.Theme.getFont("default") + wrapMode: Text.WordWrap + width: parent.width + } + Label + { + text: "Author: " + "DSM" + font: UM.Theme.getFont("small") + wrapMode: Text.WordWrap + width: parent.width + // TODO: Add mail icon. + } + } + } + ScrollView { id: scroll - frameVisible: false - anchors.right: base.right - anchors.left: backMargin.right + frameVisible: true + anchors + { + right: header.right + top: header.bottom + left: header.left + bottom: base.bottom + } height: parent.height style: UM.Theme.styles.scrollview - Column + + /* + ListView { - width: scroll.width + id: contentColumn spacing: UM.Theme.getSize("base_unit").height height: childrenRect.height + (UM.Theme.getSize("double_margin").height * 2) anchors { - fill: parent + left: scroll.left + right: scroll.right + top: scroll.top topMargin: UM.Theme.getSize("double_margin").height bottomMargin: UM.Theme.getSize("double_margin").height leftMargin: UM.Theme.getSize("double_margin").width rightMargin: UM.Theme.getSize("double_margin").width } - Rectangle - { - width: parent.width - height: UM.Theme.getSize("base_unit").height * 12 - color: "transparent" - Rectangle - { - id: thumbnail - width: UM.Theme.getSize("toolbox_thumbnail_medium").width - height: UM.Theme.getSize("toolbox_thumbnail_medium").height - color: "white" - border.width: 1 - } - } + ToolboxDetailTile {} ToolboxDetailTile {} ToolboxDetailTile {} @@ -81,5 +168,6 @@ Item ToolboxDetailTile {} ToolboxDetailTile {} } + */ } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 7706b8081d..595c7307a9 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -442,7 +442,7 @@ "objects_menu_button": [0.3, 2.7], "toolbox_thumbnail_small": [6.0, 6.0], - "toolbox_thumbnail_medium": [9.0, 9.0], + "toolbox_thumbnail_medium": [8.0, 8.0], "toolbox_thumbnail_large": [12.0, 12.0] } } From b621b5ef6b5fda7c36837df8a4542a4f4c411ec4 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 3 Apr 2018 17:07:33 +0200 Subject: [PATCH 10/83] CURA-5137 Add filtering for materials and plugins and change the behavior of switching tabs. --- plugins/Toolbox/Toolbox/CuraPackageModel.py | 41 ++++++++++++++++--- plugins/Toolbox/Toolbox/Toolbox.py | 40 ++++++++++-------- .../Toolbox/resources/qml/PluginBrowser.qml | 10 ++--- plugins/Toolbox/resources/qml/ToolboxGrid.qml | 13 +++--- .../Toolbox/resources/qml/ToolboxGridTile.qml | 8 ++-- .../Toolbox/resources/qml/ToolboxHeader.qml | 20 ++++++--- .../resources/qml/ToolboxViewDetail.qml | 4 +- 7 files changed, 85 insertions(+), 51 deletions(-) diff --git a/plugins/Toolbox/Toolbox/CuraPackageModel.py b/plugins/Toolbox/Toolbox/CuraPackageModel.py index f8d6174d66..facf21cc6f 100644 --- a/plugins/Toolbox/Toolbox/CuraPackageModel.py +++ b/plugins/Toolbox/Toolbox/CuraPackageModel.py @@ -1,6 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import re from typing import Dict from PyQt5.QtCore import Qt, pyqtProperty, pyqtSignal @@ -33,7 +34,7 @@ class CuraPackageModel(ListModel): self.addRoleName(CuraPackageModel.ImageURLsRole, "image_urls") # List of filters for queries. The result is the union of the each list of results. - self._filter = None # type: Dict[str,str] + self._filter = {} # type: Dict[str,str] def setPackagesMetaData(self, data): self._packages_metadata = data @@ -54,18 +55,46 @@ class CuraPackageModel(ListModel): "image_urls": package["image_urls"] }) - items.sort(key = lambda k: k["name"]) - self.setItems(items) + # Filter on all the key-word arguments. + for key, value in self._filter.items(): + if "*" in value: + key_filter = lambda candidate, key = key, value = value: self._matchRegExp(candidate, key, value) + else: + key_filter = lambda candidate, key = key, value = value: self._matchString(candidate, key, value) + items = filter(key_filter, items) - filterChanged = pyqtSignal() + # Execute all filters. + filtered_items = list(items) + + filtered_items.sort(key = lambda k: k["name"]) + self.setItems(filtered_items) ## Set the filter of this model based on a string. # \param filter_dict \type{Dict} Dictionary to do the filtering by. def setFilter(self, filter_dict: Dict[str, str]) -> None: if filter_dict != self._filter: self._filter = filter_dict - self.filterChanged.emit() + self._update() - @pyqtProperty("QVariantMap", fset = setFilter, notify = filterChanged) + @pyqtProperty("QVariantMap", fset = setFilter, constant = True) def filter(self) -> Dict[str, str]: return self._filter + + # Check to see if a container matches with a regular expression + def _matchRegExp(self, metadata, property_name, value): + if property_name not in metadata: + return False + value = re.escape(value) #Escape for regex patterns. + value = "^" + value.replace("\\*", ".*") + "$" #Instead of (now escaped) asterisks, match on any string. Also add anchors for a complete match. + if self._ignore_case: + value_pattern = re.compile(value, re.IGNORECASE) + else: + value_pattern = re.compile(value) + + return value_pattern.match(str(metadata[property_name])) + + # Check to see if a container matches with a string + def _matchString(self, metadata, property_name, value): + if property_name not in metadata: + return False + return value.lower() == str(metadata[property_name]).lower() diff --git a/plugins/Toolbox/Toolbox/Toolbox.py b/plugins/Toolbox/Toolbox/Toolbox.py index 858a21d18a..c1cdcd5741 100644 --- a/plugins/Toolbox/Toolbox/Toolbox.py +++ b/plugins/Toolbox/Toolbox/Toolbox.py @@ -43,12 +43,12 @@ class Toolbox(QObject, Extension): self._plugin_registry = Application.getInstance().getPluginRegistry() self._packages_version_number = self._plugin_registry.APIVersion - self._packages_metadata = [] - self._packages_model = None + self._packages_metadata = [] # Stores the remote information of the packages + self._packages_model = None # Model that list the remote available packages - # Can be 'installed' or 'available' - self._view = "available" - self._detail_view = "" + # Nowadays can be 'plugins', 'materials' or 'installed' + self._current_view = "plugins" + self._detail_view = False self._restart_required = False @@ -91,6 +91,7 @@ class Toolbox(QObject, Extension): restartRequiredChanged = pyqtSignal() viewChanged = pyqtSignal() detailViewChanged = pyqtSignal() + filterChanged = pyqtSignal() @pyqtSlot(result = str) def getLicenseDialogPluginName(self): @@ -282,28 +283,31 @@ class Toolbox(QObject, Extension): self.setIsDownloading(False) @pyqtSlot(str) - def setView(self, view = "available"): - self._view = view + def filterPackagesByType(self, type): + if not self._packages_model: + return + self._packages_model.setFilter({"type": type}) + self.filterChanged.emit() + + def setCurrentView(self, view = "plugins"): + self._current_view = view self.viewChanged.emit() - self.packagesMetadataChanged.emit() - @pyqtProperty(str, notify = viewChanged) - def viewing(self): - return self._view + @pyqtProperty(str, fset = setCurrentView, notify = viewChanged) + def currentView(self): + return self._current_view - @pyqtSlot(str) - def setDetailView(self, item = ""): + def setDetailView(self, item = False): self._detail_view = item self.detailViewChanged.emit() - self.packagesMetadataChanged.emit() - @pyqtProperty(str, notify = detailViewChanged) + @pyqtProperty(bool, fset = setDetailView, notify = detailViewChanged) def detailView(self): return self._detail_view @pyqtProperty(QObject, notify = packagesMetadataChanged) def pluginsModel(self): - self._plugins_model = PluginsModel(None, self._view) + self._plugins_model = PluginsModel(None, self._current_view) # self._plugins_model.update() # Check each plugin the registry for matching plugin from server @@ -383,10 +387,10 @@ class Toolbox(QObject, Extension): json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) # Add metadata to the manager: - self._packages_metadata = json_data + self._packages_metadata = json_data["data"] if not self._packages_model: self._packages_model = CuraPackageModel() - self._packages_model.setPackagesMetaData(self._packages_metadata["data"]) + self._packages_model.setPackagesMetaData(self._packages_metadata) # self._plugin_registry.addExternalPlugins(self._packages_metadata) self.packagesMetadataChanged.emit() except json.decoder.JSONDecodeError: diff --git a/plugins/Toolbox/resources/qml/PluginBrowser.qml b/plugins/Toolbox/resources/qml/PluginBrowser.qml index 643d26bfbe..a45f717d22 100644 --- a/plugins/Toolbox/resources/qml/PluginBrowser.qml +++ b/plugins/Toolbox/resources/qml/PluginBrowser.qml @@ -14,7 +14,8 @@ import UM 1.1 as UM Window { id: base - title: catalog.i18nc("@title:tab", "Plugins"); + title: catalog.i18nc("@title:tab", "Toolbox"); + modality: Qt.ApplicationModal width: 800 * screenScaleFactor height: 640 * screenScaleFactor minimumWidth: 800 * screenScaleFactor @@ -42,18 +43,17 @@ Window ToolboxViewDownloads { id: viewDownloads - visible: manager.viewing == "available" && manager.detailView == "" ? true : false + visible: manager.currentView != "installed" && !manager.detailView } - ToolboxViewDetail { id: viewDetail - visible: manager.viewing == "available" && manager.detailView != "" ? true : false + visible: manager.currentView != "installed" && manager.detailView } ToolboxViewInstalled { id: installedPluginList - visible: manager.viewing == "installed" ? true : false + visible: manager.currentView == "installed" } } SectionShadow diff --git a/plugins/Toolbox/resources/qml/ToolboxGrid.qml b/plugins/Toolbox/resources/qml/ToolboxGrid.qml index 53c4443493..1ec87e8217 100644 --- a/plugins/Toolbox/resources/qml/ToolboxGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxGrid.qml @@ -39,13 +39,10 @@ Rectangle columnSpacing: UM.Theme.getSize("base_unit").width rowSpacing: UM.Theme.getSize("base_unit").height - ToolboxGridTile {} - ToolboxGridTile {} - ToolboxGridTile {} - ToolboxGridTile {} - ToolboxGridTile {} - ToolboxGridTile {} - ToolboxGridTile {} - ToolboxGridTile {} + Repeater + { + model: manager.packagesModel + delegate: ToolboxGridTile {} + } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxGridTile.qml index 160e59bf15..36c7b93223 100644 --- a/plugins/Toolbox/resources/qml/ToolboxGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxGridTile.qml @@ -33,7 +33,7 @@ Item Label { id: name - text: "Auto Orientation" + text: model.name width: parent.width wrapMode: Text.WordWrap height: UM.Theme.getSize("base_unit").height * 2 @@ -44,7 +44,7 @@ Item Label { id: info - text: "Automatically orientate your model." + text: model.description width: parent.width wrapMode: Text.WordWrap color: UM.Theme.getColor("text_medium") @@ -55,8 +55,6 @@ Item MouseArea { anchors.fill: parent - onClicked: { - manager.setDetailView("thingy") - } + onClicked: manager.detailView = true } } diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index cce078035d..106b988e9e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -32,7 +32,7 @@ Rectangle { implicitWidth: 96 implicitHeight: 48 Rectangle { - visible: manager.viewing == "available" ? true : false + visible: manager.currentView == "plugins" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom width: parent.width @@ -49,7 +49,11 @@ Rectangle { horizontalAlignment: Text.AlignHCenter } } - onClicked: manager.setView("available") + onClicked: + { + manager.filterPackagesByType("plugin") + manager.currentView = "plugins" + } } Button { @@ -60,7 +64,7 @@ Rectangle { implicitWidth: 96 implicitHeight: 48 Rectangle { - visible: manager.viewing == "available" ? true : false + visible: manager.currentView == "materials" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom width: parent.width @@ -77,7 +81,11 @@ Rectangle { horizontalAlignment: Text.AlignHCenter } } - onClicked: manager.setView("available") + onClicked: + { + manager.filterPackagesByType("material") + manager.currentView = "materials" + } } } @@ -91,7 +99,7 @@ Rectangle { implicitWidth: 96 implicitHeight: 48 Rectangle { - visible: manager.viewing == "installed" ? true : false + visible: manager.currentView == "installed" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom width: parent.width @@ -108,6 +116,6 @@ Rectangle { horizontalAlignment: Text.AlignHCenter } } - onClicked: manager.setView("installed") + onClicked: manager.currentView = "installed" } } diff --git a/plugins/Toolbox/resources/qml/ToolboxViewDetail.qml b/plugins/Toolbox/resources/qml/ToolboxViewDetail.qml index 10ad984bdc..c0fe5790dd 100644 --- a/plugins/Toolbox/resources/qml/ToolboxViewDetail.qml +++ b/plugins/Toolbox/resources/qml/ToolboxViewDetail.qml @@ -29,9 +29,7 @@ Item Button { text: "Back" - onClicked: { - manager.setDetailView("") - } + onClicked: manager.detailView = false } } ScrollView From 0e01e9a6a9e532ce6a1822cd747e841c043b85ae Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 3 Apr 2018 17:24:05 +0200 Subject: [PATCH 11/83] CURA-5137 Reset to the global view when switching tabs --- plugins/Toolbox/Toolbox/Toolbox.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/Toolbox/Toolbox/Toolbox.py b/plugins/Toolbox/Toolbox/Toolbox.py index c1cdcd5741..b799754cbf 100644 --- a/plugins/Toolbox/Toolbox/Toolbox.py +++ b/plugins/Toolbox/Toolbox/Toolbox.py @@ -291,6 +291,7 @@ class Toolbox(QObject, Extension): def setCurrentView(self, view = "plugins"): self._current_view = view + self._detail_view = False self.viewChanged.emit() @pyqtProperty(str, fset = setCurrentView, notify = viewChanged) From 2bf6615b53509ab1f997029f485a205940dc8e48 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 4 Apr 2018 10:51:19 +0200 Subject: [PATCH 12/83] CURA-5137 Make some adjustments in the UI. --- .../Toolbox/resources/qml/PluginBrowser.qml | 5 +--- plugins/Toolbox/resources/qml/ToolboxGrid.qml | 20 ++++++-------- .../Toolbox/resources/qml/ToolboxGridTile.qml | 16 ++++++++---- .../Toolbox/resources/qml/ToolboxShowcase.qml | 19 ++------------ .../resources/qml/ToolboxViewDownloads.qml | 26 ++++++++++--------- 5 files changed, 36 insertions(+), 50 deletions(-) diff --git a/plugins/Toolbox/resources/qml/PluginBrowser.qml b/plugins/Toolbox/resources/qml/PluginBrowser.qml index ad69f70c98..c2ce4975f4 100644 --- a/plugins/Toolbox/resources/qml/PluginBrowser.qml +++ b/plugins/Toolbox/resources/qml/PluginBrowser.qml @@ -12,7 +12,7 @@ import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM Window - { +{ id: base title: catalog.i18nc("@title:tab", "Toolbox"); modality: Qt.ApplicationModal @@ -75,9 +75,6 @@ Window } } - - - UM.I18nCatalog { id: catalog; name: "cura" } Connections diff --git a/plugins/Toolbox/resources/qml/ToolboxGrid.qml b/plugins/Toolbox/resources/qml/ToolboxGrid.qml index 1ec87e8217..115638bd71 100644 --- a/plugins/Toolbox/resources/qml/ToolboxGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxGrid.qml @@ -11,30 +11,23 @@ import UM 1.1 as UM // TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles -Rectangle +Column { id: base - width: parent.width - height: childrenRect.height + UM.Theme.getSize("double_margin").height * 8 - color: "transparent" + height: childrenRect.height + spacing: UM.Theme.getSize("base_unit").height Label { id: heading text: "Community Plugins" width: parent.width - height: UM.Theme.getSize("base_unit").width * 4 - verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") } GridLayout { id: grid - width: base.width - anchors - { - top: heading.bottom - } + width: parent.width columns: 3 columnSpacing: UM.Theme.getSize("base_unit").width rowSpacing: UM.Theme.getSize("base_unit").height @@ -42,7 +35,10 @@ Rectangle Repeater { model: manager.packagesModel - delegate: ToolboxGridTile {} + delegate: ToolboxGridTile + { + Layout.preferredWidth: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns + } } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxGridTile.qml index 36c7b93223..67c04a4cc7 100644 --- a/plugins/Toolbox/resources/qml/ToolboxGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxGridTile.qml @@ -13,7 +13,7 @@ Item { id: base height: childrenRect.height - Layout.fillWidth: true + Layout.alignment: Qt.AlignTop | Qt.AlignLeft Row { width: parent.width @@ -29,22 +29,28 @@ Item } Column { - width: UM.Theme.getSize("base_unit").width * 12 + width: parent.width - thumbnail.width - parent.spacing + spacing: Math.floor(UM.Theme.getSize("base_unit").width / 2) Label { id: name text: model.name width: parent.width wrapMode: Text.WordWrap - height: UM.Theme.getSize("base_unit").height * 2 - verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("text") font: UM.Theme.getFont("default_bold") } Label { id: info - text: model.description + text: + { + if (model.description.length > 50) + { + return model.description.substring(0, 50) + "..." + } + return model.description + } width: parent.width wrapMode: Text.WordWrap color: UM.Theme.getColor("text_medium") diff --git a/plugins/Toolbox/resources/qml/ToolboxShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxShowcase.qml index f5aec67e09..5abf14cecc 100644 --- a/plugins/Toolbox/resources/qml/ToolboxShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxShowcase.qml @@ -10,45 +10,30 @@ import UM 1.1 as UM // TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles -Rectangle +Column { id: base - width: parent.width height: childrenRect.height - color: "transparent" + spacing: UM.Theme.getSize("base_unit").height Label { id: heading text: "Top Downloads" width: parent.width - height: UM.Theme.getSize("base_unit").width * 4 - verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") } Row { height: childrenRect.height - width: childrenRect.width spacing: UM.Theme.getSize("base_unit").width * 2 anchors { horizontalCenter: parent.horizontalCenter - top: heading.bottom } ToolboxShowcaseTile {} ToolboxShowcaseTile {} ToolboxShowcaseTile {} } - Rectangle - { - color: UM.Theme.getColor("text_medium") - width: parent.width - height: UM.Theme.getSize("base_unit").height / 6 - anchors - { - bottom: parent.bottom - } - } } diff --git a/plugins/Toolbox/resources/qml/ToolboxViewDownloads.qml b/plugins/Toolbox/resources/qml/ToolboxViewDownloads.qml index 55e3650488..4141685787 100644 --- a/plugins/Toolbox/resources/qml/ToolboxViewDownloads.qml +++ b/plugins/Toolbox/resources/qml/ToolboxViewDownloads.qml @@ -1,7 +1,7 @@ // Copyright (c) 2018 Ultimaker B.V. // PluginBrowser is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.7 import QtQuick.Dialogs 1.1 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 @@ -12,29 +12,31 @@ import UM 1.1 as UM ScrollView { id: base - frameVisible: false - anchors.fill: parent + frameVisible: true + width: parent.width + height: parent.height style: UM.Theme.styles.scrollview Column { width: base.width spacing: UM.Theme.getSize("base_unit").height - height: childrenRect.height - anchors - { - fill: parent - topMargin: UM.Theme.getSize("base_unit").height - bottomMargin: UM.Theme.getSize("base_unit").height - leftMargin: UM.Theme.getSize("base_unit").width * 2 - rightMargin: UM.Theme.getSize("base_unit").width * 2 - } + padding: UM.Theme.getSize("base_unit").height * 2 + height: childrenRect.height + 2 * padding ToolboxShowcase { id: showcase + width: parent.width - 2 * parent.padding + } + Rectangle + { + color: UM.Theme.getColor("text_medium") + width: parent.width - 2 * parent.padding + height: UM.Theme.getSize("base_unit").height / 6 } ToolboxGrid { id: allPlugins + width: parent.width - 2 * parent.padding } } } From 20feabbb06a09fd9108641e4bdc1325c300147f3 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 4 Apr 2018 13:53:09 +0200 Subject: [PATCH 13/83] CURA-5035 Renaming --- plugins/Toolbox/__init__.py | 2 +- .../qml/{PluginBrowser.qml => Toolbox.qml} | 14 ++--- ...xViewDetail.qml => ToolboxDetailsPage.qml} | 24 ++++---- ...xDetailTile.qml => ToolboxDetailsTile.qml} | 0 ...olboxGrid.qml => ToolboxDownloadsGrid.qml} | 2 +- ...dTile.qml => ToolboxDownloadsGridTile.qml} | 5 +- ...Downloads.qml => ToolboxDownloadsPage.qml} | 6 +- ...wcase.qml => ToolboxDownloadsShowcase.qml} | 6 +- ...e.qml => ToolboxDownloadsShowcaseTile.qml} | 6 -- .../Toolbox/resources/qml/ToolboxHeader.qml | 59 +++++++++++-------- ...Installed.qml => ToolboxInstalledPage.qml} | 2 +- ...uginEntry.qml => ToolboxInstalledTile.qml} | 0 .../{SectionShadow.qml => ToolboxShadow.qml} | 0 .../{Toolbox => src}/CuraPackageModel.py | 0 plugins/Toolbox/{Toolbox => src}/Toolbox.py | 2 +- plugins/Toolbox/{Toolbox => src}/__init__.py | 0 16 files changed, 68 insertions(+), 60 deletions(-) rename plugins/Toolbox/resources/qml/{PluginBrowser.qml => Toolbox.qml} (90%) rename plugins/Toolbox/resources/qml/{ToolboxViewDetail.qml => ToolboxDetailsPage.qml} (92%) rename plugins/Toolbox/resources/qml/{ToolboxDetailTile.qml => ToolboxDetailsTile.qml} (100%) rename plugins/Toolbox/resources/qml/{ToolboxGrid.qml => ToolboxDownloadsGrid.qml} (95%) rename plugins/Toolbox/resources/qml/{ToolboxGridTile.qml => ToolboxDownloadsGridTile.qml} (94%) rename plugins/Toolbox/resources/qml/{ToolboxViewDownloads.qml => ToolboxDownloadsPage.qml} (92%) rename plugins/Toolbox/resources/qml/{ToolboxShowcase.qml => ToolboxDownloadsShowcase.qml} (87%) rename plugins/Toolbox/resources/qml/{ToolboxShowcaseTile.qml => ToolboxDownloadsShowcaseTile.qml} (74%) rename plugins/Toolbox/resources/qml/{ToolboxViewInstalled.qml => ToolboxInstalledPage.qml} (95%) rename plugins/Toolbox/resources/qml/{PluginEntry.qml => ToolboxInstalledTile.qml} (100%) rename plugins/Toolbox/resources/qml/{SectionShadow.qml => ToolboxShadow.qml} (100%) rename plugins/Toolbox/{Toolbox => src}/CuraPackageModel.py (100%) rename plugins/Toolbox/{Toolbox => src}/Toolbox.py (99%) rename plugins/Toolbox/{Toolbox => src}/__init__.py (100%) diff --git a/plugins/Toolbox/__init__.py b/plugins/Toolbox/__init__.py index dc2d6c9c23..2f8e192764 100644 --- a/plugins/Toolbox/__init__.py +++ b/plugins/Toolbox/__init__.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Toolbox is released under the terms of the LGPLv3 or higher. -from .Toolbox import Toolbox +from .src import Toolbox def getMetaData(): diff --git a/plugins/Toolbox/resources/qml/PluginBrowser.qml b/plugins/Toolbox/resources/qml/Toolbox.qml similarity index 90% rename from plugins/Toolbox/resources/qml/PluginBrowser.qml rename to plugins/Toolbox/resources/qml/Toolbox.qml index c2ce4975f4..b7f0c44a98 100644 --- a/plugins/Toolbox/resources/qml/PluginBrowser.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -40,23 +40,23 @@ Window top: topBar.bottom bottom: bottomBar.top } - ToolboxViewDownloads + ToolboxDownloadsPage { id: viewDownloads - visible: manager.currentView != "installed" && !manager.detailView + visible: manager.currentView != "installed" && manager.detailView == "" } - ToolboxViewDetail + ToolboxDetailsPage { id: viewDetail - visible: manager.currentView != "installed" && manager.detailView + visible: manager.currentView != "installed" && manager.detailView != "" } - ToolboxViewInstalled + ToolboxInstalledPage { id: installedPluginList visible: manager.currentView == "installed" } } - SectionShadow + ToolboxShadow { anchors { @@ -67,7 +67,7 @@ Window { id: bottomBar } - SectionShadow + ToolboxShadow { anchors { diff --git a/plugins/Toolbox/resources/qml/ToolboxViewDetail.qml b/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml similarity index 92% rename from plugins/Toolbox/resources/qml/ToolboxViewDetail.qml rename to plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml index dec4ddc1e6..d85d2559e8 100644 --- a/plugins/Toolbox/resources/qml/ToolboxViewDetail.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml @@ -44,7 +44,7 @@ Item } width: UM.Theme.getSize("base_unit").width * 4 height: UM.Theme.getSize("base_unit").height * 2 - onClicked: manager.detailView = false + onClicked: manager.detailView = "" style: ButtonStyle { background: Rectangle @@ -153,17 +153,17 @@ Item rightMargin: UM.Theme.getSize("double_margin").width } - ToolboxDetailTile {} - ToolboxDetailTile {} - ToolboxDetailTile {} - ToolboxDetailTile {} - ToolboxDetailTile {} - ToolboxDetailTile {} - ToolboxDetailTile {} - ToolboxDetailTile {} - ToolboxDetailTile {} - ToolboxDetailTile {} - ToolboxDetailTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} + ToolboxDetailsTile {} } */ } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailsTile.qml similarity index 100% rename from plugins/Toolbox/resources/qml/ToolboxDetailTile.qml rename to plugins/Toolbox/resources/qml/ToolboxDetailsTile.qml diff --git a/plugins/Toolbox/resources/qml/ToolboxGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml similarity index 95% rename from plugins/Toolbox/resources/qml/ToolboxGrid.qml rename to plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index 115638bd71..b05963ecd1 100644 --- a/plugins/Toolbox/resources/qml/ToolboxGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -35,7 +35,7 @@ Column Repeater { model: manager.packagesModel - delegate: ToolboxGridTile + delegate: ToolboxDownloadsGridTile { Layout.preferredWidth: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns } diff --git a/plugins/Toolbox/resources/qml/ToolboxGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml similarity index 94% rename from plugins/Toolbox/resources/qml/ToolboxGridTile.qml rename to plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 67c04a4cc7..a41866fc83 100644 --- a/plugins/Toolbox/resources/qml/ToolboxGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -61,6 +61,9 @@ Item MouseArea { anchors.fill: parent - onClicked: manager.detailView = true + onClicked: { + console.log(model.id) + manager.detailView = model.id + } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxViewDownloads.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml similarity index 92% rename from plugins/Toolbox/resources/qml/ToolboxViewDownloads.qml rename to plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml index 4141685787..8d1cd93f13 100644 --- a/plugins/Toolbox/resources/qml/ToolboxViewDownloads.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml @@ -12,7 +12,7 @@ import UM 1.1 as UM ScrollView { id: base - frameVisible: true + frameVisible: false width: parent.width height: parent.height style: UM.Theme.styles.scrollview @@ -22,7 +22,7 @@ ScrollView spacing: UM.Theme.getSize("base_unit").height padding: UM.Theme.getSize("base_unit").height * 2 height: childrenRect.height + 2 * padding - ToolboxShowcase + ToolboxDownloadsShowcase { id: showcase width: parent.width - 2 * parent.padding @@ -33,7 +33,7 @@ ScrollView width: parent.width - 2 * parent.padding height: UM.Theme.getSize("base_unit").height / 6 } - ToolboxGrid + ToolboxDownloadsGrid { id: allPlugins width: parent.width - 2 * parent.padding diff --git a/plugins/Toolbox/resources/qml/ToolboxShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml similarity index 87% rename from plugins/Toolbox/resources/qml/ToolboxShowcase.qml rename to plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index 5abf14cecc..c9a0babc5f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -32,8 +32,8 @@ Column horizontalCenter: parent.horizontalCenter } - ToolboxShowcaseTile {} - ToolboxShowcaseTile {} - ToolboxShowcaseTile {} + ToolboxDownloadsShowcaseTile {} + ToolboxDownloadsShowcaseTile {} + ToolboxDownloadsShowcaseTile {} } } diff --git a/plugins/Toolbox/resources/qml/ToolboxShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml similarity index 74% rename from plugins/Toolbox/resources/qml/ToolboxShowcaseTile.qml rename to plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 29a9054b2d..de0d85ec96 100644 --- a/plugins/Toolbox/resources/qml/ToolboxShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -8,12 +8,6 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -/* NOTE: This file uses the UM.Theme's "base_unit" size. It's commonly agreed -that good design is consistent design, and since the UM.Theme's JSON file does -not provide a method for interiting base units across the interface, adding more -properties for severy single UI element is undesirable for both developers and -theme makers/modfiers. Thus, "base_unit" is used wherever it can be. */ - Item { width: UM.Theme.getSize("toolbox_thumbnail_large").width diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 106b988e9e..28d97144c2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -17,21 +17,26 @@ Rectangle { color: "transparent" height: childrenRect.height - Row { + Row + { spacing: 12 height: childrenRect.height width: childrenRect.width anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width - Button { + Button + { text: "Plugins" - style: ButtonStyle { - background: Rectangle { + style: ButtonStyle + { + background: Rectangle + { color: "transparent" implicitWidth: 96 implicitHeight: 48 - Rectangle { + Rectangle + { visible: manager.currentView == "plugins" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom @@ -39,12 +44,11 @@ Rectangle { height: 3 } } - label: Text { + label: Text + { text: control.text color: UM.Theme.getColor("text") - font { - pixelSize: 15 - } + font.pixelSize: 15 verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } @@ -53,17 +57,22 @@ Rectangle { { manager.filterPackagesByType("plugin") manager.currentView = "plugins" + manager.detailView = "" } } - Button { + Button + { text: "Materials" - style: ButtonStyle { - background: Rectangle { + style: ButtonStyle + { + background: Rectangle + { color: "transparent" implicitWidth: 96 implicitHeight: 48 - Rectangle { + Rectangle + { visible: manager.currentView == "materials" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom @@ -71,12 +80,11 @@ Rectangle { height: 3 } } - label: Text { + label: Text + { text: control.text color: UM.Theme.getColor("text") - font { - pixelSize: 15 - } + font.pixelSize: 15 verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } @@ -85,16 +93,20 @@ Rectangle { { manager.filterPackagesByType("material") manager.currentView = "materials" + manager.detailView = "" } } } - Button { + Button + { text: "Installed" anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width - style: ButtonStyle { - background: Rectangle { + style: ButtonStyle + { + background: Rectangle + { color: "transparent" implicitWidth: 96 implicitHeight: 48 @@ -106,12 +118,11 @@ Rectangle { height: 3 } } - label: Text { + label: Text + { text: control.text color: UM.Theme.getColor("text") - font { - pixelSize: 15 - } + font.pixelSize: 15 verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } diff --git a/plugins/Toolbox/resources/qml/ToolboxViewInstalled.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml similarity index 95% rename from plugins/Toolbox/resources/qml/ToolboxViewInstalled.qml rename to plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index 7db50f6a24..b7ec3dad2c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxViewInstalled.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -28,6 +28,6 @@ ScrollView rightMargin: UM.Theme.getSize("default_margin").width } model: manager.pluginsModel - delegate: PluginEntry {} + delegate: ToolboxInstalledTile {} } } diff --git a/plugins/Toolbox/resources/qml/PluginEntry.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml similarity index 100% rename from plugins/Toolbox/resources/qml/PluginEntry.qml rename to plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml diff --git a/plugins/Toolbox/resources/qml/SectionShadow.qml b/plugins/Toolbox/resources/qml/ToolboxShadow.qml similarity index 100% rename from plugins/Toolbox/resources/qml/SectionShadow.qml rename to plugins/Toolbox/resources/qml/ToolboxShadow.qml diff --git a/plugins/Toolbox/Toolbox/CuraPackageModel.py b/plugins/Toolbox/src/CuraPackageModel.py similarity index 100% rename from plugins/Toolbox/Toolbox/CuraPackageModel.py rename to plugins/Toolbox/src/CuraPackageModel.py diff --git a/plugins/Toolbox/Toolbox/Toolbox.py b/plugins/Toolbox/src/Toolbox.py similarity index 99% rename from plugins/Toolbox/Toolbox/Toolbox.py rename to plugins/Toolbox/src/Toolbox.py index b799754cbf..410355bae7 100644 --- a/plugins/Toolbox/Toolbox/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -129,7 +129,7 @@ class Toolbox(QObject, Extension): self.requestPackageList() if not self._dialog: - self._dialog = self._createDialog("PluginBrowser.qml") + self._dialog = self._createDialog("Toolbox.qml") self._dialog.show() def requestPackageList(self): diff --git a/plugins/Toolbox/Toolbox/__init__.py b/plugins/Toolbox/src/__init__.py similarity index 100% rename from plugins/Toolbox/Toolbox/__init__.py rename to plugins/Toolbox/src/__init__.py From 2fe2c71754c40829eea5b55b09e68dece04ec7b3 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 4 Apr 2018 18:20:49 +0200 Subject: [PATCH 14/83] CURA-5137 Adding a loading page while the data is not yet ready. --- plugins/Toolbox/resources/qml/Toolbox.qml | 12 +++++++++--- plugins/Toolbox/src/Toolbox.py | 14 ++++++++------ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index b7f0c44a98..997e7c30ec 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -14,6 +14,7 @@ import UM 1.1 as UM Window { id: base + property bool dataReady: manager.dataReady title: catalog.i18nc("@title:tab", "Toolbox"); modality: Qt.ApplicationModal width: 800 * screenScaleFactor @@ -40,20 +41,25 @@ Window top: topBar.bottom bottom: bottomBar.top } + ToolboxLoading + { + id: loading + visible: !dataReady && manager.currentView != "installed" + } ToolboxDownloadsPage { id: viewDownloads - visible: manager.currentView != "installed" && manager.detailView == "" + visible: dataReady && manager.currentView != "installed" && manager.detailView == "" } ToolboxDetailsPage { id: viewDetail - visible: manager.currentView != "installed" && manager.detailView != "" + visible: dataReady && manager.currentView != "installed" && manager.detailView != "" } ToolboxInstalledPage { id: installedPluginList - visible: manager.currentView == "installed" + visible: dataReady && manager.currentView == "installed" } } ToolboxShadow diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 410355bae7..0bc56e95df 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -48,7 +48,7 @@ class Toolbox(QObject, Extension): # Nowadays can be 'plugins', 'materials' or 'installed' self._current_view = "plugins" - self._detail_view = False + self._detail_view = "" self._restart_required = False @@ -291,18 +291,17 @@ class Toolbox(QObject, Extension): def setCurrentView(self, view = "plugins"): self._current_view = view - self._detail_view = False self.viewChanged.emit() @pyqtProperty(str, fset = setCurrentView, notify = viewChanged) def currentView(self): return self._current_view - def setDetailView(self, item = False): - self._detail_view = item + def setDetailView(self, detail_view = ""): + self._detail_view = detail_view self.detailViewChanged.emit() - @pyqtProperty(bool, fset = setDetailView, notify = detailViewChanged) + @pyqtProperty(str, fset = setDetailView, notify = detailViewChanged) def detailView(self): return self._detail_view @@ -328,6 +327,10 @@ class Toolbox(QObject, Extension): def packagesModel(self): return self._packages_model + @pyqtProperty(bool, notify = packagesMetadataChanged) + def dataReady(self): + return self._packages_model is not None + def _checkCanUpgrade(self, id, version): # TODO: This could maybe be done more efficiently using a dictionary... @@ -392,7 +395,6 @@ class Toolbox(QObject, Extension): if not self._packages_model: self._packages_model = CuraPackageModel() self._packages_model.setPackagesMetaData(self._packages_metadata) - # self._plugin_registry.addExternalPlugins(self._packages_metadata) self.packagesMetadataChanged.emit() except json.decoder.JSONDecodeError: Logger.log("w", "Received an invalid print job state message: Not valid JSON.") From f0c36f847181eb16a04336cd58cf0962caa354d5 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 4 Apr 2018 18:23:32 +0200 Subject: [PATCH 15/83] CURA-5137 Add the mock-up component for the loading. I forget it. --- .../Toolbox/resources/qml/ToolboxLoading.qml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 plugins/Toolbox/resources/qml/ToolboxLoading.qml diff --git a/plugins/Toolbox/resources/qml/ToolboxLoading.qml b/plugins/Toolbox/resources/qml/ToolboxLoading.qml new file mode 100644 index 0000000000..91d4cec013 --- /dev/null +++ b/plugins/Toolbox/resources/qml/ToolboxLoading.qml @@ -0,0 +1,18 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +Rectangle +{ + id: base + width: parent.width + height: parent.height + color: "red" +} From 15b8d18da8e034c6fbee311d540aee69c2292f55 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 5 Apr 2018 09:47:43 +0200 Subject: [PATCH 16/83] CURA-5035 Small changes --- plugins/Toolbox/resources/qml/Toolbox.qml | 4 ++-- .../resources/qml/ToolboxDetailsPage.qml | 2 +- .../qml/ToolboxDownloadsGridTile.qml | 3 ++- .../Toolbox/resources/qml/ToolboxHeader.qml | 4 ++-- plugins/Toolbox/src/Toolbox.py | 22 ++++++++++++++++--- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 997e7c30ec..eb56cf02b1 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -49,12 +49,12 @@ Window ToolboxDownloadsPage { id: viewDownloads - visible: dataReady && manager.currentView != "installed" && manager.detailView == "" + visible: manager.currentView != "installed" && !manager.detailView } ToolboxDetailsPage { id: viewDetail - visible: dataReady && manager.currentView != "installed" && manager.detailView != "" + visible: manager.currentView != "installed" && manager.detailView } ToolboxInstalledPage { diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml index d85d2559e8..a57a6de90c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml @@ -44,7 +44,7 @@ Item } width: UM.Theme.getSize("base_unit").width * 4 height: UM.Theme.getSize("base_unit").height * 2 - onClicked: manager.detailView = "" + onClicked: manager.detailView = false style: ButtonStyle { background: Rectangle diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index a41866fc83..c3795daf51 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -63,7 +63,8 @@ Item anchors.fill: parent onClicked: { console.log(model.id) - manager.detailView = model.id + manager.detailView = true + manager.setDetailData(model.id) } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 28d97144c2..2c097f275b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -57,7 +57,7 @@ Rectangle { { manager.filterPackagesByType("plugin") manager.currentView = "plugins" - manager.detailView = "" + manager.detailView = false } } @@ -93,7 +93,7 @@ Rectangle { { manager.filterPackagesByType("material") manager.currentView = "materials" - manager.detailView = "" + manager.detailView = false } } } diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 0bc56e95df..b2b1f8e53f 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -48,7 +48,8 @@ class Toolbox(QObject, Extension): # Nowadays can be 'plugins', 'materials' or 'installed' self._current_view = "plugins" - self._detail_view = "" + self._detail_view = False + self._detail_data = {} self._restart_required = False @@ -297,14 +298,29 @@ class Toolbox(QObject, Extension): def currentView(self): return self._current_view - def setDetailView(self, detail_view = ""): - self._detail_view = detail_view + def setDetailView(self, bool = False): + self._detail_view = bool self.detailViewChanged.emit() @pyqtProperty(str, fset = setDetailView, notify = detailViewChanged) def detailView(self): return self._detail_view + # Set the detail data given a plugin ID: + @pyqtSlot(str) + def setDetailData(self, id): + if not self._packages_model: + return + for plugin in self._plugins_model.items: + if plugin.id is id: + print(plugin) + self._detail_view = plugin + self.detailViewChanged.emit() + + @pyqtProperty(QObject, notify = detailViewChanged) + def detailData(self): + return self._detail_data + @pyqtProperty(QObject, notify = packagesMetadataChanged) def pluginsModel(self): self._plugins_model = PluginsModel(None, self._current_view) From c3fe53123b2b28c36f3fa60627919916dfc758fa Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 29 Mar 2018 11:01:09 +0200 Subject: [PATCH 17/83] Create module cura.ReaderWriters CURA-4644 Move all reader writer classes into cura.ReaderWriters. --- cura/{ => ReaderWriters}/ProfileReader.py | 0 cura/{ => ReaderWriters}/ProfileWriter.py | 0 cura/ReaderWriters/__init__.py | 0 cura/Settings/CuraContainerRegistry.py | 3 +-- plugins/CuraProfileReader/CuraProfileReader.py | 2 +- plugins/CuraProfileWriter/CuraProfileWriter.py | 3 +-- plugins/GCodeProfileReader/GCodeProfileReader.py | 2 +- plugins/LegacyProfileReader/LegacyProfileReader.py | 3 +-- 8 files changed, 5 insertions(+), 8 deletions(-) rename cura/{ => ReaderWriters}/ProfileReader.py (100%) rename cura/{ => ReaderWriters}/ProfileWriter.py (100%) create mode 100644 cura/ReaderWriters/__init__.py diff --git a/cura/ProfileReader.py b/cura/ReaderWriters/ProfileReader.py similarity index 100% rename from cura/ProfileReader.py rename to cura/ReaderWriters/ProfileReader.py diff --git a/cura/ProfileWriter.py b/cura/ReaderWriters/ProfileWriter.py similarity index 100% rename from cura/ProfileWriter.py rename to cura/ReaderWriters/ProfileWriter.py diff --git a/cura/ReaderWriters/__init__.py b/cura/ReaderWriters/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 6600512672..8d4f711155 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -25,11 +25,10 @@ from UM.Resources import Resources from . import ExtruderStack from . import GlobalStack -from .ExtruderManager import ExtruderManager from cura.CuraApplication import CuraApplication from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch -from cura.ProfileReader import NoProfileException +from cura.ReaderWriters.ProfileReader import NoProfileException from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") diff --git a/plugins/CuraProfileReader/CuraProfileReader.py b/plugins/CuraProfileReader/CuraProfileReader.py index 69b2187541..12434d2c3f 100644 --- a/plugins/CuraProfileReader/CuraProfileReader.py +++ b/plugins/CuraProfileReader/CuraProfileReader.py @@ -5,7 +5,7 @@ import configparser from UM.PluginRegistry import PluginRegistry from UM.Logger import Logger from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make. -from cura.ProfileReader import ProfileReader +from cura.ReaderWriters.ProfileReader import ProfileReader import zipfile diff --git a/plugins/CuraProfileWriter/CuraProfileWriter.py b/plugins/CuraProfileWriter/CuraProfileWriter.py index 864a9b602c..78f0b078d9 100644 --- a/plugins/CuraProfileWriter/CuraProfileWriter.py +++ b/plugins/CuraProfileWriter/CuraProfileWriter.py @@ -3,8 +3,7 @@ # Uranium is released under the terms of the LGPLv3 or higher. from UM.Logger import Logger -from UM.SaveFile import SaveFile -from cura.ProfileWriter import ProfileWriter +from cura.ReaderWriters.ProfileWriter import ProfileWriter import zipfile ## Writes profiles to Cura's own profile format with config files. diff --git a/plugins/GCodeProfileReader/GCodeProfileReader.py b/plugins/GCodeProfileReader/GCodeProfileReader.py index d6bda85a48..f255950c36 100644 --- a/plugins/GCodeProfileReader/GCodeProfileReader.py +++ b/plugins/GCodeProfileReader/GCodeProfileReader.py @@ -9,7 +9,7 @@ from UM.Logger import Logger from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") -from cura.ProfileReader import ProfileReader, NoProfileException +from cura.ReaderWriters.ProfileReader import ProfileReader, NoProfileException ## A class that reads profile data from g-code files. # diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 824fc959a1..3c2b9bfa76 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -12,8 +12,7 @@ from UM.Logger import Logger # Logging errors. from UM.PluginRegistry import PluginRegistry # For getting the path to this plugin's directory. from UM.Settings.ContainerRegistry import ContainerRegistry #To create unique profile IDs. from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make. -from cura.ProfileReader import ProfileReader # The plug-in type to implement. -from cura.Settings.ExtruderManager import ExtruderManager #To get the current extruder definition. +from cura.ReaderWriters.ProfileReader import ProfileReader # The plug-in type to implement. ## A plugin that reads profile data from legacy Cura versions. From 19bc2b78f49e8738117aec28f69681069c96ab03 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 4 Apr 2018 11:49:00 +0200 Subject: [PATCH 18/83] Add Version upgrade 3.3 to 3.4 Need to distinguish between quality and quality_changes in the cura directory, so we need to move all custom quality profiles into the quality_changes directory. --- cura/CuraApplication.py | 24 ++++++----- cura/Settings/CuraContainerRegistry.py | 2 +- .../VersionUpgrade33to34.py | 43 +++++++++++++++++++ .../VersionUpgrade33to34/__init__.py | 35 +++++++++++++++ .../VersionUpgrade33to34/plugin.json | 8 ++++ 5 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py create mode 100644 plugins/VersionUpgrade/VersionUpgrade33to34/__init__.py create mode 100644 plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 67a57bd0cb..42f169ad0c 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -132,19 +132,21 @@ class CuraApplication(QtApplication): QmlFiles = Resources.UserType + 1 Firmware = Resources.UserType + 2 QualityInstanceContainer = Resources.UserType + 3 - MaterialInstanceContainer = Resources.UserType + 4 - VariantInstanceContainer = Resources.UserType + 5 - UserInstanceContainer = Resources.UserType + 6 - MachineStack = Resources.UserType + 7 - ExtruderStack = Resources.UserType + 8 - DefinitionChangesContainer = Resources.UserType + 9 - SettingVisibilityPreset = Resources.UserType + 10 + QualityChangesInstanceContainer = Resources.UserType + 4 + MaterialInstanceContainer = Resources.UserType + 5 + VariantInstanceContainer = Resources.UserType + 6 + UserInstanceContainer = Resources.UserType + 7 + MachineStack = Resources.UserType + 8 + ExtruderStack = Resources.UserType + 9 + DefinitionChangesContainer = Resources.UserType + 10 + SettingVisibilityPreset = Resources.UserType + 11 + CuraPackages = Resources.UserType + 12 Q_ENUMS(ResourceTypes) def __init__(self, **kwargs): # this list of dir names will be used by UM to detect an old cura directory - for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "user", "variants"]: + for dir_name in ["extruders", "machine_instances", "materials", "plugins", "quality", "quality_changes", "user", "variants"]: Resources.addExpectedDirNameInData(dir_name) Resources.addSearchPath(os.path.join(QtApplication.getInstallPrefix(), "share", "cura", "resources")) @@ -180,6 +182,7 @@ class CuraApplication(QtApplication): ## Add the 4 types of profiles to storage. Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") + Resources.addStorageType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes") Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials") Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") @@ -187,9 +190,10 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes") Resources.addStorageType(self.ResourceTypes.SettingVisibilityPreset, "setting_visibility") + Resources.addStorageType(self.ResourceTypes.CuraPackages, "cura_packages") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality") - ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality_changes") + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer, "variant") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MaterialInstanceContainer, "material") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer, "user") @@ -203,7 +207,7 @@ class CuraApplication(QtApplication): UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions( { - ("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"), + ("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityChangesInstanceContainer, "application/x-uranium-instancecontainer"), ("machine_stack", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.MachineStack, "application/x-cura-globalstack"), ("extruder_train", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"), ("preferences", Preferences.Version * 1000000 + self.SettingVersion): (Resources.Preferences, "application/x-uranium-preferences"), diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 8d4f711155..dbbbdc0718 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -676,7 +676,7 @@ class CuraContainerRegistry(ContainerRegistry): return extruder_stack def _findQualityChangesContainerInCuraFolder(self, name): - quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer) + quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityChangesInstanceContainer) instance_container = None diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py new file mode 100644 index 0000000000..4e7b09564a --- /dev/null +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py @@ -0,0 +1,43 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import configparser #To parse preference files. +import io #To serialise the preference files afterwards. + +from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this. + + +## Upgrades configurations from the state they were in at version 3.2 to the +# state they should be in at version 3.3. +class VersionUpgrade33to34(VersionUpgrade): + + ## Gets the version number from a CFG file in Uranium's 3.2 format. + # + # Since the format may change, this is implemented for the 3.2 format only + # and needs to be included in the version upgrade system rather than + # globally in Uranium. + # + # \param serialised The serialised form of a CFG file. + # \return The version number stored in the CFG file. + # \raises ValueError The format of the version number in the file is + # incorrect. + # \raises KeyError The format of the file is incorrect. + def getCfgVersion(self, serialised): + parser = configparser.ConfigParser(interpolation = None) + parser.read_string(serialised) + format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised. + setting_version = int(parser.get("metadata", "setting_version", fallback = 0)) + return format_version * 1000000 + setting_version + + ## Upgrades instance containers to have the new version + # number. + def upgradeInstanceContainer(self, serialized, filename): + parser = configparser.ConfigParser(interpolation = None) + parser.read_string(serialized) + + # Update version number. + parser["general"]["version"] = "4" + + result = io.StringIO() + parser.write(result) + return [filename], [result.getvalue()] diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/__init__.py b/plugins/VersionUpgrade/VersionUpgrade33to34/__init__.py new file mode 100644 index 0000000000..c36247353f --- /dev/null +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/__init__.py @@ -0,0 +1,35 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from . import VersionUpgrade33to34 + +upgrade = VersionUpgrade33to34.VersionUpgrade33to34() + + +def getMetaData(): + return { + "version_upgrade": { + # From To Upgrade function + ("definition_changes", 3000004): ("definition_changes", 4000004, upgrade.upgradeInstanceContainer), + ("quality_changes", 3000004): ("quality_changes", 4000004, upgrade.upgradeInstanceContainer), + ("user", 3000004): ("user", 4000004, upgrade.upgradeInstanceContainer), + }, + "sources": { + "definition_changes": { + "get_version": upgrade.getCfgVersion, + "location": {"./definition_changes"} + }, + "quality_changes": { + "get_version": upgrade.getCfgVersion, + "location": {"./quality"} + }, + "user": { + "get_version": upgrade.getCfgVersion, + "location": {"./user"} + } + } + } + + +def register(app): + return { "version_upgrade": upgrade } diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json new file mode 100644 index 0000000000..164b79d504 --- /dev/null +++ b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json @@ -0,0 +1,8 @@ + { + "name": "Version Upgrade 3.3 to 3.4", + "author": "Ultimaker B.V.", + "version": "1.0.0", + "description": "Upgrades configurations from Cura 3.3 to Cura 3.4.", + "api": 4, + "i18n-catalog": "cura" +} From ed390738f4677cd159edb0ff2808e5cc1bfb447c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 4 Apr 2018 11:53:35 +0200 Subject: [PATCH 19/83] Update all qualities and variants to version 4 --- resources/quality/abax_pri3/apri3_pla_fast.inst.cfg | 2 +- resources/quality/abax_pri3/apri3_pla_high.inst.cfg | 2 +- resources/quality/abax_pri3/apri3_pla_normal.inst.cfg | 2 +- resources/quality/abax_pri5/apri5_pla_fast.inst.cfg | 2 +- resources/quality/abax_pri5/apri5_pla_high.inst.cfg | 2 +- resources/quality/abax_pri5/apri5_pla_normal.inst.cfg | 2 +- resources/quality/abax_titan/atitan_pla_fast.inst.cfg | 2 +- resources/quality/abax_titan/atitan_pla_high.inst.cfg | 2 +- resources/quality/abax_titan/atitan_pla_normal.inst.cfg | 2 +- .../quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg | 2 +- .../quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg | 2 +- .../quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg | 2 +- .../quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg | 2 +- resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg | 2 +- .../builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg | 2 +- .../builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg | 2 +- resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PET_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg | 2 +- resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg | 2 +- resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_global_Coarse_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_global_High_Quality.inst.cfg | 2 +- .../quality/builder_premium/bp_global_Normal_Quality.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg | 2 +- .../quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg | 2 +- resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg | 2 +- .../cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg | 2 +- .../cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg | 2 +- .../quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg | 2 +- .../cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg | 2 +- .../quality/cartesio/cartesio_global_High_Quality.inst.cfg | 2 +- .../quality/cartesio/cartesio_global_Normal_Quality.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg | 2 +- resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg | 2 +- .../cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg | 2 +- .../quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg | 2 +- .../cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg | 2 +- .../quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg | 2 +- .../quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg | 2 +- resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg | 2 +- resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg | 2 +- .../cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg | 2 +- .../quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg | 2 +- .../quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg | 2 +- resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg | 2 +- .../quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg | 2 +- resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg | 2 +- resources/quality/coarse.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_abs_high.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_pla_high.inst.cfg | 2 +- resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg | 2 +- resources/quality/draft.inst.cfg | 2 +- resources/quality/extra_coarse.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_abs_high.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_pla_high.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg | 2 +- resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg | 2 +- resources/quality/fast.inst.cfg | 2 +- .../quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg | 2 +- .../quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg | 2 +- resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg | 2 +- resources/quality/high.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg | 2 +- .../imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg | 2 +- .../imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg | 2 +- .../imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg | 2 +- .../imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg | 2 +- .../imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg | 2 +- .../imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg | 2 +- .../quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg | 2 +- .../quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg | 2 +- .../quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg | 2 +- .../imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg | 2 +- .../quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg | 2 +- .../quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg | 2 +- .../quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg | 2 +- resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg | 2 +- resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg | 2 +- resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg | 2 +- .../malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg | 2 +- .../quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg | 2 +- resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg | 2 +- resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg | 2 +- resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg | 2 +- resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg | 2 +- resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg | 2 +- resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg | 2 +- resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg | 2 +- resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_High_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg | 2 +- .../malyan_m200_global_ThickerDraft_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg | 2 +- .../malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg | 2 +- .../quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg | 2 +- .../malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg | 2 +- resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg | 2 +- resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg | 2 +- .../malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg | 2 +- .../quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_draft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_fast.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_high.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_normal.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_ultra.inst.cfg | 2 +- .../abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_Draft_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_Fast_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_High_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_Normal_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg | 2 +- ...onoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg | 2 +- .../monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_high.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg | 2 +- .../nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_draft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_fast.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_high.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_normal.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_ultra.inst.cfg | 2 +- .../pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_draft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_fast.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_high.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_normal.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_ultra.inst.cfg | 2 +- .../petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_draft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_fast.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_high.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_normal.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_ultra.inst.cfg | 2 +- .../pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg | 2 +- resources/quality/normal.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg | 2 +- resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg | 2 +- .../quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg | 2 +- resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg | 2 +- .../quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg | 2 +- resources/quality/ultimaker2/um2_draft.inst.cfg | 2 +- resources/quality/ultimaker2/um2_fast.inst.cfg | 2 +- resources/quality/ultimaker2/um2_high.inst.cfg | 2 +- resources/quality/ultimaker2/um2_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg | 2 +- .../quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg | 2 +- resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg | 2 +- .../ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg | 2 +- .../quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg | 2 +- resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg | 2 +- resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg | 2 +- .../quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg | 2 +- .../quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg | 2 +- .../quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg | 2 +- .../quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg | 2 +- .../quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg | 2 +- .../vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg | 2 +- resources/variants/cartesio_0.25.inst.cfg | 2 +- resources/variants/cartesio_0.4.inst.cfg | 2 +- resources/variants/cartesio_0.8.inst.cfg | 2 +- resources/variants/fabtotum_hyb35.inst.cfg | 2 +- resources/variants/fabtotum_lite04.inst.cfg | 2 +- resources/variants/fabtotum_lite06.inst.cfg | 2 +- resources/variants/fabtotum_pro02.inst.cfg | 2 +- resources/variants/fabtotum_pro04.inst.cfg | 2 +- resources/variants/fabtotum_pro06.inst.cfg | 2 +- resources/variants/fabtotum_pro08.inst.cfg | 2 +- resources/variants/gmax15plus_025_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_04_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_05_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_05_jhead.inst.cfg | 2 +- resources/variants/gmax15plus_06_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_08_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_10_jhead.inst.cfg | 2 +- resources/variants/gmax15plus_dual_025_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_04_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_05_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_05_jhead.inst.cfg | 2 +- resources/variants/gmax15plus_dual_06_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_08_e3d.inst.cfg | 2 +- resources/variants/gmax15plus_dual_10_jhead.inst.cfg | 2 +- resources/variants/imade3d_jellybox_0.4.inst.cfg | 2 +- resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg | 2 +- resources/variants/ultimaker2_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_0.8.inst.cfg | 2 +- resources/variants/ultimaker2_extended_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_extended_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_extended_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_extended_0.8.inst.cfg | 2 +- resources/variants/ultimaker2_extended_plus_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_extended_plus_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_extended_plus_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_extended_plus_0.8.inst.cfg | 2 +- resources/variants/ultimaker2_plus_0.25.inst.cfg | 2 +- resources/variants/ultimaker2_plus_0.4.inst.cfg | 2 +- resources/variants/ultimaker2_plus_0.6.inst.cfg | 2 +- resources/variants/ultimaker2_plus_0.8.inst.cfg | 2 +- resources/variants/ultimaker3_aa0.25.inst.cfg | 2 +- resources/variants/ultimaker3_aa0.8.inst.cfg | 2 +- resources/variants/ultimaker3_aa04.inst.cfg | 2 +- resources/variants/ultimaker3_bb0.8.inst.cfg | 2 +- resources/variants/ultimaker3_bb04.inst.cfg | 2 +- resources/variants/ultimaker3_extended_aa0.25.inst.cfg | 2 +- resources/variants/ultimaker3_extended_aa0.8.inst.cfg | 2 +- resources/variants/ultimaker3_extended_aa04.inst.cfg | 2 +- resources/variants/ultimaker3_extended_bb0.8.inst.cfg | 2 +- resources/variants/ultimaker3_extended_bb04.inst.cfg | 2 +- 445 files changed, 445 insertions(+), 445 deletions(-) diff --git a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg index 50ff90670f..b46e2473af 100644 --- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = abax_pri3 diff --git a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg index 0bcd5ef77d..a12d8d1b72 100644 --- a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = abax_pri3 diff --git a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg index 5ef275652d..3cea7931aa 100644 --- a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg +++ b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = abax_pri3 diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg index 922da8e88e..ba1de97b89 100644 --- a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = abax_pri5 diff --git a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg index 2b1c6b017b..d1ea040f93 100644 --- a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = abax_pri5 diff --git a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg index 23b21f597b..c2bb8d343b 100644 --- a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg +++ b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = abax_pri5 diff --git a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg index 5d935a915a..ec54c373c9 100644 --- a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = abax_titan diff --git a/resources/quality/abax_titan/atitan_pla_high.inst.cfg b/resources/quality/abax_titan/atitan_pla_high.inst.cfg index 8bd45034e3..f8d016f6d0 100644 --- a/resources/quality/abax_titan/atitan_pla_high.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = abax_titan diff --git a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg index 081e5ad977..b25a0ff47e 100644 --- a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg +++ b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = abax_titan diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg index 821205ca69..ae18246f3f 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = anycubic_i3_mega diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg index e686ce50ac..bbaa9c63b1 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = anycubic_i3_mega diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg index 3e855c1bbc..d319b09952 100644 --- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg +++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = anycubic_i3_mega diff --git a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg index c5a92e3c93..8fc7946102 100644 --- a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg index 72ce4f3555..bc245b2a9e 100644 --- a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High Quality definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg index daa1d8bc78..296551d8ef 100644 --- a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg index 827c726071..d18a79671b 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg index 4c84d0ddfe..4b12d944ad 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High Quality definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg index 23813f85b9..8a968130c5 100644 --- a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg index da0d40393c..231b5f1aed 100644 --- a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg index b78a5a29d7..264642a45f 100644 --- a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High Quality definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg index 600fbed476..1d740db41e 100644 --- a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg index d1c1d4d563..5e0b1c4337 100644 --- a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg index 1063342b89..651de64134 100644 --- a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High Quality definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg index 6612c704f3..075cdc7921 100644 --- a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg index 2717ffe998..d6c5338c31 100644 --- a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg index 3ab782af5c..4b26f98cea 100644 --- a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High Quality definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg index fe24e976c7..f8abfe3347 100644 --- a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg index 708a135847..727b64b57e 100644 --- a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg index 0c96206a7d..8b40d11cc0 100644 --- a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High Quality definition = builder_premium_small diff --git a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg index 833e7e8905..1ae3561550 100644 --- a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg +++ b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = builder_premium_small diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg index 5e713275c6..6fa0c5e9e4 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg index d35dcf1c18..000cb24d31 100644 --- a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg index 06ef74108b..24c301f7e8 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg index 8e5b6aadc0..dd52f51b82 100644 --- a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg index 5da823a2d8..137f7e4453 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = cartesio diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg index 267857cff1..292b1cb9b5 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Coarse definition = cartesio diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg index e3219d145c..2054a82b7b 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg index 111bef11dc..a813357fbd 100644 --- a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg +++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg index 35dddeca91..da53c2f3c5 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg index 3234881c72..76f8d29453 100644 --- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg +++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg index 017483f79a..964290c854 100644 --- a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = cartesio diff --git a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg index aadb582309..8bad7659f6 100644 --- a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Coarse definition = cartesio diff --git a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg index e4131dc3a2..965229a38d 100644 --- a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg index e29a98c980..48b8dbb093 100644 --- a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg +++ b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg index b2dc76479f..21bea8a361 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg index c18167b97a..292777c7cc 100644 --- a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg index 506ff1807b..127eeeb34e 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg index 1f2ee24064..5300b3d883 100644 --- a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg index d117df88a6..afafe024de 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = cartesio diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg index e833abcdad..beb7537575 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Coarse definition = cartesio diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg index eee5862fea..8201acae75 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg index b0057d5b03..61eb1687a9 100644 --- a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg +++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg index 6dce2b7ea2..c32409606f 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg index 169a7cab65..4955e918a3 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg index 101fb595d5..26d83494dc 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg index dc5522bda3..6d508f785d 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg index 0b4ef88282..0b26ee6113 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = cartesio diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg index 2fd9aa3220..5027141d1b 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Coarse definition = cartesio diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg index 26f749e357..efc2577550 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg index 4843c9cbf4..47ae239bd0 100644 --- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg +++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg index d29c8c6801..92645c1e3c 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg index 35168f8ed7..7478c8492c 100644 --- a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg index 05bb623a90..83a0222c29 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg index 569ecb069a..b082d8be85 100644 --- a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg index b35681187d..efad533ca7 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = cartesio diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg index 75fe030443..20de51380f 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Coarse definition = cartesio diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg index 05232ac1b3..82eb3c3a94 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg index 106afcf992..d22b9497e0 100644 --- a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg +++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg index edeb791847..cf4bb68e6b 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg index ca95ba4d55..fdf309674d 100644 --- a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg index 47e4e74fba..2013524368 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg index 737289f778..6f59633430 100644 --- a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg index 54abbbeb46..be37fa8cf1 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = cartesio diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg index 75ef0ed89b..60b6bfc957 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Coarse definition = cartesio diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg index 2a9542ce56..c45f2bb6aa 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg index 9f27c3c8d1..541dbc3908 100644 --- a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg +++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg index 62cf3194c0..d249e1aec5 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg index 5dd27477e1..08363203f3 100644 --- a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg index b6bf3808be..3c6738e02f 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg index a03b316e6f..f87af2f1c2 100644 --- a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg index 6284ab3325..83cefd98f9 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = cartesio diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg index 58b4c347f3..6a38ef849c 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Coarse definition = cartesio diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg index f0d22251bb..57a36b73d7 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg index 44ed46ddd3..cf4df1f09a 100644 --- a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg +++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg index aa9ac8393d..0f01d381a7 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg index b4de6b5730..d5496756c4 100644 --- a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg index 5a60dfbe17..97a41d8df0 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg index 9cc57ac16a..344ac13fe1 100644 --- a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg index df1bffeb41..a563e67c5c 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = cartesio diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg index 30ade55494..2014870980 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Coarse definition = cartesio diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg index c8ab571baf..7efa837d65 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = cartesio diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg index 815694e410..cb3e1f564b 100644 --- a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg +++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = cartesio diff --git a/resources/quality/coarse.inst.cfg b/resources/quality/coarse.inst.cfg index 9dff2a02b3..ffbd57263b 100644 --- a/resources/quality/coarse.inst.cfg +++ b/resources/quality/coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse Quality definition = fdmprinter diff --git a/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg index 3863cb6940..49f5c01d2c 100644 --- a/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = deltacomb name = Fast Quality (beta) diff --git a/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg index 715d8a6841..404e19f714 100644 --- a/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = deltacomb name = High Quality (beta) diff --git a/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg index 7cddbb154a..511d8ac653 100644 --- a/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = deltacomb name = Normal Quality (beta) diff --git a/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg index 72d2b30199..e5718fdc95 100644 --- a/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast Quality (beta) definition = deltacomb diff --git a/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg index 2cd71a96b1..2b29b49c68 100644 --- a/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High Quality (beta) definition = deltacomb diff --git a/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg index d42fdee730..9853831b12 100644 --- a/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal Quality (beta) definition = deltacomb diff --git a/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg index 11fefbaed1..aef76ea72a 100644 --- a/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = deltacomb name = Fast Quality diff --git a/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg index 4b7125dbb9..45f7065deb 100644 --- a/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = deltacomb name = High Quality diff --git a/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg index e935c45567..54c976cef1 100644 --- a/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg +++ b/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = deltacomb name = Normal Quality diff --git a/resources/quality/draft.inst.cfg b/resources/quality/draft.inst.cfg index 211525e7d6..2e0e97e812 100644 --- a/resources/quality/draft.inst.cfg +++ b/resources/quality/draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft Quality definition = fdmprinter diff --git a/resources/quality/extra_coarse.inst.cfg b/resources/quality/extra_coarse.inst.cfg index e25b813f2f..98aeecbc79 100644 --- a/resources/quality/extra_coarse.inst.cfg +++ b/resources/quality/extra_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Coarse Quality definition = fdmprinter diff --git a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg index 78a4eb6f9f..f92c000b14 100644 --- a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = fabtotum name = Fast Quality diff --git a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg index 786ae18fa5..9a47542645 100644 --- a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = fabtotum name = High Quality diff --git a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg index da75417c87..e7dd3e4cb4 100644 --- a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = fabtotum name = Normal Quality diff --git a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg index db86543322..88985a7918 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast Quality definition = fabtotum diff --git a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg index 010298c472..cef9b6023a 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High Quality definition = fabtotum diff --git a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg index b9a80d82b3..63b2baf019 100644 --- a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal Quality definition = fabtotum diff --git a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg index bea0ea4aff..8c07d21094 100644 --- a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = fabtotum name = Fast Quality diff --git a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg index b77a0d8300..9a39a4f8b9 100644 --- a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = fabtotum name = High Quality diff --git a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg index 11e5890cc5..7179e67601 100644 --- a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = fabtotum name = Normal Quality diff --git a/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg index d689f704aa..3a70155981 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = fabtotum name = Fast Quality diff --git a/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg index 6193b3b573..32743651c4 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = fabtotum name = High Quality diff --git a/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg index 7ccbe296e3..e75caadb34 100644 --- a/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg +++ b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 definition = fabtotum name = Normal Quality diff --git a/resources/quality/fast.inst.cfg b/resources/quality/fast.inst.cfg index 56bc6be48d..a725947eba 100644 --- a/resources/quality/fast.inst.cfg +++ b/resources/quality/fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Quality definition = fdmprinter diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg index ae31f92447..09196ee34c 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = gMax 1.5+ Dual Normal Layers definition = gmax15plus_dual diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg index 4e262d8ecf..ea395647fc 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = gMax 1.5+ Dual Thick Layers definition = gmax15plus_dual diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg index a1b43d5d08..941c909101 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = gMax 1.5+ Dual Thin Layers definition = gmax15plus_dual diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg index 1d5c7eca91..54343e57a1 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = gMax 1.5+ Dual Very Thick Layers definition = gmax15plus_dual diff --git a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg index 1d01b82d3c..f851119f0b 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = gMax 1.5+ Normal Layers definition = gmax15plus diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg index dd6b3e702b..f1e5e838e4 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = gMax 1.5+ Thick Layers definition = gmax15plus diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg index f90cb27647..682b714533 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = gMax 1.5+ Thin Layers definition = gmax15plus diff --git a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg index 171cf2f28d..4c5bc82715 100644 --- a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg +++ b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = gMax 1.5+ Very Thick Layers definition = gmax15plus diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg index bb9e77ad38..673ce56f04 100644 --- a/resources/quality/high.inst.cfg +++ b/resources/quality/high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = fdmprinter diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg index 020e9d9b0f..25b6f1155a 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg index 3aba34126e..2d975b1240 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg index b235662e9f..c510473c3d 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Medium definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg index d5a9b09ed7..682f850c83 100644 --- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Medium definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg index 797f77fa72..264878f9d9 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg index 61bb573a25..8427144478 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg index 3c37910112..335e62c698 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg index eb31b07794..bb4f9f0570 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg index b8bbd674e0..8bb391bdaa 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Medium definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg index 56ae48379f..9e4d8efddc 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Medium definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg index 16fb70252b..aac761463d 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = UltraFine definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg index 2cab1fad46..8df712f8ee 100644 --- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg +++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = UltraFine definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg index 7a778a788f..1a4d51c25b 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Coarse definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg index 51767e0c93..b2926f271f 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg index 407ae608a4..52687b9ab5 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Medium definition = imade3d_jellybox diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg index f531d84234..b5e8be3841 100644 --- a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg +++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = UltraFine definition = imade3d_jellybox diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg index 69c2b328cf..38a5208905 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg index 0bb72ce073..9438ecbfa7 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg index 1fd5874b70..16d3367472 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg index 78f80c576d..d0b15cf47b 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg index 626de7bde6..2d32a0cc87 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg index 63a49e6bc1..373b92a0b7 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg index 2d49b01b92..32ad90dbb0 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg index e79a3188d7..e77994fb83 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg index db391b95ca..09a3b7d748 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg index 336b1f47b9..687095d841 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = kemiq_q2_beta diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg index 6044fa25a4..3fb2c90b30 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = kemiq_q2_gama diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg index 9962c554ca..8c0d1cf9ca 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = kemiq_q2_gama diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg index 4b5b3b62ed..b1e576f162 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = kemiq_q2_gama diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg index a187507632..654936deff 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low definition = kemiq_q2_gama diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg index 281f73393a..da6d2d89ae 100644 --- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg +++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = kemiq_q2_gama diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg index 104b747aea..cff97f1480 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = malyan_m200 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg index 3f2eec9867..5413880b98 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = malyan_m200 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg index 55a6c0d4ba..732da71f86 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = malyan_m200 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg index 98587bdf7d..af8f5a7a2b 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = malyan_m200 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg index 49fcd1e935..1c97c7c1d5 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg index f9a9fe3d98..cf9352bced 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg index dcc2813031..08c5457d8f 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = malyan_m200 diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg index 251d024a85..f9f3f5aaa0 100644 --- a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg index c9dd72f5f5..18625e80eb 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = M1 Quality definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg index 65d7d0d0b8..311a797b27 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = M2 Quality definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg index 89aea54fdc..1fe974f6d2 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = M3 Quality definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg index 613988a437..091035d137 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = M4 Quality definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg index 75d7601af3..1a22bbc236 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = M5 Quality definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg index 470af78595..d89eb9e6d8 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = M6 Quality definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg index 32fa8c5641..2e71c79b49 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = M7 Quality definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg index 1e168e7690..362d4b9539 100644 --- a/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = M8 Quality definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg index 12796a140f..91153f57f7 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg index 78f014bd9e..6b29fc3649 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg index bf2f25b418..c32814152f 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg index cd9609cc2d..eb29cfa8a5 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg index 880eb5068d..47bd154d90 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg index 9ebc812738..c7b6a0b44d 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg index f1841970af..f3917e23f7 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = malyan_m200 diff --git a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg index 7da342c437..281374a7f1 100644 --- a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg index 0434decedc..d6ade3b912 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = malyan_m200 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg index 2049403af4..42b04050ca 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = malyan_m200 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg index 00882f2418..a17645c080 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = malyan_m200 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg index 58ad4a1085..afdd638487 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = malyan_m200 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg index 09a72e261a..b95822412b 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg index e57b1d24f2..469ff538e6 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg index 0c3de72835..1f8f8de58b 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = malyan_m200 diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg index 0139e972f6..713e2492fd 100644 --- a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg index c30df8a9b3..a02d814db8 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = malyan_m200 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg index 8e1b0478ad..5c5d517d59 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = malyan_m200 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg index 44713b2386..3ca06f8c2d 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = malyan_m200 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg index cd6497d9bf..e17e99af9a 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = malyan_m200 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg index 447de8a48b..c17276ab75 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg index f2c5e3c9cc..ba275d1b49 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = malyan_m200 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg index 63f19bef41..d5411cc417 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = malyan_m200 diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg index 6a96b3d678..7c88294458 100644 --- a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg +++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = malyan_m200 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg index 6fec85b563..e9daac1b9c 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg index 0d79f2cc72..fb5fb56521 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg index f02e3b5838..4a3b1f612a 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg index a046cfa561..6087dae505 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg index f5861ce734..916c235233 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg index b63fd3cfad..d712976d17 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg index 6aed450961..95b32a8877 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg index 1c462fd435..5fe71b14f2 100644 --- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg index c70ccc9946..002784bf21 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg index 1bc10e2186..31965ff4ef 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg index 24d5d5819f..a828a3466f 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg index 0a884c80ca..560a98eedd 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg index 9a0928186c..32aab452b9 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg index 994ec14a3e..d591899d58 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg index 813d156588..2d1cb39569 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg index 0a461945f5..41e6553b52 100644 --- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg index d5ccd3070b..43a8a0793c 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg index aca8884024..933c536a3b 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg index 080a06d84f..aa89cac1af 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg index 7f3222d229..4b995dac7c 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg index 88777be100..96650de3e1 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg index 8880d6defa..dfac9f911c 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg index 945964cfac..e143bfc3c9 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg index fbebffde3a..d3fd94fe0d 100644 --- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg index be4f438df5..e9bf91dc3d 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg index c81f19a03e..1532f6f631 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg index 714cd66c1f..cf27cd71ca 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg index a314288364..8bd29b694e 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg index 4889d3fc7d..63a9493338 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg index 12a5c2ac6f..ec528de08a 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg index 3b70904476..1b830538bf 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg index 2ea13105ef..58e21a33de 100644 --- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg index da8f6a7c9a..e40e29274b 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg index bc151b9635..6e47686483 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg index bc1101603e..2a60451428 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg index 932bfdf97a..342294d018 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg index 77fb261821..d16e60dfa9 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg index 096ff5c2f6..9819054c68 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg index 9a3cc19a0c..46de625a99 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg index c9e0aae2c4..e553e1088b 100644 --- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg index 8f85c598bd..116d5f70d2 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg index 09e741ad07..279e7955e5 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg index cf00fb02b0..623cdbb163 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Finer definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg index eaa85450d8..1fc4376572 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg index 66f888cd6e..1ebe9c63d4 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Lowest Quality Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg index c4c2a0c2d1..0c12759bf8 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg index b9b0fea26e..04289aa6c7 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Ultra Fine definition = monoprice_select_mini_v2 diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg index bd6febd83c..e8b72e1630 100644 --- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg +++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Detail Draft definition = monoprice_select_mini_v2 diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg index 0f1a4d6905..09f063cde3 100644 --- a/resources/quality/normal.inst.cfg +++ b/resources/quality/normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = fdmprinter diff --git a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg index 57c955f4b7..dfb07a0eef 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = peopoly_moai diff --git a/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg index 4cce7e2d85..eb5e621310 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Maximum Quality definition = peopoly_moai diff --git a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg index a1465a86c9..1edc852385 100644 --- a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg +++ b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = peopoly_moai diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg index 184205b1cd..29de7591bf 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft definition = tevo_blackwidow diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg index d158af4123..e495d2d74b 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = tevo_blackwidow diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg index a44ff8bcdb..4df87784ef 100644 --- a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg +++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = tevo_blackwidow diff --git a/resources/quality/ultimaker2/um2_draft.inst.cfg b/resources/quality/ultimaker2/um2_draft.inst.cfg index dc761afc0b..faf2b68208 100644 --- a/resources/quality/ultimaker2/um2_draft.inst.cfg +++ b/resources/quality/ultimaker2/um2_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Draft Quality definition = ultimaker2 diff --git a/resources/quality/ultimaker2/um2_fast.inst.cfg b/resources/quality/ultimaker2/um2_fast.inst.cfg index 04c24dc4c2..99ddb540cc 100644 --- a/resources/quality/ultimaker2/um2_fast.inst.cfg +++ b/resources/quality/ultimaker2/um2_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Low Quality definition = ultimaker2 diff --git a/resources/quality/ultimaker2/um2_high.inst.cfg b/resources/quality/ultimaker2/um2_high.inst.cfg index 1c83ea350b..f54700bf70 100644 --- a/resources/quality/ultimaker2/um2_high.inst.cfg +++ b/resources/quality/ultimaker2/um2_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2 diff --git a/resources/quality/ultimaker2/um2_normal.inst.cfg b/resources/quality/ultimaker2/um2_normal.inst.cfg index bddbe6e243..c069d2490b 100644 --- a/resources/quality/ultimaker2/um2_normal.inst.cfg +++ b/resources/quality/ultimaker2/um2_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2 diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg index eecaa2fa0f..f9357010b2 100644 --- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg index 207d237fa3..b50de37b47 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg index 83ffa99d07..9481e3427a 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg index 683eab7166..875db4959f 100644 --- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg index 80dea5f5fd..b07b4931ca 100644 --- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg index 5c898c74ec..0e76e53316 100644 --- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg index 275a4595a0..43bdbb117e 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg index a95417c711..ded9319b3e 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg index 97d35fe6bf..c94333555c 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg index 162805f5c2..6adb9c9caf 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg index 5291356b4e..332608a2f9 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg index 01c0b5467b..f09979c212 100644 --- a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg index 1b656eb4f1..bd6d9d1aa8 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg index 8385800e15..b9ec279e07 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg index 6d810ee231..e929d9f545 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg index 1b6ab4edc5..7637f6440a 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg index 7f79c013b3..7c9598c7d8 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg index df92d3e2dd..41d531097b 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg index e83ae78d36..fe975128a0 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg index ee0b659b91..e7bb7b3449 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg index 0773a81834..9751bef5fe 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg index 4cea2db94e..203d122de5 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg index 27c3052885..b80949a627 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg index 26d44f332b..4f96db3c3b 100644 --- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg index d2c9c9d8d3..d31c23a5c0 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg index 115e4dd0d3..0f9fd57197 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg index 917715ef33..0d8371760f 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg index 125930991a..3ac77b3642 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg index 3602182288..d6332e5688 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg index c41a8b3612..22250e1147 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg index 6e68d79f34..0ba3a33812 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg index e01006cf58..5e0d64ec12 100644 --- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg index 91bc5e523a..d7cafd20a5 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg index 5407edf56d..bdaed6745a 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg index 5e0cef44cc..aaf4812786 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg index 9e400a46e7..a54ce9d946 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg index 1741eb47e9..2d50f96661 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg index 17df729157..a19483c39a 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg index 87bad0bd64..fb269e67ef 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg index e1f208b2f1..bf530cccf6 100644 --- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg index cbb4f2f881..16c4a47340 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg index ee38faa33a..d318275700 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg index 9fe8c72397..dd150d903a 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg index ba9052818c..8cb602b7eb 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg index 2a6b4d1de8..3e38caa1ec 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg index 92f605f557..39408477af 100644 --- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg index b6fe1515c0..3e5f8f8180 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg index 27e09bdf10..84065dbfdf 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker2_plus diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg index 6d0b1ef8de..ec424a6f40 100644 --- a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg +++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker2_plus diff --git a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg index c79c831984..e1cd7e77a9 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg index 83e77eb117..cc236e1a3b 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg index c3ead92b51..568b7d0f73 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg index bd95837fee..8444d0faef 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine - Experimental definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg index 7f6fb9fa4d..14345dc626 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg index 6bdd94f58f..4a3572a1c5 100644 --- a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine - Experimental definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg index 4b05943b64..f7748e3903 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg index 3b441942ac..50fb12eaa4 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg index 79cdb4069d..6215afc9df 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg index 412bc4c5a8..a7683fb249 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg index e4ef572efb..f9a2bd88a4 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg index c896c74233..d181e7e4c9 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg index 9fdcfb4cf3..4a8bde54b3 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg index 14263ee800..8f071b18d7 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg index 05d8988c36..fc6eee65bc 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg index 6a6fa94730..3559ed5e67 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg index 402e23436a..02a807c7b8 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg index 9a85ab9b3e..f3c5a75d34 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg index 7099062daf..ce6c193c46 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg index 00adfcc2d7..3cd2dc0cc8 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg index 590eddf43b..c4fa7abd7f 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg index 8ade8d4fe4..91600ed6fa 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg index 2fef1fb2a2..7db3683333 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg index 9a320ecde3..fd9ffb53b4 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg index 34efb4df95..c8ed69342d 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg index 79ae457587..b8cb9f0b89 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg index 2e07e65bbe..02be254db0 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg index 2b1b1f850b..434bd3f1ba 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg index 437ef43878..ddc8b4b527 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg index 3805d7a396..735dac3b76 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg index 3a8c6df621..b69fa30a8b 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg index 543391fd6b..325d22fe5a 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg index c3c2a8d624..910f3cec4b 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg index 1db33d9073..23d44b8442 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg index fe7da92bbe..c86a9f5578 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg index 8bbb0118b5..54406c1f55 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg index 25e7c2c0ab..59c650ef0e 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg index 0b7fa6501e..f0a889c12e 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg index 9afecb8987..1b6ac261cf 100644 --- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg index 85e1415147..9b28f51745 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg index 3167473cc6..e79e505270 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg index 0414bf724c..477ee60492 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg index 87728c2297..961e127a57 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast - Experimental definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg index 603f32a688..b112bf8f4f 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint - Experimental definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg index 432d502245..c51ee3a90f 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast - Experimental definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg index fd138ae2f2..650aaf88af 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg index feba0b3160..f983073148 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg index 1d9537097e..201ecee0ad 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg index e205720539..73016046b6 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg index f2853a8781..5940bf3ab9 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg index 442323877c..ea809095ac 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg index d8460c6971..fba7e2c824 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast - Experimental definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg index 53f613ec70..5838a48fb7 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint - Experimental definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg index a4fdaaa791..83a331e801 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast - Experimental definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg index 3293fa8382..a852bb9b47 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg index b989d7e11a..61e142a254 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg index 684eb11c5b..cb4d3ad915 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg index 8ed11c1946..3e204ab623 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg index 01b947995d..1a6e469015 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg index ba1aa89c91..db5bb4e70b 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg index e133d335f8..25dd942fbe 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg index c835de26f4..d3a28c42a0 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg index 2e3ad5cf44..bf17bc5edc 100644 --- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg index 4fff8be5ee..153e1afd58 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg index 8abce151bf..2660680d81 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg index 0caf36e51b..9cdedaf480 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg index 0a8304a743..d92a062bc8 100644 --- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg index d59f283eb6..6aacd137b6 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg index 4039d39d6a..69ec326466 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg index 247ee3d4da..7f1f18f38b 100644 --- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg +++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg index 49a514bff3..c9f519af47 100644 --- a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fast definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg index 69a94be93a..ffcfd450dd 100644 --- a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg index 2aebb18ab5..eaad3e8a92 100644 --- a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg index 5effc44fc5..e8ffaad679 100644 --- a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Fine definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg index 55f5796240..69d9e59690 100644 --- a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Sprint definition = ultimaker3 diff --git a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg index 5d72a76c7c..db914aec6d 100644 --- a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg +++ b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extra Fast definition = ultimaker3 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg index 30c2749ac6..65bf79b7c2 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extreme definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg index 102901ab3d..17e21d0d7a 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg index f2e699f571..472679665f 100644 --- a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg index 1f98ded1db..328812b4ab 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extreme definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg index f050c741c2..b0f962c789 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg index faeb8343fb..5d540c269b 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg index f5ac232d06..059f864fd3 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extreme definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg index 63ed8389db..aa3dd55a2a 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg index e84cbabade..08e0eb2c57 100644 --- a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg index a2e8a334f7..2722a86b71 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Extreme definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg index 4598332ba6..f545ca4e4a 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = High definition = vertex_delta_k8800 diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg index 7a8a964b1c..cf09714347 100644 --- a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg +++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg @@ -1,5 +1,5 @@ [general] -version = 3 +version = 4 name = Normal definition = vertex_delta_k8800 diff --git a/resources/variants/cartesio_0.25.inst.cfg b/resources/variants/cartesio_0.25.inst.cfg index a3fbe67606..79d3a33d66 100644 --- a/resources/variants/cartesio_0.25.inst.cfg +++ b/resources/variants/cartesio_0.25.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.25 mm -version = 3 +version = 4 definition = cartesio [metadata] diff --git a/resources/variants/cartesio_0.4.inst.cfg b/resources/variants/cartesio_0.4.inst.cfg index d5fbc4dc26..680eea64b0 100644 --- a/resources/variants/cartesio_0.4.inst.cfg +++ b/resources/variants/cartesio_0.4.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.4 mm -version = 3 +version = 4 definition = cartesio [metadata] diff --git a/resources/variants/cartesio_0.8.inst.cfg b/resources/variants/cartesio_0.8.inst.cfg index a309c47424..348595aa54 100644 --- a/resources/variants/cartesio_0.8.inst.cfg +++ b/resources/variants/cartesio_0.8.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.8 mm -version = 3 +version = 4 definition = cartesio [metadata] diff --git a/resources/variants/fabtotum_hyb35.inst.cfg b/resources/variants/fabtotum_hyb35.inst.cfg index d96189e88e..fa9133129a 100644 --- a/resources/variants/fabtotum_hyb35.inst.cfg +++ b/resources/variants/fabtotum_hyb35.inst.cfg @@ -1,6 +1,6 @@ [general] name = Hybrid 0.35 mm -version = 3 +version = 4 definition = fabtotum [metadata] diff --git a/resources/variants/fabtotum_lite04.inst.cfg b/resources/variants/fabtotum_lite04.inst.cfg index 0309b81733..c35beba052 100644 --- a/resources/variants/fabtotum_lite04.inst.cfg +++ b/resources/variants/fabtotum_lite04.inst.cfg @@ -1,6 +1,6 @@ [general] name = Lite 0.4 mm -version = 3 +version = 4 definition = fabtotum [metadata] diff --git a/resources/variants/fabtotum_lite06.inst.cfg b/resources/variants/fabtotum_lite06.inst.cfg index c92e621bd2..6d91977a24 100644 --- a/resources/variants/fabtotum_lite06.inst.cfg +++ b/resources/variants/fabtotum_lite06.inst.cfg @@ -1,6 +1,6 @@ [general] name = Lite 0.6 mm -version = 3 +version = 4 definition = fabtotum [metadata] diff --git a/resources/variants/fabtotum_pro02.inst.cfg b/resources/variants/fabtotum_pro02.inst.cfg index 29d245a24a..ead17fc1b1 100644 --- a/resources/variants/fabtotum_pro02.inst.cfg +++ b/resources/variants/fabtotum_pro02.inst.cfg @@ -1,6 +1,6 @@ [general] name = Pro 0.2 mm -version = 3 +version = 4 definition = fabtotum [metadata] diff --git a/resources/variants/fabtotum_pro04.inst.cfg b/resources/variants/fabtotum_pro04.inst.cfg index 42be71b89d..c6d8c9b082 100644 --- a/resources/variants/fabtotum_pro04.inst.cfg +++ b/resources/variants/fabtotum_pro04.inst.cfg @@ -1,6 +1,6 @@ [general] name = Pro 0.4 mm -version = 3 +version = 4 definition = fabtotum [metadata] diff --git a/resources/variants/fabtotum_pro06.inst.cfg b/resources/variants/fabtotum_pro06.inst.cfg index 9c17d83f47..ee7ec5eea6 100644 --- a/resources/variants/fabtotum_pro06.inst.cfg +++ b/resources/variants/fabtotum_pro06.inst.cfg @@ -1,6 +1,6 @@ [general] name = Pro 0.6 mm -version = 3 +version = 4 definition = fabtotum [metadata] diff --git a/resources/variants/fabtotum_pro08.inst.cfg b/resources/variants/fabtotum_pro08.inst.cfg index 2fc5507024..cd226056eb 100644 --- a/resources/variants/fabtotum_pro08.inst.cfg +++ b/resources/variants/fabtotum_pro08.inst.cfg @@ -1,6 +1,6 @@ [general] name = Pro 0.8 mm -version = 3 +version = 4 definition = fabtotum [metadata] diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_025_e3d.inst.cfg index 53e6a14b23..eed2123e25 100644 --- a/resources/variants/gmax15plus_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_025_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.25mm E3D (Difficult) -version = 3 +version = 4 definition = gmax15plus [metadata] diff --git a/resources/variants/gmax15plus_04_e3d.inst.cfg b/resources/variants/gmax15plus_04_e3d.inst.cfg index a0b0d58b92..4dc9a9ffdd 100644 --- a/resources/variants/gmax15plus_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_04_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.4mm E3D -version = 3 +version = 4 definition = gmax15plus [metadata] diff --git a/resources/variants/gmax15plus_05_e3d.inst.cfg b/resources/variants/gmax15plus_05_e3d.inst.cfg index 333ab55f81..d7eeb44096 100644 --- a/resources/variants/gmax15plus_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_05_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.5mm E3D (Default) -version = 3 +version = 4 definition = gmax15plus [metadata] diff --git a/resources/variants/gmax15plus_05_jhead.inst.cfg b/resources/variants/gmax15plus_05_jhead.inst.cfg index 51902ffa0c..e146b31ae7 100644 --- a/resources/variants/gmax15plus_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_05_jhead.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.5mm J-Head -version = 3 +version = 4 definition = gmax15plus [metadata] diff --git a/resources/variants/gmax15plus_06_e3d.inst.cfg b/resources/variants/gmax15plus_06_e3d.inst.cfg index 3452e5e81f..a4de943b4c 100644 --- a/resources/variants/gmax15plus_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_06_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.6mm E3D -version = 3 +version = 4 definition = gmax15plus [metadata] diff --git a/resources/variants/gmax15plus_08_e3d.inst.cfg b/resources/variants/gmax15plus_08_e3d.inst.cfg index cdee755efc..163fbf0639 100644 --- a/resources/variants/gmax15plus_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_08_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.8mm E3D -version = 3 +version = 4 definition = gmax15plus [metadata] diff --git a/resources/variants/gmax15plus_10_jhead.inst.cfg b/resources/variants/gmax15plus_10_jhead.inst.cfg index ee60c71cc2..519a432423 100644 --- a/resources/variants/gmax15plus_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_10_jhead.inst.cfg @@ -1,6 +1,6 @@ [general] name = 1.0mm J-Head -version = 3 +version = 4 definition = gmax15plus [metadata] diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg index 002af1a0c5..f972c5d72c 100644 --- a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.25mm E3D (Difficult) -version = 3 +version = 4 definition = gmax15plus_dual [metadata] diff --git a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg index a98637e9e1..0be4501ecb 100644 --- a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.4mm E3D -version = 3 +version = 4 definition = gmax15plus_dual [metadata] diff --git a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg index dc7d711043..c80ed97be7 100644 --- a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.5mm E3D (Default) -version = 3 +version = 4 definition = gmax15plus_dual [metadata] diff --git a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg index fc4f17d057..0c2c8de793 100644 --- a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.5mm J-Head -version = 3 +version = 4 definition = gmax15plus_dual [metadata] diff --git a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg index 506f2df06e..ab7080e929 100644 --- a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.6mm E3D -version = 3 +version = 4 definition = gmax15plus_dual [metadata] diff --git a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg index d008df70f6..bd031e430a 100644 --- a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg +++ b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.8mm E3D -version = 3 +version = 4 definition = gmax15plus_dual [metadata] diff --git a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg index 825810997e..f81a2d5d39 100644 --- a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg +++ b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg @@ -1,6 +1,6 @@ [general] name = 1.0mm J-Head -version = 3 +version = 4 definition = gmax15plus_dual [metadata] diff --git a/resources/variants/imade3d_jellybox_0.4.inst.cfg b/resources/variants/imade3d_jellybox_0.4.inst.cfg index 99b55866c7..5f696425a6 100644 --- a/resources/variants/imade3d_jellybox_0.4.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.4 mm -version = 3 +version = 4 definition = imade3d_jellybox [metadata] diff --git a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg index 890c394a36..410a0fee0a 100644 --- a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg +++ b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.4 mm 2-fans -version = 3 +version = 4 definition = imade3d_jellybox [metadata] diff --git a/resources/variants/ultimaker2_0.25.inst.cfg b/resources/variants/ultimaker2_0.25.inst.cfg index c4d778e5cf..931bddafe2 100644 --- a/resources/variants/ultimaker2_0.25.inst.cfg +++ b/resources/variants/ultimaker2_0.25.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.25 mm -version = 3 +version = 4 definition = ultimaker2 [metadata] diff --git a/resources/variants/ultimaker2_0.4.inst.cfg b/resources/variants/ultimaker2_0.4.inst.cfg index 2ce766a1ac..b65ac26483 100644 --- a/resources/variants/ultimaker2_0.4.inst.cfg +++ b/resources/variants/ultimaker2_0.4.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.4 mm -version = 3 +version = 4 definition = ultimaker2 [metadata] diff --git a/resources/variants/ultimaker2_0.6.inst.cfg b/resources/variants/ultimaker2_0.6.inst.cfg index 0c5bdca240..db4f21a3e8 100644 --- a/resources/variants/ultimaker2_0.6.inst.cfg +++ b/resources/variants/ultimaker2_0.6.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.6 mm -version = 3 +version = 4 definition = ultimaker2 [metadata] diff --git a/resources/variants/ultimaker2_0.8.inst.cfg b/resources/variants/ultimaker2_0.8.inst.cfg index fd11520eca..f9117aa5d5 100644 --- a/resources/variants/ultimaker2_0.8.inst.cfg +++ b/resources/variants/ultimaker2_0.8.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.8 mm -version = 3 +version = 4 definition = ultimaker2 [metadata] diff --git a/resources/variants/ultimaker2_extended_0.25.inst.cfg b/resources/variants/ultimaker2_extended_0.25.inst.cfg index b8a31641e3..8efa86af23 100644 --- a/resources/variants/ultimaker2_extended_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.25.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.25 mm -version = 3 +version = 4 definition = ultimaker2_extended [metadata] diff --git a/resources/variants/ultimaker2_extended_0.4.inst.cfg b/resources/variants/ultimaker2_extended_0.4.inst.cfg index dbceac2890..3b5f99c4f6 100644 --- a/resources/variants/ultimaker2_extended_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.4.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.4 mm -version = 3 +version = 4 definition = ultimaker2_extended [metadata] diff --git a/resources/variants/ultimaker2_extended_0.6.inst.cfg b/resources/variants/ultimaker2_extended_0.6.inst.cfg index 6fbb489160..184f08c876 100644 --- a/resources/variants/ultimaker2_extended_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.6.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.6 mm -version = 3 +version = 4 definition = ultimaker2_extended [metadata] diff --git a/resources/variants/ultimaker2_extended_0.8.inst.cfg b/resources/variants/ultimaker2_extended_0.8.inst.cfg index 94b38de8f2..8e87bdd230 100644 --- a/resources/variants/ultimaker2_extended_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_0.8.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.8 mm -version = 3 +version = 4 definition = ultimaker2_extended [metadata] diff --git a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg index 89916470bb..c2dcd1ea31 100644 --- a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.25 mm -version = 3 +version = 4 definition = ultimaker2_extended_plus [metadata] diff --git a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg index 0de416da11..0a85b710b7 100644 --- a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.4 mm -version = 3 +version = 4 definition = ultimaker2_extended_plus [metadata] diff --git a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg index 4e6ace5a59..b47dc55a6b 100644 --- a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.6 mm -version = 3 +version = 4 definition = ultimaker2_extended_plus [metadata] diff --git a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg index 7540d5783a..dca992e45e 100644 --- a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.8 mm -version = 3 +version = 4 definition = ultimaker2_extended_plus [metadata] diff --git a/resources/variants/ultimaker2_plus_0.25.inst.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg index d59476a4f7..45168fcc5e 100644 --- a/resources/variants/ultimaker2_plus_0.25.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.25 mm -version = 3 +version = 4 definition = ultimaker2_plus [metadata] diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg index a188d10d4a..27a9aad065 100644 --- a/resources/variants/ultimaker2_plus_0.4.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.4 mm -version = 3 +version = 4 definition = ultimaker2_plus [metadata] diff --git a/resources/variants/ultimaker2_plus_0.6.inst.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg index b3aad334c3..5fe0b91ed1 100644 --- a/resources/variants/ultimaker2_plus_0.6.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.6 mm -version = 3 +version = 4 definition = ultimaker2_plus [metadata] diff --git a/resources/variants/ultimaker2_plus_0.8.inst.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg index 3c5dec79f6..316a0270cd 100644 --- a/resources/variants/ultimaker2_plus_0.8.inst.cfg +++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg @@ -1,6 +1,6 @@ [general] name = 0.8 mm -version = 3 +version = 4 definition = ultimaker2_plus [metadata] diff --git a/resources/variants/ultimaker3_aa0.25.inst.cfg b/resources/variants/ultimaker3_aa0.25.inst.cfg index 447bf0e49c..2f1b93c627 100644 --- a/resources/variants/ultimaker3_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_aa0.25.inst.cfg @@ -1,6 +1,6 @@ [general] name = AA 0.25 -version = 3 +version = 4 definition = ultimaker3 [metadata] diff --git a/resources/variants/ultimaker3_aa0.8.inst.cfg b/resources/variants/ultimaker3_aa0.8.inst.cfg index 97ee3587cf..025c346377 100644 --- a/resources/variants/ultimaker3_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_aa0.8.inst.cfg @@ -1,6 +1,6 @@ [general] name = AA 0.8 -version = 3 +version = 4 definition = ultimaker3 [metadata] diff --git a/resources/variants/ultimaker3_aa04.inst.cfg b/resources/variants/ultimaker3_aa04.inst.cfg index 0e0187e4df..84b137df60 100644 --- a/resources/variants/ultimaker3_aa04.inst.cfg +++ b/resources/variants/ultimaker3_aa04.inst.cfg @@ -1,6 +1,6 @@ [general] name = AA 0.4 -version = 3 +version = 4 definition = ultimaker3 [metadata] diff --git a/resources/variants/ultimaker3_bb0.8.inst.cfg b/resources/variants/ultimaker3_bb0.8.inst.cfg index f80fa05d1d..2c2a16f97f 100644 --- a/resources/variants/ultimaker3_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_bb0.8.inst.cfg @@ -1,6 +1,6 @@ [general] name = BB 0.8 -version = 3 +version = 4 definition = ultimaker3 [metadata] diff --git a/resources/variants/ultimaker3_bb04.inst.cfg b/resources/variants/ultimaker3_bb04.inst.cfg index 91e70f9f98..5eb54c1051 100644 --- a/resources/variants/ultimaker3_bb04.inst.cfg +++ b/resources/variants/ultimaker3_bb04.inst.cfg @@ -1,6 +1,6 @@ [general] name = BB 0.4 -version = 3 +version = 4 definition = ultimaker3 [metadata] diff --git a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg index b06ec0830b..6e61372453 100644 --- a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg @@ -1,6 +1,6 @@ [general] name = AA 0.25 -version = 3 +version = 4 definition = ultimaker3_extended [metadata] diff --git a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg index 149b832514..ea2e92478a 100644 --- a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg @@ -1,6 +1,6 @@ [general] name = AA 0.8 -version = 3 +version = 4 definition = ultimaker3_extended [metadata] diff --git a/resources/variants/ultimaker3_extended_aa04.inst.cfg b/resources/variants/ultimaker3_extended_aa04.inst.cfg index 8a2f061224..e653616c89 100644 --- a/resources/variants/ultimaker3_extended_aa04.inst.cfg +++ b/resources/variants/ultimaker3_extended_aa04.inst.cfg @@ -1,6 +1,6 @@ [general] name = AA 0.4 -version = 3 +version = 4 definition = ultimaker3_extended [metadata] diff --git a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg index 541034f119..e47efc1951 100644 --- a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg @@ -1,6 +1,6 @@ [general] name = BB 0.8 -version = 3 +version = 4 definition = ultimaker3_extended [metadata] diff --git a/resources/variants/ultimaker3_extended_bb04.inst.cfg b/resources/variants/ultimaker3_extended_bb04.inst.cfg index 5b35351312..f9cfff1d66 100644 --- a/resources/variants/ultimaker3_extended_bb04.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb04.inst.cfg @@ -1,6 +1,6 @@ [general] name = BB 0.4 -version = 3 +version = 4 definition = ultimaker3_extended [metadata] From 6ae96949985a47aa1b649f250bb006344d0cd80f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 5 Apr 2018 14:16:29 +0200 Subject: [PATCH 20/83] Add CuraPackageManager --- cura/CuraApplication.py | 9 ++ cura/CuraPackageManager.py | 190 +++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 cura/CuraPackageManager.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 42f169ad0c..56d9dfcc87 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -233,6 +233,7 @@ class CuraApplication(QtApplication): self._simple_mode_settings_manager = None self._cura_scene_controller = None self._machine_error_checker = None + self._cura_package_manager = None self._additional_components = {} # Components to add to certain areas in the interface @@ -649,6 +650,10 @@ class CuraApplication(QtApplication): container_registry = ContainerRegistry.getInstance() + from cura.CuraPackageManager import CuraPackageManager + self._cura_package_manager = CuraPackageManager(self) + self._cura_package_manager.initialize() + Logger.log("i", "Initializing variant manager") self._variant_manager = VariantManager(container_registry) self._variant_manager.initialize() @@ -786,6 +791,10 @@ class CuraApplication(QtApplication): self._extruder_manager = ExtruderManager.createExtruderManager() return self._extruder_manager + @pyqtSlot(result = QObject) + def getCuraPackageManager(self, *args): + return self._cura_package_manager + def getVariantManager(self, *args): return self._variant_manager diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py new file mode 100644 index 0000000000..233e93110b --- /dev/null +++ b/cura/CuraPackageManager.py @@ -0,0 +1,190 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from typing import Optional, Dict +import json +import os +import re +import shutil +import urllib.parse +import zipfile + +from PyQt5.QtCore import pyqtSlot, QObject, QUrl + +from UM.Logger import Logger +from UM.MimeTypeDatabase import MimeTypeDatabase +from UM.Settings.InstanceContainer import InstanceContainer +from UM.Resources import Resources + + +class CuraPackageManager(QObject): + + # The prefix that's added to all files for an installed package to avoid naming conflicts with user created + # files. + PREFIX_PLACE_HOLDER = "-CP;" + + def __init__(self, parent = None): + super().__init__(parent) + + self._application = parent + self._registry = self._application.getContainerRegistry() + + # The JSON file that keeps track of all installed packages. + self._package_management_file_path = os.path.join(os.path.abspath(Resources.getDataStoragePath()), + "packages.json") + self._installed_package_dict = {} # type: Dict[str, dict] + + self._semantic_version_regex = re.compile(r"^[0-9]+(.[0-9]+)+$") + + def initialize(self): + # Load the package management file if exists + if os.path.exists(self._package_management_file_path): + with open(self._package_management_file_path, "r", encoding = "utf-8") as f: + self._installed_package_dict = json.loads(f.read(), encoding = "utf-8") + Logger.log("i", "Package management file %s is loaded", self._package_management_file_path) + + def _saveManagementData(self): + with open(self._package_management_file_path, "w", encoding = "utf-8") as f: + json.dump(self._installed_package_dict, f) + Logger.log("i", "Package management file %s is saved", self._package_management_file_path) + + @pyqtSlot(str, result = bool) + def isPackageFile(self, file_name: str): + extension = os.path.splitext(file_name)[1].strip(".") + if extension.lower() in ("curapackage",): + return True + return False + + # Checks the given package is installed. If so, return a dictionary that contains the package's information. + def getInstalledPackage(self, package_id: str) -> Optional[dict]: + return self._installed_package_dict.get(package_id) + + # Gets all installed packages + def getAllInstalledPackages(self) -> Dict[str, dict]: + return self._installed_package_dict + + # Installs the given package file. + @pyqtSlot(str) + def install(self, file_name: str) -> None: + file_url = QUrl(file_name) + file_name = file_url.toLocalFile() + + archive = zipfile.ZipFile(file_name) + + # Get package information + try: + with archive.open("package.json", "r") as f: + package_info_dict = json.loads(f.read(), encoding = "utf-8") + except Exception as e: + raise RuntimeError("Could not get package information from file '%s': %s" % (file_name, e)) + + # Check if it is installed + installed_package = self.getInstalledPackage(package_info_dict["package_id"]) + has_installed_version = installed_package is not None + + if has_installed_version: + # Remove the existing package first + Logger.log("i", "Another version of [%s] [%s] has already been installed, will overwrite it with version [%s]", + installed_package["package_id"], installed_package["package_version"], + package_info_dict["package_version"]) + self.remove(package_info_dict["package_id"]) + + # Install the package + self._installPackage(file_name, archive, package_info_dict) + + archive.close() + + def _installPackage(self, file_name: str, archive: zipfile.ZipFile, package_info_dict: dict): + from cura.CuraApplication import CuraApplication + + package_id = package_info_dict["package_id"] + package_type = package_info_dict["package_type"] + if package_type == "material": + package_root_dir = Resources.getPath(CuraApplication.ResourceTypes.MaterialInstanceContainer) + material_class = self._registry.getContainerForMimeType(MimeTypeDatabase.getMimeType("application/x-ultimaker-material-profile")) + file_extension = self._registry.getMimeTypeForContainer(material_class).preferredSuffix + elif package_type == "quality": + package_root_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer) + file_extension = "." + self._registry.getMimeTypeForContainer(InstanceContainer).preferredSuffix + else: + raise RuntimeError("Unexpected package type [%s] in file [%s]" % (package_type, file_name)) + + Logger.log("i", "Prepare package directory [%s]", package_root_dir) + + # get package directory + package_installation_path = os.path.join(os.path.abspath(package_root_dir), package_id) + if os.path.exists(package_installation_path): + Logger.log("w", "Path [%s] exists, removing it.", package_installation_path) + if os.path.isfile(package_installation_path): + os.remove(package_installation_path) + else: + shutil.rmtree(package_installation_path, ignore_errors = True) + + os.makedirs(package_installation_path, exist_ok = True) + + # Only extract the needed files + for file_info in archive.infolist(): + if file_info.is_dir(): + continue + + file_name = os.path.basename(file_info.filename) + if not file_name.endswith(file_extension): + continue + + # Generate new file name and save to file + new_file_name = urllib.parse.quote_plus(self.PREFIX_PLACE_HOLDER + package_id + "-" + file_name) + new_file_path = os.path.join(package_installation_path, new_file_name) + with archive.open(file_info.filename, "r") as f: + content = f.read() + with open(new_file_path, "wb") as f2: + f2.write(content) + + Logger.log("i", "Installed package file to [%s]", new_file_name) + + self._installed_package_dict[package_id] = package_info_dict + self._saveManagementData() + Logger.log("i", "Package [%s] has been installed", package_id) + + # Removes a package with the given package ID. + @pyqtSlot(str) + def remove(self, package_id: str) -> None: + from cura.CuraApplication import CuraApplication + + package_info_dict = self.getInstalledPackage(package_id) + if package_info_dict is None: + Logger.log("w", "Attempt to remove non-existing package [%s], do nothing.", package_id) + return + + package_type = package_info_dict["package_type"] + if package_type == "material": + package_root_dir = Resources.getPath(CuraApplication.ResourceTypes.MaterialInstanceContainer) + elif package_type == "quality": + package_root_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer) + else: + raise RuntimeError("Unexpected package type [%s] for package [%s]" % (package_type, package_id)) + + # Get package directory + package_installation_path = os.path.join(os.path.abspath(package_root_dir), package_id) + if os.path.exists(package_installation_path): + if os.path.isfile(package_installation_path): + os.remove(package_installation_path) + else: + shutil.rmtree(package_installation_path, ignore_errors=True) + + if package_id in self._installed_package_dict: + del self._installed_package_dict[package_id] + self._saveManagementData() + Logger.log("i", "Package [%s] has been removed.", package_id) + + # Gets package information from the given file. + def getPackageInfo(self, file_name: str) -> dict: + archive = zipfile.ZipFile(file_name) + try: + # All information is in package.json + with archive.open("package.json", "r") as f: + package_info_dict = json.loads(f.read().decode("utf-8")) + return package_info_dict + except Exception as e: + raise RuntimeError("Could not get package information from file '%s': %s" % (e, file_name)) + finally: + archive.close() From 1737267dfd65aac5fc9943ac2edb695e9f11c922 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 5 Apr 2018 14:17:42 +0200 Subject: [PATCH 21/83] Accept drag-and-drop for curapackage files --- resources/qml/Cura.qml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index c4ebb790e8..0e68d0c40a 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -345,6 +345,10 @@ UM.MainWindow pluginInstallDialog.open(); return; } + else if (CuraApplication.getCuraPackageManager().isPackageFile(drop.urls[0])) + { + CuraApplication.getCuraPackageManager().install(drop.urls[0]); + } } openDialog.handleOpenFileUrls(drop.urls); From e36ef583b7778d158c3dea97c328ff13ec12cc38 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 4 Apr 2018 11:55:46 +0200 Subject: [PATCH 22/83] Minor changes and cleanup --- cura/CuraApplication.py | 9 +++++++-- cura/Settings/CuraContainerRegistry.py | 1 - 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 56d9dfcc87..6fbf7b79be 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -534,7 +534,9 @@ class CuraApplication(QtApplication): self._plugins_loaded = True @classmethod - def addCommandLineOptions(self, parser, parsed_command_line = {}): + def addCommandLineOptions(cls, parser, parsed_command_line = None): + if parsed_command_line is None: + parsed_command_line = {} super().addCommandLineOptions(parser, parsed_command_line = parsed_command_line) parser.add_argument("file", nargs="*", help="Files to load after starting the application.") parser.add_argument("--single-instance", action="store_true", default=False) @@ -591,7 +593,10 @@ class CuraApplication(QtApplication): # This should be called directly before creating an instance of CuraApplication. # \returns \type{bool} True if the whole Cura app should continue running. @classmethod - def preStartUp(cls, parser = None, parsed_command_line = {}): + def preStartUp(cls, parser = None, parsed_command_line = None): + if parsed_command_line is None: + parsed_command_line = {} + # Peek the arguments and look for the 'single-instance' flag. if not parser: parser = argparse.ArgumentParser(prog = "cura", add_help = False) # pylint: disable=bad-whitespace diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index dbbbdc0718..751ca40c58 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -2,7 +2,6 @@ # Cura is released under the terms of the LGPLv3 or higher. import os -import os.path import re import configparser From dc00156410a4c50599ee9f088a8f1694027a41b8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 5 Apr 2018 15:33:07 +0200 Subject: [PATCH 23/83] CURA-5035 Added thumbnails and detail view --- plugins/Toolbox/resources/images/logobot.svg | 161 ++++++++++++++++++ plugins/Toolbox/resources/qml/Toolbox.qml | 6 +- .../resources/qml/ToolboxDetailsPage.qml | 11 +- .../qml/ToolboxDownloadsGridTile.qml | 7 + .../resources/qml/ToolboxRestartDialog.qml | 3 - plugins/Toolbox/src/Toolbox.py | 17 +- 6 files changed, 187 insertions(+), 18 deletions(-) create mode 100644 plugins/Toolbox/resources/images/logobot.svg diff --git a/plugins/Toolbox/resources/images/logobot.svg b/plugins/Toolbox/resources/images/logobot.svg new file mode 100644 index 0000000000..8234f66887 --- /dev/null +++ b/plugins/Toolbox/resources/images/logobot.svg @@ -0,0 +1,161 @@ + + + + +logo +Created with Sketch. + + + + + + + + + + + + diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index eb56cf02b1..3803dff2ab 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -17,10 +17,10 @@ Window property bool dataReady: manager.dataReady title: catalog.i18nc("@title:tab", "Toolbox"); modality: Qt.ApplicationModal - width: 800 * screenScaleFactor + width: 960 * screenScaleFactor height: 640 * screenScaleFactor - minimumWidth: 800 * screenScaleFactor - maximumWidth: 800 * screenScaleFactor + minimumWidth: 960 * screenScaleFactor + maximumWidth: 960 * screenScaleFactor minimumHeight: 350 * screenScaleFactor color: UM.Theme.getColor("sidebar") Item diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml index a57a6de90c..2f152e5859 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml @@ -72,12 +72,13 @@ Item right: parent.right } height: UM.Theme.getSize("base_unit").height * 12 - Rectangle + Image { id: thumbnail width: UM.Theme.getSize("toolbox_thumbnail_medium").width height: UM.Theme.getSize("toolbox_thumbnail_medium").height - color: "grey" + fillMode: Image.PreserveAspectFit + source: manager.detailData["icon_url"] || "../images/logobot.svg" anchors { top: parent.top @@ -99,21 +100,21 @@ Item spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) Label { - text: "DSM" + text: manager.detailData["type"] == "material" ? manager.detailData["author"] : manager.detailData["name"] font: UM.Theme.getFont("large") wrapMode: Text.WordWrap width: parent.width } Label { - text: "Sets the horizontal and vertical alignment of the text within the Text items width and height. By default, the text is vertically aligned to the top." + text: manager.detailData["description"] font: UM.Theme.getFont("default") wrapMode: Text.WordWrap width: parent.width } Label { - text: "Author: " + "DSM" + text: "Author: " + manager.detailData["author"]["name"] font: UM.Theme.getFont("small") wrapMode: Text.WordWrap width: parent.width diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index c3795daf51..9cdcb4e400 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -26,6 +26,13 @@ Item height: UM.Theme.getSize("toolbox_thumbnail_small").height color: "white" border.width: 1 + Image { + anchors.centerIn: parent + width: UM.Theme.getSize("toolbox_thumbnail_small").width - 26 + height: UM.Theme.getSize("toolbox_thumbnail_small").height - 26 + fillMode: Image.PreserveAspectFit + source: model.icon_url || "../images/logobot.svg" + } } Column { diff --git a/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml b/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml index 08c5e759b8..ab95bddef6 100644 --- a/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml @@ -6,9 +6,6 @@ import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 - -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - import UM 1.1 as UM Window { diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index b2b1f8e53f..bca58ac4a4 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -302,7 +302,7 @@ class Toolbox(QObject, Extension): self._detail_view = bool self.detailViewChanged.emit() - @pyqtProperty(str, fset = setDetailView, notify = detailViewChanged) + @pyqtProperty(bool, fset = setDetailView, notify = detailViewChanged) def detailView(self): return self._detail_view @@ -311,13 +311,13 @@ class Toolbox(QObject, Extension): def setDetailData(self, id): if not self._packages_model: return - for plugin in self._plugins_model.items: - if plugin.id is id: - print(plugin) - self._detail_view = plugin + for package in self._packages_model.items: + if package["id"] == id: + print(package) + self._detail_data = package self.detailViewChanged.emit() - @pyqtProperty(QObject, notify = detailViewChanged) + @pyqtProperty("QVariantMap", notify = detailViewChanged) def detailData(self): return self._detail_data @@ -336,7 +336,10 @@ class Toolbox(QObject, Extension): for item in self._packages_metadata: if item["id"] == plugin["id"]: plugin["update_url"] = item["file_location"] - + if self._current_view == "plugins": + self.filterPackagesByType("plugin") + elif self._current_view == "materials": + self.filterPackagesByType("material") return self._plugins_model @pyqtProperty(QObject, notify = packagesMetadataChanged) From 91001455ade8e42d740a11569ad94369b72441c8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 6 Apr 2018 17:26:25 +0200 Subject: [PATCH 24/83] Improved structure and enabled display by author --- plugins/Toolbox/resources/qml/Toolbox.qml | 41 +++--- .../resources/qml/ToolboxAuthorPage.qml | 138 ++++++++++++++++++ .../resources/qml/ToolboxDetailList.qml | 36 +++++ ...xDetailsPage.qml => ToolboxDetailPage.qml} | 47 +----- ...xDetailsTile.qml => ToolboxDetailTile.qml} | 12 +- .../qml/ToolboxDownloadsGridTile.qml | 19 ++- .../Toolbox/resources/qml/ToolboxHeader.qml | 16 +- ...lboxLoading.qml => ToolboxLoadingPage.qml} | 0 plugins/Toolbox/src/Toolbox.py | 92 ++++++++++-- 9 files changed, 310 insertions(+), 91 deletions(-) create mode 100644 plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml create mode 100644 plugins/Toolbox/resources/qml/ToolboxDetailList.qml rename plugins/Toolbox/resources/qml/{ToolboxDetailsPage.qml => ToolboxDetailPage.qml} (75%) rename plugins/Toolbox/resources/qml/{ToolboxDetailsTile.qml => ToolboxDetailTile.qml} (90%) rename plugins/Toolbox/resources/qml/{ToolboxLoading.qml => ToolboxLoadingPage.qml} (100%) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 3803dff2ab..cfe768e1d1 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -25,11 +25,10 @@ Window color: UM.Theme.getColor("sidebar") Item { - id: view anchors.fill: parent ToolboxHeader { - id: topBar + id: header } Rectangle { @@ -38,47 +37,49 @@ Window color: "transparent" anchors { - top: topBar.bottom - bottom: bottomBar.top + top: header.bottom + bottom: footer.top } - ToolboxLoading + // TODO: This could be improved using viewFilter instead of viewCategory + ToolboxLoadingPage { - id: loading - visible: !dataReady && manager.currentView != "installed" + id: viewLoading + visible: manager.viewCategory != "installed" && !dataReady + // TODO: Replace !dataReady with manager.viewPage == "loading" } ToolboxDownloadsPage { id: viewDownloads - visible: manager.currentView != "installed" && !manager.detailView + visible: manager.viewCategory != "installed" && manager.viewPage == "overview" } - ToolboxDetailsPage + ToolboxDetailPage { id: viewDetail - visible: manager.currentView != "installed" && manager.detailView + visible: manager.viewCategory != "installed" && manager.viewPage == "detail" + } + ToolboxAuthorPage + { + id: viewAuthor + visible: manager.viewCategory != "installed" && manager.viewPage == "author" } ToolboxInstalledPage { id: installedPluginList - visible: dataReady && manager.currentView == "installed" + visible: manager.viewCategory == "installed" && dataReady + // TODO: Replace !dataReady with manager.viewPage == "loading" } } ToolboxShadow { - anchors - { - top: topBar.bottom - } + anchors.top: header.bottom } ToolboxFooter { - id: bottomBar + id: footer } ToolboxShadow { - anchors - { - top: bottomBar.top - } + anchors.top: footer.top } UM.I18nCatalog { id: catalog; name: "cura" } diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml new file mode 100644 index 0000000000..200cac33fa --- /dev/null +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -0,0 +1,138 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles + +Item +{ + id: base + anchors.fill: parent + Item + { + id: sidebar + height: parent.height + width: UM.Theme.getSize("base_unit").width * 6 + anchors + { + top: parent.top + left: parent.left + topMargin: UM.Theme.getSize("double_margin").height + leftMargin: UM.Theme.getSize("default_margin").width + rightMargin: UM.Theme.getSize("default_margin").width + } + Button + { + text: "Back" + UM.RecolorImage + { + id: backArrow + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + 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("arrow_left") + } + width: UM.Theme.getSize("base_unit").width * 4 + height: UM.Theme.getSize("base_unit").height * 2 + onClicked: + { + manager.viewPage = "overview" + manager.filterPackages("type", manager.viewCategory) + } + style: ButtonStyle + { + background: Rectangle + { + color: "transparent" + } + label: Label + { + text: control.text + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default_bold") + horizontalAlignment: Text.AlignRight + width: control.width + } + } + } + } + + Rectangle + { + id: header + anchors + { + left: sidebar.right + right: parent.right + } + height: UM.Theme.getSize("base_unit").height * 12 + Image + { + id: thumbnail + width: UM.Theme.getSize("toolbox_thumbnail_medium").width + height: UM.Theme.getSize("toolbox_thumbnail_medium").height + fillMode: Image.PreserveAspectFit + source: manager.detailData["icon_url"] || "../images/logobot.svg" + anchors + { + top: parent.top + left: parent.left + leftMargin: UM.Theme.getSize("double_margin").width + topMargin: UM.Theme.getSize("double_margin").height + } + } + Column + { + anchors + { + top: thumbnail.top + left: thumbnail.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("double_margin").width + } + spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) + Label + { + text: manager.detailData["name"] + font: UM.Theme.getFont("large") + wrapMode: Text.WordWrap + width: parent.width + } + Label + { + text: "HELLO THIS IS AN AUTHOR PAGE" + font: UM.Theme.getFont("default") + wrapMode: Text.WordWrap + width: parent.width + } + Label + { + text: "Author: " + manager.detailData["author"]["name"] + font: UM.Theme.getFont("small") + wrapMode: Text.WordWrap + width: parent.width + // TODO: Add mail icon. + } + } + } + ToolboxDetailList { + anchors + { + right: header.right + top: header.bottom + left: header.left + bottom: base.bottom + } + } +} diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml new file mode 100644 index 0000000000..fe65eed7c4 --- /dev/null +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -0,0 +1,36 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +Item +{ + id: base + anchors + { + topMargin: UM.Theme.getSize("default_margin").height + bottomMargin: UM.Theme.getSize("default_margin").height + leftMargin: UM.Theme.getSize("double_margin").width + rightMargin: UM.Theme.getSize("double_margin").width + } + ScrollView + { + frameVisible: false + anchors.fill: base + style: UM.Theme.styles.scrollview + Column + { + height: childrenRect.height + spacing: UM.Theme.getSize("default_margin").height + Repeater + { + model: manager.packagesModel + delegate: ToolboxDetailTile {} + } + } + } +} diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml similarity index 75% rename from plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml rename to plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 2f152e5859..6054414405 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -44,7 +44,11 @@ Item } width: UM.Theme.getSize("base_unit").width * 4 height: UM.Theme.getSize("base_unit").height * 2 - onClicked: manager.detailView = false + onClicked: + { + manager.viewPage = "overview" + manager.filterPackages("type", manager.viewCategory) + } style: ButtonStyle { background: Rectangle @@ -100,7 +104,7 @@ Item spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) Label { - text: manager.detailData["type"] == "material" ? manager.detailData["author"] : manager.detailData["name"] + text: manager.detailData["name"] font: UM.Theme.getFont("large") wrapMode: Text.WordWrap width: parent.width @@ -122,11 +126,7 @@ Item } } } - - ScrollView - { - id: scroll - frameVisible: true + ToolboxDetailList { anchors { right: header.right @@ -134,38 +134,5 @@ Item left: header.left bottom: base.bottom } - height: parent.height - style: UM.Theme.styles.scrollview - - /* - ListView - { - id: contentColumn - spacing: UM.Theme.getSize("base_unit").height - height: childrenRect.height + (UM.Theme.getSize("double_margin").height * 2) - anchors - { - left: scroll.left - right: scroll.right - top: scroll.top - topMargin: UM.Theme.getSize("double_margin").height - bottomMargin: UM.Theme.getSize("double_margin").height - leftMargin: UM.Theme.getSize("double_margin").width - rightMargin: UM.Theme.getSize("double_margin").width - } - - ToolboxDetailsTile {} - ToolboxDetailsTile {} - ToolboxDetailsTile {} - ToolboxDetailsTile {} - ToolboxDetailsTile {} - ToolboxDetailsTile {} - ToolboxDetailsTile {} - ToolboxDetailsTile {} - ToolboxDetailsTile {} - ToolboxDetailsTile {} - ToolboxDetailsTile {} - } - */ } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailsTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml similarity index 90% rename from plugins/Toolbox/resources/qml/ToolboxDetailsTile.qml rename to plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index abe2cdf450..5671e95495 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailsTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -9,9 +9,9 @@ import UM 1.1 as UM Rectangle { - width: parent.width - height: childrenRect.height - color: "transparent" + width: base.width + height: UM.Theme.getSize("base_unit").height * 12 + color: "steelblue" Column { anchors @@ -27,7 +27,7 @@ Rectangle { width: parent.width height: UM.Theme.getSize("base_unit").height * 2 - text: "DSM Abrasive" + text: model.name wrapMode: Text.WordWrap color: UM.Theme.getColor("text") font: UM.Theme.getFont("default_bold") @@ -35,10 +35,10 @@ Rectangle Label { width: parent.width - text: "DSM abrasive material provides extra stiffness. It’s suitable for printing \"Functional prototypes\" and \"End parts\"." + text: model.description wrapMode: Text.WordWrap color: UM.Theme.getColor("text") - font: UM.Theme.getFont("normal") + font: UM.Theme.getFont("default") } } Rectangle diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 9cdcb4e400..e8b4f2453f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -50,8 +50,7 @@ Item Label { id: info - text: - { + text: { if (model.description.length > 50) { return model.description.substring(0, 50) + "..." @@ -69,9 +68,19 @@ Item { anchors.fill: parent onClicked: { - console.log(model.id) - manager.detailView = true - manager.setDetailData(model.id) + if ( manager.viewCategory == "material" ) + { + console.log("filtering by " + model.author) + manager.viewSelection = model.author.name + manager.viewPage = "author" + manager.filterPackages("author", model.author) + } + else + { + manager.viewSelection = model.id + manager.viewPage = "detail" + manager.filterPackages("id", model.id) + } } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 2c097f275b..cedf95fda7 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -37,7 +37,7 @@ Rectangle { implicitHeight: 48 Rectangle { - visible: manager.currentView == "plugins" + visible: manager.viewCategory == "plugin" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom width: parent.width @@ -56,8 +56,8 @@ Rectangle { onClicked: { manager.filterPackagesByType("plugin") - manager.currentView = "plugins" - manager.detailView = false + manager.viewCategory = "plugin" + manager.viewPage = "overview" } } @@ -73,7 +73,7 @@ Rectangle { implicitHeight: 48 Rectangle { - visible: manager.currentView == "materials" + visible: manager.viewCategory == "material" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom width: parent.width @@ -92,8 +92,8 @@ Rectangle { onClicked: { manager.filterPackagesByType("material") - manager.currentView = "materials" - manager.detailView = false + manager.viewCategory = "material" + manager.viewPage = "overview" } } } @@ -111,7 +111,7 @@ Rectangle { implicitWidth: 96 implicitHeight: 48 Rectangle { - visible: manager.currentView == "installed" + visible: manager.viewCategory == "installed" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom width: parent.width @@ -127,6 +127,6 @@ Rectangle { horizontalAlignment: Text.AlignHCenter } } - onClicked: manager.currentView = "installed" + onClicked: manager.viewCategory = "installed" } } diff --git a/plugins/Toolbox/resources/qml/ToolboxLoading.qml b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml similarity index 100% rename from plugins/Toolbox/resources/qml/ToolboxLoading.qml rename to plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index bca58ac4a4..60e43b357e 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -46,10 +46,36 @@ class Toolbox(QObject, Extension): self._packages_metadata = [] # Stores the remote information of the packages self._packages_model = None # Model that list the remote available packages + + # These properties are for keeping track of the UI state: + # ---------------------------------------------------------------------- + + # View category defines which filter to use, and therefore effectively + # which category is currently being displayed. For example, possible + # values include "plugin" or "material", but also "installed". + # Formerly self._current_view. + self._view_category = "plugin" + + # View page defines which type of page layout to use. For example, + # possible values include "overview", "detail" or "author". + # Formerly self._detail_view. + self._view_page = "overview" + + # View selection defines what is currently selected and should be + # used in filtering. This could be an author name (if _view_page is set + # to "author" or a plugin name if it is set to "detail"). + self._view_selection = "" + + # For any view page above, self._packages_model can be filtered. + # For example: + # self._view_category = "material" + # if self._view_page == "author": + # filter with "author == self._view_selection" + # Nowadays can be 'plugins', 'materials' or 'installed' self._current_view = "plugins" self._detail_view = False - self._detail_data = {} + self._detail_data = {} # Extraneous since can just use the data prop of the model. self._restart_required = False @@ -283,13 +309,6 @@ class Toolbox(QObject, Extension): self.setDownloadProgress(0) self.setIsDownloading(False) - @pyqtSlot(str) - def filterPackagesByType(self, type): - if not self._packages_model: - return - self._packages_model.setFilter({"type": type}) - self.filterChanged.emit() - def setCurrentView(self, view = "plugins"): self._current_view = view self.viewChanged.emit() @@ -336,10 +355,11 @@ class Toolbox(QObject, Extension): for item in self._packages_metadata: if item["id"] == plugin["id"]: plugin["update_url"] = item["file_location"] - if self._current_view == "plugins": - self.filterPackagesByType("plugin") - elif self._current_view == "materials": - self.filterPackagesByType("material") + + # if self._current_view == "plugins": + # self.filterPackagesByType("plugin") + # elif self._current_view == "materials": + # self.filterPackagesByType("material") return self._plugins_model @pyqtProperty(QObject, notify = packagesMetadataChanged) @@ -447,3 +467,51 @@ class Toolbox(QObject, Extension): @pyqtSlot() def restart(self): CuraApplication.getInstance().windowClosed() + + + # Getter & Setter for self._view_category + def setViewCategory(self, category = "plugins"): + self._view_category = category + self.viewChanged.emit() + @pyqtProperty(str, fset = setViewCategory, notify = viewChanged) + def viewCategory(self): + return self._view_category + + # Getter & Setter for self._view_page + def setViewPage(self, page = "overview"): + self._view_page = page + self.viewChanged.emit() + @pyqtProperty(str, fset = setViewPage, notify = viewChanged) + def viewPage(self): + return self._view_page + + # Getter & Setter for self._view_selection + def setViewSelection(self, selection = ""): + self._view_selection = selection + self.viewChanged.emit() + @pyqtProperty(str, fset = setViewSelection, notify = viewChanged) + def viewSelection(self): + return self._view_selection + + + # Filtering + @pyqtSlot(str) + def filterPackagesByType(self, type): + if not self._packages_model: + return + self._packages_model.setFilter({"type": type}) + self.filterChanged.emit() + + @pyqtSlot(str, str) + def filterPackages(self, filterType, parameter): + if not self._packages_model: + return + self._packages_model.setFilter({filterType: parameter}) + self.filterChanged.emit() + + @pyqtSlot() + def unfilterPackages(self): + if not self._packages_model: + return + self._packages_model.setFilter({}) + self.filterChanged.emit() From 817b7249940fa0afe43164da90b746cd942b0f97 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 9 Apr 2018 15:55:56 +0200 Subject: [PATCH 25/83] Added author and material views --- .../resources/qml/ToolboxDetailList.qml | 8 +- .../resources/qml/ToolboxDetailPage.qml | 11 ++- .../resources/qml/ToolboxDetailTile.qml | 7 +- .../resources/qml/ToolboxDownloadsGrid.qml | 2 +- .../qml/ToolboxDownloadsGridTile.qml | 6 +- .../qml/ToolboxDownloadsShowcase.qml | 2 +- .../Toolbox/resources/qml/ToolboxHeader.qml | 6 +- plugins/Toolbox/src/AuthorsModel.py | 88 +++++++++++++++++++ plugins/Toolbox/src/CuraPackageModel.py | 15 ++-- plugins/Toolbox/src/Toolbox.py | 70 +++++++++++---- 10 files changed, 172 insertions(+), 43 deletions(-) create mode 100644 plugins/Toolbox/src/AuthorsModel.py diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index fe65eed7c4..ba772b343a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -12,10 +12,8 @@ Item id: base anchors { - topMargin: UM.Theme.getSize("default_margin").height - bottomMargin: UM.Theme.getSize("default_margin").height - leftMargin: UM.Theme.getSize("double_margin").width - rightMargin: UM.Theme.getSize("double_margin").width + topMargin: UM.Theme.getSize("double_margin").height + bottomMargin: UM.Theme.getSize("double_margin").height } ScrollView { @@ -24,6 +22,8 @@ Item style: UM.Theme.styles.scrollview Column { + anchors.right: base.right + anchors.rightMargin: UM.Theme.getSize("double_margin").width height: childrenRect.height spacing: UM.Theme.getSize("default_margin").height Repeater diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 6054414405..156c829767 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -11,6 +11,7 @@ import UM 1.1 as UM Item { + property var details: manager.packagesModel.items[0] id: base anchors.fill: parent Item @@ -82,7 +83,7 @@ Item width: UM.Theme.getSize("toolbox_thumbnail_medium").width height: UM.Theme.getSize("toolbox_thumbnail_medium").height fillMode: Image.PreserveAspectFit - source: manager.detailData["icon_url"] || "../images/logobot.svg" + source: details.icon_url || "../images/logobot.svg" anchors { top: parent.top @@ -104,21 +105,21 @@ Item spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) Label { - text: manager.detailData["name"] + text: details.name font: UM.Theme.getFont("large") wrapMode: Text.WordWrap width: parent.width } Label { - text: manager.detailData["description"] + text: details.description font: UM.Theme.getFont("default") wrapMode: Text.WordWrap width: parent.width } Label { - text: "Author: " + manager.detailData["author"]["name"] + text: "Author: " + details.author_name font: UM.Theme.getFont("small") wrapMode: Text.WordWrap width: parent.width @@ -131,8 +132,10 @@ Item { right: header.right top: header.bottom + left: header.left bottom: base.bottom + } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 5671e95495..cc4e61c55b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -9,9 +9,9 @@ import UM 1.1 as UM Rectangle { - width: base.width - height: UM.Theme.getSize("base_unit").height * 12 - color: "steelblue" + width: base.width - UM.Theme.getSize("double_margin").width + height: UM.Theme.getSize("base_unit").height * 8 + color: "transparent" Column { anchors @@ -20,7 +20,6 @@ Rectangle right: controls.left rightMargin: UM.Theme.getSize("default_margin").width top: parent.top - leftMargin: UM.Theme.getSize("default_margin").width topMargin: UM.Theme.getSize("default_margin").height } Label diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index b05963ecd1..45eedbedbd 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -34,7 +34,7 @@ Column Repeater { - model: manager.packagesModel + model: manager.viewCategory == "material" ? manager.authorsModel : manager.packagesModel delegate: ToolboxDownloadsGridTile { Layout.preferredWidth: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index e8b4f2453f..193857f756 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -70,16 +70,16 @@ Item onClicked: { if ( manager.viewCategory == "material" ) { - console.log("filtering by " + model.author) - manager.viewSelection = model.author.name + manager.viewSelection = model.name manager.viewPage = "author" - manager.filterPackages("author", model.author) + manager.filterPackages("author_name", model.name) } else { manager.viewSelection = model.id manager.viewPage = "detail" manager.filterPackages("id", model.id) + } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index c9a0babc5f..78a884c95d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -18,7 +18,7 @@ Column Label { id: heading - text: "Top Downloads" + text: "Showcase" width: parent.width color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index cedf95fda7..16c82866dc 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -55,7 +55,8 @@ Rectangle { } onClicked: { - manager.filterPackagesByType("plugin") + manager.filterPackages("type", "plugin") + manager.filterAuthors("type", "plugin") manager.viewCategory = "plugin" manager.viewPage = "overview" } @@ -91,7 +92,8 @@ Rectangle { } onClicked: { - manager.filterPackagesByType("material") + manager.filterPackages("type", "material") + manager.filterAuthors("type", "material") manager.viewCategory = "material" manager.viewPage = "overview" } diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py new file mode 100644 index 0000000000..2156534b31 --- /dev/null +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -0,0 +1,88 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import re +from typing import Dict + +from PyQt5.QtCore import Qt, pyqtProperty, pyqtSignal + +from UM.Qt.ListModel import ListModel + +## Model that holds cura packages. By setting the filter property the instances held by this model can be changed. +class AuthorsModel(ListModel): + NameRole = Qt.UserRole + 1 + EmailRole = Qt.UserRole + 2 + WebsiteRole = Qt.UserRole + 3 + TypeRole = Qt.UserRole + 4 + + def __init__(self, parent = None): + super().__init__(parent) + + self._authors_metadata = None + + self.addRoleName(AuthorsModel.NameRole, "name") + self.addRoleName(AuthorsModel.EmailRole, "email") + self.addRoleName(AuthorsModel.WebsiteRole, "website") + self.addRoleName(AuthorsModel.TypeRole, "type") + + # List of filters for queries. The result is the union of the each list of results. + self._filter = {} # type: Dict[str,str] + + def setMetaData(self, data): + self._authors_metadata = data + self._update() + + def _update(self): + items = [] + + for author in self._authors_metadata: + items.append({ + "name": author["name"], + "email": author["email"], + "website": author["website"], + "type": author["type"] + }) + + # Filter on all the key-word arguments. + for key, value in self._filter.items(): + if "*" in value: + key_filter = lambda candidate, key = key, value = value: self._matchRegExp(candidate, key, value) + else: + key_filter = lambda candidate, key = key, value = value: self._matchString(candidate, key, value) + items = filter(key_filter, items) + + # Execute all filters. + filtered_items = list(items) + + filtered_items.sort(key = lambda k: k["name"]) + self.setItems(filtered_items) + + ## Set the filter of this model based on a string. + # \param filter_dict \type{Dict} Dictionary to do the filtering by. + def setFilter(self, filter_dict: Dict[str, str]) -> None: + if filter_dict != self._filter: + self._filter = filter_dict + self._update() + + @pyqtProperty("QVariantMap", fset = setFilter, constant = True) + def filter(self) -> Dict[str, str]: + return self._filter + + # Check to see if a container matches with a regular expression + def _matchRegExp(self, metadata, property_name, value): + if property_name not in metadata: + return False + value = re.escape(value) #Escape for regex patterns. + value = "^" + value.replace("\\*", ".*") + "$" #Instead of (now escaped) asterisks, match on any string. Also add anchors for a complete match. + if self._ignore_case: + value_pattern = re.compile(value, re.IGNORECASE) + else: + value_pattern = re.compile(value) + + return value_pattern.match(str(metadata[property_name])) + + # Check to see if a container matches with a string + def _matchString(self, metadata, property_name, value): + if property_name not in metadata: + return False + return value.lower() == str(metadata[property_name]).lower() diff --git a/plugins/Toolbox/src/CuraPackageModel.py b/plugins/Toolbox/src/CuraPackageModel.py index facf21cc6f..de105cf6a1 100644 --- a/plugins/Toolbox/src/CuraPackageModel.py +++ b/plugins/Toolbox/src/CuraPackageModel.py @@ -14,10 +14,11 @@ class CuraPackageModel(ListModel): TypeRole = Qt.UserRole + 2 NameRole = Qt.UserRole + 3 VersionRole = Qt.UserRole + 4 - AuthorRole = Qt.UserRole + 5 - DescriptionRole = Qt.UserRole + 6 - IconURLRole = Qt.UserRole + 7 - ImageURLsRole = Qt.UserRole + 8 + AuthorNameRole = Qt.UserRole + 5 + AuthorEmailRole = Qt.UserRole + 6 + DescriptionRole = Qt.UserRole + 7 + IconURLRole = Qt.UserRole + 8 + ImageURLsRole = Qt.UserRole + 9 def __init__(self, parent = None): super().__init__(parent) @@ -28,7 +29,8 @@ class CuraPackageModel(ListModel): self.addRoleName(CuraPackageModel.TypeRole, "type") self.addRoleName(CuraPackageModel.NameRole, "name") self.addRoleName(CuraPackageModel.VersionRole, "version") - self.addRoleName(CuraPackageModel.AuthorRole, "author") + self.addRoleName(CuraPackageModel.AuthorNameRole, "author_name") + self.addRoleName(CuraPackageModel.AuthorEmailRole, "author_email") self.addRoleName(CuraPackageModel.DescriptionRole, "description") self.addRoleName(CuraPackageModel.IconURLRole, "icon_url") self.addRoleName(CuraPackageModel.ImageURLsRole, "image_urls") @@ -49,7 +51,8 @@ class CuraPackageModel(ListModel): "type": package["package_type"], "name": package["display_name"], "version": package["package_version"], - "author": package["author"], + "author_name": package["author"]["name"], + "author_email": package["author"]["email"], "description": package["description"], "icon_url": package["icon_url"] if "icon_url" in package else None, "image_urls": package["image_urls"] diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 60e43b357e..abac3c560d 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -22,6 +22,7 @@ import platform import zipfile from cura.CuraApplication import CuraApplication +from .AuthorsModel import AuthorsModel from .CuraPackageModel import CuraPackageModel i18n_catalog = i18nCatalog("cura") @@ -32,7 +33,7 @@ class Toolbox(QObject, Extension): super().__init__(parent) self._api_version = 1 - self._api_url = "https://api-staging.ultimaker.com/cura-packages/v%s/" % self._api_version + self._api_url = "https://api-staging.ultimaker.com/cura-packages/v%s" % self._api_version self._package_list_request = None self._download_plugin_request = None @@ -45,6 +46,8 @@ class Toolbox(QObject, Extension): self._packages_metadata = [] # Stores the remote information of the packages self._packages_model = None # Model that list the remote available packages + self._showcase_model = None + self._authors_model = None # These properties are for keeping track of the UI state: @@ -112,10 +115,14 @@ class Toolbox(QObject, Extension): showLicenseDialog = pyqtSignal() showRestartDialog = pyqtSignal() + packagesMetadataChanged = pyqtSignal() + authorsMetadataChanged = pyqtSignal() + onDownloadProgressChanged = pyqtSignal() onIsDownloadingChanged = pyqtSignal() restartRequiredChanged = pyqtSignal() + viewChanged = pyqtSignal() detailViewChanged = pyqtSignal() filterChanged = pyqtSignal() @@ -161,7 +168,7 @@ class Toolbox(QObject, Extension): def requestPackageList(self): Logger.log("i", "Requesting package list") - url = QUrl("{base_url}packages?cura_version={version}".format(base_url = self._api_url, version = self._packages_version_number)) + url = QUrl("{base_url}/cura/v{version}/packages".format(base_url = self._api_url, version = self._packages_version_number)) self._package_list_request = QNetworkRequest(url) self._package_list_request.setRawHeader(*self._request_header) self._network_manager.get(self._package_list_request) @@ -355,17 +362,16 @@ class Toolbox(QObject, Extension): for item in self._packages_metadata: if item["id"] == plugin["id"]: plugin["update_url"] = item["file_location"] - - # if self._current_view == "plugins": - # self.filterPackagesByType("plugin") - # elif self._current_view == "materials": - # self.filterPackagesByType("material") return self._plugins_model @pyqtProperty(QObject, notify = packagesMetadataChanged) def packagesModel(self): return self._packages_model + @pyqtProperty(QObject, notify = authorsMetadataChanged) + def authorsModel(self): + return self._authors_model + @pyqtProperty(bool, notify = packagesMetadataChanged) def dataReady(self): return self._packages_model is not None @@ -425,16 +431,35 @@ class Toolbox(QObject, Extension): return if reply.operation() == QNetworkAccessManager.GetOperation: - if reply_url == "{base_url}packages?cura_version={version}".format(base_url = self._api_url, version = self._packages_version_number): + if reply_url == "{base_url}/cura/v{version}/packages".format(base_url = self._api_url, version = self._packages_version_number): try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) - + print(json_data) # Add metadata to the manager: - self._packages_metadata = json_data["data"] + + + # Create packages model with all packages: if not self._packages_model: self._packages_model = CuraPackageModel() + self._packages_metadata = json_data["data"] self._packages_model.setPackagesMetaData(self._packages_metadata) self.packagesMetadataChanged.emit() + + # Create authors model with all authors: + if not self._authors_model: + self._authors_model = AuthorsModel() + # In the future, this will be its own API call. + self._authors_metadata = [] + for package in self._packages_metadata: + package["author"]["type"] = package["package_type"] + print(package["author"]) + if package["author"] not in self._authors_metadata: + self._authors_metadata.append(package["author"]) + self._authors_model.setMetaData(self._authors_metadata) + self.authorsMetadataChanged.emit() + + + except json.decoder.JSONDecodeError: Logger.log("w", "Received an invalid print job state message: Not valid JSON.") return @@ -469,6 +494,7 @@ class Toolbox(QObject, Extension): CuraApplication.getInstance().windowClosed() + # Getter & Setter for self._view_category def setViewCategory(self, category = "plugins"): self._view_category = category @@ -494,19 +520,13 @@ class Toolbox(QObject, Extension): return self._view_selection - # Filtering - @pyqtSlot(str) - def filterPackagesByType(self, type): - if not self._packages_model: - return - self._packages_model.setFilter({"type": type}) - self.filterChanged.emit() + # Filtering @pyqtSlot(str, str) def filterPackages(self, filterType, parameter): if not self._packages_model: return - self._packages_model.setFilter({filterType: parameter}) + self._packages_model.setFilter({ filterType: parameter }) self.filterChanged.emit() @pyqtSlot() @@ -515,3 +535,17 @@ class Toolbox(QObject, Extension): return self._packages_model.setFilter({}) self.filterChanged.emit() + + @pyqtSlot(str, str) + def filterAuthors(self, filterType, parameter): + if not self._authors_model: + return + self._authors_model.setFilter({ filterType: parameter }) + self.filterChanged.emit() + + @pyqtSlot() + def unfilterAuthors(self): + if not self._authors_model: + return + self._authors_model.setFilter({}) + self.filterChanged.emit() From 7359554641f082372b6ae1ee6c54fa23a512e169 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 10 Apr 2018 11:05:34 +0200 Subject: [PATCH 26/83] Implimented showcase --- .../resources/qml/ToolboxDetailPage.qml | 73 +++++++++++++++---- .../resources/qml/ToolboxDownloadsGrid.qml | 2 +- .../qml/ToolboxDownloadsGridTile.qml | 2 +- .../resources/qml/ToolboxDownloadsPage.qml | 8 +- .../qml/ToolboxDownloadsShowcase.qml | 10 ++- .../qml/ToolboxDownloadsShowcaseTile.qml | 32 +++++++- plugins/Toolbox/src/Toolbox.py | 44 ++++++++--- 7 files changed, 133 insertions(+), 38 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 156c829767..4bf28e0cff 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -92,8 +92,10 @@ Item topMargin: UM.Theme.getSize("double_margin").height } } - Column + + Label { + id: title anchors { top: thumbnail.top @@ -101,29 +103,72 @@ Item leftMargin: UM.Theme.getSize("default_margin").width right: parent.right rightMargin: UM.Theme.getSize("double_margin").width + bottomMargin: UM.Theme.getSize("default_margin").height + } + text: details.name + font: UM.Theme.getFont("large") + wrapMode: Text.WordWrap + width: parent.width + height: UM.Theme.getSize("base_unit") * 2 + } + + Column + { + id: properties + anchors + { + top: title.bottom + left: title.left + } + spacing: Math.floor(UM.Theme.getSize("default_margin").height / 2) + width: childrenRect.width + Label + { + text: "Version:" + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text_medium") + } + Label + { + text: "Last Update:" + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text_medium") + } + Label + { + text: "Author:" + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text_medium") + } + } + Column + { + id: values + anchors + { + top: title.bottom + left: properties.right + leftMargin: UM.Theme.getSize("default_margin").width } spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) + width: UM.Theme.getSize("base_unit").width * 12 Label { - text: details.name - font: UM.Theme.getFont("large") - wrapMode: Text.WordWrap - width: parent.width + text: details.version + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text") } Label { - text: details.description - font: UM.Theme.getFont("default") - wrapMode: Text.WordWrap - width: parent.width + text: details.generated_time + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text") } Label { - text: "Author: " + details.author_name - font: UM.Theme.getFont("small") - wrapMode: Text.WordWrap - width: parent.width - // TODO: Add mail icon. + text: details.author_name + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text") } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index 45eedbedbd..f7325d5fd9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -19,7 +19,7 @@ Column Label { id: heading - text: "Community Plugins" + text: manager.viewCategory == "material" ? "Maker Choices" : "Community Plugins" width: parent.width color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 193857f756..0dc5bb6aa2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -26,6 +26,7 @@ Item height: UM.Theme.getSize("toolbox_thumbnail_small").height color: "white" border.width: 1 + border.color: UM.Theme.getColor("text_medium") Image { anchors.centerIn: parent width: UM.Theme.getSize("toolbox_thumbnail_small").width - 26 @@ -79,7 +80,6 @@ Item manager.viewSelection = model.id manager.viewPage = "detail" manager.filterPackages("id", model.id) - } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml index 8d1cd93f13..2171a4e2bf 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml @@ -7,8 +7,6 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - ScrollView { id: base @@ -19,8 +17,8 @@ ScrollView Column { width: base.width - spacing: UM.Theme.getSize("base_unit").height - padding: UM.Theme.getSize("base_unit").height * 2 + spacing: UM.Theme.getSize("default_margin").height + padding: UM.Theme.getSize("double_margin").height height: childrenRect.height + 2 * padding ToolboxDownloadsShowcase { @@ -31,7 +29,7 @@ ScrollView { color: UM.Theme.getColor("text_medium") width: parent.width - 2 * parent.padding - height: UM.Theme.getSize("base_unit").height / 6 + height: UM.Theme.getSize("default_lining").height } ToolboxDownloadsGrid { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index 78a884c95d..621650a42a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -18,7 +18,7 @@ Column Label { id: heading - text: "Showcase" + text: "Featured" width: parent.width color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") @@ -32,8 +32,10 @@ Column horizontalCenter: parent.horizontalCenter } - ToolboxDownloadsShowcaseTile {} - ToolboxDownloadsShowcaseTile {} - ToolboxDownloadsShowcaseTile {} + Repeater + { + model: manager.materialShowcaseModel + delegate: ToolboxDownloadsShowcaseTile {} + } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index de0d85ec96..90ea0c5421 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -15,18 +15,26 @@ Item Rectangle { color: "white" - width: UM.Theme.getSize("base_unit").width * 8 - height: UM.Theme.getSize("base_unit").width * 8 + width: UM.Theme.getSize("toolbox_thumbnail_medium").width + height: UM.Theme.getSize("toolbox_thumbnail_medium").height border.width: 1 + border.color: UM.Theme.getColor("text_medium") anchors { top: parent.top horizontalCenter: parent.horizontalCenter } + Image { + anchors.centerIn: parent + width: UM.Theme.getSize("toolbox_thumbnail_medium").width - 26 + height: UM.Theme.getSize("toolbox_thumbnail_medium").height - 26 + fillMode: Image.PreserveAspectFit + source: model.icon_url || "../images/logobot.svg" + } } Label { - text: "Solidworks Integration" + text: model.name anchors { bottom: parent.bottom @@ -39,4 +47,22 @@ Item color: UM.Theme.getColor("text") font: UM.Theme.getFont("medium_bold") } + MouseArea + { + anchors.fill: parent + onClicked: { + if ( manager.viewCategory == "material" ) + { + manager.viewSelection = model.name + manager.viewPage = "author" + manager.filterPackages("author_name", model.name) + } + else + { + manager.viewSelection = model.id + manager.viewPage = "detail" + manager.filterPackages("id", model.id) + } + } + } } diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index abac3c560d..edad7b0825 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -36,8 +36,9 @@ class Toolbox(QObject, Extension): self._api_url = "https://api-staging.ultimaker.com/cura-packages/v%s" % self._api_version self._package_list_request = None - self._download_plugin_request = None + self._showcase_request = None + self._download_plugin_request = None self._download_plugin_reply = None self._network_manager = None @@ -118,6 +119,7 @@ class Toolbox(QObject, Extension): packagesMetadataChanged = pyqtSignal() authorsMetadataChanged = pyqtSignal() + showcaseMetadataChanged = pyqtSignal() onDownloadProgressChanged = pyqtSignal() onIsDownloadingChanged = pyqtSignal() @@ -160,6 +162,7 @@ class Toolbox(QObject, Extension): @pyqtSlot() def browsePackages(self): self._createNetworkManager() + self.requestShowcase() self.requestPackageList() if not self._dialog: @@ -173,6 +176,13 @@ class Toolbox(QObject, Extension): self._package_list_request.setRawHeader(*self._request_header) self._network_manager.get(self._package_list_request) + def requestShowcase(self): + Logger.log("i", "Requesting showcase list") + url = QUrl("{base_url}/cura/v{version}/showcase".format(base_url = self._api_url, version = self._packages_version_number)) + self._showcase_request = QNetworkRequest(url) + self._showcase_request.setRawHeader(*self._request_header) + self._network_manager.get(self._showcase_request) + def _createDialog(self, qml_name): Logger.log("d", "Creating dialog [%s]", qml_name) path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) @@ -364,6 +374,10 @@ class Toolbox(QObject, Extension): plugin["update_url"] = item["file_location"] return self._plugins_model + @pyqtProperty(QObject, notify = showcaseMetadataChanged) + def materialShowcaseModel(self): + return self._showcase_model + @pyqtProperty(QObject, notify = packagesMetadataChanged) def packagesModel(self): return self._packages_model @@ -434,9 +448,6 @@ class Toolbox(QObject, Extension): if reply_url == "{base_url}/cura/v{version}/packages".format(base_url = self._api_url, version = self._packages_version_number): try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) - print(json_data) - # Add metadata to the manager: - # Create packages model with all packages: if not self._packages_model: @@ -448,20 +459,33 @@ class Toolbox(QObject, Extension): # Create authors model with all authors: if not self._authors_model: self._authors_model = AuthorsModel() - # In the future, this will be its own API call. + # TODO: Remove this hacky code once there's an API call for this. self._authors_metadata = [] for package in self._packages_metadata: package["author"]["type"] = package["package_type"] - print(package["author"]) if package["author"] not in self._authors_metadata: self._authors_metadata.append(package["author"]) self._authors_model.setMetaData(self._authors_metadata) self.authorsMetadataChanged.emit() - - - except json.decoder.JSONDecodeError: - Logger.log("w", "Received an invalid print job state message: Not valid JSON.") + Logger.log("w", "Toolbox: Received invalid JSON for package list.") + return + + + elif reply_url == "{base_url}/cura/v{version}/showcase".format(base_url = self._api_url, version = self._packages_version_number): + try: + json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) + # Create packages model with all packages: + if not self._showcase_model: + self._showcase_model = CuraPackageModel() + self._showcase_metadata = json_data["data"] + print(self._showcase_metadata) + self._showcase_model.setPackagesMetaData(self._showcase_metadata) + for package in self._showcase_model.items: + print(package) + self.showcaseMetadataChanged.emit() + except json.decoder.JSONDecodeError: + Logger.log("w", "Toolbox: Received invalid JSON for showcase.") return else: # Ignore any operation that is not a get operation From d4cc4659d8e19e3b992e598a37d22ea40d9b55c1 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 10 Apr 2018 16:07:39 +0200 Subject: [PATCH 27/83] CURA-5035 More styling & layout --- plugins/Toolbox/resources/qml/Toolbox.qml | 6 +- .../resources/qml/ToolboxAuthorPage.qml | 138 +++++++++--------- .../resources/qml/ToolboxBackColumn.qml | 64 ++++++++ .../resources/qml/ToolboxDetailList.qml | 14 +- .../resources/qml/ToolboxDetailPage.qml | 74 ++-------- .../resources/qml/ToolboxDetailTile.qml | 15 +- .../resources/qml/ToolboxDownloadsGrid.qml | 2 +- .../qml/ToolboxDownloadsGridTile.qml | 23 ++- .../qml/ToolboxDownloadsShowcaseTile.qml | 2 + .../{CuraPackageModel.py => PackagesModel.py} | 28 ++-- plugins/Toolbox/src/Toolbox.py | 62 +++++--- 11 files changed, 248 insertions(+), 180 deletions(-) create mode 100644 plugins/Toolbox/resources/qml/ToolboxBackColumn.qml rename plugins/Toolbox/src/{CuraPackageModel.py => PackagesModel.py} (77%) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index cfe768e1d1..ca00a4a8c5 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -17,10 +17,10 @@ Window property bool dataReady: manager.dataReady title: catalog.i18nc("@title:tab", "Toolbox"); modality: Qt.ApplicationModal - width: 960 * screenScaleFactor + width: 720 * screenScaleFactor height: 640 * screenScaleFactor - minimumWidth: 960 * screenScaleFactor - maximumWidth: 960 * screenScaleFactor + minimumWidth: 720 * screenScaleFactor + maximumWidth: 720 * screenScaleFactor minimumHeight: 350 * screenScaleFactor color: UM.Theme.getColor("sidebar") Item diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 200cac33fa..7934526639 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -7,66 +7,15 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - Item { id: base + property var details: manager.authorsModel.items[0] anchors.fill: parent - Item + ToolboxBackColumn { id: sidebar - height: parent.height - width: UM.Theme.getSize("base_unit").width * 6 - anchors - { - top: parent.top - left: parent.left - topMargin: UM.Theme.getSize("double_margin").height - leftMargin: UM.Theme.getSize("default_margin").width - rightMargin: UM.Theme.getSize("default_margin").width - } - Button - { - text: "Back" - UM.RecolorImage - { - id: backArrow - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - 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("arrow_left") - } - width: UM.Theme.getSize("base_unit").width * 4 - height: UM.Theme.getSize("base_unit").height * 2 - onClicked: - { - manager.viewPage = "overview" - manager.filterPackages("type", manager.viewCategory) - } - style: ButtonStyle - { - background: Rectangle - { - color: "transparent" - } - label: Label - { - text: control.text - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default_bold") - horizontalAlignment: Text.AlignRight - width: control.width - } - } - } } - Rectangle { id: header @@ -74,6 +23,7 @@ Item { left: sidebar.right right: parent.right + rightMargin: UM.Theme.getSize("double_margin").width } height: UM.Theme.getSize("base_unit").height * 12 Image @@ -82,7 +32,7 @@ Item width: UM.Theme.getSize("toolbox_thumbnail_medium").width height: UM.Theme.getSize("toolbox_thumbnail_medium").height fillMode: Image.PreserveAspectFit - source: manager.detailData["icon_url"] || "../images/logobot.svg" + source: details.icon_url || "../images/logobot.svg" anchors { top: parent.top @@ -91,8 +41,10 @@ Item topMargin: UM.Theme.getSize("double_margin").height } } - Column + + Label { + id: title anchors { top: thumbnail.top @@ -100,39 +52,79 @@ Item leftMargin: UM.Theme.getSize("default_margin").width right: parent.right rightMargin: UM.Theme.getSize("double_margin").width + bottomMargin: UM.Theme.getSize("default_margin").height + } + text: details.name + font: UM.Theme.getFont("large") + wrapMode: Text.WordWrap + width: parent.width + height: UM.Theme.getSize("base_unit") * 2 + } + + Column + { + id: properties + anchors + { + top: title.bottom + left: title.left + topMargin: UM.Theme.getSize("default_margin").height + } + spacing: Math.floor(UM.Theme.getSize("default_margin").height / 2) + width: childrenRect.width + Label + { + text: "Version:" + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text_medium") + } + Label + { + text: "Author:" + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text_medium") + } + } + Column + { + id: values + anchors + { + top: title.bottom + left: properties.right + leftMargin: UM.Theme.getSize("default_margin").width + topMargin: UM.Theme.getSize("default_margin").height } spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) + width: UM.Theme.getSize("base_unit").width * 12 Label { - text: manager.detailData["name"] - font: UM.Theme.getFont("large") - wrapMode: Text.WordWrap - width: parent.width + text: details.name + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text") } Label { - text: "HELLO THIS IS AN AUTHOR PAGE" - font: UM.Theme.getFont("default") - wrapMode: Text.WordWrap - width: parent.width - } - Label - { - text: "Author: " + manager.detailData["author"]["name"] - font: UM.Theme.getFont("small") - wrapMode: Text.WordWrap - width: parent.width - // TODO: Add mail icon. + text: details.name + font: UM.Theme.getFont("very_small") + color: UM.Theme.getColor("text") } } + Rectangle + { + color: UM.Theme.getColor("text_medium") + width: parent.width + height: UM.Theme.getSize("default_lining").height + anchors.bottom: parent.bottom + } } ToolboxDetailList { anchors { - right: header.right top: header.bottom - left: header.left bottom: base.bottom + left: header.left + right: base.right } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml new file mode 100644 index 0000000000..dc15c42677 --- /dev/null +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -0,0 +1,64 @@ +// Copyright (c) 2018 Ultimaker B.V. +// PluginBrowser is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +Item +{ + id: sidebar + height: parent.height + width: UM.Theme.getSize("base_unit").width * 6 + anchors + { + top: parent.top + left: parent.left + topMargin: UM.Theme.getSize("double_margin").height + leftMargin: UM.Theme.getSize("default_margin").width + rightMargin: UM.Theme.getSize("default_margin").width + } + Button + { + id: button + text: "Back" + UM.RecolorImage + { + id: backArrow + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: height + color: button.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("text") + source: UM.Theme.getIcon("arrow_left") + } + width: UM.Theme.getSize("base_unit").width * 4 + height: UM.Theme.getSize("base_unit").height * 2 + onClicked: + { + manager.viewPage = "overview" + manager.filterPackages("type", manager.viewCategory) + } + style: ButtonStyle + { + background: Rectangle + { + color: "transparent" + } + label: Label + { + id: labelStyle + text: control.text + color: control.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("text") + font: UM.Theme.getFont("default_bold") + horizontalAlignment: Text.AlignRight + width: control.width + } + } + } +} diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index ba772b343a..1d391496c4 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -10,11 +10,6 @@ import UM 1.1 as UM Item { id: base - anchors - { - topMargin: UM.Theme.getSize("double_margin").height - bottomMargin: UM.Theme.getSize("double_margin").height - } ScrollView { frameVisible: false @@ -22,8 +17,13 @@ Item style: UM.Theme.styles.scrollview Column { - anchors.right: base.right - anchors.rightMargin: UM.Theme.getSize("double_margin").width + anchors + { + right: base.right + topMargin: UM.Theme.getSize("double_margin").height + bottomMargin: UM.Theme.getSize("double_margin").height + top: parent.top + } height: childrenRect.height spacing: UM.Theme.getSize("default_margin").height Repeater diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 4bf28e0cff..85cb01240c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -7,67 +7,15 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - Item { - property var details: manager.packagesModel.items[0] id: base + property var details: manager.packagesModel.items[0] anchors.fill: parent - Item + ToolboxBackColumn { id: sidebar - height: parent.height - width: UM.Theme.getSize("base_unit").width * 6 - anchors - { - top: parent.top - left: parent.left - topMargin: UM.Theme.getSize("double_margin").height - leftMargin: UM.Theme.getSize("default_margin").width - rightMargin: UM.Theme.getSize("default_margin").width - } - Button - { - text: "Back" - UM.RecolorImage - { - id: backArrow - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width - 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("arrow_left") - } - width: UM.Theme.getSize("base_unit").width * 4 - height: UM.Theme.getSize("base_unit").height * 2 - onClicked: - { - manager.viewPage = "overview" - manager.filterPackages("type", manager.viewCategory) - } - style: ButtonStyle - { - background: Rectangle - { - color: "transparent" - } - label: Label - { - text: control.text - color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default_bold") - horizontalAlignment: Text.AlignRight - width: control.width - } - } - } } - Rectangle { id: header @@ -75,6 +23,7 @@ Item { left: sidebar.right right: parent.right + rightMargin: UM.Theme.getSize("double_margin").width } height: UM.Theme.getSize("base_unit").height * 12 Image @@ -119,6 +68,7 @@ Item { top: title.bottom left: title.left + topMargin: UM.Theme.getSize("default_margin").height } spacing: Math.floor(UM.Theme.getSize("default_margin").height / 2) width: childrenRect.width @@ -149,6 +99,7 @@ Item top: title.bottom left: properties.right leftMargin: UM.Theme.getSize("default_margin").width + topMargin: UM.Theme.getSize("default_margin").height } spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) width: UM.Theme.getSize("base_unit").width * 12 @@ -160,7 +111,7 @@ Item } Label { - text: details.generated_time + text: Qt.formatDateTime(details.last_updated, "dd MMM yyyy") font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") } @@ -171,16 +122,21 @@ Item color: UM.Theme.getColor("text") } } + Rectangle + { + color: UM.Theme.getColor("text_medium") + width: parent.width + height: UM.Theme.getSize("default_lining").height + anchors.bottom: parent.bottom + } } ToolboxDetailList { anchors { - right: header.right top: header.bottom - - left: header.left bottom: base.bottom - + left: header.left + right: base.right } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index cc4e61c55b..162b072dbc 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -20,7 +20,6 @@ Rectangle right: controls.left rightMargin: UM.Theme.getSize("default_margin").width top: parent.top - topMargin: UM.Theme.getSize("default_margin").height } Label { @@ -45,7 +44,6 @@ Rectangle id: controls anchors.right: parent.right anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("default_margin").height width: childrenRect.width Button { id: installButton @@ -54,7 +52,7 @@ Rectangle { if ( manager.isDownloading ) { - return pluginList.activePlugin == model ? true : false + return manager.activePackage == model ? true : false } else { @@ -79,19 +77,20 @@ Rectangle } onClicked: { - if ( manager.isDownloading && pluginList.activePlugin == model ) + console.log( "MODEL", model.download_url ) + if ( manager.isDownloading && manager.activePackage == model ) { manager.cancelDownload(); } else { - pluginList.activePlugin = model; + // manager.activePackage = model; if ( model.can_upgrade ) { - manager.downloadAndInstallPlugin( model.update_url ); + // manager.downloadAndInstallPlugin( model.update_url ); } else { - manager.downloadAndInstallPlugin( model.file_location ); + manager.startDownload( model.download_url ); } } } @@ -102,6 +101,6 @@ Rectangle color: UM.Theme.getColor("text_medium") width: parent.width height: UM.Theme.getSize("default_lining").height - anchors.top: parent.top + anchors.bottom: parent.bottom } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index f7325d5fd9..a1e86552bf 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -28,7 +28,7 @@ Column { id: grid width: parent.width - columns: 3 + columns: 2 columnSpacing: UM.Theme.getSize("base_unit").width rowSpacing: UM.Theme.getSize("base_unit").height diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 0dc5bb6aa2..3fa717e70f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -14,6 +14,13 @@ Item id: base height: childrenRect.height Layout.alignment: Qt.AlignTop | Qt.AlignLeft + Rectangle + { + id: highlight + anchors.fill: parent + opacity: 0.0 + color: UM.Theme.getColor("primary") + } Row { width: parent.width @@ -68,17 +75,31 @@ Item MouseArea { anchors.fill: parent - onClicked: { + hoverEnabled: true + onEntered: + { + thumbnail.border.color = UM.Theme.getColor("primary") + highlight.opacity = 0.1 + } + onExited: + { + thumbnail.border.color = UM.Theme.getColor("text") + highlight.opacity = 0.0 + } + onClicked: + { if ( manager.viewCategory == "material" ) { manager.viewSelection = model.name manager.viewPage = "author" + manager.filterAuthors("name", model.name) manager.filterPackages("author_name", model.name) } else { manager.viewSelection = model.id manager.viewPage = "detail" + manager.filterAuthors("name", model.author_name) manager.filterPackages("id", model.id) } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 90ea0c5421..a4eae5b4ab 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -55,12 +55,14 @@ Item { manager.viewSelection = model.name manager.viewPage = "author" + manager.filterAuthors("name", model.name) manager.filterPackages("author_name", model.name) } else { manager.viewSelection = model.id manager.viewPage = "detail" + manager.filterAuthors("name", model.author_name) manager.filterPackages("id", model.id) } } diff --git a/plugins/Toolbox/src/CuraPackageModel.py b/plugins/Toolbox/src/PackagesModel.py similarity index 77% rename from plugins/Toolbox/src/CuraPackageModel.py rename to plugins/Toolbox/src/PackagesModel.py index de105cf6a1..860e5aaaea 100644 --- a/plugins/Toolbox/src/CuraPackageModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -9,7 +9,7 @@ from PyQt5.QtCore import Qt, pyqtProperty, pyqtSignal from UM.Qt.ListModel import ListModel ## Model that holds cura packages. By setting the filter property the instances held by this model can be changed. -class CuraPackageModel(ListModel): +class PackagesModel(ListModel): IdRole = Qt.UserRole + 1 TypeRole = Qt.UserRole + 2 NameRole = Qt.UserRole + 3 @@ -19,21 +19,25 @@ class CuraPackageModel(ListModel): DescriptionRole = Qt.UserRole + 7 IconURLRole = Qt.UserRole + 8 ImageURLsRole = Qt.UserRole + 9 + DownloadURLRole = Qt.UserRole + 10 + LastUpdatedRole = Qt.UserRole + 11 def __init__(self, parent = None): super().__init__(parent) self._packages_metadata = None - self.addRoleName(CuraPackageModel.IdRole, "id") - self.addRoleName(CuraPackageModel.TypeRole, "type") - self.addRoleName(CuraPackageModel.NameRole, "name") - self.addRoleName(CuraPackageModel.VersionRole, "version") - self.addRoleName(CuraPackageModel.AuthorNameRole, "author_name") - self.addRoleName(CuraPackageModel.AuthorEmailRole, "author_email") - self.addRoleName(CuraPackageModel.DescriptionRole, "description") - self.addRoleName(CuraPackageModel.IconURLRole, "icon_url") - self.addRoleName(CuraPackageModel.ImageURLsRole, "image_urls") + self.addRoleName(PackagesModel.IdRole, "id") + self.addRoleName(PackagesModel.TypeRole, "type") + self.addRoleName(PackagesModel.NameRole, "name") + self.addRoleName(PackagesModel.VersionRole, "version") + self.addRoleName(PackagesModel.AuthorNameRole, "author_name") + self.addRoleName(PackagesModel.AuthorEmailRole, "author_email") + self.addRoleName(PackagesModel.DescriptionRole, "description") + self.addRoleName(PackagesModel.IconURLRole, "icon_url") + self.addRoleName(PackagesModel.ImageURLsRole, "image_urls") + self.addRoleName(PackagesModel.DownloadURLRole, "download_url") + self.addRoleName(PackagesModel.LastUpdatedRole, "last_updated") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str,str] @@ -55,7 +59,9 @@ class CuraPackageModel(ListModel): "author_email": package["author"]["email"], "description": package["description"], "icon_url": package["icon_url"] if "icon_url" in package else None, - "image_urls": package["image_urls"] + "image_urls": package["image_urls"], + "download_url": package["download_url"], + "last_updated": package["last_updated"] }) # Filter on all the key-word arguments. diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index edad7b0825..b35ec9ca08 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -23,7 +23,7 @@ import zipfile from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel -from .CuraPackageModel import CuraPackageModel +from .PackagesModel import PackagesModel i18n_catalog = i18nCatalog("cura") @@ -32,8 +32,10 @@ class Toolbox(QObject, Extension): def __init__(self, parent=None): super().__init__(parent) + self._plugin_registry = Application.getInstance().getPluginRegistry() + self._packages_version = self._plugin_registry.APIVersion self._api_version = 1 - self._api_url = "https://api-staging.ultimaker.com/cura-packages/v%s" % self._api_version + self._api_url = "https://api.ultimaker.com/cura-packages/v{api_version}/cura/v{package_version}".format( api_version = self._api_version, package_version = self._packages_version) self._package_list_request = None self._showcase_request = None @@ -42,8 +44,7 @@ class Toolbox(QObject, Extension): self._download_plugin_reply = None self._network_manager = None - self._plugin_registry = Application.getInstance().getPluginRegistry() - self._packages_version_number = self._plugin_registry.APIVersion + self._packages_metadata = [] # Stores the remote information of the packages self._packages_model = None # Model that list the remote available packages @@ -76,11 +77,17 @@ class Toolbox(QObject, Extension): # if self._view_page == "author": # filter with "author == self._view_selection" + # Active package refers to which package is currently being downloaded, + # installed, or otherwise modified. + self._active_package = None + + # Nowadays can be 'plugins', 'materials' or 'installed' self._current_view = "plugins" - self._detail_view = False self._detail_data = {} # Extraneous since can just use the data prop of the model. + + self._restart_required = False self._dialog = None @@ -121,6 +128,7 @@ class Toolbox(QObject, Extension): authorsMetadataChanged = pyqtSignal() showcaseMetadataChanged = pyqtSignal() + activePackageChanged = pyqtSignal() onDownloadProgressChanged = pyqtSignal() onIsDownloadingChanged = pyqtSignal() restartRequiredChanged = pyqtSignal() @@ -155,9 +163,7 @@ class Toolbox(QObject, Extension): self._restart_dialog_message = message self.showRestartDialog.emit() - @pyqtProperty(bool, notify = onIsDownloadingChanged) - def isDownloading(self): - return self._is_downloading + @pyqtSlot() def browsePackages(self): @@ -171,14 +177,14 @@ class Toolbox(QObject, Extension): def requestPackageList(self): Logger.log("i", "Requesting package list") - url = QUrl("{base_url}/cura/v{version}/packages".format(base_url = self._api_url, version = self._packages_version_number)) + url = QUrl("{base_url}/packages".format(base_url = self._api_url)) self._package_list_request = QNetworkRequest(url) self._package_list_request.setRawHeader(*self._request_header) self._network_manager.get(self._package_list_request) def requestShowcase(self): Logger.log("i", "Requesting showcase list") - url = QUrl("{base_url}/cura/v{version}/showcase".format(base_url = self._api_url, version = self._packages_version_number)) + url = QUrl("{base_url}/showcase".format(base_url = self._api_url)) self._showcase_request = QNetworkRequest(url) self._showcase_request.setRawHeader(*self._request_header) self._network_manager.get(self._showcase_request) @@ -315,6 +321,18 @@ class Toolbox(QObject, Extension): self.setIsDownloading(True) self._download_plugin_reply.downloadProgress.connect(self._onDownloadPluginProgress) + # DOWNLOADING BEHAVIOR + @pyqtSlot(str) + def startDownload(self, url): + Logger.log("i", "Attempting to download & install package from %s", url) + url = QUrl(url) + self._download_plugin_request = QNetworkRequest(url) + self._download_plugin_request.setRawHeader(*self._request_header) + self._download_plugin_reply = self._network_manager.get(self._download_plugin_request) + self.setDownloadProgress(0) + self.setIsDownloading(True) + self._download_plugin_reply.downloadProgress.connect(self._onDownloadPluginProgress) + @pyqtSlot() def cancelDownload(self): Logger.log("i", "user cancelled the download of a plugin") @@ -445,13 +463,13 @@ class Toolbox(QObject, Extension): return if reply.operation() == QNetworkAccessManager.GetOperation: - if reply_url == "{base_url}/cura/v{version}/packages".format(base_url = self._api_url, version = self._packages_version_number): + if reply_url == "{base_url}/packages".format(base_url = self._api_url): try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) - + print(json_data) # Create packages model with all packages: if not self._packages_model: - self._packages_model = CuraPackageModel() + self._packages_model = PackagesModel() self._packages_metadata = json_data["data"] self._packages_model.setPackagesMetaData(self._packages_metadata) self.packagesMetadataChanged.emit() @@ -472,12 +490,12 @@ class Toolbox(QObject, Extension): return - elif reply_url == "{base_url}/cura/v{version}/showcase".format(base_url = self._api_url, version = self._packages_version_number): + elif reply_url == "{base_url}/showcase".format(base_url = self._api_url): try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) # Create packages model with all packages: if not self._showcase_model: - self._showcase_model = CuraPackageModel() + self._showcase_model = PackagesModel() self._showcase_metadata = json_data["data"] print(self._showcase_metadata) self._showcase_model.setPackagesMetaData(self._showcase_metadata) @@ -520,6 +538,18 @@ class Toolbox(QObject, Extension): # Getter & Setter for self._view_category + + @pyqtProperty(bool, notify = onIsDownloadingChanged) + def isDownloading(self): + return self._is_downloading + + def setActivePackage(self, package): + self._active_package = package + self.activePackageChanged.emit() + @pyqtProperty(QObject, fset = setActivePackage, notify = activePackageChanged) + def activePackage(self): + return self._active_package + def setViewCategory(self, category = "plugins"): self._view_category = category self.viewChanged.emit() @@ -527,7 +557,6 @@ class Toolbox(QObject, Extension): def viewCategory(self): return self._view_category - # Getter & Setter for self._view_page def setViewPage(self, page = "overview"): self._view_page = page self.viewChanged.emit() @@ -535,7 +564,6 @@ class Toolbox(QObject, Extension): def viewPage(self): return self._view_page - # Getter & Setter for self._view_selection def setViewSelection(self, selection = ""): self._view_selection = selection self.viewChanged.emit() From 3c7760b514c5e4d1e31caf5de3b4208b9434f99f Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 10 Apr 2018 16:54:32 +0200 Subject: [PATCH 28/83] CURA-5035 Code organization --- .../resources/qml/ToolboxDetailTile.qml | 17 +- plugins/Toolbox/src/Toolbox.py | 259 ++++++++---------- 2 files changed, 127 insertions(+), 149 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 162b072dbc..0ace432a2a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -47,12 +47,22 @@ Rectangle width: childrenRect.width Button { id: installButton - text: catalog.i18nc("@action:button", "Install") + text: { + if ( manager.isDownloading ) + { + return catalog.i18nc("@action:button", "Cancel") + } + else + { + return catalog.i18nc("@action:button", "Install") + } + } enabled: { if ( manager.isDownloading ) { - return manager.activePackage == model ? true : false + return true + // return manager.activePackage == model ? true : false } else { @@ -78,7 +88,8 @@ Rectangle onClicked: { console.log( "MODEL", model.download_url ) - if ( manager.isDownloading && manager.activePackage == model ) + // if ( manager.isDownloading && manager.activePackage == model ) + if ( manager.isDownloading ) { manager.cancelDownload(); } diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index b35ec9ca08..51ee26c6f1 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -35,13 +35,15 @@ class Toolbox(QObject, Extension): self._plugin_registry = Application.getInstance().getPluginRegistry() self._packages_version = self._plugin_registry.APIVersion self._api_version = 1 - self._api_url = "https://api.ultimaker.com/cura-packages/v{api_version}/cura/v{package_version}".format( api_version = self._api_version, package_version = self._packages_version) + self._api_url = "https://api-staging.ultimaker.com/cura-packages/v{api_version}/cura/v{package_version}".format( api_version = self._api_version, package_version = self._packages_version) - self._package_list_request = None - self._showcase_request = None + self._get_packages_request = None + self._get_showcase_request = None - self._download_plugin_request = None - self._download_plugin_reply = None + self._download_request = None + self._download_reply = None + self._download_progress = 0 + self._is_downloading = False self._network_manager = None @@ -92,9 +94,8 @@ class Toolbox(QObject, Extension): self._dialog = None self._restartDialog = None - self._download_progress = 0 - self._is_downloading = False + self._request_header = [b"User-Agent", str.encode("%s/%s (%s %s)" % (Application.getInstance().getApplicationName(), @@ -109,7 +110,6 @@ class Toolbox(QObject, Extension): # prevent the user from downloading the same file over and over again, # we keep track of the upgraded plugins. - # NOTE: This will be depreciated in favor of the 'status' system. self._newly_installed_plugin_ids = [] self._newly_uninstalled_plugin_ids = [] @@ -169,56 +169,19 @@ class Toolbox(QObject, Extension): def browsePackages(self): self._createNetworkManager() self.requestShowcase() - self.requestPackageList() - + self.requestPackages() if not self._dialog: self._dialog = self._createDialog("Toolbox.qml") self._dialog.show() - def requestPackageList(self): - Logger.log("i", "Requesting package list") - url = QUrl("{base_url}/packages".format(base_url = self._api_url)) - self._package_list_request = QNetworkRequest(url) - self._package_list_request.setRawHeader(*self._request_header) - self._network_manager.get(self._package_list_request) - def requestShowcase(self): - Logger.log("i", "Requesting showcase list") - url = QUrl("{base_url}/showcase".format(base_url = self._api_url)) - self._showcase_request = QNetworkRequest(url) - self._showcase_request.setRawHeader(*self._request_header) - self._network_manager.get(self._showcase_request) def _createDialog(self, qml_name): - Logger.log("d", "Creating dialog [%s]", qml_name) + Logger.log("d", "Toolbox: Creating dialog [%s].", qml_name) path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) dialog = Application.getInstance().createQmlComponent(path, {"manager": self}) return dialog - def setIsDownloading(self, is_downloading): - if self._is_downloading != is_downloading: - self._is_downloading = is_downloading - self.onIsDownloadingChanged.emit() - - def _onDownloadPluginProgress(self, bytes_sent, bytes_total): - if bytes_total > 0: - new_progress = bytes_sent / bytes_total * 100 - self.setDownloadProgress(new_progress) - if new_progress == 100.0: - self.setIsDownloading(False) - self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadPluginProgress) - - # must not delete the temporary file on Windows - self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curaplugin", delete = False) - location = self._temp_plugin_file.name - - # write first and close, otherwise on Windows, it cannot read the file - self._temp_plugin_file.write(self._download_plugin_reply.readAll()) - self._temp_plugin_file.close() - - self._checkPluginLicenseOrInstall(location) - return - ## Checks if the downloaded plugin ZIP file contains a license file or not. # If it does, it will show a popup dialog displaying the license to the user. The plugin will be installed if the # user accepts the license. @@ -301,80 +264,6 @@ class Toolbox(QObject, Extension): self.packagesMetadataChanged.emit() Logger.log("i", "%s was set as 'deactive'", id) - @pyqtProperty(int, notify = onDownloadProgressChanged) - def downloadProgress(self): - return self._download_progress - - def setDownloadProgress(self, progress): - if progress != self._download_progress: - self._download_progress = progress - self.onDownloadProgressChanged.emit() - - @pyqtSlot(str) - def downloadAndInstallPlugin(self, url): - Logger.log("i", "Attempting to download & install plugin from %s", url) - url = QUrl(url) - self._download_plugin_request = QNetworkRequest(url) - self._download_plugin_request.setRawHeader(*self._request_header) - self._download_plugin_reply = self._network_manager.get(self._download_plugin_request) - self.setDownloadProgress(0) - self.setIsDownloading(True) - self._download_plugin_reply.downloadProgress.connect(self._onDownloadPluginProgress) - - # DOWNLOADING BEHAVIOR - @pyqtSlot(str) - def startDownload(self, url): - Logger.log("i", "Attempting to download & install package from %s", url) - url = QUrl(url) - self._download_plugin_request = QNetworkRequest(url) - self._download_plugin_request.setRawHeader(*self._request_header) - self._download_plugin_reply = self._network_manager.get(self._download_plugin_request) - self.setDownloadProgress(0) - self.setIsDownloading(True) - self._download_plugin_reply.downloadProgress.connect(self._onDownloadPluginProgress) - - @pyqtSlot() - def cancelDownload(self): - Logger.log("i", "user cancelled the download of a plugin") - self._download_plugin_reply.abort() - self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadPluginProgress) - self._download_plugin_reply = None - self._download_plugin_request = None - - self.setDownloadProgress(0) - self.setIsDownloading(False) - - def setCurrentView(self, view = "plugins"): - self._current_view = view - self.viewChanged.emit() - - @pyqtProperty(str, fset = setCurrentView, notify = viewChanged) - def currentView(self): - return self._current_view - - def setDetailView(self, bool = False): - self._detail_view = bool - self.detailViewChanged.emit() - - @pyqtProperty(bool, fset = setDetailView, notify = detailViewChanged) - def detailView(self): - return self._detail_view - - # Set the detail data given a plugin ID: - @pyqtSlot(str) - def setDetailData(self, id): - if not self._packages_model: - return - for package in self._packages_model.items: - if package["id"] == id: - print(package) - self._detail_data = package - self.detailViewChanged.emit() - - @pyqtProperty("QVariantMap", notify = detailViewChanged) - def detailData(self): - return self._detail_data - @pyqtProperty(QObject, notify = packagesMetadataChanged) def pluginsModel(self): self._plugins_model = PluginsModel(None, self._current_view) @@ -445,6 +334,73 @@ class Toolbox(QObject, Extension): if id in self._plugin_registry.getActivePlugins(): return True return False + def _createNetworkManager(self): + if self._network_manager: + self._network_manager.finished.disconnect(self._onRequestFinished) + self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccesibleChanged) + self._network_manager = QNetworkAccessManager() + self._network_manager.finished.connect(self._onRequestFinished) + self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) + + @pyqtProperty(bool, notify = restartRequiredChanged) + def restartRequired(self): + return self._restart_required + + @pyqtSlot() + def restart(self): + CuraApplication.getInstance().windowClosed() + + + + # Make API Calls + # -------------------------------------------------------------------------- + def requestPackages(self): + Logger.log("i", "Toolbox: Requesting package list from server.") + url = QUrl("{base_url}/packages".format(base_url = self._api_url)) + self._get_packages_request = QNetworkRequest(url) + self._get_packages_request.setRawHeader(*self._request_header) + self._network_manager.get(self._get_packages_request) + + def requestShowcase(self): + Logger.log("i", "Toolbox: Requesting showcase list from server.") + url = QUrl("{base_url}/showcase".format(base_url = self._api_url)) + self._get_showcase_request = QNetworkRequest(url) + self._get_showcase_request.setRawHeader(*self._request_header) + self._network_manager.get(self._get_showcase_request) + + @pyqtSlot(str) + def startDownload(self, url): + Logger.log("i", "Toolbox: Attempting to download & install package from %s.", url) + url = QUrl(url) + self._download_request = QNetworkRequest(url) + self._download_request.setRawHeader(*self._request_header) + self._download_reply = self._network_manager.get(self._download_request) + self.setDownloadProgress(0) + self.setIsDownloading(True) + self._download_reply.downloadProgress.connect(self._onDownloadProgress) + + @pyqtSlot() + def cancelDownload(self): + Logger.log("i", "Toolbox: User cancelled the download of a plugin.") + self._download_reply.abort() + self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) + self._download_reply = None + self._download_request = None + self.setDownloadProgress(0) + self.setIsDownloading(False) + + + + # Handlers for Download Events + # -------------------------------------------------------------------------- + def _onNetworkAccesibleChanged(self, accessible): + if accessible == 0: + self.setDownloadProgress(0) + self.setIsDownloading(False) + if self._download_reply: + self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) + self._download_reply.abort() + self._download_reply = None def _onRequestFinished(self, reply): reply_url = reply.url().toString() @@ -454,7 +410,7 @@ class Toolbox(QObject, Extension): self.setDownloadProgress(0) self.setIsDownloading(False) if self._download_plugin_reply: - self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadPluginProgress) + self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadProgress) self._download_plugin_reply.abort() self._download_plugin_reply = None return @@ -509,37 +465,47 @@ class Toolbox(QObject, Extension): # Ignore any operation that is not a get operation pass - def _onNetworkAccesibleChanged(self, accessible): - if accessible == 0: - self.setDownloadProgress(0) - self.setIsDownloading(False) - if self._download_plugin_reply: - self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadPluginProgress) - self._download_plugin_reply.abort() - self._download_plugin_reply = None + def _onDownloadProgress(self, bytes_sent, bytes_total): + print("Downloading bytes:", bytes_total) + if bytes_total > 0: + new_progress = bytes_sent / bytes_total * 100 + self.setDownloadProgress(new_progress) + if new_progress == 100.0: + Logger.log("i", "Toolbox: Download complete.") + self.setIsDownloading(False) + self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) - def _createNetworkManager(self): - if self._network_manager: - self._network_manager.finished.disconnect(self._onRequestFinished) - self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccesibleChanged) + # must not delete the temporary file on Windows + self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curaplugin", delete = False) + location = self._temp_plugin_file.name - self._network_manager = QNetworkAccessManager() - self._network_manager.finished.connect(self._onRequestFinished) - self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) + # write first and close, otherwise on Windows, it cannot read the file + self._temp_plugin_file.write(self._download_reply.readAll()) + self._temp_plugin_file.close() - @pyqtProperty(bool, notify = restartRequiredChanged) - def restartRequired(self): - return self._restart_required + self._checkPluginLicenseOrInstall(location) + return - @pyqtSlot() - def restart(self): - CuraApplication.getInstance().windowClosed() + def _onDownloadComplete(self, location): + return - # Getter & Setter for self._view_category + # Getter & Setters + # -------------------------------------------------------------------------- + def setDownloadProgress(self, progress): + if progress != self._download_progress: + self._download_progress = progress + self.onDownloadProgressChanged.emit() + @pyqtProperty(int, fset = setDownloadProgress, notify = onDownloadProgressChanged) + def downloadProgress(self): + return self._download_progress - @pyqtProperty(bool, notify = onIsDownloadingChanged) + def setIsDownloading(self, is_downloading): + if self._is_downloading != is_downloading: + self._is_downloading = is_downloading + self.onIsDownloadingChanged.emit() + @pyqtProperty(bool, fset = setIsDownloading, notify = onIsDownloadingChanged) def isDownloading(self): return self._is_downloading @@ -573,7 +539,8 @@ class Toolbox(QObject, Extension): - # Filtering + # Model Filtering + # -------------------------------------------------------------------------- @pyqtSlot(str, str) def filterPackages(self, filterType, parameter): if not self._packages_model: From 1ddde146dd3f6c242604f3332cd611090064b2eb Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 10 Apr 2018 17:14:44 +0200 Subject: [PATCH 29/83] CURA-5137 Download URL works now --- plugins/Toolbox/src/Toolbox.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 51ee26c6f1..b80757309d 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -163,8 +163,6 @@ class Toolbox(QObject, Extension): self._restart_dialog_message = message self.showRestartDialog.emit() - - @pyqtSlot() def browsePackages(self): self._createNetworkManager() @@ -174,8 +172,6 @@ class Toolbox(QObject, Extension): self._dialog = self._createDialog("Toolbox.qml") self._dialog.show() - - def _createDialog(self, qml_name): Logger.log("d", "Toolbox: Creating dialog [%s].", qml_name) path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) @@ -373,6 +369,7 @@ class Toolbox(QObject, Extension): Logger.log("i", "Toolbox: Attempting to download & install package from %s.", url) url = QUrl(url) self._download_request = QNetworkRequest(url) + self._download_request.setAttribute(QNetworkRequest.RedirectPolicyAttribute, QNetworkRequest.NoLessSafeRedirectPolicy) self._download_request.setRawHeader(*self._request_header) self._download_reply = self._network_manager.get(self._download_request) self.setDownloadProgress(0) From bd6acc75029e4c8a4d1ab82fd1fb21cc32647fc0 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 11 Apr 2018 11:02:33 +0200 Subject: [PATCH 30/83] CURA-5035 More style improvements --- .../resources/qml/ToolboxDetailTile.qml | 10 +- .../Toolbox/resources/qml/ToolboxFooter.qml | 70 ++++++++---- plugins/Toolbox/src/Toolbox.py | 104 +++++++----------- 3 files changed, 92 insertions(+), 92 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 0ace432a2a..20e8fe548a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -48,7 +48,7 @@ Rectangle Button { id: installButton text: { - if ( manager.isDownloading ) + if ( manager.isDownloading && manager.activePackage == model ) { return catalog.i18nc("@action:button", "Cancel") } @@ -61,8 +61,7 @@ Rectangle { if ( manager.isDownloading ) { - return true - // return manager.activePackage == model ? true : false + return manager.activePackage == model ? true : false } else { @@ -75,7 +74,7 @@ Rectangle { implicitWidth: 96 implicitHeight: 30 - color: UM.Theme.getColor("primary") + color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary") } label: Label { @@ -87,7 +86,8 @@ Rectangle } onClicked: { - console.log( "MODEL", model.download_url ) + console.log( "MODEL", model.id ) + manager.activePackage = model // if ( manager.isDownloading && manager.activePackage == model ) if ( manager.isDownloading ) { diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index b1ef00f313..598514a176 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -11,36 +11,51 @@ import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -Rectangle { +Item +{ width: parent.width height: UM.Theme.getSize("base_unit").height * 4 - color: "transparent" anchors.bottom: parent.bottom - - Label { + Label + { visible: manager.restartRequired text: "You will need to restart Cura before changes in plugins have effect." - height: 30 + height: UM.Theme.getSize("base_unit").height * 2 verticalAlignment: Text.AlignVCenter + anchors + { + top: closeButton.top + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + } } - Button { - id: restartChangedButton + Button + { + id: restartButton text: "Quit Cura" - anchors.right: closeButton.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width + anchors + { + top: closeButton.top + right: closeButton.left + rightMargin: UM.Theme.getSize("default_margin").width + } visible: manager.restartRequired iconName: "dialog-restart" onClicked: manager.restart() - style: ButtonStyle { - background: Rectangle { + style: ButtonStyle + { + background: Rectangle + { implicitWidth: 96 - implicitHeight: 30 - color: UM.Theme.getColor("primary") + implicitHeight: UM.Theme.getSize("base_unit").height * 2 + color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary") } - label: Text { + label: Text + { verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("button_text") - font { + font + { pixelSize: 13 bold: true } @@ -50,12 +65,15 @@ Rectangle { } } - Button { + Button + { id: closeButton text: catalog.i18nc("@action:button", "Close") iconName: "dialog-close" - onClicked: { - if ( manager.isDownloading ) { + onClicked: + { + if ( manager.isDownloading ) + { manager.cancelDownload() } base.close(); @@ -65,19 +83,23 @@ Rectangle { top: parent.top topMargin: UM.Theme.getSize("default_margin").height right: parent.right - rightMargin: UM.Theme.getSize("default_margin").height + rightMargin: UM.Theme.getSize("default_margin").width } - style: ButtonStyle { - background: Rectangle { + style: ButtonStyle + { + background: Rectangle + { color: "transparent" implicitWidth: 96 - implicitHeight: 30 - border { + implicitHeight: UM.Theme.getSize("base_unit").height * 2 + border + { width: 1 color: UM.Theme.getColor("lining") } } - label: Text { + label: Text + { verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("text") text: control.text diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index b80757309d..fef45dec7c 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -52,7 +52,7 @@ class Toolbox(QObject, Extension): self._packages_model = None # Model that list the remote available packages self._showcase_model = None self._authors_model = None - + self._installed_model = None # These properties are for keeping track of the UI state: # ---------------------------------------------------------------------- @@ -73,12 +73,6 @@ class Toolbox(QObject, Extension): # to "author" or a plugin name if it is set to "detail"). self._view_selection = "" - # For any view page above, self._packages_model can be filtered. - # For example: - # self._view_category = "material" - # if self._view_page == "author": - # filter with "author == self._view_selection" - # Active package refers to which package is currently being downloaded, # installed, or otherwise modified. self._active_package = None @@ -88,15 +82,11 @@ class Toolbox(QObject, Extension): self._current_view = "plugins" self._detail_data = {} # Extraneous since can just use the data prop of the model. - - self._restart_required = False self._dialog = None self._restartDialog = None - - self._request_header = [b"User-Agent", str.encode("%s/%s (%s %s)" % (Application.getInstance().getApplicationName(), Application.getInstance().getVersion(), @@ -178,56 +168,12 @@ class Toolbox(QObject, Extension): dialog = Application.getInstance().createQmlComponent(path, {"manager": self}) return dialog - ## Checks if the downloaded plugin ZIP file contains a license file or not. - # If it does, it will show a popup dialog displaying the license to the user. The plugin will be installed if the - # user accepts the license. - # If there is no license file, the plugin will be directory installed. - def _checkPluginLicenseOrInstall(self, file_path): - with zipfile.ZipFile(file_path, "r") as zip_ref: - plugin_id = None - for file in zip_ref.infolist(): - if file.filename.endswith("/"): - plugin_id = file.filename.strip("/") - break - - if plugin_id is None: - msg = i18n_catalog.i18nc("@info:status", "Failed to get plugin ID from {0}", file_path) - msg_title = i18n_catalog.i18nc("@info:tile", "Warning") - self._progress_message = Message(msg, lifetime=0, dismissable=False, title = msg_title) - return - - # find a potential license file - plugin_root_dir = plugin_id + "/" - license_file = None - for f in zip_ref.infolist(): - # skip directories (with file_size = 0) and files not in the plugin directory - if f.file_size == 0 or not f.filename.startswith(plugin_root_dir): - continue - file_name = os.path.basename(f.filename).lower() - file_base_name, file_ext = os.path.splitext(file_name) - if file_base_name in ["license", "licence"]: - license_file = f.filename - break - - # show a dialog for user to read and accept/decline the license - if license_file is not None: - Logger.log("i", "Found license file for plugin [%s], showing the license dialog to the user", plugin_id) - license_content = zip_ref.read(license_file).decode('utf-8') - self.openLicenseDialog(plugin_id, license_content, file_path) - return - - # there is no license file, directly install the plugin - self.installPlugin(file_path) - @pyqtSlot(str) def installPlugin(self, file_path): # Ensure that it starts with a /, as otherwise it doesn't work on windows. if not file_path.startswith("/"): - location = "/" + file_path - else: - location = file_path - - result = PluginRegistry.getInstance().installPlugin("file://" + location) + file_path = "/" + file_path + result = PluginRegistry.getInstance().installPlugin("file://" + file_path) self._newly_installed_plugin_ids.append(result["id"]) self.packagesMetadataChanged.emit() @@ -294,9 +240,6 @@ class Toolbox(QObject, Extension): return self._packages_model is not None def _checkCanUpgrade(self, id, version): - - # TODO: This could maybe be done more efficiently using a dictionary... - # Scan plugin server data for plugin with the given id: for plugin in self._packages_metadata: if id == plugin["id"]: @@ -474,16 +417,51 @@ class Toolbox(QObject, Extension): # must not delete the temporary file on Windows self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curaplugin", delete = False) - location = self._temp_plugin_file.name + file_path = self._temp_plugin_file.name # write first and close, otherwise on Windows, it cannot read the file self._temp_plugin_file.write(self._download_reply.readAll()) self._temp_plugin_file.close() - self._checkPluginLicenseOrInstall(location) + self._onDownloadComplete(file_path) return - def _onDownloadComplete(self, location): + def _onDownloadComplete(self, file_path): + with zipfile.ZipFile(file_path, "r") as zip_ref: + plugin_id = None + for file in zip_ref.infolist(): + if file.filename.endswith("/"): + plugin_id = file.filename.strip("/") + break + + if plugin_id is None: + msg = i18n_catalog.i18nc("@info:status", "Failed to get plugin ID from {0}", file_path) + msg_title = i18n_catalog.i18nc("@info:tile", "Warning") + self._progress_message = Message(msg, lifetime=0, dismissable=False, title = msg_title) + return + + # find a potential license file + plugin_root_dir = plugin_id + "/" + license_file = None + for f in zip_ref.infolist(): + # skip directories (with file_size = 0) and files not in the plugin directory + if f.file_size == 0 or not f.filename.startswith(plugin_root_dir): + continue + file_name = os.path.basename(f.filename).lower() + file_base_name, file_ext = os.path.splitext(file_name) + if file_base_name in ["license", "licence"]: + license_file = f.filename + break + + # show a dialog for user to read and accept/decline the license + if license_file is not None: + Logger.log("i", "Found license file for plugin [%s], showing the license dialog to the user", plugin_id) + license_content = zip_ref.read(license_file).decode('utf-8') + self.openLicenseDialog(plugin_id, license_content, file_path) + return + + # there is no license file, directly install the plugin + self.installPlugin(file_path) return From 80c21acf795a9c40085b422fe1b55367f546bf24 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 11 Apr 2018 11:08:50 +0200 Subject: [PATCH 31/83] Merge branch 'CURA-4644-package-reader' into feature_material_marketplace --- plugins/Toolbox/src/Toolbox.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 9876bffa4e..fef45dec7c 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -223,7 +223,6 @@ class Toolbox(QObject, Extension): plugin["update_url"] = item["file_location"] return self._plugins_model -<<<<<<< HEAD:plugins/Toolbox/src/Toolbox.py @pyqtProperty(QObject, notify = showcaseMetadataChanged) def materialShowcaseModel(self): return self._showcase_model @@ -239,10 +238,6 @@ class Toolbox(QObject, Extension): @pyqtProperty(bool, notify = packagesMetadataChanged) def dataReady(self): return self._packages_model is not None -======= - def _checkCanUpgrade(self, id, version): - # TODO: This could maybe be done more efficiently using a dictionary... ->>>>>>> CURA-4644-package-reader:plugins/PluginBrowser/PluginBrowser.py def _checkCanUpgrade(self, id, version): # Scan plugin server data for plugin with the given id: @@ -255,7 +250,6 @@ class Toolbox(QObject, Extension): return True return False -<<<<<<< HEAD:plugins/Toolbox/src/Toolbox.py def _checkAlreadyInstalled(self, id): metadata = self._plugin_registry.getMetaData(id) # We already installed this plugin, but the registry just doesn't know it yet. @@ -348,8 +342,6 @@ class Toolbox(QObject, Extension): self._download_reply.abort() self._download_reply = None -======= ->>>>>>> CURA-4644-package-reader:plugins/PluginBrowser/PluginBrowser.py def _onRequestFinished(self, reply): reply_url = reply.url().toString() if reply.error() == QNetworkReply.TimeoutError: From a947b768d319fb2e4263acaf83723927f1cbd90c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 11 Apr 2018 14:59:59 +0200 Subject: [PATCH 32/83] CURA-5035 Re-implemented "installed" view --- plugins/Toolbox/resources/qml/Toolbox.qml | 5 +- .../qml/ToolboxDownloadsShowcase.qml | 2 +- .../resources/qml/ToolboxInstalledPage.qml | 101 ++++++++-- .../resources/qml/ToolboxInstalledTile.qml | 2 +- .../resources/qml/ToolboxLoadingPage.qml | 10 +- plugins/Toolbox/src/Toolbox.py | 182 +++++++++--------- 6 files changed, 192 insertions(+), 110 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index ca00a4a8c5..e965aca05a 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -44,7 +44,7 @@ Window ToolboxLoadingPage { id: viewLoading - visible: manager.viewCategory != "installed" && !dataReady + visible: manager.viewCategory != "installed" && manager.viewPage == "loading" // TODO: Replace !dataReady with manager.viewPage == "loading" } ToolboxDownloadsPage @@ -65,8 +65,7 @@ Window ToolboxInstalledPage { id: installedPluginList - visible: manager.viewCategory == "installed" && dataReady - // TODO: Replace !dataReady with manager.viewPage == "loading" + visible: manager.viewCategory == "installed" } } ToolboxShadow diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index 621650a42a..3221602bc0 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -34,7 +34,7 @@ Column Repeater { - model: manager.materialShowcaseModel + model: manager.pluginsShowcaseModel delegate: ToolboxDownloadsShowcaseTile {} } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index b7ec3dad2c..cb17ccadd3 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -1,33 +1,102 @@ // Copyright (c) 2018 Ultimaker B.V. // PluginBrowser is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.7 import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 - -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - import UM 1.1 as UM ScrollView { - anchors.fill: parent - ListView + id: base + frameVisible: true + width: parent.width + height: parent.height + style: UM.Theme.styles.scrollview + Column { - id: pluginList - property var activePlugin - property var filter: "installed" + spacing: UM.Theme.getSize("default_margin").height anchors { - fill: parent - topMargin: UM.Theme.getSize("default_margin").height - bottomMargin: UM.Theme.getSize("default_margin").height - leftMargin: UM.Theme.getSize("default_margin").width - rightMargin: UM.Theme.getSize("default_margin").width + right: parent.right + left: parent.left + leftMargin: UM.Theme.getSize("double_margin").width + topMargin: UM.Theme.getSize("double_margin").height + bottomMargin: UM.Theme.getSize("double_margin").height + top: parent.top + } + height: childrenRect.height + 4 * UM.Theme.getSize("default_margin").height + Label + { + width: parent.width + text: "Plugins" + color: UM.Theme.getColor("text_medium") + font: UM.Theme.getFont("medium") + } + Rectangle + { + color: "transparent" + width: parent.width + height: childrenRect.height + 1 * UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("text_medium") + border.width: UM.Theme.getSize("default_lining").width + Column + { + height: childrenRect.height + anchors + { + top: parent.top + right: parent.right + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + rightMargin: UM.Theme.getSize("default_margin").width + topMargin: UM.Theme.getSize("default_lining").width + bottomMargin: UM.Theme.getSize("default_lining").width + } + Repeater + { + id: materialList + model: manager.packagesModel + delegate: ToolboxInstalledTile {} + } + } + } + Label + { + width: base.width + text: "Materials" + color: UM.Theme.getColor("text_medium") + font: UM.Theme.getFont("medium") + } + Rectangle + { + color: "transparent" + width: parent.width + height: childrenRect.height + 1 * UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("text_medium") + border.width: UM.Theme.getSize("default_lining").width + Column + { + height: childrenRect.height + anchors + { + top: parent.top + right: parent.right + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + rightMargin: UM.Theme.getSize("default_margin").width + topMargin: UM.Theme.getSize("default_lining").width + bottomMargin: UM.Theme.getSize("default_lining").width + } + Repeater + { + id: pluginList + model: manager.packagesModel + delegate: ToolboxInstalledTile {} + } + } } - model: manager.pluginsModel - delegate: ToolboxInstalledTile {} } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 5ab4d1b2bf..9081801bb3 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -19,7 +19,7 @@ Component { // Don't show required plugins as they can't be managed anyway: height: !model.required ? 84 : 0 visible: !model.required ? true : false - color: Qt.rgba(1.0, 0.0, 0.0, 0.1) + // color: Qt.rgba(1.0, 0.0, 0.0, 0.1) anchors { left: parent.left right: parent.right diff --git a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml index 91d4cec013..0ef8585679 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml @@ -14,5 +14,13 @@ Rectangle id: base width: parent.width height: parent.height - color: "red" + color: "transparent" + Label + { + text: "Fetching packages..." + anchors + { + centerIn: parent + } + } } diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index fef45dec7c..de1a7f6156 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -22,6 +22,7 @@ import platform import zipfile from cura.CuraApplication import CuraApplication +from cura.CuraPackageManager import CuraPackageManager from .AuthorsModel import AuthorsModel from .PackagesModel import PackagesModel @@ -33,6 +34,7 @@ class Toolbox(QObject, Extension): super().__init__(parent) self._plugin_registry = Application.getInstance().getPluginRegistry() + self._package_manager = None self._packages_version = self._plugin_registry.APIVersion self._api_version = 1 self._api_url = "https://api-staging.ultimaker.com/cura-packages/v{api_version}/cura/v{package_version}".format( api_version = self._api_version, package_version = self._packages_version) @@ -48,11 +50,14 @@ class Toolbox(QObject, Extension): self._network_manager = None - self._packages_metadata = [] # Stores the remote information of the packages - self._packages_model = None # Model that list the remote available packages - self._showcase_model = None + self._packages_metadata = [] + self._packages_model = None + self._plugins_showcase_model = None + self._plugins_installed_model = None + self._materials_showcase_model = None + self._materials_installed_model = None self._authors_model = None - self._installed_model = None + # These properties are for keeping track of the UI state: # ---------------------------------------------------------------------- @@ -66,7 +71,7 @@ class Toolbox(QObject, Extension): # View page defines which type of page layout to use. For example, # possible values include "overview", "detail" or "author". # Formerly self._detail_view. - self._view_page = "overview" + self._view_page = "loading" # View selection defines what is currently selected and should be # used in filtering. This could be an author name (if _view_page is set @@ -155,9 +160,19 @@ class Toolbox(QObject, Extension): @pyqtSlot() def browsePackages(self): - self._createNetworkManager() - self.requestShowcase() - self.requestPackages() + self._package_manager = Application.getInstance().getCuraPackageManager() + # Create the network manager: + # This was formerly its own function but really had no reason to be as + # it was never called more than once ever. + if self._network_manager: + self._network_manager.finished.disconnect(self._onRequestFinished) + self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccesibleChanged) + self._network_manager = QNetworkAccessManager() + self._network_manager.finished.connect(self._onRequestFinished) + self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) + + self._requestShowcase() + self._requestPackages() if not self._dialog: self._dialog = self._createDialog("Toolbox.qml") self._dialog.show() @@ -224,8 +239,8 @@ class Toolbox(QObject, Extension): return self._plugins_model @pyqtProperty(QObject, notify = showcaseMetadataChanged) - def materialShowcaseModel(self): - return self._showcase_model + def pluginsShowcaseModel(self): + return self._plugins_showcase_model @pyqtProperty(QObject, notify = packagesMetadataChanged) def packagesModel(self): @@ -239,6 +254,18 @@ class Toolbox(QObject, Extension): def dataReady(self): return self._packages_model is not None + @pyqtProperty(bool, notify = restartRequiredChanged) + def restartRequired(self): + return self._restart_required + + @pyqtSlot() + def restart(self): + CuraApplication.getInstance().windowClosed() + + + + # Checks + # -------------------------------------------------------------------------- def _checkCanUpgrade(self, id, version): # Scan plugin server data for plugin with the given id: for plugin in self._packages_metadata: @@ -250,57 +277,32 @@ class Toolbox(QObject, Extension): return True return False - def _checkAlreadyInstalled(self, id): - metadata = self._plugin_registry.getMetaData(id) - # We already installed this plugin, but the registry just doesn't know it yet. - if id in self._newly_installed_plugin_ids: - return True - # We already uninstalled this plugin, but the registry just doesn't know it yet: - elif id in self._newly_uninstalled_plugin_ids: + def _checkInstalled(self, id): + if id in self._will_uninstall: return False - elif metadata != {}: + if id in self._package_manager.getInstalledPackages(): return True - else: - return False - - def _checkInstallStatus(self, plugin_id): - if plugin_id in self._plugin_registry.getInstalledPlugins(): - return "installed" - else: - return "uninstalled" + if id in self._will_install: + return True + return False def _checkEnabled(self, id): if id in self._plugin_registry.getActivePlugins(): return True return False - def _createNetworkManager(self): - if self._network_manager: - self._network_manager.finished.disconnect(self._onRequestFinished) - self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccesibleChanged) - self._network_manager = QNetworkAccessManager() - self._network_manager.finished.connect(self._onRequestFinished) - self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) - - @pyqtProperty(bool, notify = restartRequiredChanged) - def restartRequired(self): - return self._restart_required - - @pyqtSlot() - def restart(self): - CuraApplication.getInstance().windowClosed() # Make API Calls # -------------------------------------------------------------------------- - def requestPackages(self): + def _requestPackages(self): Logger.log("i", "Toolbox: Requesting package list from server.") url = QUrl("{base_url}/packages".format(base_url = self._api_url)) self._get_packages_request = QNetworkRequest(url) self._get_packages_request.setRawHeader(*self._request_header) self._network_manager.get(self._get_packages_request) - def requestShowcase(self): + def _requestShowcase(self): Logger.log("i", "Toolbox: Requesting showcase list from server.") url = QUrl("{base_url}/showcase".format(base_url = self._api_url)) self._get_showcase_request = QNetworkRequest(url) @@ -381,6 +383,7 @@ class Toolbox(QObject, Extension): self._authors_metadata.append(package["author"]) self._authors_model.setMetaData(self._authors_metadata) self.authorsMetadataChanged.emit() + self.setViewPage("overview") except json.decoder.JSONDecodeError: Logger.log("w", "Toolbox: Received invalid JSON for package list.") return @@ -390,12 +393,12 @@ class Toolbox(QObject, Extension): try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) # Create packages model with all packages: - if not self._showcase_model: - self._showcase_model = PackagesModel() + if not self._plugins_showcase_model: + self._plugins_showcase_model = PackagesModel() self._showcase_metadata = json_data["data"] print(self._showcase_metadata) - self._showcase_model.setPackagesMetaData(self._showcase_metadata) - for package in self._showcase_model.items: + self._plugins_showcase_model.setPackagesMetaData(self._showcase_metadata) + for package in self._plugins_showcase_model.items: print(package) self.showcaseMetadataChanged.emit() except json.decoder.JSONDecodeError: @@ -406,63 +409,66 @@ class Toolbox(QObject, Extension): pass def _onDownloadProgress(self, bytes_sent, bytes_total): - print("Downloading bytes:", bytes_total) if bytes_total > 0: new_progress = bytes_sent / bytes_total * 100 self.setDownloadProgress(new_progress) if new_progress == 100.0: - Logger.log("i", "Toolbox: Download complete.") self.setIsDownloading(False) self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) - # must not delete the temporary file on Windows - self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curaplugin", delete = False) + self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curapackage", delete = False) file_path = self._temp_plugin_file.name - # write first and close, otherwise on Windows, it cannot read the file self._temp_plugin_file.write(self._download_reply.readAll()) self._temp_plugin_file.close() - self._onDownloadComplete(file_path) return def _onDownloadComplete(self, file_path): - with zipfile.ZipFile(file_path, "r") as zip_ref: - plugin_id = None - for file in zip_ref.infolist(): - if file.filename.endswith("/"): - plugin_id = file.filename.strip("/") - break + Logger.log("i", "Toolbox: Download complete.") + print(file_path) + if self._package_manager.isPackageFile(file_path): + self._package_manager.install(file_path) + return + else: + Logger.log("w", "Toolbox: Package was not a valid CuraPackage.") - if plugin_id is None: - msg = i18n_catalog.i18nc("@info:status", "Failed to get plugin ID from {0}", file_path) - msg_title = i18n_catalog.i18nc("@info:tile", "Warning") - self._progress_message = Message(msg, lifetime=0, dismissable=False, title = msg_title) - return - - # find a potential license file - plugin_root_dir = plugin_id + "/" - license_file = None - for f in zip_ref.infolist(): - # skip directories (with file_size = 0) and files not in the plugin directory - if f.file_size == 0 or not f.filename.startswith(plugin_root_dir): - continue - file_name = os.path.basename(f.filename).lower() - file_base_name, file_ext = os.path.splitext(file_name) - if file_base_name in ["license", "licence"]: - license_file = f.filename - break - - # show a dialog for user to read and accept/decline the license - if license_file is not None: - Logger.log("i", "Found license file for plugin [%s], showing the license dialog to the user", plugin_id) - license_content = zip_ref.read(license_file).decode('utf-8') - self.openLicenseDialog(plugin_id, license_content, file_path) - return - - # there is no license file, directly install the plugin - self.installPlugin(file_path) - return + # with zipfile.ZipFile(file_path, "r") as zip_ref: + # plugin_id = None + # for file in zip_ref.infolist(): + # if file.filename.endswith("/"): + # plugin_id = file.filename.strip("/") + # break + # + # if plugin_id is None: + # msg = i18n_catalog.i18nc("@info:status", "Failed to get plugin ID from {0}", file_path) + # msg_title = i18n_catalog.i18nc("@info:tile", "Warning") + # self._progress_message = Message(msg, lifetime=0, dismissable=False, title = msg_title) + # return + # + # # find a potential license file + # plugin_root_dir = plugin_id + "/" + # license_file = None + # for f in zip_ref.infolist(): + # # skip directories (with file_size = 0) and files not in the plugin directory + # if f.file_size == 0 or not f.filename.startswith(plugin_root_dir): + # continue + # file_name = os.path.basename(f.filename).lower() + # file_base_name, file_ext = os.path.splitext(file_name) + # if file_base_name in ["license", "licence"]: + # license_file = f.filename + # break + # + # # show a dialog for user to read and accept/decline the license + # if license_file is not None: + # Logger.log("i", "Found license file for plugin [%s], showing the license dialog to the user", plugin_id) + # license_content = zip_ref.read(license_file).decode('utf-8') + # self.openLicenseDialog(plugin_id, license_content, file_path) + # return + # + # # there is no license file, directly install the plugin + # self.installPlugin(file_path) + # return From 594e9aa4143a0aded716ac3a0c6be53dedd4384c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 11 Apr 2018 17:05:16 +0200 Subject: [PATCH 33/83] Cura-5035 Further style improvements --- plugins/Toolbox/resources/qml/Toolbox.qml | 1 - .../resources/qml/ToolboxAuthorPage.qml | 2 +- .../resources/qml/ToolboxDetailPage.qml | 2 +- .../resources/qml/ToolboxDetailTile.qml | 5 +- .../qml/ToolboxDownloadsGridTile.qml | 4 +- .../resources/qml/ToolboxDownloadsPage.qml | 2 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 2 +- .../resources/qml/ToolboxInstalledPage.qml | 6 +- .../resources/qml/ToolboxInstalledTile.qml | 604 +++++------------- 9 files changed, 163 insertions(+), 465 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index e965aca05a..83c3d369d3 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -45,7 +45,6 @@ Window { id: viewLoading visible: manager.viewCategory != "installed" && manager.viewPage == "loading" - // TODO: Replace !dataReady with manager.viewPage == "loading" } ToolboxDownloadsPage { diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 7934526639..a7562ca50b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -112,7 +112,7 @@ Item } Rectangle { - color: UM.Theme.getColor("text_medium") + color: UM.Theme.getColor("lining") width: parent.width height: UM.Theme.getSize("default_lining").height anchors.bottom: parent.bottom diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 85cb01240c..4e7a79225b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -124,7 +124,7 @@ Item } Rectangle { - color: UM.Theme.getColor("text_medium") + color: UM.Theme.getColor("lining") width: parent.width height: UM.Theme.getSize("default_lining").height anchors.bottom: parent.bottom diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 20e8fe548a..d9c6ae7d30 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -79,9 +79,10 @@ Rectangle label: Label { text: control.text - color: "white" + color: control.hovered ? UM.Theme.getColor("button_text") : UM.Theme.getColor("button_text_hover") verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter + font: UM.Theme.getFont("default_bold") } } onClicked: @@ -109,7 +110,7 @@ Rectangle } Rectangle { - color: UM.Theme.getColor("text_medium") + color: UM.Theme.getColor("lining") width: parent.width height: UM.Theme.getSize("default_lining").height anchors.bottom: parent.bottom diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 3fa717e70f..cad2691d1c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -32,8 +32,8 @@ Item width: UM.Theme.getSize("toolbox_thumbnail_small").width height: UM.Theme.getSize("toolbox_thumbnail_small").height color: "white" - border.width: 1 - border.color: UM.Theme.getColor("text_medium") + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") Image { anchors.centerIn: parent width: UM.Theme.getSize("toolbox_thumbnail_small").width - 26 diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml index 2171a4e2bf..3f6f15151e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml @@ -27,7 +27,7 @@ ScrollView } Rectangle { - color: UM.Theme.getColor("text_medium") + color: UM.Theme.getColor("lining") width: parent.width - 2 * parent.padding height: UM.Theme.getSize("default_lining").height } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index a4eae5b4ab..94255dd946 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -18,7 +18,7 @@ Item width: UM.Theme.getSize("toolbox_thumbnail_medium").width height: UM.Theme.getSize("toolbox_thumbnail_medium").height border.width: 1 - border.color: UM.Theme.getColor("text_medium") + border.color: UM.Theme.getColor("lining") anchors { top: parent.top diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index cb17ccadd3..4ebd13ba84 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -11,7 +11,7 @@ import UM 1.1 as UM ScrollView { id: base - frameVisible: true + frameVisible: false width: parent.width height: parent.height style: UM.Theme.styles.scrollview @@ -40,7 +40,7 @@ ScrollView color: "transparent" width: parent.width height: childrenRect.height + 1 * UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("text_medium") + border.color: UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width Column { @@ -75,7 +75,7 @@ ScrollView color: "transparent" width: parent.width height: childrenRect.height + 1 * UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("text_medium") + border.color: UM.Theme.getColor("lining") border.width: UM.Theme.getSize("default_lining").width Column { diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 9081801bb3..e2d04eee26 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -6,479 +6,177 @@ import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 - -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - import UM 1.1 as UM -Component { - id: pluginDelegate - - Rectangle { - - // Don't show required plugins as they can't be managed anyway: - height: !model.required ? 84 : 0 - visible: !model.required ? true : false - // color: Qt.rgba(1.0, 0.0, 0.0, 0.1) - anchors { +Item +{ + id: base + height: UM.Theme.getSize("base_unit").height * 8 + anchors + { + left: parent.left + right: parent.right + } + Rectangle + { + color: UM.Theme.getColor("lining") + width: parent.width + height: UM.Theme.getSize("default_lining").height + anchors.bottom: parent.bottom + } + Column + { + id: pluginInfo + property var color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining") + height: parent.height + anchors + { left: parent.left - right: parent.right + top: parent.top + right: authorInfo.left + topMargin: UM.Theme.getSize("default_margin").height + rightMargin: UM.Theme.getSize("default_margin").width } - - - // Bottom border: - Rectangle { - color: UM.Theme.getColor("lining") + Label + { + text: model.name width: parent.width - height: 1 - anchors.bottom: parent.bottom + height: 24 + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + font { + pixelSize: 13 + bold: true + } + color: pluginInfo.color + } + Text + { + text: model.description + width: parent.width + height: 36 + clip: true + wrapMode: Text.WordWrap + color: pluginInfo.color + elide: Text.ElideRight + } + } + Column + { + id: authorInfo + width: 192 + height: parent.height + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("default_margin").height + right: pluginActions.left + rightMargin: UM.Theme.getSize("default_margin").width + } + Label + { + text: ""+model.author+"" + width: parent.width + height: 24 + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignLeft + onLinkActivated: Qt.openUrlExternally("mailto:"+model.author_email+"?Subject=Cura: "+model.name+" Plugin") + color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining") + } + } + + // Plugin actions + Column + { + id: pluginActions + width: childrenRect.width + height: childrenRect.height + spacing: UM.Theme.getSize("default_margin").height + anchors + { + top: parent.top + right: parent.right + topMargin: UM.Theme.getSize("default_margin").height } - // Plugin info - Column { - id: pluginInfo - - property var color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining") - - // Styling: - height: parent.height - anchors { - left: parent.left - top: parent.top - topMargin: UM.Theme.getSize("default_margin").height - right: authorInfo.left - rightMargin: UM.Theme.getSize("default_margin").width - } - - - Label { - text: model.name - width: parent.width - height: 24 - wrapMode: Text.WordWrap - verticalAlignment: Text.AlignVCenter - font { - pixelSize: 13 - bold: true - } - color: pluginInfo.color - - } - - Text { - text: model.description - width: parent.width - height: 36 - clip: true - wrapMode: Text.WordWrap - color: pluginInfo.color - elide: Text.ElideRight - } - } - - // Author info - Column { - id: authorInfo - width: 192 - height: parent.height - anchors { - top: parent.top - topMargin: UM.Theme.getSize("default_margin").height - right: pluginActions.left - rightMargin: UM.Theme.getSize("default_margin").width - } - - Label { - text: ""+model.author+"" - width: parent.width - height: 24 - wrapMode: Text.WordWrap - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - onLinkActivated: Qt.openUrlExternally("mailto:"+model.author_email+"?Subject=Cura: "+model.name+" Plugin") - color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining") - } - } - - // Plugin actions - Row { - id: pluginActions - - width: 96 - height: parent.height - anchors { - top: parent.top - right: parent.right - topMargin: UM.Theme.getSize("default_margin").height - } - layoutDirection: Qt.RightToLeft - spacing: UM.Theme.getSize("default_margin").width - - // For 3rd-Party Plugins: - Button { - id: installButton - text: { - if ( manager.isDownloading && pluginList.activePlugin == model ) { - return catalog.i18nc( "@action:button", "Cancel" ); - } else { - if (model.can_upgrade) { - return catalog.i18nc("@action:button", "Update"); - } - return catalog.i18nc("@action:button", "Install"); - } - } - enabled: + Button { + id: removeButton + text: "Uninstall" + visible: model.can_uninstall && model.status == "installed" + enabled: !manager.isDownloading + style: ButtonStyle + { + background: Rectangle { - if ( manager.isDownloading ) + implicitWidth: UM.Theme.getSize("base_unit").width * 8 + implicitHeight: UM.Theme.getSize("base_unit").width * 2.5 + color: "transparent" + border { - return pluginList.activePlugin == model ? true : false - } - else - { - return true + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") } } - opacity: enabled ? 1.0 : 0.5 - visible: model.external && ((model.status !== "installed") || model.can_upgrade) - style: ButtonStyle { - background: Rectangle { - implicitWidth: 96 - implicitHeight: 30 - color: "transparent" - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Label { - text: control.text - color: UM.Theme.getColor("text") - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - } - onClicked: { - if ( manager.isDownloading && pluginList.activePlugin == model ) { - manager.cancelDownload(); - } else { - pluginList.activePlugin = model; - if ( model.can_upgrade ) { - manager.downloadAndInstallPlugin( model.update_url ); - } else { - manager.downloadAndInstallPlugin( model.file_location ); - } - - } + label: Text { + text: control.text + color: UM.Theme.getColor("text") + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter } } - Button { - id: removeButton - text: "Uninstall" - visible: model.can_uninstall && model.status == "installed" - enabled: !manager.isDownloading - style: ButtonStyle { - background: Rectangle { - implicitWidth: 96 - implicitHeight: 30 - color: "transparent" - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text { - text: control.text - color: UM.Theme.getColor("text") - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - } - onClicked: manager.removePlugin( model.id ) - } + onClicked: manager.removePlugin( model.id ) + } - // For Ultimaker Plugins: - Button { - id: enableButton - text: "Enable" - visible: !model.external && model.enabled == false - style: ButtonStyle { - background: Rectangle { - implicitWidth: 96 - implicitHeight: 30 - color: "transparent" - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text { - text: control.text - color: UM.Theme.getColor("text") - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } + Button { + id: updateButton + text: "Update" + enabled: model.can_update + style: ButtonStyle + { + background: Rectangle + { + implicitWidth: UM.Theme.getSize("base_unit").width * 8 + implicitHeight: UM.Theme.getSize("base_unit").width * 2.5 + color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary") } - onClicked: { - manager.enablePlugin(model.id); + label: Label + { + text: control.text + color: control.hovered ? UM.Theme.getColor("button_text") : UM.Theme.getColor("button_text_hover") + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font: UM.Theme.getFont("default_bold") } } - Button { - id: disableButton - text: "Disable" - visible: !model.external && model.enabled == true - style: ButtonStyle { - background: Rectangle { - implicitWidth: 96 - implicitHeight: 30 - color: "transparent" - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text { - text: control.text - color: UM.Theme.getColor("text") - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } + onClicked: + { + manager.updatePackage(model.id); + } + } + ProgressBar + { + id: progressbar + minimumValue: 0; + maximumValue: 100 + anchors.left: installButton.left + anchors.right: installButton.right + anchors.top: installButton.bottom + anchors.topMargin: 4 + value: manager.isDownloading ? manager.downloadProgress : 0 + visible: manager.isDownloading && pluginList.activePlugin == model + style: ProgressBarStyle + { + background: Rectangle + { + color: "lightgray" + implicitHeight: 6 } - onClicked: { - manager.disablePlugin(model.id); + progress: Rectangle + { + color: UM.Theme.getColor("primary") } } - /* - Rectangle { - id: removeControls - visible: model.status == "installed" && model.enabled - width: 96 - height: 30 - color: "transparent" - Button { - id: removeButton - text: "Disable" - enabled: { - if ( manager.isDownloading && pluginList.activePlugin == model ) { - return false; - } else if ( model.required ) { - return false; - } else { - return true; - } - } - onClicked: { - manager.disablePlugin(model.id); - } - style: ButtonStyle { - background: Rectangle { - color: "white" - implicitWidth: 96 - implicitHeight: 30 - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: "grey" - text: control.text - horizontalAlignment: Text.AlignLeft - } - } - } - Button { - id: removeDropDown - property bool open: false - UM.RecolorImage { - anchors.centerIn: parent - height: 10 - width: 10 - source: UM.Theme.getIcon("arrow_bottom") - color: "grey" - } - enabled: { - if ( manager.isDownloading && pluginList.activePlugin == model ) { - return false; - } else if ( model.required ) { - return false; - } else { - return true; - } - } - anchors.right: parent.right - style: ButtonStyle { - background: Rectangle { - color: "transparent" - implicitWidth: 30 - implicitHeight: 30 - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: "grey" - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - - - - // For the disable option: - // onClicked: pluginList.model.setEnabled(model.id, checked) - - onClicked: { - if ( !removeDropDown.open ) { - removeDropDown.open = true - } - else { - removeDropDown.open = false - } - } - } - - Rectangle { - id: divider - width: 1 - height: parent.height - anchors.right: removeDropDown.left - color: UM.Theme.getColor("lining") - } - - Column { - id: options - anchors { - top: removeButton.bottom - left: parent.left - right: parent.right - } - height: childrenRect.height - visible: removeDropDown.open - - Button { - id: disableButton - text: "Remove" - height: 30 - width: parent.width - onClicked: { - removeDropDown.open = false; - manager.removePlugin( model.id ); - } - } - } - } - */ - /* - Button { - id: enableButton - visible: !model.enabled && model.status == "installed" - onClicked: manager.enablePlugin( model.id ); - - text: "Enable" - style: ButtonStyle { - background: Rectangle { - color: "transparent" - implicitWidth: 96 - implicitHeight: 30 - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("text") - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - } - - Button { - id: updateButton - visible: model.status == "installed" && model.can_upgrade && model.enabled - // visible: model.already_installed - text: { - // If currently downloading: - if ( manager.isDownloading && pluginList.activePlugin == model ) { - return catalog.i18nc( "@action:button", "Cancel" ); - } else { - return catalog.i18nc("@action:button", "Update"); - } - } - style: ButtonStyle { - background: Rectangle { - color: UM.Theme.getColor("primary") - implicitWidth: 96 - implicitHeight: 30 - // radius: 4 - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: "white" - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - } - Button { - id: externalControls - visible: model.status == "available" ? true : false - text: { - // If currently downloading: - if ( manager.isDownloading && pluginList.activePlugin == model ) { - return catalog.i18nc( "@action:button", "Cancel" ); - } else { - return catalog.i18nc("@action:button", "Install"); - } - } - onClicked: { - if ( manager.isDownloading && pluginList.activePlugin == model ) { - manager.cancelDownload(); - } else { - pluginList.activePlugin = model; - manager.downloadAndInstallPlugin( model.file_location ); - } - } - style: ButtonStyle { - background: Rectangle { - color: "transparent" - implicitWidth: 96 - implicitHeight: 30 - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: "grey" - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - } - */ - ProgressBar { - id: progressbar - minimumValue: 0; - maximumValue: 100 - anchors.left: installButton.left - anchors.right: installButton.right - anchors.top: installButton.bottom - anchors.topMargin: 4 - value: manager.isDownloading ? manager.downloadProgress : 0 - visible: manager.isDownloading && pluginList.activePlugin == model - style: ProgressBarStyle { - background: Rectangle { - color: "lightgray" - implicitHeight: 6 - } - progress: Rectangle { - color: UM.Theme.getColor("primary") - } - } - } - } } } From 87c194178d825ec688ee2b8d8bb199989fbdbbd7 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 12 Apr 2018 12:49:31 +0200 Subject: [PATCH 34/83] CURA-5035 Added fake material showcase model --- plugins/Toolbox/resources/qml/Toolbox.qml | 3 +- .../resources/qml/ToolboxAuthorPage.qml | 2 +- .../resources/qml/ToolboxBackColumn.qml | 3 +- .../resources/qml/ToolboxDetailList.qml | 2 +- .../resources/qml/ToolboxDetailPage.qml | 2 +- .../resources/qml/ToolboxDetailTile.qml | 2 +- .../resources/qml/ToolboxDownloadsGrid.qml | 2 +- .../qml/ToolboxDownloadsGridTile.qml | 2 +- .../resources/qml/ToolboxDownloadsPage.qml | 2 +- .../qml/ToolboxDownloadsShowcase.qml | 13 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 27 ++-- .../Toolbox/resources/qml/ToolboxFooter.qml | 2 +- .../Toolbox/resources/qml/ToolboxHeader.qml | 2 +- .../resources/qml/ToolboxInstalledPage.qml | 2 +- .../resources/qml/ToolboxInstalledTile.qml | 10 +- .../resources/qml/ToolboxLicenseDialog.qml | 2 +- .../resources/qml/ToolboxLoadingPage.qml | 6 +- .../resources/qml/ToolboxRestartDialog.qml | 2 +- .../Toolbox/resources/qml/ToolboxShadow.qml | 2 +- plugins/Toolbox/src/Toolbox.py | 117 ++++++++---------- 20 files changed, 95 insertions(+), 110 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 83c3d369d3..ab7c731e7d 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 @@ -14,7 +14,6 @@ import UM 1.1 as UM Window { id: base - property bool dataReady: manager.dataReady title: catalog.i18nc("@title:tab", "Toolbox"); modality: Qt.ApplicationModal width: 720 * screenScaleFactor diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index a7562ca50b..76f62f2a0d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml index dc15c42677..a0332a0a42 100644 --- a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 @@ -43,6 +43,7 @@ Item { manager.viewPage = "overview" manager.filterPackages("type", manager.viewCategory) + manager.filterAuthors("type", manager.viewCategory) } style: ButtonStyle { diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index 1d391496c4..0ac45d93b5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 4e7a79225b..5db7a37f98 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index d9c6ae7d30..16f719c478 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index a1e86552bf..ea14ef1cf2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index cad2691d1c..7016b09cd9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml index 3f6f15151e..ed905e7845 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index 3221602bc0..7e31d4a182 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 @@ -34,7 +34,16 @@ Column Repeater { - model: manager.pluginsShowcaseModel + model: { + if ( manager.viewCategory == "plugin" ) + { + return manager.pluginsShowcaseModel + } + if ( manager.viewCategory == "material" ) + { + return manager.materialsShowcaseModel + } + } delegate: ToolboxDownloadsShowcaseTile {} } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 94255dd946..830ef1ac5a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 @@ -51,19 +51,20 @@ Item { anchors.fill: parent onClicked: { - if ( manager.viewCategory == "material" ) + switch(manager.viewCategory) { - manager.viewSelection = model.name - manager.viewPage = "author" - manager.filterAuthors("name", model.name) - manager.filterPackages("author_name", model.name) - } - else - { - manager.viewSelection = model.id - manager.viewPage = "detail" - manager.filterAuthors("name", model.author_name) - manager.filterPackages("id", model.id) + case "material": + manager.viewSelection = model.name + manager.viewPage = "author" + manager.filterAuthors("name", model.name) + manager.filterPackages("author_name", model.name) + break + default: + manager.viewSelection = model.id + manager.viewPage = "detail" + manager.filterAuthors("name", model.author_name) + manager.filterPackages("id", model.id) + break } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index 598514a176..fcbc2f0ddc 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 16c82866dc..9abe315d1b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index 4ebd13ba84..cfe85dab92 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index e2d04eee26..c78cd8eff5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 @@ -157,20 +157,18 @@ Item ProgressBar { id: progressbar - minimumValue: 0; - maximumValue: 100 anchors.left: installButton.left anchors.right: installButton.right anchors.top: installButton.bottom anchors.topMargin: 4 value: manager.isDownloading ? manager.downloadProgress : 0 - visible: manager.isDownloading && pluginList.activePlugin == model + visible: manager.isDownloading style: ProgressBarStyle { background: Rectangle { - color: "lightgray" - implicitHeight: 6 + color: UM.Theme.getColor("lining") + implicitHeight: Math.floor(UM.Theme.getSize("base_unit").height / 2) } progress: Rectangle { diff --git a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml index eb9f7fb5e7..c08b93b13d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml index 0ef8585679..755479803e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml @@ -1,13 +1,9 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Dialogs 1.1 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 -import UM 1.1 as UM - -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles Rectangle { diff --git a/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml b/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml index ab95bddef6..a0c961682c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Dialogs 1.1 diff --git a/plugins/Toolbox/resources/qml/ToolboxShadow.qml b/plugins/Toolbox/resources/qml/ToolboxShadow.qml index 362c88575d..f22e3b5cc3 100644 --- a/plugins/Toolbox/resources/qml/ToolboxShadow.qml +++ b/plugins/Toolbox/resources/qml/ToolboxShadow.qml @@ -1,5 +1,5 @@ // Copyright (c) 2018 Ultimaker B.V. -// PluginBrowser is released under the terms of the LGPLv3 or higher. +// Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index de1a7f6156..bf702c34b7 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -48,7 +48,17 @@ class Toolbox(QObject, Extension): self._is_downloading = False self._network_manager = None - + self._request_header = [ + b"User-Agent", + str.encode( + "%s/%s (%s %s)" % ( + Application.getInstance().getApplicationName(), + Application.getInstance().getVersion(), + platform.system(), + platform.machine(), + ) + ) + ] self._packages_metadata = [] self._packages_model = None @@ -58,19 +68,15 @@ class Toolbox(QObject, Extension): self._materials_installed_model = None self._authors_model = None - # These properties are for keeping track of the UI state: # ---------------------------------------------------------------------- - # View category defines which filter to use, and therefore effectively # which category is currently being displayed. For example, possible # values include "plugin" or "material", but also "installed". - # Formerly self._current_view. self._view_category = "plugin" # View page defines which type of page layout to use. For example, # possible values include "overview", "detail" or "author". - # Formerly self._detail_view. self._view_page = "loading" # View selection defines what is currently selected and should be @@ -82,55 +88,40 @@ class Toolbox(QObject, Extension): # installed, or otherwise modified. self._active_package = None - - # Nowadays can be 'plugins', 'materials' or 'installed' - self._current_view = "plugins" - self._detail_data = {} # Extraneous since can just use the data prop of the model. - - self._restart_required = False - self._dialog = None self._restartDialog = None - - self._request_header = [b"User-Agent", - str.encode("%s/%s (%s %s)" % (Application.getInstance().getApplicationName(), - Application.getInstance().getVersion(), - platform.system(), - platform.machine(), - ) - ) - ] + self._restart_required = False # Installed plugins are really installed after reboot. In order to # prevent the user from downloading the same file over and over again, # we keep track of the upgraded plugins. - self._newly_installed_plugin_ids = [] self._newly_uninstalled_plugin_ids = [] - self._plugin_statuses = {} # type: Dict[str, str] - # variables for the license agreement dialog self._license_dialog_plugin_name = "" self._license_dialog_license_content = "" self._license_dialog_plugin_file_location = "" self._restart_dialog_message = "" - showLicenseDialog = pyqtSignal() - showRestartDialog = pyqtSignal() - + # Metadata changes packagesMetadataChanged = pyqtSignal() authorsMetadataChanged = pyqtSignal() - showcaseMetadataChanged = pyqtSignal() + pluginsShowcaseMetadataChanged = pyqtSignal() + materialsShowcaseMetadataChanged = pyqtSignal() + # Downloading changes activePackageChanged = pyqtSignal() onDownloadProgressChanged = pyqtSignal() onIsDownloadingChanged = pyqtSignal() restartRequiredChanged = pyqtSignal() + # UI changes viewChanged = pyqtSignal() detailViewChanged = pyqtSignal() filterChanged = pyqtSignal() + showLicenseDialog = pyqtSignal() + showRestartDialog = pyqtSignal() @pyqtSlot(result = str) def getLicenseDialogPluginName(self): @@ -223,7 +214,7 @@ class Toolbox(QObject, Extension): @pyqtProperty(QObject, notify = packagesMetadataChanged) def pluginsModel(self): - self._plugins_model = PluginsModel(None, self._current_view) + self._plugins_model = PluginsModel(None, self._view_category) # self._plugins_model.update() # Check each plugin the registry for matching plugin from server @@ -238,10 +229,14 @@ class Toolbox(QObject, Extension): plugin["update_url"] = item["file_location"] return self._plugins_model - @pyqtProperty(QObject, notify = showcaseMetadataChanged) + @pyqtProperty(QObject, notify = pluginsShowcaseMetadataChanged) def pluginsShowcaseModel(self): return self._plugins_showcase_model + @pyqtProperty(QObject, notify = materialsShowcaseMetadataChanged) + def materialsShowcaseModel(self): + return self._materials_showcase_model + @pyqtProperty(QObject, notify = packagesMetadataChanged) def packagesModel(self): return self._packages_model @@ -344,6 +339,7 @@ class Toolbox(QObject, Extension): self._download_reply.abort() self._download_reply = None + # TODO: This function is sooooo ugly. Needs a rework: def _onRequestFinished(self, reply): reply_url = reply.url().toString() if reply.error() == QNetworkReply.TimeoutError: @@ -384,6 +380,28 @@ class Toolbox(QObject, Extension): self._authors_model.setMetaData(self._authors_metadata) self.authorsMetadataChanged.emit() self.setViewPage("overview") + + # TODO: Also replace this with a proper API call: + if not self._materials_showcase_model: + self._materials_showcase_model = AuthorsModel() + # TODO: Remove this hacky code once there's an API call for this. + self._materials_showcase_model.setMetaData([ + { + "name": "DSM", + "email": "contact@dsm.nl", + "website": "www.dsm.nl", + "type": "material" + }, + { + "name": "BASF", + "email": "contact@basf.de", + "website": "www.basf.de", + "type": "material" + } + ]) + self.materialsShowcaseMetadataChanged.emit() + self.setViewPage("overview") + except json.decoder.JSONDecodeError: Logger.log("w", "Toolbox: Received invalid JSON for package list.") return @@ -400,7 +418,7 @@ class Toolbox(QObject, Extension): self._plugins_showcase_model.setPackagesMetaData(self._showcase_metadata) for package in self._plugins_showcase_model.items: print(package) - self.showcaseMetadataChanged.emit() + self.pluginsShowcaseMetadataChanged.emit() except json.decoder.JSONDecodeError: Logger.log("w", "Toolbox: Received invalid JSON for showcase.") return @@ -433,43 +451,6 @@ class Toolbox(QObject, Extension): else: Logger.log("w", "Toolbox: Package was not a valid CuraPackage.") - # with zipfile.ZipFile(file_path, "r") as zip_ref: - # plugin_id = None - # for file in zip_ref.infolist(): - # if file.filename.endswith("/"): - # plugin_id = file.filename.strip("/") - # break - # - # if plugin_id is None: - # msg = i18n_catalog.i18nc("@info:status", "Failed to get plugin ID from {0}", file_path) - # msg_title = i18n_catalog.i18nc("@info:tile", "Warning") - # self._progress_message = Message(msg, lifetime=0, dismissable=False, title = msg_title) - # return - # - # # find a potential license file - # plugin_root_dir = plugin_id + "/" - # license_file = None - # for f in zip_ref.infolist(): - # # skip directories (with file_size = 0) and files not in the plugin directory - # if f.file_size == 0 or not f.filename.startswith(plugin_root_dir): - # continue - # file_name = os.path.basename(f.filename).lower() - # file_base_name, file_ext = os.path.splitext(file_name) - # if file_base_name in ["license", "licence"]: - # license_file = f.filename - # break - # - # # show a dialog for user to read and accept/decline the license - # if license_file is not None: - # Logger.log("i", "Found license file for plugin [%s], showing the license dialog to the user", plugin_id) - # license_content = zip_ref.read(license_file).decode('utf-8') - # self.openLicenseDialog(plugin_id, license_content, file_path) - # return - # - # # there is no license file, directly install the plugin - # self.installPlugin(file_path) - # return - # Getter & Setters From 596e0be7b6a6f903e9e2f5b0b05616a619ed388c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 11 Apr 2018 15:17:23 +0200 Subject: [PATCH 35/83] CuraPackageManager handles packages and plugins CURA-4644 --- cura/CuraApplication.py | 14 +- cura/CuraPackageManager.py | 331 +++++++++++++++++++++------------ cura/Utils/VersionTools.py | 43 +++++ cura/Utils/__init__.py | 0 plugins/Toolbox/src/Toolbox.py | 101 +++++----- 5 files changed, 317 insertions(+), 172 deletions(-) create mode 100644 cura/Utils/VersionTools.py create mode 100644 cura/Utils/__init__.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 8ace011209..6e19ab3a30 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -140,7 +140,6 @@ class CuraApplication(QtApplication): ExtruderStack = Resources.UserType + 9 DefinitionChangesContainer = Resources.UserType + 10 SettingVisibilityPreset = Resources.UserType + 11 - CuraPackages = Resources.UserType + 12 Q_ENUMS(ResourceTypes) @@ -190,7 +189,6 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes") Resources.addStorageType(self.ResourceTypes.SettingVisibilityPreset, "setting_visibility") - Resources.addStorageType(self.ResourceTypes.CuraPackages, "cura_packages") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality") ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes") @@ -233,7 +231,6 @@ class CuraApplication(QtApplication): self._simple_mode_settings_manager = None self._cura_scene_controller = None self._machine_error_checker = None - self._cura_package_manager = None self._additional_components = {} # Components to add to certain areas in the interface @@ -244,6 +241,13 @@ class CuraApplication(QtApplication): tray_icon_name = "cura-icon-32.png", **kwargs) + # Initialize the package manager to remove and install scheduled packages. + from cura.CuraPackageManager import CuraPackageManager + self._cura_package_manager = CuraPackageManager(self) + self._cura_package_manager.initialize() + + self.initialize() + # FOR TESTING ONLY if kwargs["parsed_command_line"].get("trigger_early_crash", False): assert not "This crash is triggered by the trigger_early_crash command line argument." @@ -655,10 +659,6 @@ class CuraApplication(QtApplication): container_registry = ContainerRegistry.getInstance() - from cura.CuraPackageManager import CuraPackageManager - self._cura_package_manager = CuraPackageManager(self) - self._cura_package_manager.initialize() - Logger.log("i", "Initializing variant manager") self._variant_manager = VariantManager(container_registry) self._variant_manager.initialize() diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 233e93110b..9c63de751d 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -1,21 +1,21 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Optional, Dict +from typing import Optional import json import os import re import shutil -import urllib.parse import zipfile +import tempfile -from PyQt5.QtCore import pyqtSlot, QObject, QUrl +from PyQt5.QtCore import pyqtSlot, QObject, pyqtSignal from UM.Logger import Logger -from UM.MimeTypeDatabase import MimeTypeDatabase -from UM.Settings.InstanceContainer import InstanceContainer from UM.Resources import Resources +from cura.Utils import VersionTools + class CuraPackageManager(QObject): @@ -27,164 +27,249 @@ class CuraPackageManager(QObject): super().__init__(parent) self._application = parent - self._registry = self._application.getContainerRegistry() + self._container_registry = self._application.getContainerRegistry() + self._plugin_registry = self._application.getPluginRegistry() - # The JSON file that keeps track of all installed packages. + # JSON file that keeps track of all installed packages. self._package_management_file_path = os.path.join(os.path.abspath(Resources.getDataStoragePath()), "packages.json") - self._installed_package_dict = {} # type: Dict[str, dict] + self._installed_package_dict = {} # a dict of all installed packages + self._to_remove_package_set = set() # a set of packages that need to be removed at the next start + self._to_install_package_dict = {} # a dict of packages that need to be installed at the next start self._semantic_version_regex = re.compile(r"^[0-9]+(.[0-9]+)+$") - def initialize(self): - # Load the package management file if exists - if os.path.exists(self._package_management_file_path): - with open(self._package_management_file_path, "r", encoding = "utf-8") as f: - self._installed_package_dict = json.loads(f.read(), encoding = "utf-8") - Logger.log("i", "Package management file %s is loaded", self._package_management_file_path) + installedPackagesChanged = pyqtSignal() # Emitted whenever the installed packages collection have been changed. - def _saveManagementData(self): + def initialize(self): + self._loadManagementData() + self._removeAllScheduledPackages() + self._installAllScheduledPackages() + + # (for initialize) Loads the package management file if exists + def _loadManagementData(self) -> None: + if not os.path.exists(self._package_management_file_path): + Logger.log("i", "Package management file %s doesn't exist, do nothing", self._package_management_file_path) + return + + with open(self._package_management_file_path, "r", encoding = "utf-8") as f: + management_dict = json.loads(f.read(), encoding = "utf-8") + + self._installed_package_dict = management_dict["installed"] + self._to_remove_package_set = set(management_dict["to_remove"]) + self._to_install_package_dict = management_dict["to_install"] + + Logger.log("i", "Package management file %s is loaded", self._package_management_file_path) + + def _saveManagementData(self) -> None: with open(self._package_management_file_path, "w", encoding = "utf-8") as f: - json.dump(self._installed_package_dict, f) + data_dict = {"installed": self._installed_package_dict, + "to_remove": list(self._to_remove_package_set), + "to_install": self._to_install_package_dict} + data_dict["to_remove"] = list(data_dict["to_remove"]) + json.dump(data_dict, f) Logger.log("i", "Package management file %s is saved", self._package_management_file_path) + # (for initialize) Removes all packages that have been scheduled to be removed. + def _removeAllScheduledPackages(self) -> None: + for package_id in self._to_remove_package_set: + self._purgePackage(package_id) + self._to_remove_package_set.clear() + self._saveManagementData() + + # (for initialize) Installs all packages that have been scheduled to be installed. + def _installAllScheduledPackages(self) -> None: + for package_id, installation_package_data in self._to_install_package_dict.items(): + self._installPackage(installation_package_data) + self._to_install_package_dict.clear() + self._saveManagementData() + @pyqtSlot(str, result = bool) def isPackageFile(self, file_name: str): + # TODO: remove this extension = os.path.splitext(file_name)[1].strip(".") if extension.lower() in ("curapackage",): return True return False # Checks the given package is installed. If so, return a dictionary that contains the package's information. - def getInstalledPackage(self, package_id: str) -> Optional[dict]: + def getInstalledPackageInfo(self, package_id: str) -> Optional[dict]: + if package_id in self._to_remove_package_set: + return None + if package_id in self._to_install_package_dict: + return self._to_install_package_dict[package_id]["package_info"] + return self._installed_package_dict.get(package_id) - # Gets all installed packages - def getAllInstalledPackages(self) -> Dict[str, dict]: - return self._installed_package_dict + # Checks if the given package is installed. + def isPackageInstalled(self, package_id: str) -> bool: + return self.getInstalledPackageInfo(package_id) is not None - # Installs the given package file. + # Schedules the given package file to be installed upon the next start. @pyqtSlot(str) - def install(self, file_name: str) -> None: - file_url = QUrl(file_name) - file_name = file_url.toLocalFile() - - archive = zipfile.ZipFile(file_name) - + def installPackage(self, filename: str) -> None: # Get package information - try: - with archive.open("package.json", "r") as f: - package_info_dict = json.loads(f.read(), encoding = "utf-8") - except Exception as e: - raise RuntimeError("Could not get package information from file '%s': %s" % (file_name, e)) + package_info = self.getPackageInfo(filename) + package_id = package_info["package_id"] + + has_changes = False + # Check the delayed installation and removal lists first + if package_id in self._to_remove_package_set: + self._to_remove_package_set.remove(package_id) + has_changes = True # Check if it is installed - installed_package = self.getInstalledPackage(package_info_dict["package_id"]) - has_installed_version = installed_package is not None + installed_package_info = self.getInstalledPackageInfo(package_info["package_id"]) + to_install_package = installed_package_info is None # Install if the package has not been installed + if installed_package_info is not None: + # Compare versions and only schedule the installation if the given package is newer + new_version = package_info["package_version"] + installed_version = installed_package_info["package_version"] + if VersionTools.compareSemanticVersions(new_version, installed_version) > 0: + Logger.log("i", "Package [%s] version [%s] is newer than the installed version [%s], update it.", + package_id, new_version, installed_version) + to_install_package = True - if has_installed_version: - # Remove the existing package first - Logger.log("i", "Another version of [%s] [%s] has already been installed, will overwrite it with version [%s]", - installed_package["package_id"], installed_package["package_version"], - package_info_dict["package_version"]) - self.remove(package_info_dict["package_id"]) + if to_install_package: + Logger.log("i", "Package [%s] version [%s] is scheduled to be installed.", + package_id, package_info["package_version"]) + self._to_install_package_dict[package_id] = {"package_info": package_info, + "filename": filename} + has_changes = True + + self._saveManagementData() + if has_changes: + self.installedPackagesChanged.emit() + + # Schedules the given package to be removed upon the next start. + @pyqtSlot(str) + def removePackage(self, package_id: str) -> None: + # Check the delayed installation and removal lists first + if not self.isPackageInstalled(package_id): + Logger.log("i", "Attempt to remove package [%s] that is not installed, do nothing.", package_id) + return + + # Remove from the delayed installation list if present + if package_id in self._to_install_package_dict: + del self._to_install_package_dict[package_id] + + # If the package has already been installed, schedule for a delayed removal + if package_id in self._installed_package_dict: + self._to_remove_package_set.add(package_id) + + self._saveManagementData() + self.installedPackagesChanged.emit() + + # Removes everything associated with the given package ID. + def _purgePackage(self, package_id: str) -> None: + # Get all folders that need to be checked for installed packages, including: + # - materials + # - qualities + # - plugins + from cura.CuraApplication import CuraApplication + dirs_to_check = [ + Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer), + Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer), + os.path.join(os.path.abspath(Resources.getDataStoragePath()), "plugins"), + ] + + for root_dir in dirs_to_check: + package_dir = os.path.join(root_dir, package_id) + if os.path.exists(package_dir): + Logger.log("i", "Removing '%s' for package [%s]", package_dir, package_id) + shutil.rmtree(package_dir) + + # Installs all files associated with the given package. + def _installPackage(self, installation_package_data: dict): + package_info = installation_package_data["package_info"] + filename = installation_package_data["filename"] + + package_id = package_info["package_id"] + + Logger.log("i", "Installing package [%s] from file [%s]", package_id, filename) + + # If it's installed, remove it first and then install + if package_id in self._installed_package_dict: + self._purgePackage(package_id) # Install the package - self._installPackage(file_name, archive, package_info_dict) + archive = zipfile.ZipFile(filename, "r") + + temp_dir = tempfile.TemporaryDirectory() + archive.extractall(temp_dir.name) + + from cura.CuraApplication import CuraApplication + installation_dirs_dict = { + "materials": Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer), + "quality": Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer), + "plugins": os.path.join(os.path.abspath(Resources.getDataStoragePath()), "plugins"), + } + + for sub_dir_name, installation_root_dir in installation_dirs_dict.items(): + src_dir_path = os.path.join(temp_dir.name, "files", sub_dir_name) + dst_dir_path = os.path.join(installation_root_dir, package_id) + + if not os.path.exists(src_dir_path): + continue + + # Need to rename the container files so they don't get ID conflicts + to_rename_files = sub_dir_name not in ("plugins",) + self.__installPackageFiles(package_id, src_dir_path, dst_dir_path, need_to_rename_files= to_rename_files) archive.close() - def _installPackage(self, file_name: str, archive: zipfile.ZipFile, package_info_dict: dict): - from cura.CuraApplication import CuraApplication + def __installPackageFiles(self, package_id: str, src_dir: str, dst_dir: str, need_to_rename_files: bool = True) -> None: + shutil.move(src_dir, dst_dir) - package_id = package_info_dict["package_id"] - package_type = package_info_dict["package_type"] - if package_type == "material": - package_root_dir = Resources.getPath(CuraApplication.ResourceTypes.MaterialInstanceContainer) - material_class = self._registry.getContainerForMimeType(MimeTypeDatabase.getMimeType("application/x-ultimaker-material-profile")) - file_extension = self._registry.getMimeTypeForContainer(material_class).preferredSuffix - elif package_type == "quality": - package_root_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer) - file_extension = "." + self._registry.getMimeTypeForContainer(InstanceContainer).preferredSuffix - else: - raise RuntimeError("Unexpected package type [%s] in file [%s]" % (package_type, file_name)) - - Logger.log("i", "Prepare package directory [%s]", package_root_dir) - - # get package directory - package_installation_path = os.path.join(os.path.abspath(package_root_dir), package_id) - if os.path.exists(package_installation_path): - Logger.log("w", "Path [%s] exists, removing it.", package_installation_path) - if os.path.isfile(package_installation_path): - os.remove(package_installation_path) - else: - shutil.rmtree(package_installation_path, ignore_errors = True) - - os.makedirs(package_installation_path, exist_ok = True) - - # Only extract the needed files - for file_info in archive.infolist(): - if file_info.is_dir(): - continue - - file_name = os.path.basename(file_info.filename) - if not file_name.endswith(file_extension): - continue - - # Generate new file name and save to file - new_file_name = urllib.parse.quote_plus(self.PREFIX_PLACE_HOLDER + package_id + "-" + file_name) - new_file_path = os.path.join(package_installation_path, new_file_name) - with archive.open(file_info.filename, "r") as f: - content = f.read() - with open(new_file_path, "wb") as f2: - f2.write(content) - - Logger.log("i", "Installed package file to [%s]", new_file_name) - - self._installed_package_dict[package_id] = package_info_dict - self._saveManagementData() - Logger.log("i", "Package [%s] has been installed", package_id) - - # Removes a package with the given package ID. - @pyqtSlot(str) - def remove(self, package_id: str) -> None: - from cura.CuraApplication import CuraApplication - - package_info_dict = self.getInstalledPackage(package_id) - if package_info_dict is None: - Logger.log("w", "Attempt to remove non-existing package [%s], do nothing.", package_id) + # Rename files if needed + if not need_to_rename_files: return - - package_type = package_info_dict["package_type"] - if package_type == "material": - package_root_dir = Resources.getPath(CuraApplication.ResourceTypes.MaterialInstanceContainer) - elif package_type == "quality": - package_root_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer) - else: - raise RuntimeError("Unexpected package type [%s] for package [%s]" % (package_type, package_id)) - - # Get package directory - package_installation_path = os.path.join(os.path.abspath(package_root_dir), package_id) - if os.path.exists(package_installation_path): - if os.path.isfile(package_installation_path): - os.remove(package_installation_path) - else: - shutil.rmtree(package_installation_path, ignore_errors=True) - - if package_id in self._installed_package_dict: - del self._installed_package_dict[package_id] - self._saveManagementData() - Logger.log("i", "Package [%s] has been removed.", package_id) + for root, _, file_names in os.walk(dst_dir): + for filename in file_names: + new_filename = self.PREFIX_PLACE_HOLDER + package_id + "-" + filename + old_file_path = os.path.join(root, filename) + new_file_path = os.path.join(root, new_filename) + os.rename(old_file_path, new_file_path) # Gets package information from the given file. - def getPackageInfo(self, file_name: str) -> dict: - archive = zipfile.ZipFile(file_name) + def getPackageInfo(self, filename: str) -> dict: + archive = zipfile.ZipFile(filename, "r") try: # All information is in package.json with archive.open("package.json", "r") as f: package_info_dict = json.loads(f.read().decode("utf-8")) return package_info_dict except Exception as e: - raise RuntimeError("Could not get package information from file '%s': %s" % (e, file_name)) + raise RuntimeError("Could not get package information from file '%s': %s" % (filename, e)) finally: archive.close() + + # Gets the license file content if present in the given package file. + # Returns None if there is no license file found. + def getPackageLicense(self, filename: str) -> Optional[str]: + license_string = None + archive = zipfile.ZipFile(filename) + try: + # Go through all the files and use the first successful read as the result + for file_info in archive.infolist(): + if file_info.is_dir() or not file_info.filename.startswith("files/"): + continue + + filename_parts = os.path.basename(file_info.filename.lower()).split(".") + stripped_filename = filename_parts[0] + if stripped_filename in ("license", "licence"): + Logger.log("i", "Found potential license file '%s'", file_info.filename) + try: + with archive.open(file_info.filename, "r") as f: + data = f.read() + license_string = data.decode("utf-8") + break + except: + Logger.logException("e", "Failed to load potential license file '%s' as text file.", + file_info.filename) + license_string = None + except Exception as e: + raise RuntimeError("Could not get package license from file '%s': %s" % (filename, e)) + finally: + archive.close() + return license_string diff --git a/cura/Utils/VersionTools.py b/cura/Utils/VersionTools.py new file mode 100644 index 0000000000..ab0ac6d813 --- /dev/null +++ b/cura/Utils/VersionTools.py @@ -0,0 +1,43 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import re + + +# Regex for checking if a string is a semantic version number +_SEMANTIC_VERSION_REGEX = re.compile(r"^[0-9]+(.[0-9]+)+$") + + +# Checks if the given version string is a valid semantic version number. +def isSemanticVersion(version: str) -> bool: + return _SEMANTIC_VERSION_REGEX.match(version) is not None + + +# Compares the two given semantic version strings and returns: +# -1 if version1 < version2 +# 0 if version1 == version2 +# +1 if version1 > version2 +# Note that this function only works with semantic versions such as "a.b.c..." +def compareSemanticVersions(version1: str, version2: str) -> int: + # Validate the version numbers first + for version in (version1, version2): + if not isSemanticVersion(version): + raise ValueError("Invalid Package version '%s'" % version) + + # Split the version strings into lists of integers + version1_parts = [int(p) for p in version1.split(".")] + version2_parts = [int(p) for p in version2.split(".")] + max_part_length = max(len(version1_parts), len(version2_parts)) + + # Make sure that two versions have the same number of parts. For missing parts, just append 0s. + for parts in (version1_parts, version2_parts): + for _ in range(max_part_length - len(parts)): + parts.append(0) + + # Compare the version parts and return the result + result = 0 + for idx in range(max_part_length): + result = version1_parts[idx] - version2_parts[idx] + if result != 0: + break + return result diff --git a/cura/Utils/__init__.py b/cura/Utils/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index bf702c34b7..d88a1c0f37 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -1,6 +1,11 @@ # Copyright (c) 2018 Ultimaker B.V. # Toolbox is released under the terms of the LGPLv3 or higher. + from typing import Dict +import json +import os +import tempfile +import platform from PyQt5.QtCore import QUrl, QObject, pyqtProperty, pyqtSignal, pyqtSlot from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply @@ -11,28 +16,22 @@ from UM.PluginRegistry import PluginRegistry from UM.Qt.Bindings.PluginsModel import PluginsModel from UM.Extension import Extension from UM.i18n import i18nCatalog - -from UM.Version import Version -from UM.Message import Message - -import json -import os -import tempfile -import platform -import zipfile +from cura.Utils.VersionTools import compareSemanticVersions from cura.CuraApplication import CuraApplication -from cura.CuraPackageManager import CuraPackageManager from .AuthorsModel import AuthorsModel from .PackagesModel import PackagesModel i18n_catalog = i18nCatalog("cura") + ## The Toolbox class is responsible of communicating with the server through the API class Toolbox(QObject, Extension): def __init__(self, parent=None): super().__init__(parent) + self._application = Application.getInstance() + self._package_manager = None self._plugin_registry = Application.getInstance().getPluginRegistry() self._package_manager = None self._packages_version = self._plugin_registry.APIVersion @@ -88,6 +87,10 @@ class Toolbox(QObject, Extension): # installed, or otherwise modified. self._active_package = None + # Nowadays can be 'plugins', 'materials' or 'installed' + self._current_view = "plugins" + self._detail_data = {} # Extraneous since can just use the data prop of the model. + self._dialog = None self._restartDialog = None self._restart_required = False @@ -97,6 +100,7 @@ class Toolbox(QObject, Extension): # we keep track of the upgraded plugins. self._newly_installed_plugin_ids = [] self._newly_uninstalled_plugin_ids = [] + self._plugin_statuses = {} # type: Dict[str, str] # variables for the license agreement dialog self._license_dialog_plugin_name = "" @@ -104,7 +108,11 @@ class Toolbox(QObject, Extension): self._license_dialog_plugin_file_location = "" self._restart_dialog_message = "" - # Metadata changes + Application.getInstance().initializationFinished.connect(self._onAppInitialized) + + def _onAppInitialized(self): + self._package_manager = Application.getInstance().getCuraPackageManager() + packagesMetadataChanged = pyqtSignal() authorsMetadataChanged = pyqtSignal() pluginsShowcaseMetadataChanged = pyqtSignal() @@ -176,29 +184,24 @@ class Toolbox(QObject, Extension): @pyqtSlot(str) def installPlugin(self, file_path): - # Ensure that it starts with a /, as otherwise it doesn't work on windows. - if not file_path.startswith("/"): - file_path = "/" + file_path - result = PluginRegistry.getInstance().installPlugin("file://" + file_path) + self._package_manager.installPackage(file_path) - self._newly_installed_plugin_ids.append(result["id"]) self.packagesMetadataChanged.emit() - self.openRestartDialog(result["message"]) + self.openRestartDialog("TODO") self._restart_required = True self.restartRequiredChanged.emit() @pyqtSlot(str) def removePlugin(self, plugin_id): - result = PluginRegistry.getInstance().uninstallPlugin(plugin_id) + self._package_manager.removePackage(plugin_id) - self._newly_uninstalled_plugin_ids.append(result["id"]) self.packagesMetadataChanged.emit() self._restart_required = True self.restartRequiredChanged.emit() - Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Plugin browser"), result["message"]) + Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Plugin browser"), "TODO") @pyqtSlot(str) def enablePlugin(self, plugin_id): @@ -261,31 +264,38 @@ class Toolbox(QObject, Extension): # Checks # -------------------------------------------------------------------------- - def _checkCanUpgrade(self, id, version): - # Scan plugin server data for plugin with the given id: - for plugin in self._packages_metadata: - if id == plugin["id"]: - reg_version = Version(version) - new_version = Version(plugin["version"]) - if new_version > reg_version: - Logger.log("i", "%s has an update availible: %s", plugin["id"], plugin["version"]) - return True - return False - - def _checkInstalled(self, id): - if id in self._will_uninstall: + def _checkCanUpgrade(self, package_id: str, version: str) -> bool: + installed_plugin_data = self._package_manager.getInstalledPackageInfo(package_id) + if installed_plugin_data is None: return False - if id in self._package_manager.getInstalledPackages(): - return True - if id in self._will_install: - return True - return False + + installed_version = installed_plugin_data["package_version"] + return compareSemanticVersions(version, installed_version) > 0 + + def _checkInstalled(self, package_id: str): + return self._package_manager.isPackageInstalled(package_id) def _checkEnabled(self, id): if id in self._plugin_registry.getActivePlugins(): return True return False + def _createNetworkManager(self): + if self._network_manager: + self._network_manager.finished.disconnect(self._onRequestFinished) + self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccesibleChanged) + self._network_manager = QNetworkAccessManager() + self._network_manager.finished.connect(self._onRequestFinished) + self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) + + @pyqtProperty(bool, notify = restartRequiredChanged) + def restartRequired(self): + return self._restart_required + + @pyqtSlot() + def restart(self): + CuraApplication.getInstance().windowClosed() + # Make API Calls @@ -445,12 +455,19 @@ class Toolbox(QObject, Extension): def _onDownloadComplete(self, file_path): Logger.log("i", "Toolbox: Download complete.") print(file_path) - if self._package_manager.isPackageFile(file_path): - self._package_manager.install(file_path) + try: + package_info = self._package_manager.getPackageInfo(file_path) + except: + Logger.logException("w", "Toolbox: Package file [%s] was not a valid CuraPackage.", file_path) return - else: - Logger.log("w", "Toolbox: Package was not a valid CuraPackage.") + license_content = self._package_manager.getPackageLicense(file_path) + if license_content is not None: + self.openLicenseDialog(package_info["package_id"], license_content, file_path) + return + + self._package_manager.installPlugin(file_path) + return # Getter & Setters From 0abc925f3d09856cbabb148325bc1299c77b31ec Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 12 Apr 2018 13:07:24 +0200 Subject: [PATCH 36/83] CURA-5035 Removing logic --- plugins/Toolbox/src/Toolbox.py | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index d88a1c0f37..0df6226038 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -117,6 +117,7 @@ class Toolbox(QObject, Extension): authorsMetadataChanged = pyqtSignal() pluginsShowcaseMetadataChanged = pyqtSignal() materialsShowcaseMetadataChanged = pyqtSignal() + metadataChanged = pyqtSignal() # Downloading changes activePackageChanged = pyqtSignal() @@ -185,9 +186,7 @@ class Toolbox(QObject, Extension): @pyqtSlot(str) def installPlugin(self, file_path): self._package_manager.installPackage(file_path) - - self.packagesMetadataChanged.emit() - + self.metadataChanged.emit() self.openRestartDialog("TODO") self._restart_required = True self.restartRequiredChanged.emit() @@ -195,9 +194,7 @@ class Toolbox(QObject, Extension): @pyqtSlot(str) def removePlugin(self, plugin_id): self._package_manager.removePackage(plugin_id) - - self.packagesMetadataChanged.emit() - + self.metadataChanged.emit() self._restart_required = True self.restartRequiredChanged.emit() @@ -206,16 +203,16 @@ class Toolbox(QObject, Extension): @pyqtSlot(str) def enablePlugin(self, plugin_id): self._plugin_registry.enablePlugin(plugin_id) - self.packagesMetadataChanged.emit() + self.metadataChanged.emit() Logger.log("i", "%s was set as 'active'", id) @pyqtSlot(str) def disablePlugin(self, plugin_id): self._plugin_registry.disablePlugin(plugin_id) - self.packagesMetadataChanged.emit() + self.metadataChanged.emit() Logger.log("i", "%s was set as 'deactive'", id) - @pyqtProperty(QObject, notify = packagesMetadataChanged) + @pyqtProperty(QObject, notify = metadataChanged) def pluginsModel(self): self._plugins_model = PluginsModel(None, self._view_category) # self._plugins_model.update() @@ -232,23 +229,23 @@ class Toolbox(QObject, Extension): plugin["update_url"] = item["file_location"] return self._plugins_model - @pyqtProperty(QObject, notify = pluginsShowcaseMetadataChanged) + @pyqtProperty(QObject, notify = metadataChanged) def pluginsShowcaseModel(self): return self._plugins_showcase_model - @pyqtProperty(QObject, notify = materialsShowcaseMetadataChanged) + @pyqtProperty(QObject, notify = metadataChanged) def materialsShowcaseModel(self): return self._materials_showcase_model - @pyqtProperty(QObject, notify = packagesMetadataChanged) + @pyqtProperty(QObject, notify = metadataChanged) def packagesModel(self): return self._packages_model - @pyqtProperty(QObject, notify = authorsMetadataChanged) + @pyqtProperty(QObject, notify = metadataChanged) def authorsModel(self): return self._authors_model - @pyqtProperty(bool, notify = packagesMetadataChanged) + @pyqtProperty(bool, notify = metadataChanged) def dataReady(self): return self._packages_model is not None @@ -376,7 +373,7 @@ class Toolbox(QObject, Extension): self._packages_model = PackagesModel() self._packages_metadata = json_data["data"] self._packages_model.setPackagesMetaData(self._packages_metadata) - self.packagesMetadataChanged.emit() + self.metadataChanged.emit() # Create authors model with all authors: if not self._authors_model: @@ -388,7 +385,7 @@ class Toolbox(QObject, Extension): if package["author"] not in self._authors_metadata: self._authors_metadata.append(package["author"]) self._authors_model.setMetaData(self._authors_metadata) - self.authorsMetadataChanged.emit() + self.metadataChanged.emit() self.setViewPage("overview") # TODO: Also replace this with a proper API call: @@ -409,7 +406,7 @@ class Toolbox(QObject, Extension): "type": "material" } ]) - self.materialsShowcaseMetadataChanged.emit() + self.metadataChanged.emit() self.setViewPage("overview") except json.decoder.JSONDecodeError: @@ -428,7 +425,7 @@ class Toolbox(QObject, Extension): self._plugins_showcase_model.setPackagesMetaData(self._showcase_metadata) for package in self._plugins_showcase_model.items: print(package) - self.pluginsShowcaseMetadataChanged.emit() + self.metadataChanged.emit() except json.decoder.JSONDecodeError: Logger.log("w", "Toolbox: Received invalid JSON for showcase.") return From 406b64b3318f07639410838dc380560ae7145c8e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 12 Apr 2018 13:14:30 +0200 Subject: [PATCH 37/83] Remove unneeded code CURA-4644 --- cura/CuraPackageManager.py | 11 ----------- resources/qml/Cura.qml | 4 ---- 2 files changed, 15 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 9c63de751d..ad9e6d19c3 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -4,7 +4,6 @@ from typing import Optional import json import os -import re import shutil import zipfile import tempfile @@ -37,8 +36,6 @@ class CuraPackageManager(QObject): self._to_remove_package_set = set() # a set of packages that need to be removed at the next start self._to_install_package_dict = {} # a dict of packages that need to be installed at the next start - self._semantic_version_regex = re.compile(r"^[0-9]+(.[0-9]+)+$") - installedPackagesChanged = pyqtSignal() # Emitted whenever the installed packages collection have been changed. def initialize(self): @@ -84,14 +81,6 @@ class CuraPackageManager(QObject): self._to_install_package_dict.clear() self._saveManagementData() - @pyqtSlot(str, result = bool) - def isPackageFile(self, file_name: str): - # TODO: remove this - extension = os.path.splitext(file_name)[1].strip(".") - if extension.lower() in ("curapackage",): - return True - return False - # Checks the given package is installed. If so, return a dictionary that contains the package's information. def getInstalledPackageInfo(self, package_id: str) -> Optional[dict]: if package_id in self._to_remove_package_set: diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index c632e7dbfd..e20a29fe16 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -345,10 +345,6 @@ UM.MainWindow pluginInstallDialog.open(); return; } - else if (CuraApplication.getCuraPackageManager().isPackageFile(drop.urls[0])) - { - CuraApplication.getCuraPackageManager().install(drop.urls[0]); - } } openDialog.handleOpenFileUrls(drop.urls); From 8a181ea395972b621ff28278a6cc7d396340bd4e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 12 Apr 2018 13:25:22 +0200 Subject: [PATCH 38/83] Save curapackage into cache for delayed installation CURA-4644 Do not rely on the originally provided curapackage file because they can be gone after Cura restarts. Copy the curapackages into cache for delayed installation. --- cura/CuraPackageManager.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index ad9e6d19c3..d07a3aced0 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -122,8 +122,16 @@ class CuraPackageManager(QObject): if to_install_package: Logger.log("i", "Package [%s] version [%s] is scheduled to be installed.", package_id, package_info["package_version"]) + # Copy the file to cache dir so we don't need to rely on the original file to be present + package_cache_dir = os.path.join(os.path.abspath(Resources.getCacheStoragePath()), "cura_packages") + if not os.path.exists(package_cache_dir): + os.makedirs(package_cache_dir, exist_ok=True) + + target_file_path = os.path.join(package_cache_dir, package_id + ".curapackage") + shutil.copy2(filename, target_file_path) + self._to_install_package_dict[package_id] = {"package_info": package_info, - "filename": filename} + "filename": target_file_path} has_changes = True self._saveManagementData() @@ -175,6 +183,10 @@ class CuraPackageManager(QObject): package_id = package_info["package_id"] + if not os.path.exists(filename): + Logger.log("w", "Package [%s] file '%s' is missing, cannot install this package", package_id, filename) + return + Logger.log("i", "Installing package [%s] from file [%s]", package_id, filename) # If it's installed, remove it first and then install @@ -207,6 +219,9 @@ class CuraPackageManager(QObject): archive.close() + # Remove the file + os.remove(filename) + def __installPackageFiles(self, package_id: str, src_dir: str, dst_dir: str, need_to_rename_files: bool = True) -> None: shutil.move(src_dir, dst_dir) From 74a9ac6ba74eba8323b49cbe94a95366a55b822e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 12 Apr 2018 13:30:24 +0200 Subject: [PATCH 39/83] Fix installPlugin in toolbox CURA-4644 --- plugins/Toolbox/src/Toolbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index d88a1c0f37..7d1fffdca5 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -466,7 +466,7 @@ class Toolbox(QObject, Extension): self.openLicenseDialog(package_info["package_id"], license_content, file_path) return - self._package_manager.installPlugin(file_path) + self.installPlugin(file_path) return From e13c45daeee1fdb40b25ceb7a7793942f124c4c3 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 12 Apr 2018 14:03:53 +0200 Subject: [PATCH 40/83] CURA-5035: Clean-up --- plugins/Toolbox/resources/qml/Toolbox.qml | 22 +- .../resources/qml/ToolboxAuthorPage.qml | 2 +- .../resources/qml/ToolboxBackColumn.qml | 6 +- .../resources/qml/ToolboxDetailList.qml | 2 +- .../resources/qml/ToolboxDetailPage.qml | 2 +- .../resources/qml/ToolboxDetailTile.qml | 20 +- .../resources/qml/ToolboxDownloadsGrid.qml | 4 +- .../qml/ToolboxDownloadsGridTile.qml | 18 +- .../qml/ToolboxDownloadsShowcase.qml | 8 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 18 +- .../Toolbox/resources/qml/ToolboxFooter.qml | 10 +- .../Toolbox/resources/qml/ToolboxHeader.qml | 24 +- .../resources/qml/ToolboxInstalledPage.qml | 4 +- .../resources/qml/ToolboxInstalledTile.qml | 10 +- .../resources/qml/ToolboxLicenseDialog.qml | 2 +- .../resources/qml/ToolboxRestartDialog.qml | 2 +- plugins/Toolbox/src/AuthorsModel.py | 2 +- plugins/Toolbox/src/PackagesModel.py | 2 +- plugins/Toolbox/src/Toolbox.py | 206 +++++++++--------- 19 files changed, 185 insertions(+), 179 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index ab7c731e7d..d0a165138e 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -43,27 +43,27 @@ Window ToolboxLoadingPage { id: viewLoading - visible: manager.viewCategory != "installed" && manager.viewPage == "loading" + visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "loading" } ToolboxDownloadsPage { id: viewDownloads - visible: manager.viewCategory != "installed" && manager.viewPage == "overview" + visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "overview" } ToolboxDetailPage { id: viewDetail - visible: manager.viewCategory != "installed" && manager.viewPage == "detail" + visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "detail" } ToolboxAuthorPage { id: viewAuthor - visible: manager.viewCategory != "installed" && manager.viewPage == "author" + visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "author" } ToolboxInstalledPage { id: installedPluginList - visible: manager.viewCategory == "installed" + visible: toolbox.viewCategory == "installed" } } ToolboxShadow @@ -83,21 +83,21 @@ Window Connections { - target: manager + target: toolbox onShowLicenseDialog: { - licenseDialog.pluginName = manager.getLicenseDialogPluginName(); - licenseDialog.licenseContent = manager.getLicenseDialogLicenseContent(); - licenseDialog.pluginFileLocation = manager.getLicenseDialogPluginFileLocation(); + licenseDialog.pluginName = toolbox.getLicenseDialogPluginName(); + licenseDialog.licenseContent = toolbox.getLicenseDialogLicenseContent(); + licenseDialog.pluginFileLocation = toolbox.getLicenseDialogPluginFileLocation(); licenseDialog.show(); } } Connections { - target: manager + target: toolbox onShowRestartDialog: { - restartDialog.message = manager.getRestartDialogMessage(); + restartDialog.message = toolbox.getRestartDialogMessage(); restartDialog.show(); } } diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 76f62f2a0d..4236a282e1 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -10,7 +10,7 @@ import UM 1.1 as UM Item { id: base - property var details: manager.authorsModel.items[0] + property var details: toolbox.authorsModel.items[0] anchors.fill: parent ToolboxBackColumn { diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml index a0332a0a42..01f6d44033 100644 --- a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -41,9 +41,9 @@ Item height: UM.Theme.getSize("base_unit").height * 2 onClicked: { - manager.viewPage = "overview" - manager.filterPackages("type", manager.viewCategory) - manager.filterAuthors("type", manager.viewCategory) + toolbox.viewPage = "overview" + toolbox.filterPackages("type", toolbox.viewCategory) + toolbox.filterAuthors("type", toolbox.viewCategory) } style: ButtonStyle { diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index 0ac45d93b5..333b2c1673 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -28,7 +28,7 @@ Item spacing: UM.Theme.getSize("default_margin").height Repeater { - model: manager.packagesModel + model: toolbox.packagesModel delegate: ToolboxDetailTile {} } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 5db7a37f98..f0982cdf80 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -10,7 +10,7 @@ import UM 1.1 as UM Item { id: base - property var details: manager.packagesModel.items[0] + property var details: toolbox.packagesModel.items[0] anchors.fill: parent ToolboxBackColumn { diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 16f719c478..689a008a67 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -48,7 +48,7 @@ Rectangle Button { id: installButton text: { - if ( manager.isDownloading && manager.activePackage == model ) + if ( toolbox.isDownloading && toolbox.activePackage == model ) { return catalog.i18nc("@action:button", "Cancel") } @@ -59,9 +59,9 @@ Rectangle } enabled: { - if ( manager.isDownloading ) + if ( toolbox.isDownloading ) { - return manager.activePackage == model ? true : false + return toolbox.activePackage == model ? true : false } else { @@ -88,21 +88,21 @@ Rectangle onClicked: { console.log( "MODEL", model.id ) - manager.activePackage = model - // if ( manager.isDownloading && manager.activePackage == model ) - if ( manager.isDownloading ) + toolbox.activePackage = model + // if ( toolbox.isDownloading && toolbox.activePackage == model ) + if ( toolbox.isDownloading ) { - manager.cancelDownload(); + toolbox.cancelDownload(); } else { - // manager.activePackage = model; + // toolbox.activePackage = model; if ( model.can_upgrade ) { - // manager.downloadAndInstallPlugin( model.update_url ); + // toolbox.downloadAndInstallPlugin( model.update_url ); } else { - manager.startDownload( model.download_url ); + toolbox.startDownload( model.download_url ); } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index ea14ef1cf2..b3a3a89200 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -19,7 +19,7 @@ Column Label { id: heading - text: manager.viewCategory == "material" ? "Maker Choices" : "Community Plugins" + text: toolbox.viewCategory == "material" ? "Maker Choices" : "Community Plugins" width: parent.width color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") @@ -34,7 +34,7 @@ Column Repeater { - model: manager.viewCategory == "material" ? manager.authorsModel : manager.packagesModel + model: toolbox.viewCategory == "material" ? toolbox.authorsModel : toolbox.packagesModel delegate: ToolboxDownloadsGridTile { Layout.preferredWidth: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 7016b09cd9..729d1e17d6 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -88,19 +88,19 @@ Item } onClicked: { - if ( manager.viewCategory == "material" ) + if ( toolbox.viewCategory == "material" ) { - manager.viewSelection = model.name - manager.viewPage = "author" - manager.filterAuthors("name", model.name) - manager.filterPackages("author_name", model.name) + toolbox.viewSelection = model.name + toolbox.viewPage = "author" + toolbox.filterAuthors("name", model.name) + toolbox.filterPackages("author_name", model.name) } else { - manager.viewSelection = model.id - manager.viewPage = "detail" - manager.filterAuthors("name", model.author_name) - manager.filterPackages("id", model.id) + toolbox.viewSelection = model.id + toolbox.viewPage = "detail" + toolbox.filterAuthors("name", model.author_name) + toolbox.filterPackages("id", model.id) } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index 7e31d4a182..83740fa46f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -35,13 +35,13 @@ Column Repeater { model: { - if ( manager.viewCategory == "plugin" ) + if ( toolbox.viewCategory == "plugin" ) { - return manager.pluginsShowcaseModel + return toolbox.pluginsShowcaseModel } - if ( manager.viewCategory == "material" ) + if ( toolbox.viewCategory == "material" ) { - return manager.materialsShowcaseModel + return toolbox.materialsShowcaseModel } } delegate: ToolboxDownloadsShowcaseTile {} diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 830ef1ac5a..b7888f257f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -51,19 +51,19 @@ Item { anchors.fill: parent onClicked: { - switch(manager.viewCategory) + switch(toolbox.viewCategory) { case "material": - manager.viewSelection = model.name - manager.viewPage = "author" - manager.filterAuthors("name", model.name) - manager.filterPackages("author_name", model.name) + toolbox.viewSelection = model.name + toolbox.viewPage = "author" + toolbox.filterAuthors("name", model.name) + toolbox.filterPackages("author_name", model.name) break default: - manager.viewSelection = model.id - manager.viewPage = "detail" - manager.filterAuthors("name", model.author_name) - manager.filterPackages("id", model.id) + toolbox.viewSelection = model.id + toolbox.viewPage = "detail" + toolbox.filterAuthors("name", model.author_name) + toolbox.filterPackages("id", model.id) break } } diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index fcbc2f0ddc..cebf501762 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -18,7 +18,7 @@ Item anchors.bottom: parent.bottom Label { - visible: manager.restartRequired + visible: toolbox.restartRequired text: "You will need to restart Cura before changes in plugins have effect." height: UM.Theme.getSize("base_unit").height * 2 verticalAlignment: Text.AlignVCenter @@ -39,9 +39,9 @@ Item right: closeButton.left rightMargin: UM.Theme.getSize("default_margin").width } - visible: manager.restartRequired + visible: toolbox.restartRequired iconName: "dialog-restart" - onClicked: manager.restart() + onClicked: toolbox.restart() style: ButtonStyle { background: Rectangle @@ -72,9 +72,9 @@ Item iconName: "dialog-close" onClicked: { - if ( manager.isDownloading ) + if ( toolbox.isDownloading ) { - manager.cancelDownload() + toolbox.cancelDownload() } base.close(); } diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 9abe315d1b..060eefa493 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -37,7 +37,7 @@ Rectangle { implicitHeight: 48 Rectangle { - visible: manager.viewCategory == "plugin" + visible: toolbox.viewCategory == "plugin" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom width: parent.width @@ -55,10 +55,10 @@ Rectangle { } onClicked: { - manager.filterPackages("type", "plugin") - manager.filterAuthors("type", "plugin") - manager.viewCategory = "plugin" - manager.viewPage = "overview" + toolbox.filterPackages("type", "plugin") + toolbox.filterAuthors("type", "plugin") + toolbox.viewCategory = "plugin" + toolbox.viewPage = "overview" } } @@ -74,7 +74,7 @@ Rectangle { implicitHeight: 48 Rectangle { - visible: manager.viewCategory == "material" + visible: toolbox.viewCategory == "material" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom width: parent.width @@ -92,10 +92,10 @@ Rectangle { } onClicked: { - manager.filterPackages("type", "material") - manager.filterAuthors("type", "material") - manager.viewCategory = "material" - manager.viewPage = "overview" + toolbox.filterPackages("type", "material") + toolbox.filterAuthors("type", "material") + toolbox.viewCategory = "material" + toolbox.viewPage = "overview" } } } @@ -113,7 +113,7 @@ Rectangle { implicitWidth: 96 implicitHeight: 48 Rectangle { - visible: manager.viewCategory == "installed" + visible: toolbox.viewCategory == "installed" color: UM.Theme.getColor("primary") anchors.bottom: parent.bottom width: parent.width @@ -129,6 +129,6 @@ Rectangle { horizontalAlignment: Text.AlignHCenter } } - onClicked: manager.viewCategory = "installed" + onClicked: toolbox.viewCategory = "installed" } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index cfe85dab92..d8169906b5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -58,7 +58,7 @@ ScrollView Repeater { id: materialList - model: manager.packagesModel + model: toolbox.packagesModel delegate: ToolboxInstalledTile {} } } @@ -93,7 +93,7 @@ ScrollView Repeater { id: pluginList - model: manager.packagesModel + model: toolbox.packagesModel delegate: ToolboxInstalledTile {} } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index c78cd8eff5..25bcbab895 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -104,7 +104,7 @@ Item id: removeButton text: "Uninstall" visible: model.can_uninstall && model.status == "installed" - enabled: !manager.isDownloading + enabled: !toolbox.isDownloading style: ButtonStyle { background: Rectangle @@ -125,7 +125,7 @@ Item horizontalAlignment: Text.AlignHCenter } } - onClicked: manager.removePlugin( model.id ) + onClicked: toolbox.removePlugin( model.id ) } Button { @@ -151,7 +151,7 @@ Item } onClicked: { - manager.updatePackage(model.id); + toolbox.updatePackage(model.id); } } ProgressBar @@ -161,8 +161,8 @@ Item anchors.right: installButton.right anchors.top: installButton.bottom anchors.topMargin: 4 - value: manager.isDownloading ? manager.downloadProgress : 0 - visible: manager.isDownloading + value: toolbox.isDownloading ? toolbox.downloadProgress : 0 + visible: toolbox.isDownloading style: ProgressBarStyle { background: Rectangle diff --git a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml index c08b93b13d..0e89c49d1a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml @@ -59,7 +59,7 @@ UM.Dialog { onClicked: { licenseDialog.close(); - manager.installPlugin(licenseDialog.pluginFileLocation); + toolbox.installPlugin(licenseDialog.pluginFileLocation); } }, Button diff --git a/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml b/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml index a0c961682c..8970515cac 100644 --- a/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml @@ -66,7 +66,7 @@ Window { bottom: parent.bottom bottomMargin: UM.Theme.getSize("default_margin").height } - onClicked: manager.restart() + onClicked: toolbox.restart() style: ButtonStyle { background: Rectangle { implicitWidth: 96 diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index 2156534b31..6d44c6c789 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -28,7 +28,7 @@ class AuthorsModel(ListModel): # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str,str] - def setMetaData(self, data): + def setMetadata(self, data): self._authors_metadata = data self._update() diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index 860e5aaaea..12462f4b77 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -42,7 +42,7 @@ class PackagesModel(ListModel): # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str,str] - def setPackagesMetaData(self, data): + def setMetadata(self, data): self._packages_metadata = data self._update() diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 127254795d..8d8c7a3654 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -24,7 +24,6 @@ from .PackagesModel import PackagesModel i18n_catalog = i18nCatalog("cura") - ## The Toolbox class is responsible of communicating with the server through the API class Toolbox(QObject, Extension): def __init__(self, parent=None): @@ -33,19 +32,17 @@ class Toolbox(QObject, Extension): self._application = Application.getInstance() self._package_manager = None self._plugin_registry = Application.getInstance().getPluginRegistry() - self._package_manager = None self._packages_version = self._plugin_registry.APIVersion self._api_version = 1 self._api_url = "https://api-staging.ultimaker.com/cura-packages/v{api_version}/cura/v{package_version}".format( api_version = self._api_version, package_version = self._packages_version) + # Network: self._get_packages_request = None self._get_showcase_request = None - self._download_request = None self._download_reply = None self._download_progress = 0 self._is_downloading = False - self._network_manager = None self._request_header = [ b"User-Agent", @@ -59,13 +56,43 @@ class Toolbox(QObject, Extension): ) ] + # Data: + self._authors_metadata = [] self._packages_metadata = [] + self._metadata = { + "authors": [], + "packages": [], + "materials_showcase": [ + { + "name": "DSM", + "email": "contact@dsm.nl", + "website": "www.dsm.nl", + "type": "material" + }, + { + "name": "BASF", + "email": "contact@basf.de", + "website": "www.basf.de", + "type": "material" + } + ] + } + + # Models: + self._authors_model = None self._packages_model = None self._plugins_showcase_model = None self._plugins_installed_model = None self._materials_showcase_model = None self._materials_installed_model = None - self._authors_model = None + self._models = { + "authors": None, + "packages": None, + "plugins_showcase": None, + "plugins_installed": None, + "materials_showcase": None, + "materials_installed": None + } # These properties are for keeping track of the UI state: # ---------------------------------------------------------------------- @@ -87,21 +114,10 @@ class Toolbox(QObject, Extension): # installed, or otherwise modified. self._active_package = None - # Nowadays can be 'plugins', 'materials' or 'installed' - self._current_view = "plugins" - self._detail_data = {} # Extraneous since can just use the data prop of the model. - self._dialog = None self._restartDialog = None self._restart_required = False - # Installed plugins are really installed after reboot. In order to - # prevent the user from downloading the same file over and over again, - # we keep track of the upgraded plugins. - self._newly_installed_plugin_ids = [] - self._newly_uninstalled_plugin_ids = [] - self._plugin_statuses = {} # type: Dict[str, str] - # variables for the license agreement dialog self._license_dialog_plugin_name = "" self._license_dialog_license_content = "" @@ -110,15 +126,10 @@ class Toolbox(QObject, Extension): Application.getInstance().initializationFinished.connect(self._onAppInitialized) - def _onAppInitialized(self): - self._package_manager = Application.getInstance().getCuraPackageManager() - packagesMetadataChanged = pyqtSignal() - authorsMetadataChanged = pyqtSignal() - pluginsShowcaseMetadataChanged = pyqtSignal() - materialsShowcaseMetadataChanged = pyqtSignal() - metadataChanged = pyqtSignal() + # Signals: + # -------------------------------------------------------------------------- # Downloading changes activePackageChanged = pyqtSignal() onDownloadProgressChanged = pyqtSignal() @@ -129,6 +140,7 @@ class Toolbox(QObject, Extension): viewChanged = pyqtSignal() detailViewChanged = pyqtSignal() filterChanged = pyqtSignal() + metadataChanged = pyqtSignal() showLicenseDialog = pyqtSignal() showRestartDialog = pyqtSignal() @@ -158,9 +170,11 @@ class Toolbox(QObject, Extension): self._restart_dialog_message = message self.showRestartDialog.emit() + def _onAppInitialized(self): + self._package_manager = Application.getInstance().getCuraPackageManager() + @pyqtSlot() def browsePackages(self): - self._package_manager = Application.getInstance().getCuraPackageManager() # Create the network manager: # This was formerly its own function but really had no reason to be as # it was never called more than once ever. @@ -180,13 +194,14 @@ class Toolbox(QObject, Extension): def _createDialog(self, qml_name): Logger.log("d", "Toolbox: Creating dialog [%s].", qml_name) path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) - dialog = Application.getInstance().createQmlComponent(path, {"manager": self}) + dialog = Application.getInstance().createQmlComponent(path, {"toolbox": self}) return dialog @pyqtSlot(str) def installPlugin(self, file_path): self._package_manager.installPackage(file_path) self.metadataChanged.emit() + # TODO: Stuff self.openRestartDialog("TODO") self._restart_required = True self.restartRequiredChanged.emit() @@ -197,53 +212,20 @@ class Toolbox(QObject, Extension): self.metadataChanged.emit() self._restart_required = True self.restartRequiredChanged.emit() - + # TODO: Stuff Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Plugin browser"), "TODO") @pyqtSlot(str) def enablePlugin(self, plugin_id): self._plugin_registry.enablePlugin(plugin_id) self.metadataChanged.emit() - Logger.log("i", "%s was set as 'active'", id) + Logger.log("i", "%s was set as 'active'.", plugin_id) @pyqtSlot(str) def disablePlugin(self, plugin_id): self._plugin_registry.disablePlugin(plugin_id) self.metadataChanged.emit() - Logger.log("i", "%s was set as 'deactive'", id) - - @pyqtProperty(QObject, notify = metadataChanged) - def pluginsModel(self): - self._plugins_model = PluginsModel(None, self._view_category) - # self._plugins_model.update() - - # Check each plugin the registry for matching plugin from server - # metadata, and if found, compare the versions. Higher version sets - # 'can_upgrade' to 'True': - for plugin in self._plugins_model.items: - if self._checkCanUpgrade(plugin["id"], plugin["version"]): - plugin["can_upgrade"] = True - - for item in self._packages_metadata: - if item["id"] == plugin["id"]: - plugin["update_url"] = item["file_location"] - return self._plugins_model - - @pyqtProperty(QObject, notify = metadataChanged) - def pluginsShowcaseModel(self): - return self._plugins_showcase_model - - @pyqtProperty(QObject, notify = metadataChanged) - def materialsShowcaseModel(self): - return self._materials_showcase_model - - @pyqtProperty(QObject, notify = metadataChanged) - def packagesModel(self): - return self._packages_model - - @pyqtProperty(QObject, notify = metadataChanged) - def authorsModel(self): - return self._authors_model + Logger.log("i", "%s was set as 'deactive'.", plugin_id) @pyqtProperty(bool, notify = metadataChanged) def dataReady(self): @@ -257,6 +239,23 @@ class Toolbox(QObject, Extension): def restart(self): CuraApplication.getInstance().windowClosed() + # @pyqtProperty(QObject, notify = metadataChanged) + # def pluginsModel(self): + # self._plugins_model = PluginsModel(None, self._view_category) + # # self._plugins_model.update() + # + # # Check each plugin the registry for matching plugin from server + # # metadata, and if found, compare the versions. Higher version sets + # # 'can_upgrade' to 'True': + # for plugin in self._plugins_model.items: + # if self._checkCanUpgrade(plugin["id"], plugin["version"]): + # plugin["can_upgrade"] = True + # + # for item in self._packages_metadata: + # if item["id"] == plugin["id"]: + # plugin["update_url"] = item["file_location"] + # return self._plugins_model + # Checks @@ -285,14 +284,6 @@ class Toolbox(QObject, Extension): self._network_manager.finished.connect(self._onRequestFinished) self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) - @pyqtProperty(bool, notify = restartRequiredChanged) - def restartRequired(self): - return self._restart_required - - @pyqtSlot() - def restart(self): - CuraApplication.getInstance().windowClosed() - # Make API Calls @@ -311,6 +302,8 @@ class Toolbox(QObject, Extension): self._get_showcase_request.setRawHeader(*self._request_header) self._network_manager.get(self._get_showcase_request) + # TODO: Request authors and request material showcase + @pyqtSlot(str) def startDownload(self, url): Logger.log("i", "Toolbox: Attempting to download & install package from %s.", url) @@ -335,7 +328,7 @@ class Toolbox(QObject, Extension): - # Handlers for Download Events + # Handlers for Network Events # -------------------------------------------------------------------------- def _onNetworkAccesibleChanged(self, accessible): if accessible == 0: @@ -369,44 +362,29 @@ class Toolbox(QObject, Extension): json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) print(json_data) # Create packages model with all packages: - if not self._packages_model: - self._packages_model = PackagesModel() - self._packages_metadata = json_data["data"] - self._packages_model.setPackagesMetaData(self._packages_metadata) + if not self._models["packages"]: + self._models["packages"] = PackagesModel() + self._metadata["packages"] = json_data["data"] + self._models["packages"].setMetadata(self._metadata["packages"]) self.metadataChanged.emit() # Create authors model with all authors: if not self._authors_model: self._authors_model = AuthorsModel() - # TODO: Remove this hacky code once there's an API call for this. - self._authors_metadata = [] - for package in self._packages_metadata: + # TODO: Replace this with a proper API call: + for package in self._metadata["packages"]: package["author"]["type"] = package["package_type"] if package["author"] not in self._authors_metadata: - self._authors_metadata.append(package["author"]) - self._authors_model.setMetaData(self._authors_metadata) + self._metadata["authors"].append(package["author"]) + self._models["author"].setMetadata(self._metadata["authors"]) self.metadataChanged.emit() - self.setViewPage("overview") - # TODO: Also replace this with a proper API call: - if not self._materials_showcase_model: - self._materials_showcase_model = AuthorsModel() - # TODO: Remove this hacky code once there's an API call for this. - self._materials_showcase_model.setMetaData([ - { - "name": "DSM", - "email": "contact@dsm.nl", - "website": "www.dsm.nl", - "type": "material" - }, - { - "name": "BASF", - "email": "contact@basf.de", - "website": "www.basf.de", - "type": "material" - } - ]) + if not self._models["materials_showcase"]: + self._models["materials_showcase"] = AuthorsModel() + # TODO: Replace this with a proper API call: + self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"]) self.metadataChanged.emit() + self.setViewPage("overview") except json.decoder.JSONDecodeError: @@ -467,7 +445,7 @@ class Toolbox(QObject, Extension): return - # Getter & Setters + # Getter & Setters for Properties: # -------------------------------------------------------------------------- def setDownloadProgress(self, progress): if progress != self._download_progress: @@ -515,7 +493,35 @@ class Toolbox(QObject, Extension): - # Model Filtering + # Expose Models: + # -------------------------------------------------------------------------- + @pyqtProperty(QObject, notify = metadataChanged) + def authorsModel(self): + return self._models["authors"] + + @pyqtProperty(QObject, notify = metadataChanged) + def packagesModel(self): + return self._models["packages"] + + @pyqtProperty(QObject, notify = metadataChanged) + def pluginsShowcaseModel(self): + return self._models["plugins_showcase"] + + @pyqtProperty(QObject, notify = metadataChanged) + def pluginsInstalledModel(self): + return self._models["plugins_installed"] + + @pyqtProperty(QObject, notify = metadataChanged) + def materialsShowcaseModel(self): + return self._models["materials_showcase"] + + @pyqtProperty(QObject, notify = metadataChanged) + def materialsInstalledModel(self): + return self._models["materials_installed"] + + + + # Filter Models: # -------------------------------------------------------------------------- @pyqtSlot(str, str) def filterPackages(self, filterType, parameter): From f510603cb5f875114482b698ae4c4fb88826f4a0 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 12 Apr 2018 15:43:25 +0200 Subject: [PATCH 41/83] CURA-5035 Enjoy Lipu --- plugins/Toolbox/src/AuthorsModel.py | 6 +- plugins/Toolbox/src/PackagesModel.py | 7 +- plugins/Toolbox/src/ShowcaseModel.py | 110 ++++++++++++++++++++ plugins/Toolbox/src/Toolbox.py | 147 ++++++++++++++++----------- 4 files changed, 206 insertions(+), 64 deletions(-) create mode 100644 plugins/Toolbox/src/ShowcaseModel.py diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index 6d44c6c789..ace609b0ac 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -18,7 +18,7 @@ class AuthorsModel(ListModel): def __init__(self, parent = None): super().__init__(parent) - self._authors_metadata = None + self._metadata = None self.addRoleName(AuthorsModel.NameRole, "name") self.addRoleName(AuthorsModel.EmailRole, "email") @@ -29,13 +29,13 @@ class AuthorsModel(ListModel): self._filter = {} # type: Dict[str,str] def setMetadata(self, data): - self._authors_metadata = data + self._metadata = data self._update() def _update(self): items = [] - for author in self._authors_metadata: + for author in self._metadata: items.append({ "name": author["name"], "email": author["email"], diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index 12462f4b77..d11dc61029 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -25,7 +25,7 @@ class PackagesModel(ListModel): def __init__(self, parent = None): super().__init__(parent) - self._packages_metadata = None + self._metadata = None self.addRoleName(PackagesModel.IdRole, "id") self.addRoleName(PackagesModel.TypeRole, "type") @@ -43,13 +43,14 @@ class PackagesModel(ListModel): self._filter = {} # type: Dict[str,str] def setMetadata(self, data): - self._packages_metadata = data + self._metadata = data self._update() def _update(self): items = [] - for package in self._packages_metadata: + for package in self._metadata: + print(package) items.append({ "id": package["package_id"], "type": package["package_type"], diff --git a/plugins/Toolbox/src/ShowcaseModel.py b/plugins/Toolbox/src/ShowcaseModel.py new file mode 100644 index 0000000000..2dcfc45762 --- /dev/null +++ b/plugins/Toolbox/src/ShowcaseModel.py @@ -0,0 +1,110 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import re +from typing import Dict + +from PyQt5.QtCore import Qt, pyqtProperty, pyqtSignal + +from UM.Qt.ListModel import ListModel + +## Model that holds cura packages. By setting the filter property the instances held by this model can be changed. +class ShowcaseModel(ListModel): + IdRole = Qt.UserRole + 1 + TypeRole = Qt.UserRole + 2 + NameRole = Qt.UserRole + 3 + VersionRole = Qt.UserRole + 4 + AuthorNameRole = Qt.UserRole + 5 + AuthorEmailRole = Qt.UserRole + 6 + DescriptionRole = Qt.UserRole + 7 + IconURLRole = Qt.UserRole + 8 + ImageURLsRole = Qt.UserRole + 9 + DownloadURLRole = Qt.UserRole + 10 + LastUpdatedRole = Qt.UserRole + 11 + + def __init__(self, parent = None): + super().__init__(parent) + + self._metadata = None + + self.addRoleName(ShowcaseModel.IdRole, "id") + self.addRoleName(ShowcaseModel.TypeRole, "type") + self.addRoleName(ShowcaseModel.NameRole, "name") + self.addRoleName(ShowcaseModel.VersionRole, "version") + self.addRoleName(ShowcaseModel.AuthorNameRole, "author_name") + self.addRoleName(ShowcaseModel.AuthorEmailRole, "author_email") + self.addRoleName(ShowcaseModel.DescriptionRole, "description") + self.addRoleName(ShowcaseModel.IconURLRole, "icon_url") + self.addRoleName(ShowcaseModel.ImageURLsRole, "image_urls") + self.addRoleName(ShowcaseModel.DownloadURLRole, "download_url") + self.addRoleName(ShowcaseModel.LastUpdatedRole, "last_updated") + + # List of filters for queries. The result is the union of the each list of results. + self._filter = {} # type: Dict[str,str] + + def setMetadata(self, data): + self._metadata = data + self._update() + + def _update(self): + items = [] + + for package in self._metadata: + print(package) + items.append({ + "id": package["id"], + "type": package["type"], + "name": package["name"], + "version": package["package_version"], + "author_name": package["author"]["name"], + "author_email": package["author"]["email"], + "description": package["description"], + "icon_url": package["icon_url"] if "icon_url" in package else None, + "image_urls": package["image_urls"], + "download_url": package["download_url"], + "last_updated": package["last_updated"] + }) + + # Filter on all the key-word arguments. + for key, value in self._filter.items(): + if "*" in value: + key_filter = lambda candidate, key = key, value = value: self._matchRegExp(candidate, key, value) + else: + key_filter = lambda candidate, key = key, value = value: self._matchString(candidate, key, value) + items = filter(key_filter, items) + + # Execute all filters. + filtered_items = list(items) + + filtered_items.sort(key = lambda k: k["name"]) + self.setItems(filtered_items) + + ## Set the filter of this model based on a string. + # \param filter_dict \type{Dict} Dictionary to do the filtering by. + def setFilter(self, filter_dict: Dict[str, str]) -> None: + if filter_dict != self._filter: + self._filter = filter_dict + self._update() + + @pyqtProperty("QVariantMap", fset = setFilter, constant = True) + def filter(self) -> Dict[str, str]: + return self._filter + + # Check to see if a container matches with a regular expression + def _matchRegExp(self, metadata, property_name, value): + if property_name not in metadata: + return False + value = re.escape(value) #Escape for regex patterns. + value = "^" + value.replace("\\*", ".*") + "$" #Instead of (now escaped) asterisks, match on any string. Also add anchors for a complete match. + if self._ignore_case: + value_pattern = re.compile(value, re.IGNORECASE) + else: + value_pattern = re.compile(value) + + return value_pattern.match(str(metadata[property_name])) + + # Check to see if a container matches with a string + def _matchString(self, metadata, property_name, value): + if property_name not in metadata: + return False + return value.lower() == str(metadata[property_name]).lower() diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 8d8c7a3654..b3b46d283e 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -21,6 +21,7 @@ from cura.Utils.VersionTools import compareSemanticVersions from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel from .PackagesModel import PackagesModel +from .ShowcaseModel import ShowcaseModel i18n_catalog = i18nCatalog("cura") @@ -55,13 +56,18 @@ class Toolbox(QObject, Extension): ) ) ] + self._request_urls = { + "authors": None, + "packages": QUrl("{base_url}/packages".format(base_url = self._api_url)), + "plugins_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)), + "materials_showcase": None + } # Data: - self._authors_metadata = [] - self._packages_metadata = [] self._metadata = { "authors": [], "packages": [], + "plugins_showcase": [], "materials_showcase": [ { "name": "DSM", @@ -79,19 +85,13 @@ class Toolbox(QObject, Extension): } # Models: - self._authors_model = None - self._packages_model = None - self._plugins_showcase_model = None - self._plugins_installed_model = None - self._materials_showcase_model = None - self._materials_installed_model = None self._models = { - "authors": None, - "packages": None, - "plugins_showcase": None, - "plugins_installed": None, - "materials_showcase": None, - "materials_installed": None + "authors": AuthorsModel(self), + "packages": PackagesModel(self), + "plugins_showcase": PackagesModel(self), + "plugins_installed": PackagesModel(self), + "materials_showcase": AuthorsModel(self), + "materials_installed": PackagesModel(self) } # These properties are for keeping track of the UI state: @@ -185,8 +185,9 @@ class Toolbox(QObject, Extension): self._network_manager.finished.connect(self._onRequestFinished) self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) - self._requestShowcase() - self._requestPackages() + self.makeRequestByType("packages") + self.makeRequestByType("plugins_showcase") + if not self._dialog: self._dialog = self._createDialog("Toolbox.qml") self._dialog.show() @@ -239,23 +240,6 @@ class Toolbox(QObject, Extension): def restart(self): CuraApplication.getInstance().windowClosed() - # @pyqtProperty(QObject, notify = metadataChanged) - # def pluginsModel(self): - # self._plugins_model = PluginsModel(None, self._view_category) - # # self._plugins_model.update() - # - # # Check each plugin the registry for matching plugin from server - # # metadata, and if found, compare the versions. Higher version sets - # # 'can_upgrade' to 'True': - # for plugin in self._plugins_model.items: - # if self._checkCanUpgrade(plugin["id"], plugin["version"]): - # plugin["can_upgrade"] = True - # - # for item in self._packages_metadata: - # if item["id"] == plugin["id"]: - # plugin["update_url"] = item["file_location"] - # return self._plugins_model - # Checks @@ -288,17 +272,21 @@ class Toolbox(QObject, Extension): # Make API Calls # -------------------------------------------------------------------------- + def makeRequestByType(self, type): + Logger.log("i", "Toolbox: Requesting %s metadata from server.", type) + request = QNetworkRequest(self._request_urls[type]) + request.setRawHeader(*self._request_header) + self._network_manager.get(request) + def _requestPackages(self): Logger.log("i", "Toolbox: Requesting package list from server.") - url = QUrl("{base_url}/packages".format(base_url = self._api_url)) - self._get_packages_request = QNetworkRequest(url) + self._get_packages_request = QNetworkRequest(self._request_urls["packages"]) self._get_packages_request.setRawHeader(*self._request_header) self._network_manager.get(self._get_packages_request) def _requestShowcase(self): Logger.log("i", "Toolbox: Requesting showcase list from server.") - url = QUrl("{base_url}/showcase".format(base_url = self._api_url)) - self._get_showcase_request = QNetworkRequest(url) + self._get_showcase_request = QNetworkRequest(self._request_urls["plugins_showcase"]) self._get_showcase_request.setRawHeader(*self._request_header) self._network_manager.get(self._get_showcase_request) @@ -341,7 +329,7 @@ class Toolbox(QObject, Extension): # TODO: This function is sooooo ugly. Needs a rework: def _onRequestFinished(self, reply): - reply_url = reply.url().toString() + if reply.error() == QNetworkReply.TimeoutError: Logger.log("w", "Got a timeout.") # Reset everything. @@ -357,7 +345,27 @@ class Toolbox(QObject, Extension): return if reply.operation() == QNetworkAccessManager.GetOperation: - if reply_url == "{base_url}/packages".format(base_url = self._api_url): + + # TODO: In the future use the following to build any model from any + # request. Right now this doesn't work though as the packages + # request is also responsible for populating other models. + # for type, url in self._request_urls.items(): + # if reply.url() == url: + # try: + # json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) + # if not self._models[type]: + # Logger.log("e", "Could not find the %s model.", type) + # break + # self._metadata[type] = json_data["data"] + # self._models[type].setMetadata(self._metadata[type]) + # self.metadataChanged.emit() + # self.setViewPage("overview") + # return + # except json.decoder.JSONDecodeError: + # Logger.log("w", "Toolbox: Received invalid JSON for %s.", type) + # break + + if reply.url() == self._request_urls["packages"]: try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) print(json_data) @@ -369,14 +377,14 @@ class Toolbox(QObject, Extension): self.metadataChanged.emit() # Create authors model with all authors: - if not self._authors_model: - self._authors_model = AuthorsModel() + if not self._models["authors"]: + self._models["authors"] = AuthorsModel() # TODO: Replace this with a proper API call: for package in self._metadata["packages"]: package["author"]["type"] = package["package_type"] - if package["author"] not in self._authors_metadata: + if package["author"] not in self._metadata["authors"]: self._metadata["authors"].append(package["author"]) - self._models["author"].setMetadata(self._metadata["authors"]) + self._models["authors"].setMetadata(self._metadata["authors"]) self.metadataChanged.emit() if not self._models["materials_showcase"]: @@ -386,24 +394,28 @@ class Toolbox(QObject, Extension): self.metadataChanged.emit() self.setViewPage("overview") + return except json.decoder.JSONDecodeError: Logger.log("w", "Toolbox: Received invalid JSON for package list.") return - elif reply_url == "{base_url}/showcase".format(base_url = self._api_url): + if reply.url() == self._request_urls["plugins_showcase"]: try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) # Create packages model with all packages: - if not self._plugins_showcase_model: - self._plugins_showcase_model = PackagesModel() - self._showcase_metadata = json_data["data"] - print(self._showcase_metadata) - self._plugins_showcase_model.setPackagesMetaData(self._showcase_metadata) - for package in self._plugins_showcase_model.items: + if not self._models["plugins_showcase"]: + self._models["plugins_showcase"] = PackagesModel() + self._metadata["plugins_showcase"] = json_data["data"] + self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"]) + for package in self._models["plugins_showcase"].items: print(package) self.metadataChanged.emit() + + self.setViewPage("overview") + return + except json.decoder.JSONDecodeError: Logger.log("w", "Toolbox: Received invalid JSON for showcase.") return @@ -495,6 +507,8 @@ class Toolbox(QObject, Extension): # Expose Models: # -------------------------------------------------------------------------- + # TODO: Maybe replace this with simply exposing self._models to Qt and then + # setting model: toolbox.models.foobar instead of toolbox.foobarModel @pyqtProperty(QObject, notify = metadataChanged) def authorsModel(self): return self._models["authors"] @@ -523,30 +537,47 @@ class Toolbox(QObject, Extension): # Filter Models: # -------------------------------------------------------------------------- + @pyqtSlot(str, str, str) + def filterModelByProp(self, modelType, filterType, parameter): + if not self._models[modelType]: + Logger.log("w", "Toolbox: Couldn't filter %s model because it doesn't exist.", modelType) + return + self._models[modelType].setFilter({ filterType: parameter }) + self.filterChanged.emit() + + @pyqtSlot() + def removeFilters(self, modelType): + if not self._models[modelType]: + Logger.log("w", "Toolbox: Couldn't remove filters on %s model because it doesn't exist.", modelType) + return + self._models[modelType].setFilter({}) + self.filterChanged.emit() + + # TODO: Eventually dump everything below here: @pyqtSlot(str, str) def filterPackages(self, filterType, parameter): - if not self._packages_model: + if not self._models["packages"]: return - self._packages_model.setFilter({ filterType: parameter }) + self._models["packages"].setFilter({ filterType: parameter }) self.filterChanged.emit() @pyqtSlot() def unfilterPackages(self): - if not self._packages_model: + if not self._models["packages"]: return - self._packages_model.setFilter({}) + self._models["packages"].setFilter({}) self.filterChanged.emit() @pyqtSlot(str, str) def filterAuthors(self, filterType, parameter): - if not self._authors_model: + if not self._models["authors"]: return - self._authors_model.setFilter({ filterType: parameter }) + self._models["authors"].setFilter({ filterType: parameter }) self.filterChanged.emit() @pyqtSlot() def unfilterAuthors(self): - if not self._authors_model: + if not self._models["authors"]: return - self._authors_model.setFilter({}) + self._models["authors"].setFilter({}) self.filterChanged.emit() From 0f966115e65762149d61009b4968598a5bb33c20 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 12 Apr 2018 15:19:18 +0200 Subject: [PATCH 42/83] WIP: Make CuraPackageManager aggregate PluginRegistry data CURA-4644 --- cura/CuraApplication.py | 11 +--- cura/CuraPackageManager.py | 75 ++++++++++++++++++++++++++-- plugins/Toolbox/src/PackagesModel.py | 6 ++- plugins/Toolbox/src/Toolbox.py | 11 ++-- resources/qml/Cura.qml | 33 ------------ 5 files changed, 83 insertions(+), 53 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 6e19ab3a30..53b6f68f22 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -100,7 +100,6 @@ from PyQt5.QtWidgets import QMessageBox from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType import sys -import os.path import numpy import copy import os @@ -248,6 +247,8 @@ class CuraApplication(QtApplication): self.initialize() + self._cura_package_manager.getAllInstalledPackagesInfo() + # FOR TESTING ONLY if kwargs["parsed_command_line"].get("trigger_early_crash", False): assert not "This crash is triggered by the trigger_early_crash command line argument." @@ -395,8 +396,6 @@ class CuraApplication(QtApplication): self.globalContainerStackChanged.connect(self._onGlobalContainerChanged) self._onGlobalContainerChanged() - self._plugin_registry.addSupportedPluginExtension("curaplugin", "Cura Plugin") - self.getCuraSceneController().setActiveBuildPlate(0) # Initialize self._quality_profile_drop_down_menu_model = None @@ -404,7 +403,6 @@ class CuraApplication(QtApplication): CuraApplication.Created = True - def _onEngineCreated(self): self._engine.addImageProvider("camera", CameraImageProvider.CameraImageProvider()) @@ -508,11 +506,6 @@ class CuraApplication(QtApplication): def getStaticVersion(cls): return CuraVersion - ## Handle removing the unneeded plugins - # \sa PluginRegistry - def _removePlugins(self): - self._plugin_registry.removePlugins() - ## Handle loading of all plugin types (and the backend explicitly) # \sa PluginRegistry def _loadPlugins(self): diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index d07a3aced0..abfad86b20 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -85,10 +85,79 @@ class CuraPackageManager(QObject): def getInstalledPackageInfo(self, package_id: str) -> Optional[dict]: if package_id in self._to_remove_package_set: return None - if package_id in self._to_install_package_dict: - return self._to_install_package_dict[package_id]["package_info"] - return self._installed_package_dict.get(package_id) + if package_id in self._to_install_package_dict: + package_info = self._to_install_package_dict[package_id]["package_info"] + package_info["is_bundled"] = False + return package_info + + if package_id in self._installed_package_dict: + package_info = self._installed_package_dict.get(package_id) + package_info["is_bundled"] = False + return package_info + + # TODO: get from plugin registry + #self._plugin_registry. + + return None + + def getAllInstalledPackagesInfo(self) -> dict: + installed_package_id_set = set(self._installed_package_dict.keys()) | set(self._to_install_package_dict.keys()) + installed_package_id_set = installed_package_id_set.difference(self._to_remove_package_set) + + managed_package_id_set = set(installed_package_id_set) | self._to_remove_package_set + + # map of -> -> + installed_packages_dict = {} + for package_id in installed_package_id_set: + if package_id in self._to_install_package_dict: + package_info = self._to_install_package_dict[package_id]["package_info"] + else: + package_info = self._installed_package_dict[package_id] + package_info["is_bundled"] = False + + package_type = package_info["package_type"] + if package_type not in installed_packages_dict: + installed_packages_dict[package_type] = {} + installed_packages_dict[package_type][package_id] = package_info + + # We also need to get information from the plugin registry such as if a plugin is active + package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id) + + # Also get all bundled plugins + all_metadata = self._plugin_registry.getAllMetaData() + for item in all_metadata: + plugin_package_info = self.__convertPluginMetadataToPackageMetadata(item) + # Only gather the bundled plugins here. + package_id = plugin_package_info["package_id"] + if package_id in managed_package_id_set: + continue + + plugin_package_info["is_bundled"] = True + plugin_package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id) + package_type = "plugin" + if package_type not in installed_packages_dict: + installed_packages_dict[package_type] = {} + installed_packages_dict[package_type][package_id] = plugin_package_info + + return installed_packages_dict + + def __convertPluginMetadataToPackageMetadata(self, plugin_metadata: dict) -> dict: + package_metadata = {"package_id": plugin_metadata["id"], + "package_type": "plugin", + "display_name": plugin_metadata["plugin"]["name"], + "description": plugin_metadata["plugin"].get("description"), + "package_version": plugin_metadata["plugin"]["version"], + "cura_version": int(plugin_metadata["plugin"]["api"]), + "website": "", + "author": { + "name": plugin_metadata["plugin"].get("author", ""), + "email": "", + "website": "", + }, + "tags": ["plugin"], + } + return package_metadata # Checks if the given package is installed. def isPackageInstalled(self, package_id: str) -> bool: diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index d11dc61029..7bf023f707 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -4,10 +4,12 @@ import re from typing import Dict -from PyQt5.QtCore import Qt, pyqtProperty, pyqtSignal +from PyQt5.QtCore import Qt, pyqtProperty +from UM.Application import Application from UM.Qt.ListModel import ListModel + ## Model that holds cura packages. By setting the filter property the instances held by this model can be changed. class PackagesModel(ListModel): IdRole = Qt.UserRole + 1 @@ -40,7 +42,7 @@ class PackagesModel(ListModel): self.addRoleName(PackagesModel.LastUpdatedRole, "last_updated") # List of filters for queries. The result is the union of the each list of results. - self._filter = {} # type: Dict[str,str] + self._filter = {} # type: Dict[str, str] def setMetadata(self, data): self._metadata = data diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index b3b46d283e..92bd5eefec 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -218,13 +218,13 @@ class Toolbox(QObject, Extension): @pyqtSlot(str) def enablePlugin(self, plugin_id): - self._plugin_registry.enablePlugin(plugin_id) + self._plugin_registry.setPluginEnabled(plugin_id, True) self.metadataChanged.emit() Logger.log("i", "%s was set as 'active'.", plugin_id) @pyqtSlot(str) def disablePlugin(self, plugin_id): - self._plugin_registry.disablePlugin(plugin_id) + self._plugin_registry.setPluginEnabled(plugin_id, False) self.metadataChanged.emit() Logger.log("i", "%s was set as 'deactive'.", plugin_id) @@ -371,7 +371,7 @@ class Toolbox(QObject, Extension): print(json_data) # Create packages model with all packages: if not self._models["packages"]: - self._models["packages"] = PackagesModel() + self._models["packages"] = PackagesModel(self) self._metadata["packages"] = json_data["data"] self._models["packages"].setMetadata(self._metadata["packages"]) self.metadataChanged.emit() @@ -388,7 +388,7 @@ class Toolbox(QObject, Extension): self.metadataChanged.emit() if not self._models["materials_showcase"]: - self._models["materials_showcase"] = AuthorsModel() + self._models["materials_showcase"] = AuthorsModel(self) # TODO: Replace this with a proper API call: self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"]) self.metadataChanged.emit() @@ -400,8 +400,7 @@ class Toolbox(QObject, Extension): Logger.log("w", "Toolbox: Received invalid JSON for package list.") return - - if reply.url() == self._request_urls["plugins_showcase"]: + if reply.url() == self._request_urls["plugins_showcase"]: try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) # Create packages model with all packages: diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index e20a29fe16..23feede6a0 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -322,31 +322,6 @@ UM.MainWindow { if (drop.urls.length > 0) { - // As the drop area also supports plugins, first check if it's a plugin that was dropped. - if (drop.urls.length == 1) - { - if (PluginRegistry.isPluginFile(drop.urls[0])) - { - // Try to install plugin & close. - var result = PluginRegistry.installPlugin(drop.urls[0]); - pluginInstallDialog.text = result.message; - if (result.status == "ok") - { - pluginInstallDialog.icon = StandardIcon.Information; - } - else if (result.status == "duplicate") - { - pluginInstallDialog.icon = StandardIcon.Warning; - } - else - { - pluginInstallDialog.icon = StandardIcon.Critical; - } - pluginInstallDialog.open(); - return; - } - } - openDialog.handleOpenFileUrls(drop.urls); } } @@ -813,14 +788,6 @@ UM.MainWindow } } - MessageDialog - { - id: pluginInstallDialog - title: catalog.i18nc("@window:title", "Install Plugin"); - standardButtons: StandardButton.Ok - modality: Qt.ApplicationModal - } - MessageDialog { id: infoMultipleFilesWithGcodeDialog title: catalog.i18nc("@title:window", "Open File(s)") From 5d395f549ac487ae362f8b30eb41cb2e8c11b070 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 12 Apr 2018 17:22:50 +0200 Subject: [PATCH 43/83] CURA-5035 Added already installed plugins --- cura/CuraPackageManager.py | 8 +- .../resources/qml/ToolboxBackColumn.qml | 4 +- .../qml/ToolboxDownloadsGridTile.qml | 8 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 8 +- .../Toolbox/resources/qml/ToolboxHeader.qml | 11 +- .../resources/qml/ToolboxInstalledPage.qml | 4 +- .../resources/qml/ToolboxInstalledTile.qml | 10 +- plugins/Toolbox/src/PackagesModel.py | 7 +- plugins/Toolbox/src/ShowcaseModel.py | 110 ------------------ plugins/Toolbox/src/Toolbox.py | 87 ++++---------- 10 files changed, 51 insertions(+), 206 deletions(-) delete mode 100644 plugins/Toolbox/src/ShowcaseModel.py diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index abfad86b20..f787a8b29b 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -118,8 +118,8 @@ class CuraPackageManager(QObject): package_type = package_info["package_type"] if package_type not in installed_packages_dict: - installed_packages_dict[package_type] = {} - installed_packages_dict[package_type][package_id] = package_info + installed_packages_dict[package_type] = [] + installed_packages_dict[package_type].append( package_info ) # We also need to get information from the plugin registry such as if a plugin is active package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id) @@ -137,8 +137,8 @@ class CuraPackageManager(QObject): plugin_package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id) package_type = "plugin" if package_type not in installed_packages_dict: - installed_packages_dict[package_type] = {} - installed_packages_dict[package_type][package_id] = plugin_package_info + installed_packages_dict[package_type] = [] + installed_packages_dict[package_type].append( plugin_package_info ) return installed_packages_dict diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml index 01f6d44033..faeac08b3c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -42,8 +42,8 @@ Item onClicked: { toolbox.viewPage = "overview" - toolbox.filterPackages("type", toolbox.viewCategory) - toolbox.filterAuthors("type", toolbox.viewCategory) + toolbox.filterModelByProp("packages", "type", toolbox.viewCategory) + toolbox.filterModelByProp("authors", "type", toolbox.viewCategory) } style: ButtonStyle { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 729d1e17d6..cac8be8ae9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -92,15 +92,15 @@ Item { toolbox.viewSelection = model.name toolbox.viewPage = "author" - toolbox.filterAuthors("name", model.name) - toolbox.filterPackages("author_name", model.name) + toolbox.filterModelByProp("authors", "name", model.name) + toolbox.filterModelByProp("packages", "author_name", model.name) } else { toolbox.viewSelection = model.id toolbox.viewPage = "detail" - toolbox.filterAuthors("name", model.author_name) - toolbox.filterPackages("id", model.id) + toolbox.filterModelByProp("authors", "name", model.author_name) + toolbox.filterModelByProp("packages", "id", model.id) } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index b7888f257f..51ccc9b0e5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -56,14 +56,14 @@ Item case "material": toolbox.viewSelection = model.name toolbox.viewPage = "author" - toolbox.filterAuthors("name", model.name) - toolbox.filterPackages("author_name", model.name) + toolbox.filterModelByProp("authors", "name", model.name) + toolbox.filterModelByProp("packages", "author_name", model.name) break default: toolbox.viewSelection = model.id toolbox.viewPage = "detail" - toolbox.filterAuthors("name", model.author_name) - toolbox.filterPackages("id", model.id) + toolbox.filterModelByProp("authors", "name", model.author_name) + toolbox.filterModelByProp("packages", "id", model.id) break } } diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 060eefa493..5604814afd 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -6,9 +6,6 @@ import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 - -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - import UM 1.1 as UM Rectangle { @@ -55,8 +52,8 @@ Rectangle { } onClicked: { - toolbox.filterPackages("type", "plugin") - toolbox.filterAuthors("type", "plugin") + toolbox.filterModelByProp("packages", "type", "plugin") + toolbox.filterModelByProp("authors", "type", "plugin") toolbox.viewCategory = "plugin" toolbox.viewPage = "overview" } @@ -92,8 +89,8 @@ Rectangle { } onClicked: { - toolbox.filterPackages("type", "material") - toolbox.filterAuthors("type", "material") + toolbox.filterModelByProp("packages", "type", "material") + toolbox.filterModelByProp("authors", "type", "material") toolbox.viewCategory = "material" toolbox.viewPage = "overview" } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index d8169906b5..cfcd8acf32 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -58,7 +58,7 @@ ScrollView Repeater { id: materialList - model: toolbox.packagesModel + model: toolbox.pluginsInstalledModel delegate: ToolboxInstalledTile {} } } @@ -93,7 +93,7 @@ ScrollView Repeater { id: pluginList - model: toolbox.packagesModel + model: toolbox.materialsInstalledModel delegate: ToolboxInstalledTile {} } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 25bcbab895..75314e9af5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -103,7 +103,7 @@ Item Button { id: removeButton text: "Uninstall" - visible: model.can_uninstall && model.status == "installed" + // visible: model.can_uninstall && model.status == "installed" enabled: !toolbox.isDownloading style: ButtonStyle { @@ -131,7 +131,7 @@ Item Button { id: updateButton text: "Update" - enabled: model.can_update + // enabled: model.can_update style: ButtonStyle { background: Rectangle @@ -157,9 +157,9 @@ Item ProgressBar { id: progressbar - anchors.left: installButton.left - anchors.right: installButton.right - anchors.top: installButton.bottom + anchors.left: updateButton.left + anchors.right: updateButton.right + anchors.top: updateButton.bottom anchors.topMargin: 4 value: toolbox.isDownloading ? toolbox.downloadProgress : 0 visible: toolbox.isDownloading diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index 7bf023f707..dc1eb2cb78 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -52,7 +52,6 @@ class PackagesModel(ListModel): items = [] for package in self._metadata: - print(package) items.append({ "id": package["package_id"], "type": package["package_type"], @@ -62,9 +61,9 @@ class PackagesModel(ListModel): "author_email": package["author"]["email"], "description": package["description"], "icon_url": package["icon_url"] if "icon_url" in package else None, - "image_urls": package["image_urls"], - "download_url": package["download_url"], - "last_updated": package["last_updated"] + "image_urls": package["image_urls"] if "image_urls" in package else None, + "download_url": package["download_url"] if "download_url" in package else None, + "last_updated": package["last_updated"] if "last_updated" in package else None }) # Filter on all the key-word arguments. diff --git a/plugins/Toolbox/src/ShowcaseModel.py b/plugins/Toolbox/src/ShowcaseModel.py deleted file mode 100644 index 2dcfc45762..0000000000 --- a/plugins/Toolbox/src/ShowcaseModel.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -import re -from typing import Dict - -from PyQt5.QtCore import Qt, pyqtProperty, pyqtSignal - -from UM.Qt.ListModel import ListModel - -## Model that holds cura packages. By setting the filter property the instances held by this model can be changed. -class ShowcaseModel(ListModel): - IdRole = Qt.UserRole + 1 - TypeRole = Qt.UserRole + 2 - NameRole = Qt.UserRole + 3 - VersionRole = Qt.UserRole + 4 - AuthorNameRole = Qt.UserRole + 5 - AuthorEmailRole = Qt.UserRole + 6 - DescriptionRole = Qt.UserRole + 7 - IconURLRole = Qt.UserRole + 8 - ImageURLsRole = Qt.UserRole + 9 - DownloadURLRole = Qt.UserRole + 10 - LastUpdatedRole = Qt.UserRole + 11 - - def __init__(self, parent = None): - super().__init__(parent) - - self._metadata = None - - self.addRoleName(ShowcaseModel.IdRole, "id") - self.addRoleName(ShowcaseModel.TypeRole, "type") - self.addRoleName(ShowcaseModel.NameRole, "name") - self.addRoleName(ShowcaseModel.VersionRole, "version") - self.addRoleName(ShowcaseModel.AuthorNameRole, "author_name") - self.addRoleName(ShowcaseModel.AuthorEmailRole, "author_email") - self.addRoleName(ShowcaseModel.DescriptionRole, "description") - self.addRoleName(ShowcaseModel.IconURLRole, "icon_url") - self.addRoleName(ShowcaseModel.ImageURLsRole, "image_urls") - self.addRoleName(ShowcaseModel.DownloadURLRole, "download_url") - self.addRoleName(ShowcaseModel.LastUpdatedRole, "last_updated") - - # List of filters for queries. The result is the union of the each list of results. - self._filter = {} # type: Dict[str,str] - - def setMetadata(self, data): - self._metadata = data - self._update() - - def _update(self): - items = [] - - for package in self._metadata: - print(package) - items.append({ - "id": package["id"], - "type": package["type"], - "name": package["name"], - "version": package["package_version"], - "author_name": package["author"]["name"], - "author_email": package["author"]["email"], - "description": package["description"], - "icon_url": package["icon_url"] if "icon_url" in package else None, - "image_urls": package["image_urls"], - "download_url": package["download_url"], - "last_updated": package["last_updated"] - }) - - # Filter on all the key-word arguments. - for key, value in self._filter.items(): - if "*" in value: - key_filter = lambda candidate, key = key, value = value: self._matchRegExp(candidate, key, value) - else: - key_filter = lambda candidate, key = key, value = value: self._matchString(candidate, key, value) - items = filter(key_filter, items) - - # Execute all filters. - filtered_items = list(items) - - filtered_items.sort(key = lambda k: k["name"]) - self.setItems(filtered_items) - - ## Set the filter of this model based on a string. - # \param filter_dict \type{Dict} Dictionary to do the filtering by. - def setFilter(self, filter_dict: Dict[str, str]) -> None: - if filter_dict != self._filter: - self._filter = filter_dict - self._update() - - @pyqtProperty("QVariantMap", fset = setFilter, constant = True) - def filter(self) -> Dict[str, str]: - return self._filter - - # Check to see if a container matches with a regular expression - def _matchRegExp(self, metadata, property_name, value): - if property_name not in metadata: - return False - value = re.escape(value) #Escape for regex patterns. - value = "^" + value.replace("\\*", ".*") + "$" #Instead of (now escaped) asterisks, match on any string. Also add anchors for a complete match. - if self._ignore_case: - value_pattern = re.compile(value, re.IGNORECASE) - else: - value_pattern = re.compile(value) - - return value_pattern.match(str(metadata[property_name])) - - # Check to see if a container matches with a string - def _matchString(self, metadata, property_name, value): - if property_name not in metadata: - return False - return value.lower() == str(metadata[property_name]).lower() diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 92bd5eefec..dacf806fe6 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -21,7 +21,6 @@ from cura.Utils.VersionTools import compareSemanticVersions from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel from .PackagesModel import PackagesModel -from .ShowcaseModel import ShowcaseModel i18n_catalog = i18nCatalog("cura") @@ -68,6 +67,8 @@ class Toolbox(QObject, Extension): "authors": [], "packages": [], "plugins_showcase": [], + "plugins_installed": [], + # TODO: Replace this with a proper API call: "materials_showcase": [ { "name": "DSM", @@ -81,7 +82,8 @@ class Toolbox(QObject, Extension): "website": "www.basf.de", "type": "material" } - ] + ], + "materials_installed": [] } # Models: @@ -185,8 +187,20 @@ class Toolbox(QObject, Extension): self._network_manager.finished.connect(self._onRequestFinished) self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) - self.makeRequestByType("packages") - self.makeRequestByType("plugins_showcase") + # Make remote requests: + self._makeRequestByType("packages") + self._makeRequestByType("plugins_showcase") + + # Gather installed packages: + all_packages = self._package_manager.getAllInstalledPackagesInfo() + if "plugin" in all_packages: + self._metadata["plugins_installed"] = all_packages["plugin"] + self._models["plugins_installed"].setMetadata(self._metadata["plugins_installed"]) + self.metadataChanged.emit() + if "material" in all_packages: + self._metadata["materials_installed"] = all_packages["material"] + self._models["materials_installed"].setMetadata(self._metadata["materials_installed"]) + self.metadataChanged.emit() if not self._dialog: self._dialog = self._createDialog("Toolbox.qml") @@ -248,7 +262,6 @@ class Toolbox(QObject, Extension): installed_plugin_data = self._package_manager.getInstalledPackageInfo(package_id) if installed_plugin_data is None: return False - installed_version = installed_plugin_data["package_version"] return compareSemanticVersions(version, installed_version) > 0 @@ -260,36 +273,15 @@ class Toolbox(QObject, Extension): return True return False - def _createNetworkManager(self): - if self._network_manager: - self._network_manager.finished.disconnect(self._onRequestFinished) - self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccesibleChanged) - self._network_manager = QNetworkAccessManager() - self._network_manager.finished.connect(self._onRequestFinished) - self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) - # Make API Calls # -------------------------------------------------------------------------- - def makeRequestByType(self, type): + def _makeRequestByType(self, type): Logger.log("i", "Toolbox: Requesting %s metadata from server.", type) request = QNetworkRequest(self._request_urls[type]) request.setRawHeader(*self._request_header) self._network_manager.get(request) - - def _requestPackages(self): - Logger.log("i", "Toolbox: Requesting package list from server.") - self._get_packages_request = QNetworkRequest(self._request_urls["packages"]) - self._get_packages_request.setRawHeader(*self._request_header) - self._network_manager.get(self._get_packages_request) - - def _requestShowcase(self): - Logger.log("i", "Toolbox: Requesting showcase list from server.") - self._get_showcase_request = QNetworkRequest(self._request_urls["plugins_showcase"]) - self._get_showcase_request.setRawHeader(*self._request_header) - self._network_manager.get(self._get_showcase_request) - # TODO: Request authors and request material showcase @pyqtSlot(str) @@ -327,7 +319,6 @@ class Toolbox(QObject, Extension): self._download_reply.abort() self._download_reply = None - # TODO: This function is sooooo ugly. Needs a rework: def _onRequestFinished(self, reply): if reply.error() == QNetworkReply.TimeoutError: @@ -340,15 +331,16 @@ class Toolbox(QObject, Extension): self._download_plugin_reply.abort() self._download_plugin_reply = None return - elif reply.error() == QNetworkReply.HostNotFoundError: + + if reply.error() == QNetworkReply.HostNotFoundError: Logger.log("w", "Unable to reach server.") return if reply.operation() == QNetworkAccessManager.GetOperation: # TODO: In the future use the following to build any model from any - # request. Right now this doesn't work though as the packages - # request is also responsible for populating other models. + # request. Right now this doesn't work because the packages request + # is also responsible for populating other models. # for type, url in self._request_urls.items(): # if reply.url() == url: # try: @@ -368,7 +360,6 @@ class Toolbox(QObject, Extension): if reply.url() == self._request_urls["packages"]: try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) - print(json_data) # Create packages model with all packages: if not self._models["packages"]: self._models["packages"] = PackagesModel(self) @@ -408,8 +399,6 @@ class Toolbox(QObject, Extension): self._models["plugins_showcase"] = PackagesModel() self._metadata["plugins_showcase"] = json_data["data"] self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"]) - for package in self._models["plugins_showcase"].items: - print(package) self.metadataChanged.emit() self.setViewPage("overview") @@ -440,7 +429,6 @@ class Toolbox(QObject, Extension): def _onDownloadComplete(self, file_path): Logger.log("i", "Toolbox: Download complete.") - print(file_path) try: package_info = self._package_manager.getPackageInfo(file_path) except: @@ -551,32 +539,3 @@ class Toolbox(QObject, Extension): return self._models[modelType].setFilter({}) self.filterChanged.emit() - - # TODO: Eventually dump everything below here: - @pyqtSlot(str, str) - def filterPackages(self, filterType, parameter): - if not self._models["packages"]: - return - self._models["packages"].setFilter({ filterType: parameter }) - self.filterChanged.emit() - - @pyqtSlot() - def unfilterPackages(self): - if not self._models["packages"]: - return - self._models["packages"].setFilter({}) - self.filterChanged.emit() - - @pyqtSlot(str, str) - def filterAuthors(self, filterType, parameter): - if not self._models["authors"]: - return - self._models["authors"].setFilter({ filterType: parameter }) - self.filterChanged.emit() - - @pyqtSlot() - def unfilterAuthors(self): - if not self._models["authors"]: - return - self._models["authors"].setFilter({}) - self.filterChanged.emit() From 523518020c8f2860b353fd65649e67ddc6a3e159 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 13 Apr 2018 16:25:01 +0200 Subject: [PATCH 44/83] CURA-5035 Better linking between Toolbox and CuraPluginManager --- cura/CuraPackageManager.py | 9 +- .../resources/qml/ToolboxDetailTile.qml | 89 +++++++++++++++---- .../resources/qml/ToolboxInstalledTile.qml | 50 +++++++++-- .../resources/qml/ToolboxLicenseDialog.qml | 2 +- plugins/Toolbox/src/PackagesModel.py | 38 +++----- plugins/Toolbox/src/Toolbox.py | 63 +++++++++---- 6 files changed, 183 insertions(+), 68 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index f787a8b29b..1ea81863f0 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -96,8 +96,11 @@ class CuraPackageManager(QObject): package_info["is_bundled"] = False return package_info - # TODO: get from plugin registry - #self._plugin_registry. + for section, packages in self.getAllInstalledPackagesInfo().items(): + for package in packages: + if package["package_id"] == package_id: + package_info = package + return package_info return None @@ -133,7 +136,7 @@ class CuraPackageManager(QObject): if package_id in managed_package_id_set: continue - plugin_package_info["is_bundled"] = True + plugin_package_info["is_bundled"] = True if plugin_package_info["author"]["name"] == "Ultimaker B.V." else False plugin_package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id) package_type = "plugin" if package_type not in installed_packages_dict: diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 689a008a67..c12b1cfa31 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -9,6 +9,7 @@ import UM 1.1 as UM Rectangle { + property bool installed: toolbox.isInstalled(model.id) width: base.width - UM.Theme.getSize("double_margin").width height: UM.Theme.getSize("base_unit").height * 8 color: "transparent" @@ -48,17 +49,28 @@ Rectangle Button { id: installButton text: { - if ( toolbox.isDownloading && toolbox.activePackage == model ) + if (installed) { - return catalog.i18nc("@action:button", "Cancel") + return catalog.i18nc("@action:button", "Installed") } else { - return catalog.i18nc("@action:button", "Install") + if ( toolbox.isDownloading && toolbox.activePackage == model ) + { + return catalog.i18nc("@action:button", "Cancel") + } + else + { + return catalog.i18nc("@action:button", "Install") + } } } enabled: { + if (installed) + { + return true + } if ( toolbox.isDownloading ) { return toolbox.activePackage == model ? true : false @@ -74,12 +86,47 @@ Rectangle { implicitWidth: 96 implicitHeight: 30 - color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary") + color: + { + if (installed) + { + return UM.Theme.getColor("action_button_disabled") + } + else + { + if ( control.hovered ) + { + return UM.Theme.getColor("primary_hover") + } + else + { + return UM.Theme.getColor("primary") + } + } + + } } label: Label { text: control.text - color: control.hovered ? UM.Theme.getColor("button_text") : UM.Theme.getColor("button_text_hover") + color: + { + if (installed) + { + return UM.Theme.getColor("action_button_disabled_text") + } + else + { + if ( control.hovered ) + { + return UM.Theme.getColor("button_text_hover") + } + else + { + return UM.Theme.getColor("button_text") + } + } + } verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter font: UM.Theme.getFont("default_bold") @@ -87,22 +134,29 @@ Rectangle } onClicked: { - console.log( "MODEL", model.id ) - toolbox.activePackage = model - // if ( toolbox.isDownloading && toolbox.activePackage == model ) - if ( toolbox.isDownloading ) + if (installed) { - toolbox.cancelDownload(); + toolbox.viewCategory = "installed" } else { - // toolbox.activePackage = model; - if ( model.can_upgrade ) + // if ( toolbox.isDownloading && toolbox.activePackage == model ) + if ( toolbox.isDownloading ) { - // toolbox.downloadAndInstallPlugin( model.update_url ); + toolbox.cancelDownload(); } - else { - toolbox.startDownload( model.download_url ); + else + { + toolbox.activePackage = model + // toolbox.activePackage = model; + if ( model.can_upgrade ) + { + // toolbox.downloadAndInstallPlugin( model.update_url ); + } + else + { + toolbox.startDownload( model.download_url ); + } } } } @@ -115,4 +169,9 @@ Rectangle height: UM.Theme.getSize("default_lining").height anchors.bottom: parent.bottom } + Connections + { + target: toolbox + onInstallChanged: installed = toolbox.isInstalled(model.id) + } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 75314e9af5..0f30e2e78d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -11,6 +11,8 @@ import UM 1.1 as UM Item { id: base + property bool canUpdate: false + property bool isEnabled: true height: UM.Theme.getSize("base_unit").height * 8 anchors { @@ -27,7 +29,7 @@ Item Column { id: pluginInfo - property var color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining") + property var color: isEnabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining") height: parent.height anchors { @@ -75,7 +77,7 @@ Item } Label { - text: ""+model.author+"" + text: ""+model.author_name+"" width: parent.width height: 24 wrapMode: Text.WordWrap @@ -102,8 +104,17 @@ Item Button { id: removeButton - text: "Uninstall" - // visible: model.can_uninstall && model.status == "installed" + text: + { + if (model.is_bundled) + { + return isEnabled ? catalog.i18nc("@action:button", "Disable") : catalog.i18nc("@action:button", "Enable") + } + else + { + return catalog.i18nc("@action:button", "Uninstall") + } + } enabled: !toolbox.isDownloading style: ButtonStyle { @@ -125,13 +136,30 @@ Item horizontalAlignment: Text.AlignHCenter } } - onClicked: toolbox.removePlugin( model.id ) + onClicked: + { + if (model.is_bundled) + { + if (toolbox.isEnabled(model.id)) + { + toolbox.disable(model.id) + } + else + { + toolbox.enable(model.id) + } + } + else + { + toolbox.uninstall( model.id ) + } + } } Button { id: updateButton - text: "Update" - // enabled: model.can_update + text: catalog.i18nc("@action:button", "Update") + visible: canUpdate style: ButtonStyle { background: Rectangle @@ -151,7 +179,7 @@ Item } onClicked: { - toolbox.updatePackage(model.id); + toolbox.update(model.id); } } ProgressBar @@ -177,4 +205,10 @@ Item } } } + Connections + { + target: toolbox + onEnabledChanged: isEnabled = toolbox.isEnabled(model.id) + onMetadataChanged: canUpdate = toolbox.canUpdate(model.id) + } } diff --git a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml index 0e89c49d1a..9109f407c8 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml @@ -59,7 +59,7 @@ UM.Dialog { onClicked: { licenseDialog.close(); - toolbox.installPlugin(licenseDialog.pluginFileLocation); + toolbox.install(licenseDialog.pluginFileLocation); } }, Button diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index dc1eb2cb78..c81f97c944 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -12,34 +12,23 @@ from UM.Qt.ListModel import ListModel ## Model that holds cura packages. By setting the filter property the instances held by this model can be changed. class PackagesModel(ListModel): - IdRole = Qt.UserRole + 1 - TypeRole = Qt.UserRole + 2 - NameRole = Qt.UserRole + 3 - VersionRole = Qt.UserRole + 4 - AuthorNameRole = Qt.UserRole + 5 - AuthorEmailRole = Qt.UserRole + 6 - DescriptionRole = Qt.UserRole + 7 - IconURLRole = Qt.UserRole + 8 - ImageURLsRole = Qt.UserRole + 9 - DownloadURLRole = Qt.UserRole + 10 - LastUpdatedRole = Qt.UserRole + 11 - def __init__(self, parent = None): super().__init__(parent) self._metadata = None - self.addRoleName(PackagesModel.IdRole, "id") - self.addRoleName(PackagesModel.TypeRole, "type") - self.addRoleName(PackagesModel.NameRole, "name") - self.addRoleName(PackagesModel.VersionRole, "version") - self.addRoleName(PackagesModel.AuthorNameRole, "author_name") - self.addRoleName(PackagesModel.AuthorEmailRole, "author_email") - self.addRoleName(PackagesModel.DescriptionRole, "description") - self.addRoleName(PackagesModel.IconURLRole, "icon_url") - self.addRoleName(PackagesModel.ImageURLsRole, "image_urls") - self.addRoleName(PackagesModel.DownloadURLRole, "download_url") - self.addRoleName(PackagesModel.LastUpdatedRole, "last_updated") + self.addRoleName(Qt.UserRole + 1, "id") + self.addRoleName(Qt.UserRole + 2, "type") + self.addRoleName(Qt.UserRole + 3, "name") + self.addRoleName(Qt.UserRole + 4, "version") + self.addRoleName(Qt.UserRole + 5, "author_name") + self.addRoleName(Qt.UserRole + 6, "author_email") + self.addRoleName(Qt.UserRole + 7, "description") + self.addRoleName(Qt.UserRole + 8, "icon_url") + self.addRoleName(Qt.UserRole + 9, "image_urls") + self.addRoleName(Qt.UserRole + 10, "download_url") + self.addRoleName(Qt.UserRole + 11, "last_updated") + self.addRoleName(Qt.UserRole + 12, "is_bundled") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str, str] @@ -63,7 +52,8 @@ class PackagesModel(ListModel): "icon_url": package["icon_url"] if "icon_url" in package else None, "image_urls": package["image_urls"] if "image_urls" in package else None, "download_url": package["download_url"] if "download_url" in package else None, - "last_updated": package["last_updated"] if "last_updated" in package else None + "last_updated": package["last_updated"] if "last_updated" in package else None, + "is_bundled": package["is_bundled"] if "is_bundled" in package else False }) # Filter on all the key-word arguments. diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index dacf806fe6..efc40a01b1 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -70,6 +70,12 @@ class Toolbox(QObject, Extension): "plugins_installed": [], # TODO: Replace this with a proper API call: "materials_showcase": [ + { + "name": "Ultimaker", + "email": "ian.paschal@gmail.com", + "website": "ultimaker.com", + "type": "material" + }, { "name": "DSM", "email": "contact@dsm.nl", @@ -137,6 +143,8 @@ class Toolbox(QObject, Extension): onDownloadProgressChanged = pyqtSignal() onIsDownloadingChanged = pyqtSignal() restartRequiredChanged = pyqtSignal() + installChanged = pyqtSignal() + enabledChanged = pyqtSignal() # UI changes viewChanged = pyqtSignal() @@ -213,8 +221,9 @@ class Toolbox(QObject, Extension): return dialog @pyqtSlot(str) - def installPlugin(self, file_path): + def install(self, file_path): self._package_manager.installPackage(file_path) + self.installChanged.emit() self.metadataChanged.emit() # TODO: Stuff self.openRestartDialog("TODO") @@ -222,7 +231,7 @@ class Toolbox(QObject, Extension): self.restartRequiredChanged.emit() @pyqtSlot(str) - def removePlugin(self, plugin_id): + def uninstall(self, plugin_id): self._package_manager.removePackage(plugin_id) self.metadataChanged.emit() self._restart_required = True @@ -231,15 +240,15 @@ class Toolbox(QObject, Extension): Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Plugin browser"), "TODO") @pyqtSlot(str) - def enablePlugin(self, plugin_id): - self._plugin_registry.setPluginEnabled(plugin_id, True) - self.metadataChanged.emit() + def enable(self, plugin_id): + self._plugin_registry.enablePlugin(plugin_id) + self.enabledChanged.emit() Logger.log("i", "%s was set as 'active'.", plugin_id) @pyqtSlot(str) - def disablePlugin(self, plugin_id): - self._plugin_registry.setPluginEnabled(plugin_id, False) - self.metadataChanged.emit() + def disable(self, plugin_id): + self._plugin_registry.disablePlugin(plugin_id) + self.enabledChanged.emit() Logger.log("i", "%s was set as 'deactive'.", plugin_id) @pyqtProperty(bool, notify = metadataChanged) @@ -258,18 +267,30 @@ class Toolbox(QObject, Extension): # Checks # -------------------------------------------------------------------------- - def _checkCanUpgrade(self, package_id: str, version: str) -> bool: - installed_plugin_data = self._package_manager.getInstalledPackageInfo(package_id) - if installed_plugin_data is None: + @pyqtSlot(str, result = bool) + def canUpdate(self, package_id: str) -> bool: + local_package = self._package_manager.getInstalledPackageInfo(package_id) + if local_package is None: return False - installed_version = installed_plugin_data["package_version"] - return compareSemanticVersions(version, installed_version) > 0 - def _checkInstalled(self, package_id: str): + remote_package = None + for package in self._metadata["packages"]: + if package["package_id"] == package_id: + remote_package = package + if remote_package is None: + return False + + local_version = local_package["package_version"] + remote_version = remote_package["package_version"] + return compareSemanticVersions(remote_version, local_version) > 0 + + @pyqtSlot(str, result = bool) + def isInstalled(self, package_id) -> bool: return self._package_manager.isPackageInstalled(package_id) - def _checkEnabled(self, id): - if id in self._plugin_registry.getActivePlugins(): + @pyqtSlot(str, result = bool) + def isEnabled(self, package_id) -> bool: + if package_id in self._plugin_registry.getActivePlugins(): return True return False @@ -382,6 +403,12 @@ class Toolbox(QObject, Extension): self._models["materials_showcase"] = AuthorsModel(self) # TODO: Replace this with a proper API call: self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"]) + + # This part is also needed for comparing downloaded packages to + # installed packages. + self._models["packages"].setMetadata(self._metadata["packages"]) + + self.metadataChanged.emit() self.setViewPage("overview") @@ -407,6 +434,8 @@ class Toolbox(QObject, Extension): except json.decoder.JSONDecodeError: Logger.log("w", "Toolbox: Received invalid JSON for showcase.") return + + else: # Ignore any operation that is not a get operation pass @@ -440,7 +469,7 @@ class Toolbox(QObject, Extension): self.openLicenseDialog(package_info["package_id"], license_content, file_path) return - self.installPlugin(file_path) + self.install(file_path) return From 85ebe741a8082dd3160505a37525542bb9ffd682 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 13 Apr 2018 17:27:57 +0200 Subject: [PATCH 45/83] CURA-5035 Don't show authors with 0 packages --- cura/CuraPackageManager.py | 10 ++++++++-- .../qml/ToolboxDownloadsShowcaseTile.qml | 12 ++++++++++++ plugins/Toolbox/src/AuthorsModel.py | 17 +++++++---------- plugins/Toolbox/src/Toolbox.py | 16 +++++++++------- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 1ea81863f0..cbb6ef18d8 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -69,6 +69,7 @@ class CuraPackageManager(QObject): # (for initialize) Removes all packages that have been scheduled to be removed. def _removeAllScheduledPackages(self) -> None: + print("Will purge", self._to_remove_package_set) for package_id in self._to_remove_package_set: self._purgePackage(package_id) self._to_remove_package_set.clear() @@ -223,14 +224,18 @@ class CuraPackageManager(QObject): del self._to_install_package_dict[package_id] # If the package has already been installed, schedule for a delayed removal - if package_id in self._installed_package_dict: - self._to_remove_package_set.add(package_id) + # if package_id in self._installed_package_dict: + # self._to_remove_package_set.add(package_id) + # "Or rather don't because sometimes packages are not making it into the + # dict I guess." - Ian + self._to_remove_package_set.add(package_id) self._saveManagementData() self.installedPackagesChanged.emit() # Removes everything associated with the given package ID. def _purgePackage(self, package_id: str) -> None: + print("Purging",package_id) # Get all folders that need to be checked for installed packages, including: # - materials # - qualities @@ -244,6 +249,7 @@ class CuraPackageManager(QObject): for root_dir in dirs_to_check: package_dir = os.path.join(root_dir, package_id) + print(package_dir) if os.path.exists(package_dir): Logger.log("i", "Removing '%s' for package [%s]", package_dir, package_id) shutil.rmtree(package_dir) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 51ccc9b0e5..b1d8b9271a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -12,6 +12,18 @@ Item { width: UM.Theme.getSize("toolbox_thumbnail_large").width height: UM.Theme.getSize("toolbox_thumbnail_large").width + visible: + { + if (toolbox.viewCategory == "material" && model.packages_count) + { + console.log(model) + return model.packages_count > 0 + } + else + { + return true + } + } Rectangle { color: "white" diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index ace609b0ac..967a1d9efa 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -10,20 +10,16 @@ from UM.Qt.ListModel import ListModel ## Model that holds cura packages. By setting the filter property the instances held by this model can be changed. class AuthorsModel(ListModel): - NameRole = Qt.UserRole + 1 - EmailRole = Qt.UserRole + 2 - WebsiteRole = Qt.UserRole + 3 - TypeRole = Qt.UserRole + 4 - def __init__(self, parent = None): super().__init__(parent) self._metadata = None - self.addRoleName(AuthorsModel.NameRole, "name") - self.addRoleName(AuthorsModel.EmailRole, "email") - self.addRoleName(AuthorsModel.WebsiteRole, "website") - self.addRoleName(AuthorsModel.TypeRole, "type") + self.addRoleName(Qt.UserRole + 1, "name") + self.addRoleName(Qt.UserRole + 2, "email") + self.addRoleName(Qt.UserRole + 3, "website") + self.addRoleName(Qt.UserRole + 4, "type") + self.addRoleName(Qt.UserRole + 5, "packages_count") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str,str] @@ -40,7 +36,8 @@ class AuthorsModel(ListModel): "name": author["name"], "email": author["email"], "website": author["website"], - "type": author["type"] + "type": author["type"], + "packages_count": author["packages_count"] }) # Filter on all the key-word arguments. diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index efc40a01b1..5e6ea104d5 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -74,19 +74,22 @@ class Toolbox(QObject, Extension): "name": "Ultimaker", "email": "ian.paschal@gmail.com", "website": "ultimaker.com", - "type": "material" + "type": "material", + "packages_count": 7 }, { "name": "DSM", "email": "contact@dsm.nl", "website": "www.dsm.nl", - "type": "material" + "type": "material", + "packages_count": 0 }, { "name": "BASF", "email": "contact@basf.de", "website": "www.basf.de", - "type": "material" + "type": "material", + "packages_count": 0 } ], "materials_installed": [] @@ -225,19 +228,16 @@ class Toolbox(QObject, Extension): self._package_manager.installPackage(file_path) self.installChanged.emit() self.metadataChanged.emit() - # TODO: Stuff - self.openRestartDialog("TODO") self._restart_required = True self.restartRequiredChanged.emit() @pyqtSlot(str) def uninstall(self, plugin_id): self._package_manager.removePackage(plugin_id) + self.installChanged.emit() self.metadataChanged.emit() self._restart_required = True self.restartRequiredChanged.emit() - # TODO: Stuff - Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Plugin browser"), "TODO") @pyqtSlot(str) def enable(self, plugin_id): @@ -261,6 +261,7 @@ class Toolbox(QObject, Extension): @pyqtSlot() def restart(self): + self._package_manager._removeAllScheduledPackages() CuraApplication.getInstance().windowClosed() @@ -394,6 +395,7 @@ class Toolbox(QObject, Extension): # TODO: Replace this with a proper API call: for package in self._metadata["packages"]: package["author"]["type"] = package["package_type"] + package["author"]["packages_count"] = 1 if package["author"] not in self._metadata["authors"]: self._metadata["authors"].append(package["author"]) self._models["authors"].setMetadata(self._metadata["authors"]) From b763b2a5a0a4c25418c28ad0805582a44716d474 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 17 Apr 2018 15:02:13 +0200 Subject: [PATCH 46/83] Fix gcode.gz double extension problem on Mac CURA-5228 --- plugins/GCodeGzReader/GCodeGzReader.py | 6 +++--- plugins/GCodeGzReader/__init__.py | 9 ++++++--- plugins/GCodeGzWriter/__init__.py | 7 +++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/plugins/GCodeGzReader/GCodeGzReader.py b/plugins/GCodeGzReader/GCodeGzReader.py index 0843f8f3c0..fd9bf0ed84 100644 --- a/plugins/GCodeGzReader/GCodeGzReader.py +++ b/plugins/GCodeGzReader/GCodeGzReader.py @@ -3,11 +3,11 @@ import gzip -from io import TextIOWrapper - +from UM.Platform import Platform from UM.Mesh.MeshReader import MeshReader #The class we're extending/implementing. from UM.PluginRegistry import PluginRegistry + ## A file reader that reads gzipped g-code. # # If you're zipping g-code, you might as well use gzip! @@ -15,7 +15,7 @@ class GCodeGzReader(MeshReader): def __init__(self): super().__init__() - self._supported_extensions = [".gcode.gz"] + self._supported_extensions = [".gz"] def read(self, file_name): with open(file_name, "rb") as file: diff --git a/plugins/GCodeGzReader/__init__.py b/plugins/GCodeGzReader/__init__.py index 98965c00aa..6e720b1ed1 100644 --- a/plugins/GCodeGzReader/__init__.py +++ b/plugins/GCodeGzReader/__init__.py @@ -1,21 +1,24 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from UM.i18n import i18nCatalog +from UM.Platform import Platform + from . import GCodeGzReader -from UM.i18n import i18nCatalog i18n_catalog = i18nCatalog("cura") def getMetaData(): + file_extension = "gz" if Platform.isOSX() else "gcode.gz" return { "mesh_reader": [ { - "extension": "gcode.gz", + "extension": file_extension, "description": i18n_catalog.i18nc("@item:inlistbox", "Compressed G-code File") } ] } def register(app): - app.addNonSliceableExtension(".gcode.gz") + app.addNonSliceableExtension(".gz") return { "mesh_reader": GCodeGzReader.GCodeGzReader() } diff --git a/plugins/GCodeGzWriter/__init__.py b/plugins/GCodeGzWriter/__init__.py index c001467b3d..a4d576aef6 100644 --- a/plugins/GCodeGzWriter/__init__.py +++ b/plugins/GCodeGzWriter/__init__.py @@ -1,16 +1,19 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from UM.i18n import i18nCatalog +from UM.Platform import Platform + from . import GCodeGzWriter -from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") def getMetaData(): + file_extension = "gz" if Platform.isOSX() else "gcode.gz" return { "mesh_writer": { "output": [{ - "extension": "gcode.gz", + "extension": file_extension, "description": catalog.i18nc("@item:inlistbox", "Compressed G-code File"), "mime_type": "application/gzip", "mode": GCodeGzWriter.GCodeGzWriter.OutputMode.BinaryMode From 7a0fe74989bab60e067700007d7ec62b0cb8eb59 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 17 Apr 2018 17:07:06 +0200 Subject: [PATCH 47/83] CURA-5035 Added material authors + icons --- cura/CuraPackageManager.py | 9 +--- .../qml/ToolboxDownloadsGridTile.qml | 7 +-- .../resources/qml/ToolboxInstalledTile.qml | 12 ++++- plugins/Toolbox/src/AuthorsModel.py | 12 +++-- plugins/Toolbox/src/PackagesModel.py | 2 +- plugins/Toolbox/src/Toolbox.py | 48 +++++++++++++++++-- 6 files changed, 68 insertions(+), 22 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index cbb6ef18d8..1a02939e70 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -69,7 +69,6 @@ class CuraPackageManager(QObject): # (for initialize) Removes all packages that have been scheduled to be removed. def _removeAllScheduledPackages(self) -> None: - print("Will purge", self._to_remove_package_set) for package_id in self._to_remove_package_set: self._purgePackage(package_id) self._to_remove_package_set.clear() @@ -223,11 +222,7 @@ class CuraPackageManager(QObject): if package_id in self._to_install_package_dict: del self._to_install_package_dict[package_id] - # If the package has already been installed, schedule for a delayed removal - # if package_id in self._installed_package_dict: - # self._to_remove_package_set.add(package_id) - # "Or rather don't because sometimes packages are not making it into the - # dict I guess." - Ian + # Schedule for a delayed removal: self._to_remove_package_set.add(package_id) self._saveManagementData() @@ -235,7 +230,6 @@ class CuraPackageManager(QObject): # Removes everything associated with the given package ID. def _purgePackage(self, package_id: str) -> None: - print("Purging",package_id) # Get all folders that need to be checked for installed packages, including: # - materials # - qualities @@ -249,7 +243,6 @@ class CuraPackageManager(QObject): for root_dir in dirs_to_check: package_dir = os.path.join(root_dir, package_id) - print(package_dir) if os.path.exists(package_dir): Logger.log("i", "Removing '%s' for package [%s]", package_dir, package_id) shutil.rmtree(package_dir) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index cac8be8ae9..6c5907a9bd 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -83,24 +83,25 @@ Item } onExited: { - thumbnail.border.color = UM.Theme.getColor("text") + thumbnail.border.color = UM.Theme.getColor("lining") highlight.opacity = 0.0 } onClicked: { + console.log(model.icon_url) if ( toolbox.viewCategory == "material" ) { toolbox.viewSelection = model.name toolbox.viewPage = "author" - toolbox.filterModelByProp("authors", "name", model.name) toolbox.filterModelByProp("packages", "author_name", model.name) + toolbox.filterModelByProp("authors", "name", model.name) } else { toolbox.viewSelection = model.id toolbox.viewPage = "detail" - toolbox.filterModelByProp("authors", "name", model.author_name) toolbox.filterModelByProp("packages", "id", model.id) + toolbox.filterModelByProp("authors", "name", model.author_name) } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 0f30e2e78d..3bfcee8dd3 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -77,7 +77,17 @@ Item } Label { - text: ""+model.author_name+"" + text: + { + if (model.author_email) + { + return ""+model.author_name+"" + } + else + { + return model.author_name + } + } width: parent.width height: 24 wrapMode: Text.WordWrap diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index 967a1d9efa..6b75126084 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -19,7 +19,8 @@ class AuthorsModel(ListModel): self.addRoleName(Qt.UserRole + 2, "email") self.addRoleName(Qt.UserRole + 3, "website") self.addRoleName(Qt.UserRole + 4, "type") - self.addRoleName(Qt.UserRole + 5, "packages_count") + self.addRoleName(Qt.UserRole + 5, "icon_url") + self.addRoleName(Qt.UserRole + 6, "packages_count") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str,str] @@ -34,10 +35,11 @@ class AuthorsModel(ListModel): for author in self._metadata: items.append({ "name": author["name"], - "email": author["email"], - "website": author["website"], - "type": author["type"], - "packages_count": author["packages_count"] + "email": author["email"] if "email" in author else None, + "website": author["website"] if "website" in author else None, + "type": author["type"] if "type" in author else None, + "icon_url": author["icon_url"] if "icon_url" in author else None, + "packages_count": author["packages_count"] if "packages_count" in author else 0 }) # Filter on all the key-word arguments. diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index c81f97c944..b030ad895e 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -47,7 +47,7 @@ class PackagesModel(ListModel): "name": package["display_name"], "version": package["package_version"], "author_name": package["author"]["name"], - "author_email": package["author"]["email"], + "author_email": package["author"]["email"] if "email" in package["author"] else None, "description": package["description"], "icon_url": package["icon_url"] if "icon_url" in package else None, "image_urls": package["image_urls"] if "image_urls" in package else None, diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 5e6ea104d5..87edef4af2 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -75,6 +75,7 @@ class Toolbox(QObject, Extension): "email": "ian.paschal@gmail.com", "website": "ultimaker.com", "type": "material", + "icon": None, "packages_count": 7 }, { @@ -82,6 +83,7 @@ class Toolbox(QObject, Extension): "email": "contact@dsm.nl", "website": "www.dsm.nl", "type": "material", + "icon": None, "packages_count": 0 }, { @@ -89,6 +91,7 @@ class Toolbox(QObject, Extension): "email": "contact@basf.de", "website": "www.basf.de", "type": "material", + "icon": None, "packages_count": 0 } ], @@ -217,6 +220,9 @@ class Toolbox(QObject, Extension): self._dialog = self._createDialog("Toolbox.qml") self._dialog.show() + # Apply enabled/disabled state to installed plugins + self.enabledChanged.emit() + def _createDialog(self, qml_name): Logger.log("d", "Toolbox: Creating dialog [%s].", qml_name) path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) @@ -359,7 +365,6 @@ class Toolbox(QObject, Extension): return if reply.operation() == QNetworkAccessManager.GetOperation: - # TODO: In the future use the following to build any model from any # request. Right now this doesn't work because the packages request # is also responsible for populating other models. @@ -367,6 +372,14 @@ class Toolbox(QObject, Extension): # if reply.url() == url: # 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 @@ -382,9 +395,17 @@ class Toolbox(QObject, Extension): if reply.url() == self._request_urls["packages"]: 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 packages model with all packages: if not self._models["packages"]: self._models["packages"] = PackagesModel(self) + print(json_data["data"]) self._metadata["packages"] = json_data["data"] self._models["packages"].setMetadata(self._metadata["packages"]) self.metadataChanged.emit() @@ -394,11 +415,23 @@ class Toolbox(QObject, Extension): self._models["authors"] = AuthorsModel() # TODO: Replace this with a proper API call: for package in self._metadata["packages"]: - package["author"]["type"] = package["package_type"] - package["author"]["packages_count"] = 1 if package["author"] not in self._metadata["authors"]: self._metadata["authors"].append(package["author"]) + + for author in self._metadata["authors"]: + if "package_count" not in author: + author["package_count"] = 0 + + for package in self._metadata["packages"]: + if package["author"]["name"] == author["name"]: + author["package_count"] += 1 + author["type"] = package["package_type"] + if "icon_url" in package: + author["icon_url"] = package["icon_url"] + self._models["authors"].setMetadata(self._metadata["authors"]) + for author in self._models["authors"].items: + print(author["icon_url"]) self.metadataChanged.emit() if not self._models["materials_showcase"]: @@ -409,7 +442,7 @@ class Toolbox(QObject, Extension): # This part is also needed for comparing downloaded packages to # installed packages. self._models["packages"].setMetadata(self._metadata["packages"]) - + self._models["packages"].setFilter({"type": "plugin"}) self.metadataChanged.emit() @@ -423,6 +456,13 @@ class Toolbox(QObject, Extension): if reply.url() == self._request_urls["plugins_showcase"]: 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 packages model with all packages: if not self._models["plugins_showcase"]: self._models["plugins_showcase"] = PackagesModel() From f8672ecbc63f30905a642933bfb8ec8f5308c2d8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 18 Apr 2018 16:35:55 +0200 Subject: [PATCH 48/83] CURA-5035 Improved details pages --- plugins/Toolbox/resources/qml/Toolbox.qml | 8 ++++-- .../resources/qml/ToolboxAuthorPage.qml | 28 +++++++++---------- .../resources/qml/ToolboxDetailPage.qml | 19 ++++++++++--- .../resources/qml/ToolboxDetailTile.qml | 16 ++++++++++- .../qml/ToolboxDownloadsGridTile.qml | 3 +- .../Toolbox/resources/qml/ToolboxFooter.qml | 1 - .../Toolbox/resources/qml/ToolboxShadow.qml | 7 +++-- plugins/Toolbox/src/AuthorsModel.py | 2 +- plugins/Toolbox/src/Toolbox.py | 14 +++------- 9 files changed, 61 insertions(+), 37 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index d0a165138e..5f45d5770d 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -14,7 +14,7 @@ import UM 1.1 as UM Window { id: base - title: catalog.i18nc("@title:tab", "Toolbox"); + title: catalog.i18nc("@title:tab", "Toolbox") modality: Qt.ApplicationModal width: 720 * screenScaleFactor height: 640 * screenScaleFactor @@ -73,10 +73,14 @@ Window ToolboxFooter { id: footer + visible: toolbox.restartRequired + height: toolbox.restartRequired ? UM.Theme.getSize("base_unit").height * 5 : 0 } ToolboxShadow { - anchors.top: footer.top + visible: toolbox.restartRequired + anchors.bottom: footer.top + reversed: true } UM.I18nCatalog { id: catalog; name: "cura" } diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 4236a282e1..d30ec8845c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -74,13 +74,7 @@ Item width: childrenRect.width Label { - text: "Version:" - font: UM.Theme.getFont("very_small") - color: UM.Theme.getColor("text_medium") - } - Label - { - text: "Author:" + text: catalog.i18nc("@label", "Contact") + ":" font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } @@ -99,15 +93,21 @@ Item width: UM.Theme.getSize("base_unit").width * 12 Label { - text: details.name - font: UM.Theme.getFont("very_small") - color: UM.Theme.getColor("text") - } - Label - { - text: details.name + text: + { + if (details.email) + { + return ""+details.name+"" + } + else + { + console.log(""+details.author_name+"") + return ""+details.name+"" + } + } font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") + onLinkActivated: Qt.openUrlExternally(link) } } Rectangle diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index f0982cdf80..62a6db41d2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -74,19 +74,19 @@ Item width: childrenRect.width Label { - text: "Version:" + text: catalog.i18nc("@label", "Version") + ":" font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } Label { - text: "Last Update:" + text: catalog.i18nc("@label", "Last updated") + ":" font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } Label { - text: "Author:" + text: catalog.i18nc("@label", "Author") + ":" font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text_medium") } @@ -117,9 +117,20 @@ Item } Label { - text: details.author_name + text: + { + if (details.author_email) + { + return ""+details.author_name+"" + } + else + { + return ""+details.author_name+"" + } + } font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") + onLinkActivated: Qt.openUrlExternally(link) } } Rectangle diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index c12b1cfa31..bb19f9b8a1 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -34,7 +34,21 @@ Rectangle Label { width: parent.width - text: model.description + text: + { + if (model.description.length > 235) + { + if (model.description.substring(234, 235) == " ") + { + return model.description.substring(0, 234) + "..." + } + else + { + return model.description.substring(0, 235) + "..." + } + } + return model.description + } wrapMode: Text.WordWrap color: UM.Theme.getColor("text") font: UM.Theme.getFont("default") diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 6c5907a9bd..3e815e8990 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -58,7 +58,8 @@ Item Label { id: info - text: { + text: + { if (model.description.length > 50) { return model.description.substring(0, 50) + "..." diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index cebf501762..58b1d959df 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -14,7 +14,6 @@ import UM 1.1 as UM Item { width: parent.width - height: UM.Theme.getSize("base_unit").height * 4 anchors.bottom: parent.bottom Label { diff --git a/plugins/Toolbox/resources/qml/ToolboxShadow.qml b/plugins/Toolbox/resources/qml/ToolboxShadow.qml index f22e3b5cc3..0f2f98beb9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxShadow.qml +++ b/plugins/Toolbox/resources/qml/ToolboxShadow.qml @@ -5,18 +5,19 @@ import QtQuick 2.2 Rectangle { + property bool reversed: false width: parent.width height: 8 gradient: Gradient { GradientStop { - position: 0.0 - color: Qt.rgba(0,0,0,0.2) + position: reversed ? 1.0 : 0.0 + color: reversed ? Qt.rgba(0,0,0,0.05) : Qt.rgba(0,0,0,0.2) } GradientStop { - position: 1.0 + position: reversed ? 0.0 : 1.0 color: Qt.rgba(0,0,0,0) } } diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index 6b75126084..b85980bd8d 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -36,7 +36,7 @@ class AuthorsModel(ListModel): items.append({ "name": author["name"], "email": author["email"] if "email" in author else None, - "website": author["website"] if "website" in author else None, + "website": author["website"], "type": author["type"] if "type" in author else None, "icon_url": author["icon_url"] if "icon_url" in author else None, "packages_count": author["packages_count"] if "packages_count" in author else 0 diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 87edef4af2..bc2b930ff9 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -129,7 +129,6 @@ class Toolbox(QObject, Extension): self._active_package = None self._dialog = None - self._restartDialog = None self._restart_required = False # variables for the license agreement dialog @@ -158,7 +157,6 @@ class Toolbox(QObject, Extension): filterChanged = pyqtSignal() metadataChanged = pyqtSignal() showLicenseDialog = pyqtSignal() - showRestartDialog = pyqtSignal() @pyqtSlot(result = str) def getLicenseDialogPluginName(self): @@ -172,20 +170,12 @@ class Toolbox(QObject, Extension): def getLicenseDialogLicenseContent(self): return self._license_dialog_license_content - @pyqtSlot(result = str) - def getRestartDialogMessage(self): - return self._restart_dialog_message - def openLicenseDialog(self, plugin_name, license_content, plugin_file_location): self._license_dialog_plugin_name = plugin_name self._license_dialog_license_content = license_content self._license_dialog_plugin_file_location = plugin_file_location self.showLicenseDialog.emit() - def openRestartDialog(self, message): - self._restart_dialog_message = message - self.showRestartDialog.emit() - def _onAppInitialized(self): self._package_manager = Application.getInstance().getCuraPackageManager() @@ -250,12 +240,16 @@ class Toolbox(QObject, Extension): self._plugin_registry.enablePlugin(plugin_id) self.enabledChanged.emit() Logger.log("i", "%s was set as 'active'.", plugin_id) + self._restart_required = True + self.restartRequiredChanged.emit() @pyqtSlot(str) def disable(self, plugin_id): self._plugin_registry.disablePlugin(plugin_id) self.enabledChanged.emit() Logger.log("i", "%s was set as 'deactive'.", plugin_id) + self._restart_required = True + self.restartRequiredChanged.emit() @pyqtProperty(bool, notify = metadataChanged) def dataReady(self): From a5a35ef98b4583b32cc2013e54729359db88ac75 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 18 Apr 2018 16:47:28 +0200 Subject: [PATCH 49/83] CURA-5035 Added dummy author text --- .../resources/qml/ToolboxAuthorPage.qml | 18 ++++++++++++++---- plugins/Toolbox/src/AuthorsModel.py | 4 +++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index d30ec8845c..5fb92bfaa3 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -60,14 +60,24 @@ Item width: parent.width height: UM.Theme.getSize("base_unit") * 2 } - + Label + { + id: description + text: details.description + anchors + { + top: title.bottom + left: title.left + topMargin: UM.Theme.getSize("default_margin").height + } + } Column { id: properties anchors { - top: title.bottom - left: title.left + top: description.bottom + left: description.left topMargin: UM.Theme.getSize("default_margin").height } spacing: Math.floor(UM.Theme.getSize("default_margin").height / 2) @@ -84,7 +94,7 @@ Item id: values anchors { - top: title.bottom + top: description.bottom left: properties.right leftMargin: UM.Theme.getSize("default_margin").width topMargin: UM.Theme.getSize("default_margin").height diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index b85980bd8d..f61fdbe223 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -21,6 +21,7 @@ class AuthorsModel(ListModel): self.addRoleName(Qt.UserRole + 4, "type") self.addRoleName(Qt.UserRole + 5, "icon_url") self.addRoleName(Qt.UserRole + 6, "packages_count") + self.addRoleName(Qt.UserRole + 7, "description") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str,str] @@ -39,7 +40,8 @@ class AuthorsModel(ListModel): "website": author["website"], "type": author["type"] if "type" in author else None, "icon_url": author["icon_url"] if "icon_url" in author else None, - "packages_count": author["packages_count"] if "packages_count" in author else 0 + "packages_count": author["packages_count"] if "packages_count" in author else 0, + "description": "Material and quality profiles from {author_name}".format( author_name = author["name"]) }) # Filter on all the key-word arguments. From d3ba684b15c66ca83ff0177723fe567ef0c081bf Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 18 Apr 2018 17:03:27 +0200 Subject: [PATCH 50/83] CURA-5035 Installed plugins instantly move to the installed tab --- plugins/Toolbox/src/Toolbox.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index bc2b930ff9..02330b4457 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -196,15 +196,7 @@ class Toolbox(QObject, Extension): self._makeRequestByType("plugins_showcase") # Gather installed packages: - all_packages = self._package_manager.getAllInstalledPackagesInfo() - if "plugin" in all_packages: - self._metadata["plugins_installed"] = all_packages["plugin"] - self._models["plugins_installed"].setMetadata(self._metadata["plugins_installed"]) - self.metadataChanged.emit() - if "material" in all_packages: - self._metadata["materials_installed"] = all_packages["material"] - self._models["materials_installed"].setMetadata(self._metadata["materials_installed"]) - self.metadataChanged.emit() + self._updateInstalledModels() if not self._dialog: self._dialog = self._createDialog("Toolbox.qml") @@ -219,10 +211,23 @@ class Toolbox(QObject, Extension): dialog = Application.getInstance().createQmlComponent(path, {"toolbox": self}) return dialog + @pyqtSlot() + def _updateInstalledModels(self): + all_packages = self._package_manager.getAllInstalledPackagesInfo() + if "plugin" in all_packages: + self._metadata["plugins_installed"] = all_packages["plugin"] + self._models["plugins_installed"].setMetadata(self._metadata["plugins_installed"]) + self.metadataChanged.emit() + if "material" in all_packages: + self._metadata["materials_installed"] = all_packages["material"] + self._models["materials_installed"].setMetadata(self._metadata["materials_installed"]) + self.metadataChanged.emit() + @pyqtSlot(str) def install(self, file_path): self._package_manager.installPackage(file_path) self.installChanged.emit() + self._updateInstalledModels() self.metadataChanged.emit() self._restart_required = True self.restartRequiredChanged.emit() @@ -231,6 +236,7 @@ class Toolbox(QObject, Extension): def uninstall(self, plugin_id): self._package_manager.removePackage(plugin_id) self.installChanged.emit() + self._updateInstalledModels() self.metadataChanged.emit() self._restart_required = True self.restartRequiredChanged.emit() From 8f8d709b642bce616b954733e994a770d34b2ea3 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 18 Apr 2018 17:05:01 +0200 Subject: [PATCH 51/83] CURA-5035 Removed debug statements --- plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml | 1 - plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml | 1 - plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml | 1 - plugins/Toolbox/src/Toolbox.py | 3 --- 4 files changed, 6 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 5fb92bfaa3..3af4f4308a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -111,7 +111,6 @@ Item } else { - console.log(""+details.author_name+"") return ""+details.name+"" } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 3e815e8990..77e517dc08 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -89,7 +89,6 @@ Item } onClicked: { - console.log(model.icon_url) if ( toolbox.viewCategory == "material" ) { toolbox.viewSelection = model.name diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index b1d8b9271a..4b28d74a72 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -16,7 +16,6 @@ Item { if (toolbox.viewCategory == "material" && model.packages_count) { - console.log(model) return model.packages_count > 0 } else diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 02330b4457..fbf22a2788 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -405,7 +405,6 @@ class Toolbox(QObject, Extension): # Create packages model with all packages: if not self._models["packages"]: self._models["packages"] = PackagesModel(self) - print(json_data["data"]) self._metadata["packages"] = json_data["data"] self._models["packages"].setMetadata(self._metadata["packages"]) self.metadataChanged.emit() @@ -430,8 +429,6 @@ class Toolbox(QObject, Extension): author["icon_url"] = package["icon_url"] self._models["authors"].setMetadata(self._metadata["authors"]) - for author in self._models["authors"].items: - print(author["icon_url"]) self.metadataChanged.emit() if not self._models["materials_showcase"]: From 921e8f7602793989825653ce90e97de35e4e8b30 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 19 Apr 2018 16:07:31 +0200 Subject: [PATCH 52/83] CURA-5035 Clean-up --- plugins/Toolbox/resources/qml/Toolbox.qml | 44 ++----- .../resources/qml/ToolboxAuthorPage.qml | 4 +- .../resources/qml/ToolboxBackColumn.qml | 19 +-- .../resources/qml/ToolboxDetailList.qml | 1 - .../resources/qml/ToolboxDetailPage.qml | 3 +- .../resources/qml/ToolboxDetailTile.qml | 13 +- .../resources/qml/ToolboxDownloadsGrid.qml | 4 +- .../qml/ToolboxDownloadsGridTile.qml | 34 ++--- .../qml/ToolboxDownloadsShowcase.qml | 2 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 16 +-- .../Toolbox/resources/qml/ToolboxFooter.qml | 79 +++--------- .../Toolbox/resources/qml/ToolboxHeader.qml | 119 ++++-------------- .../resources/qml/ToolboxInstalledPage.qml | 4 +- .../resources/qml/ToolboxInstalledTile.qml | 38 +++--- .../resources/qml/ToolboxLicenseDialog.qml | 12 +- .../resources/qml/ToolboxRestartDialog.qml | 88 ------------- .../resources/qml/ToolboxTabButton.qml | 51 ++++++++ 17 files changed, 181 insertions(+), 350 deletions(-) delete mode 100644 plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml create mode 100644 plugins/Toolbox/resources/qml/ToolboxTabButton.qml diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 5f45d5770d..e3ee654710 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -4,17 +4,12 @@ import QtQuick 2.2 import QtQuick.Dialogs 1.1 import QtQuick.Window 2.2 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - import UM 1.1 as UM Window { id: base - title: catalog.i18nc("@title:tab", "Toolbox") + title: catalog.i18nc("@title", "Toolbox") modality: Qt.ApplicationModal width: 720 * screenScaleFactor height: 640 * screenScaleFactor @@ -22,6 +17,11 @@ Window maximumWidth: 720 * screenScaleFactor minimumHeight: 350 * screenScaleFactor color: UM.Theme.getColor("sidebar") + UM.I18nCatalog + { + id: catalog + name:"cura" + } Item { anchors.fill: parent @@ -29,11 +29,11 @@ Window { id: header } - Rectangle + Item { id: mainView width: parent.width - color: "transparent" + z: -1 anchors { top: header.bottom @@ -66,25 +66,13 @@ Window visible: toolbox.viewCategory == "installed" } } - ToolboxShadow - { - anchors.top: header.bottom - } ToolboxFooter { id: footer visible: toolbox.restartRequired height: toolbox.restartRequired ? UM.Theme.getSize("base_unit").height * 5 : 0 } - ToolboxShadow - { - visible: toolbox.restartRequired - anchors.bottom: footer.top - reversed: true - } - - UM.I18nCatalog { id: catalog; name: "cura" } - + // TODO: Clean this up: Connections { target: toolbox @@ -96,23 +84,9 @@ Window licenseDialog.show(); } } - Connections - { - target: toolbox - onShowRestartDialog: - { - restartDialog.message = toolbox.getRestartDialogMessage(); - restartDialog.show(); - } - } ToolboxLicenseDialog { id: licenseDialog } - - ToolboxRestartDialog - { - id: restartDialog - } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 3af4f4308a..1cc61a07be 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -2,7 +2,6 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -127,7 +126,8 @@ Item anchors.bottom: parent.bottom } } - ToolboxDetailList { + ToolboxDetailList + { anchors { top: header.bottom diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml index faeac08b3c..87a8f665de 100644 --- a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -2,7 +2,6 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -23,17 +22,23 @@ Item Button { id: button - text: "Back" + text: catalog.i18nc("@action:button", "Back") UM.RecolorImage { id: backArrow - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.rightMargin: UM.Theme.getSize("default_margin").width + anchors + { + verticalCenter: parent.verticalCenter + left: parent.left + rightMargin: UM.Theme.getSize("default_margin").width + } width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width - sourceSize.height: height + sourceSize + { + width: width + height: height + } color: button.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("text") source: UM.Theme.getIcon("arrow_left") } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index 333b2c1673..ebb1ae073d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -2,7 +2,6 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 62a6db41d2..d754e89ddb 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -141,7 +141,8 @@ Item anchors.bottom: parent.bottom } } - ToolboxDetailList { + ToolboxDetailList + { anchors { top: header.bottom diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index bb19f9b8a1..5c97117073 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -2,17 +2,15 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -Rectangle +Item { property bool installed: toolbox.isInstalled(model.id) width: base.width - UM.Theme.getSize("double_margin").width height: UM.Theme.getSize("base_unit").height * 8 - color: "transparent" Column { anchors @@ -60,9 +58,11 @@ Rectangle anchors.right: parent.right anchors.top: parent.top width: childrenRect.width - Button { + Button + { id: installButton - text: { + text: + { if (installed) { return catalog.i18nc("@action:button", "Installed") @@ -95,7 +95,8 @@ Rectangle } } opacity: enabled ? 1.0 : 0.5 - style: ButtonStyle { + style: ButtonStyle + { background: Rectangle { implicitWidth: 96 diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index b3a3a89200..0f030401f2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -2,8 +2,6 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 @@ -19,7 +17,7 @@ Column Label { id: heading - text: toolbox.viewCategory == "material" ? "Maker Choices" : "Community Plugins" + text: toolbox.viewCategory == "material" ? catalog.i18nc("@label", "Maker Choices") : catalog.i18nc("@label", "Community Plugins") width: parent.width color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 77e517dc08..c705f6c515 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -2,8 +2,6 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 @@ -34,7 +32,8 @@ Item color: "white" border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") - Image { + Image + { anchors.centerIn: parent width: UM.Theme.getSize("toolbox_thumbnail_small").width - 26 height: UM.Theme.getSize("toolbox_thumbnail_small").height - 26 @@ -89,19 +88,24 @@ Item } onClicked: { - if ( toolbox.viewCategory == "material" ) + switch(toolbox.viewCategory) { - toolbox.viewSelection = model.name - toolbox.viewPage = "author" - toolbox.filterModelByProp("packages", "author_name", model.name) - toolbox.filterModelByProp("authors", "name", model.name) - } - else - { - toolbox.viewSelection = model.id - toolbox.viewPage = "detail" - toolbox.filterModelByProp("packages", "id", model.id) - toolbox.filterModelByProp("authors", "name", model.author_name) + case "material": + console.log("OKAY FILTER BY AUTHOR", model.name) + toolbox.viewSelection = model.name + toolbox.viewPage = "author" + console.log(toolbox) + var name = model.name + toolbox.filterModelByProp("authors", "name", name) + toolbox.filterModelByProp("packages", "author_name", name) + console.log(toolbox) + break + default: + toolbox.viewSelection = model.id + toolbox.viewPage = "detail" + toolbox.filterModelByProp("authors", "name", model.author_name) + toolbox.filterModelByProp("packages", "id", model.id) + break } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index 83740fa46f..c64c837314 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -18,7 +18,7 @@ Column Label { id: heading - text: "Featured" + text: catalog.i18nc("@label", "Featured") width: parent.width color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 4b28d74a72..08fc6a4343 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -2,8 +2,6 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -28,8 +26,11 @@ Item color: "white" width: UM.Theme.getSize("toolbox_thumbnail_medium").width height: UM.Theme.getSize("toolbox_thumbnail_medium").height - border.width: 1 - border.color: UM.Theme.getColor("lining") + border + { + width: UM.Theme.getSize("default_lining").width + color: UM.Theme.getColor("lining") + } anchors { top: parent.top @@ -37,8 +38,8 @@ Item } Image { anchors.centerIn: parent - width: UM.Theme.getSize("toolbox_thumbnail_medium").width - 26 - height: UM.Theme.getSize("toolbox_thumbnail_medium").height - 26 + width: UM.Theme.getSize("toolbox_thumbnail_medium").width - 2 * UM.Theme.getSize("default_margin") + height: UM.Theme.getSize("toolbox_thumbnail_medium").height - 2 * UM.Theme.getSize("default_margin") fillMode: Image.PreserveAspectFit source: model.icon_url || "../images/logobot.svg" } @@ -61,7 +62,8 @@ Item MouseArea { anchors.fill: parent - onClicked: { + onClicked: + { switch(toolbox.viewCategory) { case "material": diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index 58b1d959df..1dd144b0e2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -2,30 +2,29 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 - -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - import UM 1.1 as UM Item { + id: footer width: parent.width anchors.bottom: parent.bottom + height: visible ? Math.floor(UM.Theme.getSize("base_unit").height * 5.5) : 0 Label { visible: toolbox.restartRequired text: "You will need to restart Cura before changes in plugins have effect." - height: UM.Theme.getSize("base_unit").height * 2 + height: Math.floor(UM.Theme.getSize("base_unit").height * 2.5) verticalAlignment: Text.AlignVCenter anchors { - top: closeButton.top + top: restartButton.top left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width + leftMargin: UM.Theme.getSize("double_margin").width + right: restartButton.right + rightMargin: UM.Theme.getSize("default_margin").width } } Button @@ -34,9 +33,10 @@ Item text: "Quit Cura" anchors { - top: closeButton.top - right: closeButton.left - rightMargin: UM.Theme.getSize("default_margin").width + top: parent.top + topMargin: UM.Theme.getSize("default_margin").height + right: parent.right + rightMargin: UM.Theme.getSize("double_margin").width } visible: toolbox.restartRequired iconName: "dialog-restart" @@ -45,65 +45,24 @@ Item { background: Rectangle { - implicitWidth: 96 - implicitHeight: UM.Theme.getSize("base_unit").height * 2 + implicitWidth: UM.Theme.getSize("base_unit").width * 8 + implicitHeight: Math.floor(UM.Theme.getSize("base_unit").height * 2.5) color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary") } label: Text { - verticalAlignment: Text.AlignVCenter color: UM.Theme.getColor("button_text") - font - { - pixelSize: 13 - bold: true - } + font: UM.Theme.getFont("default_bold") text: control.text + verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } } } - - Button + ToolboxShadow { - id: closeButton - text: catalog.i18nc("@action:button", "Close") - iconName: "dialog-close" - onClicked: - { - if ( toolbox.isDownloading ) - { - toolbox.cancelDownload() - } - base.close(); - } - anchors - { - top: parent.top - topMargin: UM.Theme.getSize("default_margin").height - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - } - style: ButtonStyle - { - background: Rectangle - { - color: "transparent" - implicitWidth: 96 - implicitHeight: UM.Theme.getSize("base_unit").height * 2 - border - { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text - { - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("text") - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } + visible: toolbox.restartRequired + anchors.bottom: footer.top + reversed: true } } diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 5604814afd..6049900051 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -2,54 +2,29 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -Rectangle { - +Item +{ + id: header width: parent.width - color: "transparent" - height: childrenRect.height - + height: UM.Theme.getSize("base_unit").height * 4 Row { + id: bar spacing: 12 height: childrenRect.height width: childrenRect.width - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - - Button + anchors { - text: "Plugins" - style: ButtonStyle - { - background: Rectangle - { - color: "transparent" - implicitWidth: 96 - implicitHeight: 48 - Rectangle - { - visible: toolbox.viewCategory == "plugin" - color: UM.Theme.getColor("primary") - anchors.bottom: parent.bottom - width: parent.width - height: 3 - } - } - label: Text - { - text: control.text - color: UM.Theme.getColor("text") - font.pixelSize: 15 - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - } + left: parent.left + leftMargin: UM.Theme.getSize("default_margin").width + } + ToolboxTabButton + { + text: catalog.i18nc("@title:tab", "Plugins") + active: toolbox.viewCategory == "plugin" onClicked: { toolbox.filterModelByProp("packages", "type", "plugin") @@ -58,35 +33,10 @@ Rectangle { toolbox.viewPage = "overview" } } - - Button + ToolboxTabButton { - text: "Materials" - style: ButtonStyle - { - background: Rectangle - { - color: "transparent" - implicitWidth: 96 - implicitHeight: 48 - Rectangle - { - visible: toolbox.viewCategory == "material" - color: UM.Theme.getColor("primary") - anchors.bottom: parent.bottom - width: parent.width - height: 3 - } - } - label: Text - { - text: control.text - color: UM.Theme.getColor("text") - font.pixelSize: 15 - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - } + text: catalog.i18nc("@title:tab", "Materials") + active: toolbox.viewCategory == "material" onClicked: { toolbox.filterModelByProp("packages", "type", "material") @@ -96,36 +46,19 @@ Rectangle { } } } - - Button + ToolboxTabButton { - text: "Installed" - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - style: ButtonStyle + text: catalog.i18nc("@title:tab", "Installed") + active: toolbox.viewCategory == "installed" + anchors { - background: Rectangle - { - color: "transparent" - implicitWidth: 96 - implicitHeight: 48 - Rectangle { - visible: toolbox.viewCategory == "installed" - color: UM.Theme.getColor("primary") - anchors.bottom: parent.bottom - width: parent.width - height: 3 - } - } - label: Text - { - text: control.text - color: UM.Theme.getColor("text") - font.pixelSize: 15 - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width } onClicked: toolbox.viewCategory = "installed" } + ToolboxShadow + { + anchors.top: bar.bottom + } } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index cfcd8acf32..eff055f330 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -31,7 +31,7 @@ ScrollView Label { width: parent.width - text: "Plugins" + text: catalog.i18nc("@title:tab", "Plugins") color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") } @@ -66,7 +66,7 @@ ScrollView Label { width: base.width - text: "Materials" + text: catalog.i18nc("@title:tab", "Materials") color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") } diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 3bfcee8dd3..cd51ce6954 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -2,8 +2,6 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM @@ -43,20 +41,17 @@ Item { text: model.name width: parent.width - height: 24 + height: UM.Theme.getSize("base_unit").height * 2 wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter - font { - pixelSize: 13 - bold: true - } + font: UM.Theme.getFont("default_bold") color: pluginInfo.color } Text { text: model.description width: parent.width - height: 36 + height: UM.Theme.getSize("base_unit").height * 3 clip: true wrapMode: Text.WordWrap color: pluginInfo.color @@ -66,7 +61,7 @@ Item Column { id: authorInfo - width: 192 + width: UM.Theme.getSize("base_unit").width * 16 height: parent.height anchors { @@ -89,7 +84,7 @@ Item } } width: parent.width - height: 24 + height: UM.Theme.getSize("base_unit").height * 3 wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft @@ -97,8 +92,6 @@ Item color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining") } } - - // Plugin actions Column { id: pluginActions @@ -111,7 +104,6 @@ Item right: parent.right topMargin: UM.Theme.getSize("default_margin").height } - Button { id: removeButton text: @@ -131,7 +123,7 @@ Item background: Rectangle { implicitWidth: UM.Theme.getSize("base_unit").width * 8 - implicitHeight: UM.Theme.getSize("base_unit").width * 2.5 + implicitHeight: Math.floor(UM.Theme.getSize("base_unit").width * 2.5) color: "transparent" border { @@ -139,7 +131,8 @@ Item color: UM.Theme.getColor("lining") } } - label: Text { + label: Text + { text: control.text color: UM.Theme.getColor("text") verticalAlignment: Text.AlignVCenter @@ -165,8 +158,8 @@ Item } } } - - Button { + Button + { id: updateButton text: catalog.i18nc("@action:button", "Update") visible: canUpdate @@ -195,10 +188,13 @@ Item ProgressBar { id: progressbar - anchors.left: updateButton.left - anchors.right: updateButton.right - anchors.top: updateButton.bottom - anchors.topMargin: 4 + anchors + { + left: updateButton.left + right: updateButton.right + top: updateButton.bottom + topMargin: Math.floor(UM.Theme.getSize("base_unit") / 4) + } value: toolbox.isDownloading ? toolbox.downloadProgress : 0 visible: toolbox.isDownloading style: ProgressBarStyle diff --git a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml index 9109f407c8..655edc9447 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml @@ -11,22 +11,19 @@ import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -UM.Dialog { +UM.Dialog +{ title: catalog.i18nc("@title:window", "Plugin License Agreement") - minimumWidth: UM.Theme.getSize("license_window_minimum").width minimumHeight: UM.Theme.getSize("license_window_minimum").height width: minimumWidth height: minimumHeight - property var pluginName; property var licenseContent; property var pluginFileLocation; - Item { anchors.fill: parent - Label { id: licenseTitle @@ -36,7 +33,6 @@ UM.Dialog { text: licenseDialog.pluginName + catalog.i18nc("@label", "This plugin contains a license.\nYou need to accept this license to install this plugin.\nDo you agree with the terms below?") wrapMode: Text.Wrap } - TextArea { id: licenseText @@ -49,8 +45,8 @@ UM.Dialog { text: licenseDialog.licenseContent != null ? licenseDialog.licenseContent : "" } } - - rightButtons: [ + rightButtons: + [ Button { id: acceptButton diff --git a/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml b/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml deleted file mode 100644 index 8970515cac..0000000000 --- a/plugins/Toolbox/resources/qml/ToolboxRestartDialog.qml +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2018 Ultimaker B.V. -// Toolbox is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 -import UM 1.1 as UM - -Window { - // title: catalog.i18nc("@title:tab", "Plugins"); - width: 360 * screenScaleFactor - height: 120 * screenScaleFactor - minimumWidth: 360 * screenScaleFactor - minimumHeight: 120 * screenScaleFactor - color: UM.Theme.getColor("sidebar") - property var message; - - Text { - id: message - anchors { - left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - top: parent.top - topMargin: UM.Theme.getSize("default_margin").height - } - text: restartDialog.message != null ? restartDialog.message : "" - } - Button { - id: laterButton - text: "Later" - onClicked: restartDialog.close(); - anchors { - left: parent.left - leftMargin: UM.Theme.getSize("default_margin").width - bottom: parent.bottom - bottomMargin: UM.Theme.getSize("default_margin").height - } - style: ButtonStyle { - background: Rectangle { - color: "transparent" - implicitWidth: 96 - implicitHeight: 30 - border { - width: 1 - color: UM.Theme.getColor("lining") - } - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("text") - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - } - - - Button { - id: restartButton - text: "Quit Cura" - anchors { - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width - bottom: parent.bottom - bottomMargin: UM.Theme.getSize("default_margin").height - } - onClicked: toolbox.restart() - style: ButtonStyle { - background: Rectangle { - implicitWidth: 96 - implicitHeight: 30 - color: UM.Theme.getColor("primary") - } - label: Text { - verticalAlignment: Text.AlignVCenter - color: UM.Theme.getColor("button_text") - font { - pixelSize: 13 - bold: true - } - text: control.text - horizontalAlignment: Text.AlignHCenter - } - } - } -} diff --git a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml new file mode 100644 index 0000000000..481afff67b --- /dev/null +++ b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml @@ -0,0 +1,51 @@ +// Copyright (c) 2018 Ultimaker B.V. +// Toolbox is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import UM 1.1 as UM + +Button +{ + property bool active: false + style: ButtonStyle + { + background: Rectangle + { + color: "transparent" + implicitWidth: UM.Theme.getSize("base_unit").height * 8 + implicitHeight: UM.Theme.getSize("base_unit").height * 4 + Rectangle + { + visible: control.active + color: UM.Theme.getColor("sidebar_header_highlight_hover") + anchors.bottom: parent.bottom + width: parent.width + height: UM.Theme.getSize("sidebar_header_highlight").height + } + } + label: Text + { + text: control.text + color: + { + if( control.hovered ) + { + return UM.Theme.getColor("topbar_button_text_hovered"); + } + if( control.active ) + { + return UM.Theme.getColor("topbar_button_text_active"); + } + else + { + return UM.Theme.getColor("topbar_button_text_inactive"); + } + } + font: control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium") + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + } +} From fbf73176d3dbc757c3a9f640861cbf56b6d46687 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 20 Apr 2018 11:25:39 +0200 Subject: [PATCH 53/83] Use UM.Version instead of VersionTools --- cura/CuraPackageManager.py | 6 ++---- plugins/Toolbox/src/Toolbox.py | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 1a02939e70..444e7462e8 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -12,9 +12,7 @@ from PyQt5.QtCore import pyqtSlot, QObject, pyqtSignal from UM.Logger import Logger from UM.Resources import Resources - -from cura.Utils import VersionTools - +from UM.Version import Version class CuraPackageManager(QObject): @@ -186,7 +184,7 @@ class CuraPackageManager(QObject): # Compare versions and only schedule the installation if the given package is newer new_version = package_info["package_version"] installed_version = installed_package_info["package_version"] - if VersionTools.compareSemanticVersions(new_version, installed_version) > 0: + if Version(new_version) > Version(installed_version): Logger.log("i", "Package [%s] version [%s] is newer than the installed version [%s], update it.", package_id, new_version, installed_version) to_install_package = True diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index fbf22a2788..56a726def6 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -16,7 +16,7 @@ from UM.PluginRegistry import PluginRegistry from UM.Qt.Bindings.PluginsModel import PluginsModel from UM.Extension import Extension from UM.i18n import i18nCatalog -from cura.Utils.VersionTools import compareSemanticVersions +from UM.Version import Version from cura.CuraApplication import CuraApplication from .AuthorsModel import AuthorsModel @@ -289,7 +289,7 @@ class Toolbox(QObject, Extension): local_version = local_package["package_version"] remote_version = remote_package["package_version"] - return compareSemanticVersions(remote_version, local_version) > 0 + return Version(remote_version) > Version(local_version) @pyqtSlot(str, result = bool) def isInstalled(self, package_id) -> bool: From 7f622eb300165f795dd52476c98a2908abf920b5 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 20 Apr 2018 11:27:53 +0200 Subject: [PATCH 54/83] Cura with a capital "C" --- plugins/Toolbox/plugin.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/plugin.json b/plugins/Toolbox/plugin.json index 7c85851df7..12d4042b6b 100644 --- a/plugins/Toolbox/plugin.json +++ b/plugins/Toolbox/plugin.json @@ -3,5 +3,5 @@ "author": "Ultimaker B.V.", "version": "1.0.0", "api": 4, - "description": "Find, manage and install new cura packages." -} \ No newline at end of file + "description": "Find, manage and install new Cura packages." +} From 668a92952cdc9420d09c120045f8cae3ce3e14d8 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 20 Apr 2018 13:26:23 +0200 Subject: [PATCH 55/83] CURA-5035 Review changes --- plugins/Toolbox/resources/qml/Toolbox.qml | 2 +- .../resources/qml/ToolboxAuthorPage.qml | 16 +++++++------- .../resources/qml/ToolboxBackColumn.qml | 4 ++-- .../resources/qml/ToolboxDetailList.qml | 4 ++-- .../resources/qml/ToolboxDetailPage.qml | 22 +++++++++++-------- .../resources/qml/ToolboxDetailTile.qml | 4 ++-- .../qml/ToolboxDownloadsGridTile.qml | 4 ++-- .../resources/qml/ToolboxDownloadsPage.qml | 2 +- .../qml/ToolboxDownloadsShowcase.qml | 2 +- .../Toolbox/resources/qml/ToolboxFooter.qml | 4 ++-- .../resources/qml/ToolboxInstalledPage.qml | 6 ++--- .../resources/qml/ToolboxTabButton.qml | 4 ++-- resources/themes/cura-light/theme.json | 17 ++++++++++---- 13 files changed, 52 insertions(+), 39 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index e3ee654710..3fe5e75bb0 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -70,7 +70,7 @@ Window { id: footer visible: toolbox.restartRequired - height: toolbox.restartRequired ? UM.Theme.getSize("base_unit").height * 5 : 0 + height: toolbox.restartRequired ? UM.Theme.getSize("toolbox_footer").height : 0 } // TODO: Clean this up: Connections diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 1cc61a07be..2fd8d7b99a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -22,9 +22,9 @@ Item { left: sidebar.right right: parent.right - rightMargin: UM.Theme.getSize("double_margin").width + rightMargin: UM.Theme.getSize("wide_margin").width } - height: UM.Theme.getSize("base_unit").height * 12 + height: UM.Theme.getSize("toolbox_detail_header").height Image { id: thumbnail @@ -36,8 +36,8 @@ Item { top: parent.top left: parent.left - leftMargin: UM.Theme.getSize("double_margin").width - topMargin: UM.Theme.getSize("double_margin").height + leftMargin: UM.Theme.getSize("wide_margin").width + topMargin: UM.Theme.getSize("wide_margin").height } } @@ -50,7 +50,7 @@ Item left: thumbnail.right leftMargin: UM.Theme.getSize("default_margin").width right: parent.right - rightMargin: UM.Theme.getSize("double_margin").width + rightMargin: UM.Theme.getSize("wide_margin").width bottomMargin: UM.Theme.getSize("default_margin").height } text: details.name @@ -79,7 +79,7 @@ Item left: description.left topMargin: UM.Theme.getSize("default_margin").height } - spacing: Math.floor(UM.Theme.getSize("default_margin").height / 2) + spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) width: childrenRect.width Label { @@ -98,8 +98,8 @@ Item leftMargin: UM.Theme.getSize("default_margin").width topMargin: UM.Theme.getSize("default_margin").height } - spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) - width: UM.Theme.getSize("base_unit").width * 12 + spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) + // width: UM.Theme.getSize("base_unit").width * 12 Label { text: diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml index 87a8f665de..0b82364fa2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -10,12 +10,12 @@ Item { id: sidebar height: parent.height - width: UM.Theme.getSize("base_unit").width * 6 + width: UM.Theme.getSize("toolbox_back_column").width anchors { top: parent.top left: parent.left - topMargin: UM.Theme.getSize("double_margin").height + topMargin: UM.Theme.getSize("wide_margin").height leftMargin: UM.Theme.getSize("default_margin").width rightMargin: UM.Theme.getSize("default_margin").width } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index ebb1ae073d..1b9e6e5b45 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -19,8 +19,8 @@ Item anchors { right: base.right - topMargin: UM.Theme.getSize("double_margin").height - bottomMargin: UM.Theme.getSize("double_margin").height + topMargin: UM.Theme.getSize("wide_margin").height + bottomMargin: UM.Theme.getSize("wide_margin").height top: parent.top } height: childrenRect.height diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index d754e89ddb..9106c770ed 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -23,9 +23,9 @@ Item { left: sidebar.right right: parent.right - rightMargin: UM.Theme.getSize("double_margin").width + rightMargin: UM.Theme.getSize("wide_margin").width } - height: UM.Theme.getSize("base_unit").height * 12 + height: UM.Theme.getSize("toolbox_detail_header").height Image { id: thumbnail @@ -37,8 +37,8 @@ Item { top: parent.top left: parent.left - leftMargin: UM.Theme.getSize("double_margin").width - topMargin: UM.Theme.getSize("double_margin").height + leftMargin: UM.Theme.getSize("wide_margin").width + topMargin: UM.Theme.getSize("wide_margin").height } } @@ -51,7 +51,7 @@ Item left: thumbnail.right leftMargin: UM.Theme.getSize("default_margin").width right: parent.right - rightMargin: UM.Theme.getSize("double_margin").width + rightMargin: UM.Theme.getSize("wide_margin").width bottomMargin: UM.Theme.getSize("default_margin").height } text: details.name @@ -70,7 +70,7 @@ Item left: title.left topMargin: UM.Theme.getSize("default_margin").height } - spacing: Math.floor(UM.Theme.getSize("default_margin").height / 2) + spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) width: childrenRect.width Label { @@ -101,8 +101,8 @@ Item leftMargin: UM.Theme.getSize("default_margin").width topMargin: UM.Theme.getSize("default_margin").height } - spacing: Math.floor(UM.Theme.getSize("default_margin").height/2) - width: UM.Theme.getSize("base_unit").width * 12 + spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) + // width: UM.Theme.getSize("base_unit").width * 12 Label { text: details.version @@ -111,7 +111,11 @@ Item } Label { - text: Qt.formatDateTime(details.last_updated, "dd MMM yyyy") + text: + { + var date = new Date(details.last_updated) + return date.toLocaleString(Qt.locale()) + } font: UM.Theme.getFont("very_small") color: UM.Theme.getColor("text") } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 5c97117073..c09d3516ce 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -9,8 +9,8 @@ import UM 1.1 as UM Item { property bool installed: toolbox.isInstalled(model.id) - width: base.width - UM.Theme.getSize("double_margin").width - height: UM.Theme.getSize("base_unit").height * 8 + width: base.width - UM.Theme.getSize("wide_margin").width + height: UM.Theme.getSize("toolbox_detail_tile").height Column { anchors diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index c705f6c515..60183eadbe 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -23,7 +23,7 @@ Item { width: parent.width height: childrenRect.height - spacing: Math.floor(UM.Theme.getSize("base_unit").width / 2) + spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) Rectangle { id: thumbnail @@ -44,7 +44,7 @@ Item Column { width: parent.width - thumbnail.width - parent.spacing - spacing: Math.floor(UM.Theme.getSize("base_unit").width / 2) + spacing: Math.floor(UM.Theme.getSize("narrow_margin").width) Label { id: name diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml index ed905e7845..5b93ba74bc 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml @@ -18,7 +18,7 @@ ScrollView { width: base.width spacing: UM.Theme.getSize("default_margin").height - padding: UM.Theme.getSize("double_margin").height + padding: UM.Theme.getSize("wide_margin").height height: childrenRect.height + 2 * padding ToolboxDownloadsShowcase { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index c64c837314..f783e35305 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -14,7 +14,7 @@ Column { id: base height: childrenRect.height - spacing: UM.Theme.getSize("base_unit").height + spacing: UM.Theme.getSize("toolbox_showcase_spacing").width Label { id: heading diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index 1dd144b0e2..eea208f552 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -22,7 +22,7 @@ Item { top: restartButton.top left: parent.left - leftMargin: UM.Theme.getSize("double_margin").width + leftMargin: UM.Theme.getSize("wide_margin").width right: restartButton.right rightMargin: UM.Theme.getSize("default_margin").width } @@ -36,7 +36,7 @@ Item top: parent.top topMargin: UM.Theme.getSize("default_margin").height right: parent.right - rightMargin: UM.Theme.getSize("double_margin").width + rightMargin: UM.Theme.getSize("wide_margin").width } visible: toolbox.restartRequired iconName: "dialog-restart" diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index eff055f330..c7904076dd 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -22,9 +22,9 @@ ScrollView { right: parent.right left: parent.left - leftMargin: UM.Theme.getSize("double_margin").width - topMargin: UM.Theme.getSize("double_margin").height - bottomMargin: UM.Theme.getSize("double_margin").height + leftMargin: UM.Theme.getSize("wide_margin").width + topMargin: UM.Theme.getSize("wide_margin").height + bottomMargin: UM.Theme.getSize("wide_margin").height top: parent.top } height: childrenRect.height + 4 * UM.Theme.getSize("default_margin").height diff --git a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml index 481afff67b..6991817ff5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml @@ -14,8 +14,8 @@ Button background: Rectangle { color: "transparent" - implicitWidth: UM.Theme.getSize("base_unit").height * 8 - implicitHeight: UM.Theme.getSize("base_unit").height * 4 + implicitWidth: UM.Theme.getSize("toolbox_header_tab").width + implicitHeight: UM.Theme.getSize("toolbox_header_tab").height Rectangle { visible: control.active diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 595c7307a9..f016d0eb79 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -323,13 +323,16 @@ "sizes": { "base_unit": [1.0, 1.0], "window_minimum_size": [70, 50], - "window_margin": [1.0, 1.0], - "default_margin": [1.0, 1.0], - "double_margin": [2.0, 2.0], + "default_lining": [0.08, 0.08], "default_arrow": [0.8, 0.8], "logo": [7.6, 1.6], + "default_margin": [1.0, 1.0], + "wide_margin": [2.0, 2.0], + "narrow_margin": [0.5, 0.5], + "window_margin": [1.0, 1.0], + "extruder_button_material_margin": [0.70, 0.9], "extruder_button_material": [0.75, 0.75], @@ -443,6 +446,12 @@ "toolbox_thumbnail_small": [6.0, 6.0], "toolbox_thumbnail_medium": [8.0, 8.0], - "toolbox_thumbnail_large": [12.0, 12.0] + "toolbox_thumbnail_large": [12.0, 12.0], + "toolbox_footer": [1.0, 5.0], + "toolbox_showcase_spacing": [1.0, 1.0], + "toolbox_header_tab": [8.0, 4.0], + "toolbox_detail_header": [1.0, 12.0], + "toolbox_detail_tile": [1.0, 8.0], + "toolbox_back_column": [6.0, 1.0] } } From 9b556e9c868c3e2f89d305802eb2948579434a90 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 20 Apr 2018 14:08:44 +0200 Subject: [PATCH 56/83] CURA-5035 Removed all base units --- .../resources/qml/ToolboxAuthorPage.qml | 3 +-- .../resources/qml/ToolboxBackColumn.qml | 4 ++-- .../resources/qml/ToolboxDetailPage.qml | 3 +-- .../resources/qml/ToolboxDetailTile.qml | 2 +- .../resources/qml/ToolboxDownloadsGrid.qml | 6 +++--- .../qml/ToolboxDownloadsShowcase.qml | 2 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 2 +- .../Toolbox/resources/qml/ToolboxFooter.qml | 8 +++---- .../Toolbox/resources/qml/ToolboxHeader.qml | 2 +- .../resources/qml/ToolboxInstalledTile.qml | 21 +++++++++---------- resources/themes/cura-light/theme.json | 12 +++++++++-- 11 files changed, 35 insertions(+), 30 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 2fd8d7b99a..2c723ce4d6 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -57,7 +57,7 @@ Item font: UM.Theme.getFont("large") wrapMode: Text.WordWrap width: parent.width - height: UM.Theme.getSize("base_unit") * 2 + height: UM.Theme.getSize("toolbox_property_label").height } Label { @@ -99,7 +99,6 @@ Item topMargin: UM.Theme.getSize("default_margin").height } spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) - // width: UM.Theme.getSize("base_unit").width * 12 Label { text: diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml index 0b82364fa2..989e065ed4 100644 --- a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -42,8 +42,8 @@ Item color: button.hovered ? UM.Theme.getColor("primary") : UM.Theme.getColor("text") source: UM.Theme.getIcon("arrow_left") } - width: UM.Theme.getSize("base_unit").width * 4 - height: UM.Theme.getSize("base_unit").height * 2 + width: UM.Theme.getSize("toolbox_back_button").width + height: UM.Theme.getSize("toolbox_back_button").height onClicked: { toolbox.viewPage = "overview" diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 9106c770ed..34b12a1a56 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -58,7 +58,7 @@ Item font: UM.Theme.getFont("large") wrapMode: Text.WordWrap width: parent.width - height: UM.Theme.getSize("base_unit") * 2 + height: UM.Theme.getSize("toolbox_property_label").height } Column @@ -102,7 +102,6 @@ Item topMargin: UM.Theme.getSize("default_margin").height } spacing: Math.floor(UM.Theme.getSize("narrow_margin").height) - // width: UM.Theme.getSize("base_unit").width * 12 Label { text: details.version diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index c09d3516ce..a9852b3a40 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -23,7 +23,7 @@ Item Label { width: parent.width - height: UM.Theme.getSize("base_unit").height * 2 + height: UM.Theme.getSize("toolbox_property_label").height text: model.name wrapMode: Text.WordWrap color: UM.Theme.getColor("text") diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index 0f030401f2..a519e4a86f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -13,7 +13,7 @@ Column { id: base height: childrenRect.height - spacing: UM.Theme.getSize("base_unit").height + spacing: UM.Theme.getSize("default_margin").height Label { id: heading @@ -27,8 +27,8 @@ Column id: grid width: parent.width columns: 2 - columnSpacing: UM.Theme.getSize("base_unit").width - rowSpacing: UM.Theme.getSize("base_unit").height + columnSpacing: UM.Theme.getSize("default_margin").height + rowSpacing: UM.Theme.getSize("default_margin").width Repeater { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index f783e35305..b6bb72c88d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -26,7 +26,7 @@ Column Row { height: childrenRect.height - spacing: UM.Theme.getSize("base_unit").width * 2 + spacing: UM.Theme.getSize("wide_margin").width anchors { horizontalCenter: parent.horizontalCenter diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 08fc6a4343..dbe56dbd9d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -54,7 +54,7 @@ Item } verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter - height: UM.Theme.getSize("base_unit").width * 4 + height: UM.Theme.getSize("toolbox_heading_label").height width: parent.width color: UM.Theme.getColor("text") font: UM.Theme.getFont("medium_bold") diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index eea208f552..65161634d6 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -11,12 +11,12 @@ Item id: footer width: parent.width anchors.bottom: parent.bottom - height: visible ? Math.floor(UM.Theme.getSize("base_unit").height * 5.5) : 0 + height: visible ? Math.floor(UM.Theme.getSize("toolbox_footer").height) : 0 Label { visible: toolbox.restartRequired text: "You will need to restart Cura before changes in plugins have effect." - height: Math.floor(UM.Theme.getSize("base_unit").height * 2.5) + height: Math.floor(UM.Theme.getSize("toolbox_footer_button").height) verticalAlignment: Text.AlignVCenter anchors { @@ -45,8 +45,8 @@ Item { background: Rectangle { - implicitWidth: UM.Theme.getSize("base_unit").width * 8 - implicitHeight: Math.floor(UM.Theme.getSize("base_unit").height * 2.5) + implicitWidth: UM.Theme.getSize("toolbox_footer_button").width + implicitHeight: Math.floor(UM.Theme.getSize("toolbox_footer_button").height) color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary") } label: Text diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 6049900051..cd01a34b13 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -9,7 +9,7 @@ Item { id: header width: parent.width - height: UM.Theme.getSize("base_unit").height * 4 + height: UM.Theme.getSize("toolbox_header").height * 4 Row { id: bar diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index cd51ce6954..6a4f3e7705 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -11,7 +11,7 @@ Item id: base property bool canUpdate: false property bool isEnabled: true - height: UM.Theme.getSize("base_unit").height * 8 + height: UM.Theme.getSize("toolbox_installed_tile").height anchors { left: parent.left @@ -41,7 +41,7 @@ Item { text: model.name width: parent.width - height: UM.Theme.getSize("base_unit").height * 2 + height: UM.Theme.getSize("toolbox_property_label").height wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter font: UM.Theme.getFont("default_bold") @@ -51,7 +51,7 @@ Item { text: model.description width: parent.width - height: UM.Theme.getSize("base_unit").height * 3 + height: UM.Theme.getSize("toolbox_property_label").height clip: true wrapMode: Text.WordWrap color: pluginInfo.color @@ -61,7 +61,6 @@ Item Column { id: authorInfo - width: UM.Theme.getSize("base_unit").width * 16 height: parent.height anchors { @@ -84,7 +83,7 @@ Item } } width: parent.width - height: UM.Theme.getSize("base_unit").height * 3 + height: UM.Theme.getSize("toolbox_property_label").height wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft @@ -122,8 +121,8 @@ Item { background: Rectangle { - implicitWidth: UM.Theme.getSize("base_unit").width * 8 - implicitHeight: Math.floor(UM.Theme.getSize("base_unit").width * 2.5) + implicitWidth: UM.Theme.getSize("toolbox_action_button").width + implicitHeight: UM.Theme.getSize("toolbox_action_button").height color: "transparent" border { @@ -167,8 +166,8 @@ Item { background: Rectangle { - implicitWidth: UM.Theme.getSize("base_unit").width * 8 - implicitHeight: UM.Theme.getSize("base_unit").width * 2.5 + implicitWidth: UM.Theme.getSize("toolbox_action_button").width + implicitHeight: UM.Theme.getSize("toolbox_action_button").height color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary") } label: Label @@ -193,7 +192,7 @@ Item left: updateButton.left right: updateButton.right top: updateButton.bottom - topMargin: Math.floor(UM.Theme.getSize("base_unit") / 4) + topMargin: Math.floor(UM.Theme.getSize("default_margin") / 4) } value: toolbox.isDownloading ? toolbox.downloadProgress : 0 visible: toolbox.isDownloading @@ -202,7 +201,7 @@ Item background: Rectangle { color: UM.Theme.getColor("lining") - implicitHeight: Math.floor(UM.Theme.getSize("base_unit").height / 2) + implicitHeight: Math.floor(UM.Theme.getSize("toolbox_progress_bar").height) } progress: Rectangle { diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index f016d0eb79..99d4f3f5a1 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -447,11 +447,19 @@ "toolbox_thumbnail_small": [6.0, 6.0], "toolbox_thumbnail_medium": [8.0, 8.0], "toolbox_thumbnail_large": [12.0, 12.0], - "toolbox_footer": [1.0, 5.0], + "toolbox_footer": [1.0, 5.5], + "toolbox_footer_button": [8.0, 2.5], "toolbox_showcase_spacing": [1.0, 1.0], "toolbox_header_tab": [8.0, 4.0], "toolbox_detail_header": [1.0, 12.0], "toolbox_detail_tile": [1.0, 8.0], - "toolbox_back_column": [6.0, 1.0] + "toolbox_back_column": [6.0, 1.0], + "toolbox_back_button": [4.0, 2.0], + "toolbox_installed_tile": [1.0, 8.0], + "toolbox_property_label": [1.0, 2.0], + "toolbox_heading_label": [1.0, 4.0], + "toolbox_header": [1.0, 4.0], + "toolbox_action_button": [8.0, 2.5], + "toolbox_progress_bar": [8.0, 0.5] } } From 0944bba86b4d98a49540f0c298d97d6eb4b64f1c Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 20 Apr 2018 16:21:57 +0200 Subject: [PATCH 57/83] CURA-5035 Added typings --- .../resources/qml/ToolboxDetailPage.qml | 3 +- .../resources/qml/ToolboxDownloadsGrid.qml | 3 +- .../qml/ToolboxDownloadsShowcase.qml | 6 +- .../Toolbox/resources/qml/ToolboxHeader.qml | 4 +- plugins/Toolbox/src/Toolbox.py | 76 ++++++++++--------- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 34b12a1a56..6eccae8423 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -12,11 +12,12 @@ Item id: base property var details: toolbox.packagesModel.items[0] anchors.fill: parent + width: parent.width ToolboxBackColumn { id: sidebar } - Rectangle + Item { id: header anchors diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index a519e4a86f..ac64fc5697 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -13,6 +13,7 @@ Column { id: base height: childrenRect.height + width: parent.width spacing: UM.Theme.getSize("default_margin").height Label { @@ -29,7 +30,7 @@ Column columns: 2 columnSpacing: UM.Theme.getSize("default_margin").height rowSpacing: UM.Theme.getSize("default_margin").width - + height: childrenRect.height Repeater { model: toolbox.viewCategory == "material" ? toolbox.authorsModel : toolbox.packagesModel diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index b6bb72c88d..b1c7b50b56 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -2,19 +2,16 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 -import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - Column { id: base height: childrenRect.height spacing: UM.Theme.getSize("toolbox_showcase_spacing").width + width: parent.width Label { id: heading @@ -31,7 +28,6 @@ Column { horizontalCenter: parent.horizontalCenter } - Repeater { model: { diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index cd01a34b13..12dd1b36f0 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -9,11 +9,11 @@ Item { id: header width: parent.width - height: UM.Theme.getSize("toolbox_header").height * 4 + height: UM.Theme.getSize("toolbox_header").height Row { id: bar - spacing: 12 + spacing: UM.Theme.getSize("default_margin").width height: childrenRect.height width: childrenRect.width anchors diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 56a726def6..38d333d4eb 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -159,23 +159,25 @@ class Toolbox(QObject, Extension): showLicenseDialog = pyqtSignal() @pyqtSlot(result = str) - def getLicenseDialogPluginName(self): + def getLicenseDialogPluginName(self) -> str: return self._license_dialog_plugin_name @pyqtSlot(result = str) - def getLicenseDialogPluginFileLocation(self): + def getLicenseDialogPluginFileLocation(self) -> str: return self._license_dialog_plugin_file_location @pyqtSlot(result = str) - def getLicenseDialogLicenseContent(self): + def getLicenseDialogLicenseContent(self) -> str: return self._license_dialog_license_content - def openLicenseDialog(self, plugin_name, license_content, plugin_file_location): + def openLicenseDialog(self, plugin_name: str, license_content: str, plugin_file_location: str): self._license_dialog_plugin_name = plugin_name self._license_dialog_license_content = license_content self._license_dialog_plugin_file_location = plugin_file_location self.showLicenseDialog.emit() + # This is a plugin, so most of the components required are not ready when + # this is initialized. Therefore, we wait until the application is ready. def _onAppInitialized(self): self._package_manager = Application.getInstance().getCuraPackageManager() @@ -205,7 +207,7 @@ class Toolbox(QObject, Extension): # Apply enabled/disabled state to installed plugins self.enabledChanged.emit() - def _createDialog(self, qml_name): + def _createDialog(self, qml_name: str): Logger.log("d", "Toolbox: Creating dialog [%s].", qml_name) path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) dialog = Application.getInstance().createQmlComponent(path, {"toolbox": self}) @@ -224,7 +226,7 @@ class Toolbox(QObject, Extension): self.metadataChanged.emit() @pyqtSlot(str) - def install(self, file_path): + def install(self, file_path: str): self._package_manager.installPackage(file_path) self.installChanged.emit() self._updateInstalledModels() @@ -233,7 +235,7 @@ class Toolbox(QObject, Extension): self.restartRequiredChanged.emit() @pyqtSlot(str) - def uninstall(self, plugin_id): + def uninstall(self, plugin_id: str): self._package_manager.removePackage(plugin_id) self.installChanged.emit() self._updateInstalledModels() @@ -242,7 +244,7 @@ class Toolbox(QObject, Extension): self.restartRequiredChanged.emit() @pyqtSlot(str) - def enable(self, plugin_id): + def enable(self, plugin_id: str): self._plugin_registry.enablePlugin(plugin_id) self.enabledChanged.emit() Logger.log("i", "%s was set as 'active'.", plugin_id) @@ -250,7 +252,7 @@ class Toolbox(QObject, Extension): self.restartRequiredChanged.emit() @pyqtSlot(str) - def disable(self, plugin_id): + def disable(self, plugin_id: str): self._plugin_registry.disablePlugin(plugin_id) self.enabledChanged.emit() Logger.log("i", "%s was set as 'deactive'.", plugin_id) @@ -292,11 +294,11 @@ class Toolbox(QObject, Extension): return Version(remote_version) > Version(local_version) @pyqtSlot(str, result = bool) - def isInstalled(self, package_id) -> bool: + def isInstalled(self, package_id: str) -> bool: return self._package_manager.isPackageInstalled(package_id) @pyqtSlot(str, result = bool) - def isEnabled(self, package_id) -> bool: + def isEnabled(self, package_id: str) -> bool: if package_id in self._plugin_registry.getActivePlugins(): return True return False @@ -305,7 +307,7 @@ class Toolbox(QObject, Extension): # Make API Calls # -------------------------------------------------------------------------- - def _makeRequestByType(self, type): + def _makeRequestByType(self, type: str): Logger.log("i", "Toolbox: Requesting %s metadata from server.", type) request = QNetworkRequest(self._request_urls[type]) request.setRawHeader(*self._request_header) @@ -313,7 +315,7 @@ class Toolbox(QObject, Extension): # TODO: Request authors and request material showcase @pyqtSlot(str) - def startDownload(self, url): + def startDownload(self, url: str): Logger.log("i", "Toolbox: Attempting to download & install package from %s.", url) url = QUrl(url) self._download_request = QNetworkRequest(url) @@ -338,7 +340,7 @@ class Toolbox(QObject, Extension): # Handlers for Network Events # -------------------------------------------------------------------------- - def _onNetworkAccesibleChanged(self, accessible): + def _onNetworkAccesibleChanged(self, accessible: int): if accessible == 0: self.setDownloadProgress(0) self.setIsDownloading(False) @@ -347,7 +349,7 @@ class Toolbox(QObject, Extension): self._download_reply.abort() self._download_reply = None - def _onRequestFinished(self, reply): + def _onRequestFinished(self, reply: QNetworkReply): if reply.error() == QNetworkReply.TimeoutError: Logger.log("w", "Got a timeout.") @@ -479,7 +481,7 @@ class Toolbox(QObject, Extension): # Ignore any operation that is not a get operation pass - def _onDownloadProgress(self, bytes_sent, bytes_total): + def _onDownloadProgress(self, bytes_sent: int, bytes_total: int): if bytes_total > 0: new_progress = bytes_sent / bytes_total * 100 self.setDownloadProgress(new_progress) @@ -495,7 +497,7 @@ class Toolbox(QObject, Extension): self._onDownloadComplete(file_path) return - def _onDownloadComplete(self, file_path): + def _onDownloadComplete(self, file_path: str): Logger.log("i", "Toolbox: Download complete.") try: package_info = self._package_manager.getPackageInfo(file_path) @@ -514,48 +516,48 @@ class Toolbox(QObject, Extension): # Getter & Setters for Properties: # -------------------------------------------------------------------------- - def setDownloadProgress(self, progress): + def setDownloadProgress(self, progress: int): if progress != self._download_progress: self._download_progress = progress self.onDownloadProgressChanged.emit() @pyqtProperty(int, fset = setDownloadProgress, notify = onDownloadProgressChanged) - def downloadProgress(self): + def downloadProgress(self) -> int: return self._download_progress - def setIsDownloading(self, is_downloading): + def setIsDownloading(self, is_downloading: bool): if self._is_downloading != is_downloading: self._is_downloading = is_downloading self.onIsDownloadingChanged.emit() @pyqtProperty(bool, fset = setIsDownloading, notify = onIsDownloadingChanged) - def isDownloading(self): + def isDownloading(self) -> bool: return self._is_downloading - def setActivePackage(self, package): + def setActivePackage(self, package: dict): self._active_package = package self.activePackageChanged.emit() @pyqtProperty(QObject, fset = setActivePackage, notify = activePackageChanged) - def activePackage(self): + def activePackage(self) -> dict: return self._active_package - def setViewCategory(self, category = "plugins"): + def setViewCategory(self, category: str = "plugins"): self._view_category = category self.viewChanged.emit() @pyqtProperty(str, fset = setViewCategory, notify = viewChanged) - def viewCategory(self): + def viewCategory(self) -> str: return self._view_category - def setViewPage(self, page = "overview"): + def setViewPage(self, page: str = "overview"): self._view_page = page self.viewChanged.emit() @pyqtProperty(str, fset = setViewPage, notify = viewChanged) - def viewPage(self): + def viewPage(self) -> str: return self._view_page - def setViewSelection(self, selection = ""): + def setViewSelection(self, selection: str = ""): self._view_selection = selection self.viewChanged.emit() @pyqtProperty(str, fset = setViewSelection, notify = viewChanged) - def viewSelection(self): + def viewSelection(self) -> str: return self._view_selection @@ -565,27 +567,27 @@ class Toolbox(QObject, Extension): # TODO: Maybe replace this with simply exposing self._models to Qt and then # setting model: toolbox.models.foobar instead of toolbox.foobarModel @pyqtProperty(QObject, notify = metadataChanged) - def authorsModel(self): + def authorsModel(self) -> AuthorsModel: return self._models["authors"] @pyqtProperty(QObject, notify = metadataChanged) - def packagesModel(self): + def packagesModel(self) -> PackagesModel: return self._models["packages"] @pyqtProperty(QObject, notify = metadataChanged) - def pluginsShowcaseModel(self): + def pluginsShowcaseModel(self) -> PackagesModel: return self._models["plugins_showcase"] @pyqtProperty(QObject, notify = metadataChanged) - def pluginsInstalledModel(self): + def pluginsInstalledModel(self) -> PackagesModel: return self._models["plugins_installed"] @pyqtProperty(QObject, notify = metadataChanged) - def materialsShowcaseModel(self): + def materialsShowcaseModel(self) -> PackagesModel: return self._models["materials_showcase"] @pyqtProperty(QObject, notify = metadataChanged) - def materialsInstalledModel(self): + def materialsInstalledModel(self) -> PackagesModel: return self._models["materials_installed"] @@ -593,7 +595,7 @@ class Toolbox(QObject, Extension): # Filter Models: # -------------------------------------------------------------------------- @pyqtSlot(str, str, str) - def filterModelByProp(self, modelType, filterType, parameter): + def filterModelByProp(self, modelType: str, filterType: str, parameter: str): if not self._models[modelType]: Logger.log("w", "Toolbox: Couldn't filter %s model because it doesn't exist.", modelType) return @@ -601,7 +603,7 @@ class Toolbox(QObject, Extension): self.filterChanged.emit() @pyqtSlot() - def removeFilters(self, modelType): + def removeFilters(self, modelType: str): if not self._models[modelType]: Logger.log("w", "Toolbox: Couldn't remove filters on %s model because it doesn't exist.", modelType) return From dc0dcac199b7ad909ec25fd5d5ace647a052a5ef Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Fri, 20 Apr 2018 17:06:16 +0200 Subject: [PATCH 58/83] CURA-5035 Small style tweaks --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 1 - plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml | 1 - plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml | 6 +++++- plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index 6eccae8423..cdd15f2ce4 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -2,7 +2,6 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 -import QtQuick.Dialogs 1.1 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml index 5b93ba74bc..d7101f40b3 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml @@ -2,7 +2,6 @@ // Toolbox is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 -import QtQuick.Dialogs 1.1 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index c7904076dd..075902904f 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -30,6 +30,7 @@ ScrollView height: childrenRect.height + 4 * UM.Theme.getSize("default_margin").height Label { + visible: toolbox.pluginsInstalledModel.items.length > 0 width: parent.width text: catalog.i18nc("@title:tab", "Plugins") color: UM.Theme.getColor("text_medium") @@ -37,6 +38,7 @@ ScrollView } Rectangle { + visible: toolbox.pluginsInstalledModel.items.length > 0 color: "transparent" width: parent.width height: childrenRect.height + 1 * UM.Theme.getSize("default_lining").width @@ -65,6 +67,7 @@ ScrollView } Label { + visible: toolbox.materialsInstalledModel.items.length > 0 width: base.width text: catalog.i18nc("@title:tab", "Materials") color: UM.Theme.getColor("text_medium") @@ -72,6 +75,7 @@ ScrollView } Rectangle { + visible: toolbox.materialsInstalledModel.items.length > 0 color: "transparent" width: parent.width height: childrenRect.height + 1 * UM.Theme.getSize("default_lining").width @@ -79,7 +83,7 @@ ScrollView border.width: UM.Theme.getSize("default_lining").width Column { - height: childrenRect.height + height: Math.max( UM.Theme.getSize("wide_margin").height, childrenRect.height) anchors { top: parent.top diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 6a4f3e7705..1a847ab15e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -62,6 +62,7 @@ Item { id: authorInfo height: parent.height + width: Math.floor(UM.Theme.getSize("toolbox_action_button").width * 1.25) anchors { top: parent.top From f2301eec31d91bb40c8f8b1276e0e3018718e8b4 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 24 Apr 2018 15:34:05 +0200 Subject: [PATCH 59/83] CURA-5035 Simplify selection --- plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml | 2 +- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 2 +- .../resources/qml/ToolboxDownloadsGridTile.qml | 11 ++--------- .../resources/qml/ToolboxDownloadsShowcaseTile.qml | 5 +---- plugins/Toolbox/resources/qml/ToolboxHeader.qml | 2 -- plugins/Toolbox/src/Toolbox.py | 10 ++++++---- 6 files changed, 11 insertions(+), 21 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index 2c723ce4d6..a19ab513eb 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -9,7 +9,7 @@ import UM 1.1 as UM Item { id: base - property var details: toolbox.authorsModel.items[0] + property var details: toolbox.viewSelection anchors.fill: parent ToolboxBackColumn { diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index cdd15f2ce4..ab2debbfe9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -9,7 +9,7 @@ import UM 1.1 as UM Item { id: base - property var details: toolbox.packagesModel.items[0] + property var details: toolbox.viewSelection anchors.fill: parent width: parent.width ToolboxBackColumn diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 60183eadbe..20124100ba 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -88,22 +88,15 @@ Item } onClicked: { + toolbox.viewSelection = model switch(toolbox.viewCategory) { case "material": - console.log("OKAY FILTER BY AUTHOR", model.name) - toolbox.viewSelection = model.name toolbox.viewPage = "author" - console.log(toolbox) - var name = model.name - toolbox.filterModelByProp("authors", "name", name) - toolbox.filterModelByProp("packages", "author_name", name) - console.log(toolbox) + toolbox.filterModelByProp("packages", "author_name", model.name) break default: - toolbox.viewSelection = model.id toolbox.viewPage = "detail" - toolbox.filterModelByProp("authors", "name", model.author_name) toolbox.filterModelByProp("packages", "id", model.id) break } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index dbe56dbd9d..4cc2a01c61 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -64,18 +64,15 @@ Item anchors.fill: parent onClicked: { + toolbox.viewSelection = model switch(toolbox.viewCategory) { case "material": - toolbox.viewSelection = model.name toolbox.viewPage = "author" - toolbox.filterModelByProp("authors", "name", model.name) toolbox.filterModelByProp("packages", "author_name", model.name) break default: - toolbox.viewSelection = model.id toolbox.viewPage = "detail" - toolbox.filterModelByProp("authors", "name", model.author_name) toolbox.filterModelByProp("packages", "id", model.id) break } diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 12dd1b36f0..75740982d9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -28,7 +28,6 @@ Item onClicked: { toolbox.filterModelByProp("packages", "type", "plugin") - toolbox.filterModelByProp("authors", "type", "plugin") toolbox.viewCategory = "plugin" toolbox.viewPage = "overview" } @@ -39,7 +38,6 @@ Item active: toolbox.viewCategory == "material" onClicked: { - toolbox.filterModelByProp("packages", "type", "material") toolbox.filterModelByProp("authors", "type", "material") toolbox.viewCategory = "material" toolbox.viewPage = "overview" diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 38d333d4eb..fdc089ae2d 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -122,7 +122,7 @@ class Toolbox(QObject, Extension): # View selection defines what is currently selected and should be # used in filtering. This could be an author name (if _view_page is set # to "author" or a plugin name if it is set to "detail"). - self._view_selection = "" + self._view_selection = None # Active package refers to which package is currently being downloaded, # installed, or otherwise modified. @@ -553,11 +553,13 @@ class Toolbox(QObject, Extension): def viewPage(self) -> str: return self._view_page - def setViewSelection(self, selection: str = ""): + def setViewSelection(self, selection: dict): + selection.setParent(self) self._view_selection = selection self.viewChanged.emit() - @pyqtProperty(str, fset = setViewSelection, notify = viewChanged) - def viewSelection(self) -> str: + @pyqtProperty(QObject, fset = setViewSelection, notify = viewChanged) + def viewSelection(self) -> dict: + print(dir(self._view_selection)) return self._view_selection From 236e2db47ed626cf1e85eb1df8f89c8dd8a82f3f Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 24 Apr 2018 16:59:23 +0200 Subject: [PATCH 60/83] CURA-5035 Fixed selection header --- plugins/Toolbox/resources/qml/Toolbox.qml | 1 + plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml | 8 ++++---- plugins/Toolbox/resources/qml/ToolboxDetailList.qml | 9 +++++---- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 8 ++++---- plugins/Toolbox/resources/qml/ToolboxDetailTile.qml | 12 +++++++----- .../Toolbox/resources/qml/ToolboxDownloadsGrid.qml | 1 - .../resources/qml/ToolboxDownloadsGridTile.qml | 3 +-- .../Toolbox/resources/qml/ToolboxDownloadsPage.qml | 4 ++-- .../resources/qml/ToolboxDownloadsShowcase.qml | 1 - .../resources/qml/ToolboxDownloadsShowcaseTile.qml | 2 +- .../Toolbox/resources/qml/ToolboxInstalledPage.qml | 4 ++-- .../Toolbox/resources/qml/ToolboxInstalledTile.qml | 1 - plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml | 2 +- resources/themes/cura-light/theme.json | 2 +- 14 files changed, 29 insertions(+), 29 deletions(-) diff --git a/plugins/Toolbox/resources/qml/Toolbox.qml b/plugins/Toolbox/resources/qml/Toolbox.qml index 3fe5e75bb0..0254bb0dcd 100644 --- a/plugins/Toolbox/resources/qml/Toolbox.qml +++ b/plugins/Toolbox/resources/qml/Toolbox.qml @@ -9,6 +9,7 @@ import UM 1.1 as UM Window { id: base + property var selection: null title: catalog.i18nc("@title", "Toolbox") modality: Qt.ApplicationModal width: 720 * screenScaleFactor diff --git a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml index a19ab513eb..6c87f9d2e2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxAuthorPage.qml @@ -8,8 +8,8 @@ import UM 1.1 as UM Item { - id: base - property var details: toolbox.viewSelection + id: page + property var details: base.selection anchors.fill: parent ToolboxBackColumn { @@ -130,9 +130,9 @@ Item anchors { top: header.bottom - bottom: base.bottom + bottom: page.bottom left: header.left - right: base.right + right: page.right } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index 1b9e6e5b45..7e319974a4 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -6,19 +6,20 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -Item +Rectangle { - id: base + id: detailList + // color: "green" ScrollView { frameVisible: false - anchors.fill: base + anchors.fill: detailList style: UM.Theme.styles.scrollview Column { anchors { - right: base.right + right: detailList.right topMargin: UM.Theme.getSize("wide_margin").height bottomMargin: UM.Theme.getSize("wide_margin").height top: parent.top diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index ab2debbfe9..fa1aa8ba23 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -8,8 +8,8 @@ import UM 1.1 as UM Item { - id: base - property var details: toolbox.viewSelection + id: page + property var details: base.selection anchors.fill: parent width: parent.width ToolboxBackColumn @@ -149,9 +149,9 @@ Item anchors { top: header.bottom - bottom: base.bottom + bottom: page.bottom left: header.left - right: base.right + right: page.right } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index a9852b3a40..1080a9213b 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -8,8 +8,9 @@ import UM 1.1 as UM Item { + id: tile property bool installed: toolbox.isInstalled(model.id) - width: base.width - UM.Theme.getSize("wide_margin").width + width: detailList.width - UM.Theme.getSize("wide_margin").width height: UM.Theme.getSize("toolbox_detail_tile").height Column { @@ -55,9 +56,10 @@ Item Rectangle { id: controls - anchors.right: parent.right - anchors.top: parent.top + anchors.right: tile.right + anchors.top: tile.top width: childrenRect.width + color: "blue" Button { id: installButton @@ -180,9 +182,9 @@ Item Rectangle { color: UM.Theme.getColor("lining") - width: parent.width + width: tile.width height: UM.Theme.getSize("default_lining").height - anchors.bottom: parent.bottom + anchors.bottom: tile.bottom } Connections { diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index ac64fc5697..8393eb045c 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -11,7 +11,6 @@ import UM 1.1 as UM Column { - id: base height: childrenRect.height width: parent.width spacing: UM.Theme.getSize("default_margin").height diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 20124100ba..4d479278b2 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -9,7 +9,6 @@ import UM 1.1 as UM Item { - id: base height: childrenRect.height Layout.alignment: Qt.AlignTop | Qt.AlignLeft Rectangle @@ -88,7 +87,7 @@ Item } onClicked: { - toolbox.viewSelection = model + base.selection = model switch(toolbox.viewCategory) { case "material": diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml index d7101f40b3..f665d5c5f5 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml @@ -8,14 +8,14 @@ import UM 1.1 as UM ScrollView { - id: base + id: page frameVisible: false width: parent.width height: parent.height style: UM.Theme.styles.scrollview Column { - width: base.width + width: page.width spacing: UM.Theme.getSize("default_margin").height padding: UM.Theme.getSize("wide_margin").height height: childrenRect.height + 2 * padding diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml index b1c7b50b56..d3ce443704 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcase.qml @@ -8,7 +8,6 @@ import UM 1.1 as UM Column { - id: base height: childrenRect.height spacing: UM.Theme.getSize("toolbox_showcase_spacing").width width: parent.width diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 4cc2a01c61..57dc16a4b8 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -64,7 +64,7 @@ Item anchors.fill: parent onClicked: { - toolbox.viewSelection = model + base.selection = model switch(toolbox.viewCategory) { case "material": diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml index 075902904f..9d916182f6 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledPage.qml @@ -10,7 +10,7 @@ import UM 1.1 as UM ScrollView { - id: base + id: page frameVisible: false width: parent.width height: parent.height @@ -68,7 +68,7 @@ ScrollView Label { visible: toolbox.materialsInstalledModel.items.length > 0 - width: base.width + width: page.width text: catalog.i18nc("@title:tab", "Materials") color: UM.Theme.getColor("text_medium") font: UM.Theme.getFont("medium") diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index 1a847ab15e..e8c9a17eba 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -8,7 +8,6 @@ import UM 1.1 as UM Item { - id: base property bool canUpdate: false property bool isEnabled: true height: UM.Theme.getSize("toolbox_installed_tile").height diff --git a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml index 755479803e..fc712e83e1 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml @@ -7,7 +7,7 @@ import QtQuick.Controls.Styles 1.4 Rectangle { - id: base + id: page width: parent.width height: parent.height color: "transparent" diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 99d4f3f5a1..ce54156e48 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -447,7 +447,7 @@ "toolbox_thumbnail_small": [6.0, 6.0], "toolbox_thumbnail_medium": [8.0, 8.0], "toolbox_thumbnail_large": [12.0, 12.0], - "toolbox_footer": [1.0, 5.5], + "toolbox_footer": [1.0, 4.5], "toolbox_footer_button": [8.0, 2.5], "toolbox_showcase_spacing": [1.0, 1.0], "toolbox_header_tab": [8.0, 4.0], From cbc45bffd0eb30b57d4d9c853f2ba70e4a34e53e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 25 Apr 2018 16:43:59 +0200 Subject: [PATCH 61/83] Should use .gcode.gz --- plugins/GCodeGzReader/GCodeGzReader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/GCodeGzReader/GCodeGzReader.py b/plugins/GCodeGzReader/GCodeGzReader.py index fd9bf0ed84..36fcfad01a 100644 --- a/plugins/GCodeGzReader/GCodeGzReader.py +++ b/plugins/GCodeGzReader/GCodeGzReader.py @@ -15,7 +15,7 @@ class GCodeGzReader(MeshReader): def __init__(self): super().__init__() - self._supported_extensions = [".gz"] + self._supported_extensions = [".gcode.gz"] def read(self, file_name): with open(file_name, "rb") as file: From 48eda4d0dc010997553db2d6d7a95fde6652f80c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 25 Apr 2018 16:44:32 +0200 Subject: [PATCH 62/83] Remove unused import --- plugins/GCodeGzReader/GCodeGzReader.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/GCodeGzReader/GCodeGzReader.py b/plugins/GCodeGzReader/GCodeGzReader.py index 36fcfad01a..86c0af89a2 100644 --- a/plugins/GCodeGzReader/GCodeGzReader.py +++ b/plugins/GCodeGzReader/GCodeGzReader.py @@ -3,7 +3,6 @@ import gzip -from UM.Platform import Platform from UM.Mesh.MeshReader import MeshReader #The class we're extending/implementing. from UM.PluginRegistry import PluginRegistry From 3ea80c7c7cc5bdb8e247776a87820a7da078b39a Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 25 Apr 2018 16:46:20 +0200 Subject: [PATCH 63/83] Compare ints instead of floats for progress check --- plugins/Toolbox/src/Toolbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index fdc089ae2d..d759619b3c 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -485,7 +485,7 @@ class Toolbox(QObject, Extension): if bytes_total > 0: new_progress = bytes_sent / bytes_total * 100 self.setDownloadProgress(new_progress) - if new_progress == 100.0: + if bytes_sent == bytes_total: self.setIsDownloading(False) self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) # must not delete the temporary file on Windows From d79bbe57255576431f07bfa5a993da72672b0353 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 25 Apr 2018 16:47:57 +0200 Subject: [PATCH 64/83] Remove unnecessary check for plugins_showcase models creation Already created in __init__() --- plugins/Toolbox/src/Toolbox.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index d759619b3c..f9ed921604 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -462,9 +462,6 @@ class Toolbox(QObject, Extension): Logger.log("e", "%s", error["title"]) return - # Create packages model with all packages: - if not self._models["plugins_showcase"]: - self._models["plugins_showcase"] = PackagesModel() self._metadata["plugins_showcase"] = json_data["data"] self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"]) self.metadataChanged.emit() From c33710b54b83493fae4af5c37ee40c7ff0034a37 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 25 Apr 2018 17:03:27 +0200 Subject: [PATCH 65/83] CURA-5035 Tile improvements --- .../resources/qml/ToolboxDownloadsGrid.qml | 6 ++-- .../resources/qml/ToolboxDownloadsPage.qml | 9 +++--- .../qml/ToolboxDownloadsShowcaseTile.qml | 30 +++++++++++++++---- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index 8393eb045c..d770b7c74e 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -7,8 +7,6 @@ import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 import UM 1.1 as UM -// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles - Column { height: childrenRect.height @@ -25,14 +23,14 @@ Column GridLayout { id: grid + property var model: toolbox.viewCategory == "material" ? toolbox.authorsModel : toolbox.packagesModel width: parent.width columns: 2 columnSpacing: UM.Theme.getSize("default_margin").height rowSpacing: UM.Theme.getSize("default_margin").width - height: childrenRect.height Repeater { - model: toolbox.viewCategory == "material" ? toolbox.authorsModel : toolbox.packagesModel + model: grid.model delegate: ToolboxDownloadsGridTile { Layout.preferredWidth: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml index f665d5c5f5..170fd10fc7 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsPage.qml @@ -8,32 +8,31 @@ import UM 1.1 as UM ScrollView { - id: page frameVisible: false width: parent.width height: parent.height style: UM.Theme.styles.scrollview Column { - width: page.width + width: parent.width - 2 * padding spacing: UM.Theme.getSize("default_margin").height padding: UM.Theme.getSize("wide_margin").height height: childrenRect.height + 2 * padding ToolboxDownloadsShowcase { id: showcase - width: parent.width - 2 * parent.padding + width: parent.width } Rectangle { color: UM.Theme.getColor("lining") - width: parent.width - 2 * parent.padding + width: parent.width height: UM.Theme.getSize("default_lining").height } ToolboxDownloadsGrid { id: allPlugins - width: parent.width - 2 * parent.padding + width: parent.width } } } diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 57dc16a4b8..1621340184 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -9,7 +9,7 @@ import UM 1.1 as UM Item { width: UM.Theme.getSize("toolbox_thumbnail_large").width - height: UM.Theme.getSize("toolbox_thumbnail_large").width + height: childrenRect.height visible: { if (toolbox.viewCategory == "material" && model.packages_count) @@ -23,9 +23,17 @@ Item } Rectangle { + id: highlight + anchors.fill: parent + opacity: 0.0 + color: UM.Theme.getColor("primary") + } + Rectangle + { + id: thumbnail color: "white" - width: UM.Theme.getSize("toolbox_thumbnail_medium").width - height: UM.Theme.getSize("toolbox_thumbnail_medium").height + width: UM.Theme.getSize("toolbox_thumbnail_large").width + height: UM.Theme.getSize("toolbox_thumbnail_large").height border { width: UM.Theme.getSize("default_lining").width @@ -38,8 +46,8 @@ Item } Image { anchors.centerIn: parent - width: UM.Theme.getSize("toolbox_thumbnail_medium").width - 2 * UM.Theme.getSize("default_margin") - height: UM.Theme.getSize("toolbox_thumbnail_medium").height - 2 * UM.Theme.getSize("default_margin") + width: UM.Theme.getSize("toolbox_thumbnail_large").width - 2 * UM.Theme.getSize("default_margin").width + height: UM.Theme.getSize("toolbox_thumbnail_large").height - 2 * UM.Theme.getSize("default_margin").height fillMode: Image.PreserveAspectFit source: model.icon_url || "../images/logobot.svg" } @@ -56,12 +64,24 @@ Item horizontalAlignment: Text.AlignHCenter height: UM.Theme.getSize("toolbox_heading_label").height width: parent.width + wrapMode: Text.WordWrap color: UM.Theme.getColor("text") font: UM.Theme.getFont("medium_bold") } MouseArea { anchors.fill: parent + hoverEnabled: true + onEntered: + { + thumbnail.border.color = UM.Theme.getColor("primary") + highlight.opacity = 0.1 + } + onExited: + { + thumbnail.border.color = UM.Theme.getColor("lining") + highlight.opacity = 0.0 + } onClicked: { base.selection = model From ec8b95591ea1022b67cbd31209bd38c72edd89e9 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 26 Apr 2018 13:06:30 +0200 Subject: [PATCH 66/83] CURA-5035 Fixed typo --- plugins/Toolbox/src/Toolbox.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index f9ed921604..a39a36f80f 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -188,10 +188,10 @@ class Toolbox(QObject, Extension): # it was never called more than once ever. if self._network_manager: self._network_manager.finished.disconnect(self._onRequestFinished) - self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccesibleChanged) + self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccessibleChanged) self._network_manager = QNetworkAccessManager() self._network_manager.finished.connect(self._onRequestFinished) - self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccesibleChanged) + self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccessibleChanged) # Make remote requests: self._makeRequestByType("packages") @@ -340,7 +340,7 @@ class Toolbox(QObject, Extension): # Handlers for Network Events # -------------------------------------------------------------------------- - def _onNetworkAccesibleChanged(self, accessible: int): + def _onNetworkAccessibleChanged(self, accessible: int): if accessible == 0: self.setDownloadProgress(0) self.setIsDownloading(False) From 332b7fb49787045cb4cedfe7396dfe17c894b4b5 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 26 Apr 2018 13:17:00 +0200 Subject: [PATCH 67/83] CURA-5035 Remove uncessary VersionTools --- cura/Utils/VersionTools.py | 43 -------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 cura/Utils/VersionTools.py diff --git a/cura/Utils/VersionTools.py b/cura/Utils/VersionTools.py deleted file mode 100644 index ab0ac6d813..0000000000 --- a/cura/Utils/VersionTools.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -import re - - -# Regex for checking if a string is a semantic version number -_SEMANTIC_VERSION_REGEX = re.compile(r"^[0-9]+(.[0-9]+)+$") - - -# Checks if the given version string is a valid semantic version number. -def isSemanticVersion(version: str) -> bool: - return _SEMANTIC_VERSION_REGEX.match(version) is not None - - -# Compares the two given semantic version strings and returns: -# -1 if version1 < version2 -# 0 if version1 == version2 -# +1 if version1 > version2 -# Note that this function only works with semantic versions such as "a.b.c..." -def compareSemanticVersions(version1: str, version2: str) -> int: - # Validate the version numbers first - for version in (version1, version2): - if not isSemanticVersion(version): - raise ValueError("Invalid Package version '%s'" % version) - - # Split the version strings into lists of integers - version1_parts = [int(p) for p in version1.split(".")] - version2_parts = [int(p) for p in version2.split(".")] - max_part_length = max(len(version1_parts), len(version2_parts)) - - # Make sure that two versions have the same number of parts. For missing parts, just append 0s. - for parts in (version1_parts, version2_parts): - for _ in range(max_part_length - len(parts)): - parts.append(0) - - # Compare the version parts and return the result - result = 0 - for idx in range(max_part_length): - result = version1_parts[idx] - version2_parts[idx] - if result != 0: - break - return result From 2751299fd32c13b33d152fa512f03345adc0b7dc Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 26 Apr 2018 13:24:15 +0200 Subject: [PATCH 68/83] CURA-5035 Remove un-used `base_unit` in theme --- resources/themes/cura-light/theme.json | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index ce54156e48..ee0b163185 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -321,7 +321,6 @@ }, "sizes": { - "base_unit": [1.0, 1.0], "window_minimum_size": [70, 50], "default_lining": [0.08, 0.08], From 679f87ebb3854982a1927694fd3f63831ab33a81 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Thu, 26 Apr 2018 15:11:32 +0200 Subject: [PATCH 69/83] CURA-5035 Don't show required plugins Also renamed folder of UserAgreementPlugin to UserAgreement --- cura/CuraApplication.py | 32 ++++++++++++------- cura/CuraPackageManager.py | 10 +++++- .../resources/qml/ToolboxDownloadsGrid.qml | 4 ++- plugins/Toolbox/src/Toolbox.py | 16 +--------- .../UserAgreement.py | 0 .../UserAgreement.qml | 0 .../__init__.py | 0 .../plugin.json | 0 8 files changed, 34 insertions(+), 28 deletions(-) rename plugins/{UserAgreementPlugin => UserAgreement}/UserAgreement.py (100%) rename plugins/{UserAgreementPlugin => UserAgreement}/UserAgreement.qml (100%) rename plugins/{UserAgreementPlugin => UserAgreement}/__init__.py (100%) rename plugins/{UserAgreementPlugin => UserAgreement}/plugin.json (100%) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 3f98de554f..a5bcd6a2f0 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -249,8 +249,6 @@ class CuraApplication(QtApplication): self.initialize() - self._cura_package_manager.getAllInstalledPackagesInfo() - # FOR TESTING ONLY if kwargs["parsed_command_line"].get("trigger_early_crash", False): assert not "This crash is triggered by the trigger_early_crash command line argument." @@ -262,21 +260,33 @@ class CuraApplication(QtApplication): self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) self.setRequiredPlugins([ + # Misc.: + "ConsoleLogger", "CuraEngineBackend", "UserAgreement", - "SolidView", - "SimulationView", - "STLReader", - "SelectionTool", - "CameraTool", - "GCodeWriter", - "LocalFileOutputDevice", - "TranslateTool", "FileLogger", "XmlMaterialProfile", "Toolbox", "PrepareStage", - "MonitorStage" + "MonitorStage", + "LocalFileOutputDevice", + + # Views: + "SimpleView", + "SimulationView", + "SolidView", + + # Readers & Writers: + "GCodeWriter", + "STLReader", + + # Tools: + "CameraTool", + "MirrorTool", + "RotateTool", + "ScaleTool", + "SelectionTool", + "TranslateTool" ]) self._physics = None self._volume = None diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 444e7462e8..5f998b4c18 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -10,6 +10,7 @@ import tempfile from PyQt5.QtCore import pyqtSlot, QObject, pyqtSignal +from UM.Application import Application from UM.Logger import Logger from UM.Resources import Resources from UM.Version import Version @@ -102,15 +103,20 @@ class CuraPackageManager(QObject): return None - def getAllInstalledPackagesInfo(self) -> dict: + def getAllInstalledPackagesInfo(self, includeRequired: bool = False) -> dict: installed_package_id_set = set(self._installed_package_dict.keys()) | set(self._to_install_package_dict.keys()) installed_package_id_set = installed_package_id_set.difference(self._to_remove_package_set) managed_package_id_set = set(installed_package_id_set) | self._to_remove_package_set + # TODO: For absolutely no reason, this function seems to run in a loop + # even though no loop is ever called with it. + # map of -> -> installed_packages_dict = {} for package_id in installed_package_id_set: + if package_id in Application.getInstance().getRequiredPlugins(): + continue if package_id in self._to_install_package_dict: package_info = self._to_install_package_dict[package_id]["package_info"] else: @@ -133,6 +139,8 @@ class CuraPackageManager(QObject): package_id = plugin_package_info["package_id"] if package_id in managed_package_id_set: continue + if package_id in Application.getInstance().getRequiredPlugins(): + continue plugin_package_info["is_bundled"] = True if plugin_package_info["author"]["name"] == "Ultimaker B.V." else False plugin_package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index d770b7c74e..a719128a6d 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -9,7 +9,9 @@ import UM 1.1 as UM Column { - height: childrenRect.height + // HACK: GridLayouts don't render to the correct height with odd numbers of + // items, so if odd, add some extra space. + height: grid.model.items.length % 2 == 0 ? childrenRect.height : childrenRect.height + 3 * UM.Theme.getSize("wide_margin").height width: parent.width spacing: UM.Theme.getSize("default_margin").height Label diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index a39a36f80f..d3b0032b51 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -119,11 +119,6 @@ class Toolbox(QObject, Extension): # possible values include "overview", "detail" or "author". self._view_page = "loading" - # View selection defines what is currently selected and should be - # used in filtering. This could be an author name (if _view_page is set - # to "author" or a plugin name if it is set to "detail"). - self._view_selection = None - # Active package refers to which package is currently being downloaded, # installed, or otherwise modified. self._active_package = None @@ -473,7 +468,6 @@ class Toolbox(QObject, Extension): Logger.log("w", "Toolbox: Received invalid JSON for showcase.") return - else: # Ignore any operation that is not a get operation pass @@ -511,6 +505,7 @@ class Toolbox(QObject, Extension): return + # Getter & Setters for Properties: # -------------------------------------------------------------------------- def setDownloadProgress(self, progress: int): @@ -550,15 +545,6 @@ class Toolbox(QObject, Extension): def viewPage(self) -> str: return self._view_page - def setViewSelection(self, selection: dict): - selection.setParent(self) - self._view_selection = selection - self.viewChanged.emit() - @pyqtProperty(QObject, fset = setViewSelection, notify = viewChanged) - def viewSelection(self) -> dict: - print(dir(self._view_selection)) - return self._view_selection - # Expose Models: diff --git a/plugins/UserAgreementPlugin/UserAgreement.py b/plugins/UserAgreement/UserAgreement.py similarity index 100% rename from plugins/UserAgreementPlugin/UserAgreement.py rename to plugins/UserAgreement/UserAgreement.py diff --git a/plugins/UserAgreementPlugin/UserAgreement.qml b/plugins/UserAgreement/UserAgreement.qml similarity index 100% rename from plugins/UserAgreementPlugin/UserAgreement.qml rename to plugins/UserAgreement/UserAgreement.qml diff --git a/plugins/UserAgreementPlugin/__init__.py b/plugins/UserAgreement/__init__.py similarity index 100% rename from plugins/UserAgreementPlugin/__init__.py rename to plugins/UserAgreement/__init__.py diff --git a/plugins/UserAgreementPlugin/plugin.json b/plugins/UserAgreement/plugin.json similarity index 100% rename from plugins/UserAgreementPlugin/plugin.json rename to plugins/UserAgreement/plugin.json From 01007946b49b66e40350abb56fdd1f0bc9794f1d Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 30 Apr 2018 16:42:11 +0200 Subject: [PATCH 70/83] CURA-5035 Separate API calls! --- cura/CuraPackageManager.py | 5 +- .../resources/qml/ToolboxBackColumn.qml | 1 - .../resources/qml/ToolboxDetailList.qml | 5 +- .../resources/qml/ToolboxDetailTile.qml | 89 +++++++- .../qml/ToolboxDownloadsGridTile.qml | 2 +- .../qml/ToolboxDownloadsShowcaseTile.qml | 11 - .../Toolbox/resources/qml/ToolboxHeader.qml | 2 +- plugins/Toolbox/src/AuthorsModel.py | 38 ++-- plugins/Toolbox/src/PackagesModel.py | 22 +- plugins/Toolbox/src/Toolbox.py | 196 ++++++------------ 10 files changed, 185 insertions(+), 186 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 5f998b4c18..5d59cd53ba 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -142,7 +142,7 @@ class CuraPackageManager(QObject): if package_id in Application.getInstance().getRequiredPlugins(): continue - plugin_package_info["is_bundled"] = True if plugin_package_info["author"]["name"] == "Ultimaker B.V." else False + plugin_package_info["is_bundled"] = True if plugin_package_info["author"]["display_name"] == "Ultimaker B.V." else False plugin_package_info["is_active"] = self._plugin_registry.isActivePlugin(package_id) package_type = "plugin" if package_type not in installed_packages_dict: @@ -160,7 +160,8 @@ class CuraPackageManager(QObject): "cura_version": int(plugin_metadata["plugin"]["api"]), "website": "", "author": { - "name": plugin_metadata["plugin"].get("author", ""), + "author_id": plugin_metadata["plugin"].get("author", ""), + "display_name": plugin_metadata["plugin"].get("author", ""), "email": "", "website": "", }, diff --git a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml index 989e065ed4..5c60e368a9 100644 --- a/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml +++ b/plugins/Toolbox/resources/qml/ToolboxBackColumn.qml @@ -48,7 +48,6 @@ Item { toolbox.viewPage = "overview" toolbox.filterModelByProp("packages", "type", toolbox.viewCategory) - toolbox.filterModelByProp("authors", "type", toolbox.viewCategory) } style: ButtonStyle { diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index 7e319974a4..8ac8cee4d0 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -6,10 +6,9 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import UM 1.1 as UM -Rectangle +Item { id: detailList - // color: "green" ScrollView { frameVisible: false @@ -24,6 +23,8 @@ Rectangle bottomMargin: UM.Theme.getSize("wide_margin").height top: parent.top } + // TODO: Sometimes the height is not the childrenRect.height. Lord + // knows why. Probably because QT is garbage. height: childrenRect.height spacing: UM.Theme.getSize("default_margin").height Repeater diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 1080a9213b..5071f8ed81 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -11,9 +11,14 @@ Item id: tile property bool installed: toolbox.isInstalled(model.id) width: detailList.width - UM.Theme.getSize("wide_margin").width - height: UM.Theme.getSize("toolbox_detail_tile").height - Column + // TODO: Without this line, every instance of this object has 0 height. With + // it, QML spits out tons of bugs claiming a binding loop (not true). Why? + // Because QT is garbage. + height: Math.max( UM.Theme.getSize("toolbox_detail_tile").height, childrenRect.height + UM.Theme.getSize("default_margin").height) + Item { + id: normalData + height: childrenRect.height anchors { left: parent.left @@ -23,15 +28,17 @@ Item } Label { + id: packageName width: parent.width height: UM.Theme.getSize("toolbox_property_label").height text: model.name wrapMode: Text.WordWrap color: UM.Theme.getColor("text") - font: UM.Theme.getFont("default_bold") + font: UM.Theme.getFont("medium_bold") } Label { + anchors.top: packageName.bottom width: parent.width text: { @@ -53,13 +60,13 @@ Item font: UM.Theme.getFont("default") } } - Rectangle + Item { id: controls anchors.right: tile.right anchors.top: tile.top width: childrenRect.width - color: "blue" + height: childrenRect.height Button { id: installButton @@ -179,6 +186,78 @@ Item } } } + + Item + { + anchors.top: normalData.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + height: model.type == "material" ? childrenRect.height : 0 + width: normalData.width + visible: model.type == "material" + Label + { + id: compatibilityHeading + anchors.topMargin: UM.Theme.getSize("default_margin").height + width: parent.width + text: catalog.i18nc("@label", "Compatibility") + wrapMode: Text.WordWrap + color: UM.Theme.getColor("text_medium") + font: UM.Theme.getFont("default") + } + Column + { + id: compatibilityLabels + anchors + { + top: compatibilityHeading.bottom + topMargin: UM.Theme.getSize("default_margin").height + bottomMargin: UM.Theme.getSize("default_margin").height + } + width: childrenRect.width + Label + { + text: catalog.i18nc("@label", "Machines") + ":" + font: UM.Theme.getFont("small") + } + Label + { + text: catalog.i18nc("@label", "Print Cores") + ":" + font: UM.Theme.getFont("small") + } + Label + { + text: catalog.i18nc("@label", "Quality Profiles") + ":" + font: UM.Theme.getFont("small") + } + } + Column + { + id: compatibilityValues + anchors + { + left: compatibilityLabels.right + leftMargin: UM.Theme.getSize("default_margin").height + top: compatibilityLabels.top + bottom: compatibilityLabels.bottom + } + Label + { + text: "Thingy" + font: UM.Theme.getFont("very_small") + } + Label + { + text: "Thingy" + font: UM.Theme.getFont("very_small") + } + Label + { + text: "Thingy" + font: UM.Theme.getFont("very_small") + } + } + } + Rectangle { color: UM.Theme.getColor("lining") diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index 4d479278b2..d7b1364a65 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -92,7 +92,7 @@ Item { case "material": toolbox.viewPage = "author" - toolbox.filterModelByProp("packages", "author_name", model.name) + toolbox.filterModelByProp("packages", "author_id", model.id) break default: toolbox.viewPage = "detail" diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml index 1621340184..0a2924c600 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsShowcaseTile.qml @@ -10,17 +10,6 @@ Item { width: UM.Theme.getSize("toolbox_thumbnail_large").width height: childrenRect.height - visible: - { - if (toolbox.viewCategory == "material" && model.packages_count) - { - return model.packages_count > 0 - } - else - { - return true - } - } Rectangle { id: highlight diff --git a/plugins/Toolbox/resources/qml/ToolboxHeader.qml b/plugins/Toolbox/resources/qml/ToolboxHeader.qml index 75740982d9..59dbe23ea4 100644 --- a/plugins/Toolbox/resources/qml/ToolboxHeader.qml +++ b/plugins/Toolbox/resources/qml/ToolboxHeader.qml @@ -38,7 +38,7 @@ Item active: toolbox.viewCategory == "material" onClicked: { - toolbox.filterModelByProp("authors", "type", "material") + toolbox.filterModelByProp("authors", "package_types", "material") toolbox.viewCategory = "material" toolbox.viewPage = "overview" } diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index f61fdbe223..2dfba8fb23 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -15,13 +15,14 @@ class AuthorsModel(ListModel): self._metadata = None - self.addRoleName(Qt.UserRole + 1, "name") - self.addRoleName(Qt.UserRole + 2, "email") - self.addRoleName(Qt.UserRole + 3, "website") - self.addRoleName(Qt.UserRole + 4, "type") - self.addRoleName(Qt.UserRole + 5, "icon_url") - self.addRoleName(Qt.UserRole + 6, "packages_count") - self.addRoleName(Qt.UserRole + 7, "description") + self.addRoleName(Qt.UserRole + 1, "id") + self.addRoleName(Qt.UserRole + 2, "name") + self.addRoleName(Qt.UserRole + 3, "email") + self.addRoleName(Qt.UserRole + 4, "website") + self.addRoleName(Qt.UserRole + 5, "package_count") + self.addRoleName(Qt.UserRole + 6, "package_types") + self.addRoleName(Qt.UserRole + 7, "icon_url") + self.addRoleName(Qt.UserRole + 8, "description") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str,str] @@ -35,21 +36,24 @@ class AuthorsModel(ListModel): for author in self._metadata: items.append({ - "name": author["name"], - "email": author["email"] if "email" in author else None, - "website": author["website"], - "type": author["type"] if "type" in author else None, - "icon_url": author["icon_url"] if "icon_url" in author else None, - "packages_count": author["packages_count"] if "packages_count" in author else 0, - "description": "Material and quality profiles from {author_name}".format( author_name = author["name"]) + "id": author["author_id"], + "name": author["display_name"], + "email": author["email"] if "email" in author else None, + "website": author["website"], + "package_count": author["package_count"] if "package_count" in author else 0, + "package_types": author["package_types"], + "icon_url": author["icon_url"] if "icon_url" in author else None, + "description": "Material and quality profiles from {author_name}".format( author_name = author["display_name"]) }) # Filter on all the key-word arguments. for key, value in self._filter.items(): - if "*" in value: - key_filter = lambda candidate, key = key, value = value: self._matchRegExp(candidate, key, value) + if key is "package_types": + key_filter = lambda item, value = value: value in item["package_types"] + elif "*" in value: + key_filter = lambda item, key = key, value = value: self._matchRegExp(item, key, value) else: - key_filter = lambda candidate, key = key, value = value: self._matchString(candidate, key, value) + key_filter = lambda item, key = key, value = value: self._matchString(item, key, value) items = filter(key_filter, items) # Execute all filters. diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index b030ad895e..f7ee1dd324 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -21,14 +21,15 @@ class PackagesModel(ListModel): self.addRoleName(Qt.UserRole + 2, "type") self.addRoleName(Qt.UserRole + 3, "name") self.addRoleName(Qt.UserRole + 4, "version") - self.addRoleName(Qt.UserRole + 5, "author_name") - self.addRoleName(Qt.UserRole + 6, "author_email") - self.addRoleName(Qt.UserRole + 7, "description") - self.addRoleName(Qt.UserRole + 8, "icon_url") - self.addRoleName(Qt.UserRole + 9, "image_urls") - self.addRoleName(Qt.UserRole + 10, "download_url") - self.addRoleName(Qt.UserRole + 11, "last_updated") - self.addRoleName(Qt.UserRole + 12, "is_bundled") + self.addRoleName(Qt.UserRole + 5, "author_id") + self.addRoleName(Qt.UserRole + 6, "author_name") + self.addRoleName(Qt.UserRole + 7, "author_email") + self.addRoleName(Qt.UserRole + 8, "description") + self.addRoleName(Qt.UserRole + 9, "icon_url") + self.addRoleName(Qt.UserRole + 10, "image_urls") + self.addRoleName(Qt.UserRole + 11, "download_url") + self.addRoleName(Qt.UserRole + 12, "last_updated") + self.addRoleName(Qt.UserRole + 13, "is_bundled") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str, str] @@ -46,8 +47,9 @@ class PackagesModel(ListModel): "type": package["package_type"], "name": package["display_name"], "version": package["package_version"], - "author_name": package["author"]["name"], - "author_email": package["author"]["email"] if "email" in package["author"] else None, + "author_id": package["author"]["author_id"], + "author_name": package["author"]["display_name"], + "author_email": package["author"]["email"] if "email" in package["author"] else "None", "description": package["description"], "icon_url": package["icon_url"] if "icon_url" in package else None, "image_urls": package["image_urls"] if "image_urls" in package else None, diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index d3b0032b51..104d3d323a 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -56,10 +56,10 @@ class Toolbox(QObject, Extension): ) ] self._request_urls = { - "authors": None, - "packages": QUrl("{base_url}/packages".format(base_url = self._api_url)), - "plugins_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)), - "materials_showcase": None + "authors": QUrl("{base_url}/authors".format(base_url = self._api_url)), + "packages": QUrl("{base_url}/packages".format(base_url = self._api_url)), + "plugins_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)), + "materials_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)) } # Data: @@ -68,33 +68,7 @@ class Toolbox(QObject, Extension): "packages": [], "plugins_showcase": [], "plugins_installed": [], - # TODO: Replace this with a proper API call: - "materials_showcase": [ - { - "name": "Ultimaker", - "email": "ian.paschal@gmail.com", - "website": "ultimaker.com", - "type": "material", - "icon": None, - "packages_count": 7 - }, - { - "name": "DSM", - "email": "contact@dsm.nl", - "website": "www.dsm.nl", - "type": "material", - "icon": None, - "packages_count": 0 - }, - { - "name": "BASF", - "email": "contact@basf.de", - "website": "www.basf.de", - "type": "material", - "icon": None, - "packages_count": 0 - } - ], + "materials_showcase": [], "materials_installed": [] } @@ -103,8 +77,10 @@ class Toolbox(QObject, Extension): "authors": AuthorsModel(self), "packages": PackagesModel(self), "plugins_showcase": PackagesModel(self), + "plugins_available": PackagesModel(self), "plugins_installed": PackagesModel(self), "materials_showcase": AuthorsModel(self), + "materials_available": PackagesModel(self), "materials_installed": PackagesModel(self) } @@ -190,7 +166,9 @@ class Toolbox(QObject, Extension): # Make remote requests: self._makeRequestByType("packages") + self._makeRequestByType("authors") self._makeRequestByType("plugins_showcase") + self._makeRequestByType("materials_showcase") # Gather installed packages: self._updateInstalledModels() @@ -298,6 +276,15 @@ class Toolbox(QObject, Extension): return True return False + def loadingComplete(self) -> bool: + populated = 0 + for list in self._metadata.items(): + if len(list) > 0: + populated += 1 + if populated == len(self._metadata.items()): + return True + return False + # Make API Calls @@ -362,111 +349,50 @@ class Toolbox(QObject, Extension): return if reply.operation() == QNetworkAccessManager.GetOperation: - # TODO: In the future use the following to build any model from any - # request. Right now this doesn't work because the packages request - # is also responsible for populating other models. - # for type, url in self._request_urls.items(): - # if reply.url() == url: - # 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 - # self._metadata[type] = json_data["data"] - # self._models[type].setMetadata(self._metadata[type]) - # self.metadataChanged.emit() - # self.setViewPage("overview") - # return - # except json.decoder.JSONDecodeError: - # Logger.log("w", "Toolbox: Received invalid JSON for %s.", type) - # break + 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.url() == self._request_urls["packages"]: - 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._metadata["materials_showcase"] = json_data["data"]["material"]["authors"] + 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 packages model with all packages: - if not self._models["packages"]: - self._models["packages"] = PackagesModel(self) - self._metadata["packages"] = json_data["data"] - self._models["packages"].setMetadata(self._metadata["packages"]) - self.metadataChanged.emit() - - # Create authors model with all authors: - if not self._models["authors"]: - self._models["authors"] = AuthorsModel() - # TODO: Replace this with a proper API call: - for package in self._metadata["packages"]: - if package["author"] not in self._metadata["authors"]: - self._metadata["authors"].append(package["author"]) - - for author in self._metadata["authors"]: - if "package_count" not in author: - author["package_count"] = 0 - - for package in self._metadata["packages"]: - if package["author"]["name"] == author["name"]: - author["package_count"] += 1 - author["type"] = package["package_type"] - if "icon_url" in package: - author["icon_url"] = package["icon_url"] - - self._models["authors"].setMetadata(self._metadata["authors"]) - self.metadataChanged.emit() - - if not self._models["materials_showcase"]: - self._models["materials_showcase"] = AuthorsModel(self) - # TODO: Replace this with a proper API call: - self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"]) - - # This part is also needed for comparing downloaded packages to - # installed packages. - self._models["packages"].setMetadata(self._metadata["packages"]) - self._models["packages"].setFilter({"type": "plugin"}) - - self.metadataChanged.emit() - - self.setViewPage("overview") - return - - except json.decoder.JSONDecodeError: - Logger.log("w", "Toolbox: Received invalid JSON for package list.") - return - - if reply.url() == self._request_urls["plugins_showcase"]: - 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 - - self._metadata["plugins_showcase"] = json_data["data"] - self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"]) - self.metadataChanged.emit() - - self.setViewPage("overview") - return - - except json.decoder.JSONDecodeError: - Logger.log("w", "Toolbox: Received invalid JSON for showcase.") - 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 @@ -531,7 +457,7 @@ class Toolbox(QObject, Extension): def activePackage(self) -> dict: return self._active_package - def setViewCategory(self, category: str = "plugins"): + def setViewCategory(self, category: str = "plugin"): self._view_category = category self.viewChanged.emit() @pyqtProperty(str, fset = setViewCategory, notify = viewChanged) @@ -549,8 +475,6 @@ class Toolbox(QObject, Extension): # Expose Models: # -------------------------------------------------------------------------- - # TODO: Maybe replace this with simply exposing self._models to Qt and then - # setting model: toolbox.models.foobar instead of toolbox.foobarModel @pyqtProperty(QObject, notify = metadataChanged) def authorsModel(self) -> AuthorsModel: return self._models["authors"] From 2d54251be09595937f0e7955131bbf8e2346cab1 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Mon, 30 Apr 2018 17:05:46 +0200 Subject: [PATCH 71/83] CURA-5035 Aproaching the asymptote of done --- .../resources/qml/ToolboxDetailList.qml | 4 +-- .../resources/qml/ToolboxDetailTile.qml | 5 ++-- plugins/Toolbox/src/AuthorsModel.py | 2 +- plugins/Toolbox/src/PackagesModel.py | 28 ++++++++++--------- plugins/Toolbox/src/Toolbox.py | 5 +++- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index 8ac8cee4d0..c49e3cb416 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -23,9 +23,7 @@ Item bottomMargin: UM.Theme.getSize("wide_margin").height top: parent.top } - // TODO: Sometimes the height is not the childrenRect.height. Lord - // knows why. Probably because QT is garbage. - height: childrenRect.height + height: childrenRect.height + UM.Theme.getSize("wide_margin").height spacing: UM.Theme.getSize("default_margin").height Repeater { diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml index 5071f8ed81..768f382082 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailTile.qml @@ -189,11 +189,12 @@ Item Item { + id: supportedConfigsChart anchors.top: normalData.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - height: model.type == "material" ? childrenRect.height : 0 + height: visible ? childrenRect.height : 0 width: normalData.width - visible: model.type == "material" + visible: model.type == "material" && model.supported_configs.length > 0 Label { id: compatibilityHeading diff --git a/plugins/Toolbox/src/AuthorsModel.py b/plugins/Toolbox/src/AuthorsModel.py index 2dfba8fb23..880ecbe2a0 100644 --- a/plugins/Toolbox/src/AuthorsModel.py +++ b/plugins/Toolbox/src/AuthorsModel.py @@ -41,7 +41,7 @@ class AuthorsModel(ListModel): "email": author["email"] if "email" in author else None, "website": author["website"], "package_count": author["package_count"] if "package_count" in author else 0, - "package_types": author["package_types"], + "package_types": author["package_types"] if "package_types" in author else [], "icon_url": author["icon_url"] if "icon_url" in author else None, "description": "Material and quality profiles from {author_name}".format( author_name = author["display_name"]) }) diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index f7ee1dd324..2e8cc1a97f 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -30,6 +30,7 @@ class PackagesModel(ListModel): self.addRoleName(Qt.UserRole + 11, "download_url") self.addRoleName(Qt.UserRole + 12, "last_updated") self.addRoleName(Qt.UserRole + 13, "is_bundled") + self.addRoleName(Qt.UserRole + 14, "supported_configs") # List of filters for queries. The result is the union of the each list of results. self._filter = {} # type: Dict[str, str] @@ -43,19 +44,20 @@ class PackagesModel(ListModel): for package in self._metadata: items.append({ - "id": package["package_id"], - "type": package["package_type"], - "name": package["display_name"], - "version": package["package_version"], - "author_id": package["author"]["author_id"], - "author_name": package["author"]["display_name"], - "author_email": package["author"]["email"] if "email" in package["author"] else "None", - "description": package["description"], - "icon_url": package["icon_url"] if "icon_url" in package else None, - "image_urls": package["image_urls"] if "image_urls" in package else None, - "download_url": package["download_url"] if "download_url" in package else None, - "last_updated": package["last_updated"] if "last_updated" in package else None, - "is_bundled": package["is_bundled"] if "is_bundled" in package else False + "id": package["package_id"], + "type": package["package_type"], + "name": package["display_name"], + "version": package["package_version"], + "author_id": package["author"]["author_id"], + "author_name": package["author"]["display_name"], + "author_email": package["author"]["email"] if "email" in package["author"] else "None", + "description": package["description"], + "icon_url": package["icon_url"] if "icon_url" in package else None, + "image_urls": package["image_urls"] if "image_urls" in package else None, + "download_url": package["download_url"] if "download_url" in package else None, + "last_updated": package["last_updated"] if "last_updated" in package else None, + "is_bundled": package["is_bundled"] if "is_bundled" in package else False, + "supported_configs": package["supported_configs"] if "supported_configs" in package else [] }) # Filter on all the key-word arguments. diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 104d3d323a..234f864015 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -368,14 +368,17 @@ class Toolbox(QObject, Extension): # 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"]) + print("MATERIAL SHOWCASE", 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]) + self._models[type].setMetadata(self._metadata[type]) # Do some auto filtering # TODO: Make multiple API calls in the future to handle this From bb7f9feb5e2b22e7eaf276c6a5903e2aa43e81d7 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 1 May 2018 09:02:24 +0200 Subject: [PATCH 72/83] CURA-5035 Better download resets --- plugins/Toolbox/src/Toolbox.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index 234f864015..f150083fb9 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -294,7 +294,6 @@ class Toolbox(QObject, Extension): request = QNetworkRequest(self._request_urls[type]) request.setRawHeader(*self._request_header) self._network_manager.get(request) - # TODO: Request authors and request material showcase @pyqtSlot(str) def startDownload(self, url: str): @@ -311,6 +310,10 @@ class Toolbox(QObject, Extension): @pyqtSlot() def cancelDownload(self): Logger.log("i", "Toolbox: User cancelled the download of a plugin.") + self.resetDownload(); + return + + def resetDownload(self): self._download_reply.abort() self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) self._download_reply = None @@ -324,24 +327,13 @@ class Toolbox(QObject, Extension): # -------------------------------------------------------------------------- def _onNetworkAccessibleChanged(self, accessible: int): if accessible == 0: - self.setDownloadProgress(0) - self.setIsDownloading(False) - if self._download_reply: - self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) - self._download_reply.abort() - self._download_reply = None + self.resetDownload() def _onRequestFinished(self, reply: QNetworkReply): if reply.error() == QNetworkReply.TimeoutError: Logger.log("w", "Got a timeout.") - # Reset everything. - self.setDownloadProgress(0) - self.setIsDownloading(False) - if self._download_plugin_reply: - self._download_plugin_reply.downloadProgress.disconnect(self._onDownloadProgress) - self._download_plugin_reply.abort() - self._download_plugin_reply = None + self.resetDownload() return if reply.error() == QNetworkReply.HostNotFoundError: From cff4dc8a0cdf32223a56622cc98233f817438fc4 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 1 May 2018 10:28:42 +0200 Subject: [PATCH 73/83] Use json.load() directly --- cura/CuraPackageManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 5d59cd53ba..80da6a8a7f 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -49,7 +49,7 @@ class CuraPackageManager(QObject): return with open(self._package_management_file_path, "r", encoding = "utf-8") as f: - management_dict = json.loads(f.read(), encoding = "utf-8") + management_dict = json.load(f, encoding = "utf-8") self._installed_package_dict = management_dict["installed"] self._to_remove_package_set = set(management_dict["to_remove"]) From 1fb2edace5a8effe440d2541d7d7f5260715ae48 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 1 May 2018 10:31:54 +0200 Subject: [PATCH 74/83] Use ContainerRegistry.lockFile in Cura package management Prevent concurrent I/O issues. --- cura/CuraPackageManager.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 80da6a8a7f..6e9464b266 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -48,23 +48,29 @@ class CuraPackageManager(QObject): Logger.log("i", "Package management file %s doesn't exist, do nothing", self._package_management_file_path) return - with open(self._package_management_file_path, "r", encoding = "utf-8") as f: - management_dict = json.load(f, encoding = "utf-8") + # Need to use the file lock here to prevent concurrent I/O from other processes/threads + container_registry = self._application.getContainerRegistry() + with container_registry.lockFile(): + with open(self._package_management_file_path, "r", encoding = "utf-8") as f: + management_dict = json.load(f, encoding = "utf-8") - self._installed_package_dict = management_dict["installed"] - self._to_remove_package_set = set(management_dict["to_remove"]) - self._to_install_package_dict = management_dict["to_install"] + self._installed_package_dict = management_dict["installed"] + self._to_remove_package_set = set(management_dict["to_remove"]) + self._to_install_package_dict = management_dict["to_install"] - Logger.log("i", "Package management file %s is loaded", self._package_management_file_path) + Logger.log("i", "Package management file %s is loaded", self._package_management_file_path) def _saveManagementData(self) -> None: - with open(self._package_management_file_path, "w", encoding = "utf-8") as f: - data_dict = {"installed": self._installed_package_dict, - "to_remove": list(self._to_remove_package_set), - "to_install": self._to_install_package_dict} - data_dict["to_remove"] = list(data_dict["to_remove"]) - json.dump(data_dict, f) - Logger.log("i", "Package management file %s is saved", self._package_management_file_path) + # Need to use the file lock here to prevent concurrent I/O from other processes/threads + container_registry = self._application.getContainerRegistry() + with container_registry.lockFile(): + with open(self._package_management_file_path, "w", encoding = "utf-8") as f: + data_dict = {"installed": self._installed_package_dict, + "to_remove": list(self._to_remove_package_set), + "to_install": self._to_install_package_dict} + data_dict["to_remove"] = list(data_dict["to_remove"]) + json.dump(data_dict, f) + Logger.log("i", "Package management file %s is saved", self._package_management_file_path) # (for initialize) Removes all packages that have been scheduled to be removed. def _removeAllScheduledPackages(self) -> None: From 51abd32328393dac2b7fdc9f17dbbc9f87530d71 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 1 May 2018 10:33:48 +0200 Subject: [PATCH 75/83] Use dict get fallback to prevent errors --- cura/CuraPackageManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 6e9464b266..c1d85a0101 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -54,9 +54,9 @@ class CuraPackageManager(QObject): with open(self._package_management_file_path, "r", encoding = "utf-8") as f: management_dict = json.load(f, encoding = "utf-8") - self._installed_package_dict = management_dict["installed"] - self._to_remove_package_set = set(management_dict["to_remove"]) - self._to_install_package_dict = management_dict["to_install"] + self._installed_package_dict = management_dict.get("installed", {}) + self._to_remove_package_set = set(management_dict.get("to_remove", [])) + self._to_install_package_dict = management_dict.get("to_install", {}) Logger.log("i", "Package management file %s is loaded", self._package_management_file_path) From 096f304aef94b47b28533e1f2319f8dae8723859 Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Tue, 1 May 2018 10:45:22 +0200 Subject: [PATCH 76/83] CURA-5035 Crash because old packages don't have 'author_id' --- cura/CuraPackageManager.py | 32 ++++++++++--------- .../resources/qml/ToolboxDetailList.qml | 2 +- plugins/Toolbox/src/PackagesModel.py | 5 +-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index c1d85a0101..04ca16219b 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -158,21 +158,23 @@ class CuraPackageManager(QObject): return installed_packages_dict def __convertPluginMetadataToPackageMetadata(self, plugin_metadata: dict) -> dict: - package_metadata = {"package_id": plugin_metadata["id"], - "package_type": "plugin", - "display_name": plugin_metadata["plugin"]["name"], - "description": plugin_metadata["plugin"].get("description"), - "package_version": plugin_metadata["plugin"]["version"], - "cura_version": int(plugin_metadata["plugin"]["api"]), - "website": "", - "author": { - "author_id": plugin_metadata["plugin"].get("author", ""), - "display_name": plugin_metadata["plugin"].get("author", ""), - "email": "", - "website": "", - }, - "tags": ["plugin"], - } + package_metadata = { + "package_id": plugin_metadata["id"], + "package_type": "plugin", + "display_name": plugin_metadata["plugin"]["name"], + "description": plugin_metadata["plugin"].get("description"), + "package_version": plugin_metadata["plugin"]["version"], + "cura_version": int(plugin_metadata["plugin"]["api"]), + "website": "", + "author_id": plugin_metadata["plugin"].get("author", "UnknownID"), + "author": { + "author_id": plugin_metadata["plugin"].get("author", "UnknownID"), + "display_name": plugin_metadata["plugin"].get("author", ""), + "email": "", + "website": "", + }, + "tags": ["plugin"], + } return package_metadata # Checks if the given package is installed. diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index c49e3cb416..f58e484c69 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -23,7 +23,7 @@ Item bottomMargin: UM.Theme.getSize("wide_margin").height top: parent.top } - height: childrenRect.height + UM.Theme.getSize("wide_margin").height + height: childrenRect.height + 2 * UM.Theme.getSize("wide_margin").height spacing: UM.Theme.getSize("default_margin").height Repeater { diff --git a/plugins/Toolbox/src/PackagesModel.py b/plugins/Toolbox/src/PackagesModel.py index 2e8cc1a97f..34ea5b8d42 100644 --- a/plugins/Toolbox/src/PackagesModel.py +++ b/plugins/Toolbox/src/PackagesModel.py @@ -43,13 +43,14 @@ class PackagesModel(ListModel): items = [] for package in self._metadata: + print(package["author"]) items.append({ "id": package["package_id"], "type": package["package_type"], "name": package["display_name"], "version": package["package_version"], - "author_id": package["author"]["author_id"], - "author_name": package["author"]["display_name"], + "author_id": package["author"]["author_id"] if "author_id" in package["author"] else package["author"]["name"], + "author_name": package["author"]["display_name"] if "display_name" in package["author"] else package["author"]["name"], "author_email": package["author"]["email"] if "email" in package["author"] else "None", "description": package["description"], "icon_url": package["icon_url"] if "icon_url" in package else None, From 7ee085fe50b84f4aa1993fcf805e06d3de7e3253 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 1 May 2018 10:47:28 +0200 Subject: [PATCH 77/83] Check all subdirs in data storage dir for package removal --- cura/CuraPackageManager.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 04ca16219b..baf0c153c9 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -245,22 +245,17 @@ class CuraPackageManager(QObject): # Removes everything associated with the given package ID. def _purgePackage(self, package_id: str) -> None: - # Get all folders that need to be checked for installed packages, including: - # - materials - # - qualities - # - plugins - from cura.CuraApplication import CuraApplication - dirs_to_check = [ - Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer), - Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer), - os.path.join(os.path.abspath(Resources.getDataStoragePath()), "plugins"), - ] + # Iterate through all directories in the data storage directory and look for sub-directories that belong to + # the package we need to remove, that is the sub-dirs with the package_id as names, and remove all those dirs. + data_storage_dir = os.path.abspath(Resources.getDataStoragePath()) - for root_dir in dirs_to_check: - package_dir = os.path.join(root_dir, package_id) - if os.path.exists(package_dir): - Logger.log("i", "Removing '%s' for package [%s]", package_dir, package_id) + for root, dir_names, _ in os.walk(data_storage_dir): + for dir_name in dir_names: + package_dir = os.path.join(root, dir_name, package_id) + if os.path.exists(package_dir): + Logger.log("i", "Removing '%s' for package [%s]", package_dir, package_id) shutil.rmtree(package_dir) + break # Installs all files associated with the given package. def _installPackage(self, installation_package_data: dict): From 863d67ae64efac4b9659f7d1e9313a749cabdbeb Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 1 May 2018 11:16:21 +0200 Subject: [PATCH 78/83] Use Resources.Plugins for finding plugin storage path --- cura/CuraPackageManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index baf0c153c9..3fd53437f2 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -284,7 +284,7 @@ class CuraPackageManager(QObject): installation_dirs_dict = { "materials": Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer), "quality": Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer), - "plugins": os.path.join(os.path.abspath(Resources.getDataStoragePath()), "plugins"), + "plugins": os.path.abspath(Resources.getStoragePath(Resources.Plugins)), } for sub_dir_name, installation_root_dir in installation_dirs_dict.items(): From cc207a3f9246a589d5db1be409b776730fbcd77c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 1 May 2018 11:53:52 +0200 Subject: [PATCH 79/83] Clean up unused variables --- cura/CuraPackageManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 3fd53437f2..6772006866 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -109,7 +109,7 @@ class CuraPackageManager(QObject): return None - def getAllInstalledPackagesInfo(self, includeRequired: bool = False) -> dict: + def getAllInstalledPackagesInfo(self) -> dict: installed_package_id_set = set(self._installed_package_dict.keys()) | set(self._to_install_package_dict.keys()) installed_package_id_set = installed_package_id_set.difference(self._to_remove_package_set) From 1d11fe05065cff32d65ec7970a90c519d1d76585 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 2 May 2018 09:31:46 +0200 Subject: [PATCH 80/83] Code style: Spaces around binary operators Contributes to issue CURA-5035. --- plugins/Toolbox/resources/qml/ToolboxDetailPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml index fa1aa8ba23..5a73bcc981 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml @@ -124,11 +124,11 @@ Item { if (details.author_email) { - return ""+details.author_name+"" + return "" + details.author_name + "" } else { - return ""+details.author_name+"" + return "" + details.author_name + "" } } font: UM.Theme.getFont("very_small") From 3934f6f1b366379c1fbbe5aa77123220e8094ea8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 2 May 2018 10:27:35 +0200 Subject: [PATCH 81/83] Small code style issues Contributes to issue CURA-5035. --- plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml | 4 ++-- plugins/Toolbox/resources/qml/ToolboxTabButton.qml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml index e8c9a17eba..538b0a9131 100644 --- a/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxInstalledTile.qml @@ -75,7 +75,7 @@ Item { if (model.author_email) { - return ""+model.author_name+"" + return "" + model.author_name + "" } else { @@ -87,7 +87,7 @@ Item wrapMode: Text.WordWrap verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignLeft - onLinkActivated: Qt.openUrlExternally("mailto:"+model.author_email+"?Subject=Cura: "+model.name+" Plugin") + onLinkActivated: Qt.openUrlExternally("mailto:" + model.author_email + "?Subject=Cura: " + model.name + " Plugin") color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining") } } diff --git a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml index 6991817ff5..a61e77d241 100644 --- a/plugins/Toolbox/resources/qml/ToolboxTabButton.qml +++ b/plugins/Toolbox/resources/qml/ToolboxTabButton.qml @@ -30,11 +30,11 @@ Button text: control.text color: { - if( control.hovered ) + if(control.hovered) { return UM.Theme.getColor("topbar_button_text_hovered"); } - if( control.active ) + if(control.active) { return UM.Theme.getColor("topbar_button_text_active"); } From 62aeb6c9541101740206176eb82b3568a43fbf7b Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 2 May 2018 12:01:29 +0200 Subject: [PATCH 82/83] CURA-5035 Review feedback --- cura/CuraPackageManager.py | 2 +- .../resources/qml/ToolboxDetailList.qml | 2 +- .../resources/qml/ToolboxDownloadsGrid.qml | 2 +- .../Toolbox/resources/qml/ToolboxFooter.qml | 4 +- .../resources/qml/ToolboxLicenseDialog.qml | 2 +- .../resources/qml/ToolboxLoadingPage.qml | 2 +- plugins/Toolbox/src/Toolbox.py | 4 +- .../um_s5_global_Normal_Quality.inst.cfg | 14 ------- resources/variants/ultimaker_s5_aa04.inst.cfg | 42 ------------------- .../variants/ultimaker_s5_glass.inst.cfg | 13 ------ 10 files changed, 9 insertions(+), 78 deletions(-) delete mode 100644 resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg delete mode 100644 resources/variants/ultimaker_s5_aa04.inst.cfg delete mode 100644 resources/variants/ultimaker_s5_glass.inst.cfg diff --git a/cura/CuraPackageManager.py b/cura/CuraPackageManager.py index 6772006866..e90b776e28 100644 --- a/cura/CuraPackageManager.py +++ b/cura/CuraPackageManager.py @@ -254,7 +254,7 @@ class CuraPackageManager(QObject): package_dir = os.path.join(root, dir_name, package_id) if os.path.exists(package_dir): Logger.log("i", "Removing '%s' for package [%s]", package_dir, package_id) - shutil.rmtree(package_dir) + shutil.rmtree(package_dir) break # Installs all files associated with the given package. diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml index f58e484c69..f4d6bf5458 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDetailList.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDetailList.qml @@ -18,7 +18,7 @@ Item { anchors { - right: detailList.right + right: parent.right topMargin: UM.Theme.getSize("wide_margin").height bottomMargin: UM.Theme.getSize("wide_margin").height top: parent.top diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml index a719128a6d..12578d15f6 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGrid.qml @@ -11,7 +11,7 @@ Column { // HACK: GridLayouts don't render to the correct height with odd numbers of // items, so if odd, add some extra space. - height: grid.model.items.length % 2 == 0 ? childrenRect.height : childrenRect.height + 3 * UM.Theme.getSize("wide_margin").height + height: grid.model.items.length % 2 == 0 ? childrenRect.height : childrenRect.height + UM.Theme.getSize("toolbox_thumbnail_small").height width: parent.width spacing: UM.Theme.getSize("default_margin").height Label diff --git a/plugins/Toolbox/resources/qml/ToolboxFooter.qml b/plugins/Toolbox/resources/qml/ToolboxFooter.qml index 65161634d6..098a52d49a 100644 --- a/plugins/Toolbox/resources/qml/ToolboxFooter.qml +++ b/plugins/Toolbox/resources/qml/ToolboxFooter.qml @@ -15,7 +15,7 @@ Item Label { visible: toolbox.restartRequired - text: "You will need to restart Cura before changes in plugins have effect." + text: catalog.i18nc("@info", "You will need to restart Cura before changes in plugins have effect.") height: Math.floor(UM.Theme.getSize("toolbox_footer_button").height) verticalAlignment: Text.AlignVCenter anchors @@ -30,7 +30,7 @@ Item Button { id: restartButton - text: "Quit Cura" + text: catalog.i18nc("@info:button", "Quit Cura") anchors { top: parent.top diff --git a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml index 655edc9447..33bc466d29 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLicenseDialog.qml @@ -42,7 +42,7 @@ UM.Dialog anchors.right: parent.right anchors.topMargin: UM.Theme.getSize("default_margin").height readOnly: true - text: licenseDialog.licenseContent != null ? licenseDialog.licenseContent : "" + text: licenseDialog.licenseContent } } rightButtons: diff --git a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml index fc712e83e1..1ba271dcab 100644 --- a/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml +++ b/plugins/Toolbox/resources/qml/ToolboxLoadingPage.qml @@ -13,7 +13,7 @@ Rectangle color: "transparent" Label { - text: "Fetching packages..." + text: catalog.i18nc("@info", "Fetching packages...") anchors { centerIn: parent diff --git a/plugins/Toolbox/src/Toolbox.py b/plugins/Toolbox/src/Toolbox.py index f150083fb9..2e2fb3cbb8 100644 --- a/plugins/Toolbox/src/Toolbox.py +++ b/plugins/Toolbox/src/Toolbox.py @@ -310,7 +310,7 @@ class Toolbox(QObject, Extension): @pyqtSlot() def cancelDownload(self): Logger.log("i", "Toolbox: User cancelled the download of a plugin.") - self.resetDownload(); + self.resetDownload() return def resetDownload(self): @@ -338,6 +338,7 @@ class Toolbox(QObject, Extension): if reply.error() == QNetworkReply.HostNotFoundError: Logger.log("w", "Unable to reach server.") + self.resetDownload() return if reply.operation() == QNetworkAccessManager.GetOperation: @@ -363,7 +364,6 @@ class Toolbox(QObject, Extension): 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"]) - print("MATERIAL SHOWCASE", self._metadata["materials_showcase"]) else: # ...until here. # This hack arises for multiple reasons but the main diff --git a/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg deleted file mode 100644 index ecc31f22de..0000000000 --- a/resources/quality/ultimaker_s5/um_s5_global_Normal_Quality.inst.cfg +++ /dev/null @@ -1,14 +0,0 @@ -[general] -version = 3 -name = Fine -definition = ultimaker_s5 - -[metadata] -setting_version = 4 -type = quality -quality_type = normal -weight = 0 -global_quality = True - -[values] -layer_height = 0.1 diff --git a/resources/variants/ultimaker_s5_aa04.inst.cfg b/resources/variants/ultimaker_s5_aa04.inst.cfg deleted file mode 100644 index 2984695985..0000000000 --- a/resources/variants/ultimaker_s5_aa04.inst.cfg +++ /dev/null @@ -1,42 +0,0 @@ -[general] -name = AA 0.4 -version = 3 -definition = ultimaker_s5 - -[metadata] -setting_version = 4 -type = variant -hardware_type = nozzle - -[values] -brim_width = 7 -machine_nozzle_cool_down_speed = 0.9 -machine_nozzle_id = AA 0.4 -machine_nozzle_tip_outer_diameter = 1.0 -raft_acceleration = =acceleration_print -raft_airgap = 0.3 -raft_base_thickness = =resolveOrValue('layer_height_0') * 1.2 -raft_interface_line_spacing = =raft_interface_line_width + 0.2 -raft_interface_line_width = =line_width * 2 -raft_interface_thickness = =layer_height * 1.5 -raft_jerk = =jerk_print -raft_margin = 15 -raft_surface_layers = 2 -retraction_amount = 6.5 -retraction_count_max = 25 -retraction_min_travel = =line_width * 2 -retraction_prime_speed = =retraction_speed -skin_overlap = 15 -speed_print = 70 -speed_topbottom = =math.ceil(speed_print * 30 / 70) -speed_wall = =math.ceil(speed_print * 30 / 70) -support_angle = 60 -support_bottom_distance = =support_z_distance / 2 -support_pattern = zigzag -support_top_distance = =support_z_distance -support_use_towers = True -support_z_distance = =layer_height * 2 -switch_extruder_prime_speed = =switch_extruder_retraction_speeds -switch_extruder_retraction_amount = =machine_heat_zone_length -top_bottom_thickness = 1.2 -wall_thickness = 1.3 diff --git a/resources/variants/ultimaker_s5_glass.inst.cfg b/resources/variants/ultimaker_s5_glass.inst.cfg deleted file mode 100644 index 49e032d387..0000000000 --- a/resources/variants/ultimaker_s5_glass.inst.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[general] -name = Glass -version = 3 -definition = ultimaker_s5 - -[metadata] -setting_version = 4 -type = variant -hardware_type = buildplate - -[values] -material_bed_temperature = =default_material_bed_temperature -machine_buildplate_type = glass From c2ed2a47e7ec9e4ef72de9c411a369a10173a8ee Mon Sep 17 00:00:00 2001 From: Ian Paschal Date: Wed, 2 May 2018 12:05:34 +0200 Subject: [PATCH 83/83] CURA-5035 Use elide for text clipping --- .../resources/qml/ToolboxDownloadsGridTile.qml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml index d7b1364a65..e0e25982db 100644 --- a/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml +++ b/plugins/Toolbox/resources/qml/ToolboxDownloadsGridTile.qml @@ -56,14 +56,9 @@ Item Label { id: info - text: - { - if (model.description.length > 50) - { - return model.description.substring(0, 50) + "..." - } - return model.description - } + text: model.description + maximumLineCount: 2 + elide: Text.ElideRight width: parent.width wrapMode: Text.WordWrap color: UM.Theme.getColor("text_medium")