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