Merge remote-tracking branch 'origin/master' into CURA-6959_collapse_categories

# Conflicts:
#	resources/qml/Menus/SettingVisibilityPresetsMenu.qml
#	resources/qml/Settings/SettingView.qml
This commit is contained in:
Nino van Hooff 2020-01-02 15:32:26 +01:00
commit 8dbd67f5bd
16 changed files with 313 additions and 80 deletions

View File

@ -77,6 +77,10 @@ class SettingVisibilityPresetsModel(QObject):
items.append(setting_visibility_preset) items.append(setting_visibility_preset)
# Add the "all" visibility:
all_setting_visibility_preset = SettingVisibilityPreset(preset_id = "all", name = "All", weight = 9001)
all_setting_visibility_preset.setSettings(list(CuraApplication.getInstance().getMachineManager().getAllSettingKeys()))
items.append(all_setting_visibility_preset)
# Sort them on weight (and if that fails, use ID) # Sort them on weight (and if that fails, use ID)
items.sort(key = lambda k: (int(k.weight), k.presetId)) items.sort(key = lambda k: (int(k.weight), k.presetId))

View File

@ -4,12 +4,11 @@
import time import time
import re import re
import unicodedata import unicodedata
from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast, Set
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
from UM.Decorators import deprecated
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.Interfaces import ContainerInterface from UM.Settings.Interfaces import ContainerInterface
@ -212,10 +211,13 @@ class MachineManager(QObject):
@pyqtProperty(int, constant=True) @pyqtProperty(int, constant=True)
def totalNumberOfSettings(self) -> int: def totalNumberOfSettings(self) -> int:
general_definition_containers = CuraContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter") return len(self.getAllSettingKeys())
def getAllSettingKeys(self) -> Set[str]:
general_definition_containers = CuraContainerRegistry.getInstance().findDefinitionContainers(id="fdmprinter")
if not general_definition_containers: if not general_definition_containers:
return 0 return set()
return len(general_definition_containers[0].getAllKeys()) return general_definition_containers[0].getAllKeys()
## Triggered when the global container stack is changed in CuraApplication. ## Triggered when the global container stack is changed in CuraApplication.
def _onGlobalContainerChanged(self) -> None: def _onGlobalContainerChanged(self) -> None:

View File

@ -292,6 +292,7 @@ class SimulationView(CuraView):
# #
# \param layer_view_type integer as in SimulationView.qml and this class # \param layer_view_type integer as in SimulationView.qml and this class
def setSimulationViewType(self, layer_view_type: int) -> None: def setSimulationViewType(self, layer_view_type: int) -> None:
if layer_view_type != self._layer_view_type:
self._layer_view_type = layer_view_type self._layer_view_type = layer_view_type
self.currentLayerNumChanged.emit() self.currentLayerNumChanged.emit()
@ -571,6 +572,8 @@ class SimulationView(CuraView):
def _onCurrentLayerNumChanged(self) -> None: def _onCurrentLayerNumChanged(self) -> None:
self.calculateMaxPathsOnLayer(self._current_layer_num) self.calculateMaxPathsOnLayer(self._current_layer_num)
scene = Application.getInstance().getController().getScene()
scene.sceneChanged.emit(scene.getRoot())
def _startUpdateTopLayers(self) -> None: def _startUpdateTopLayers(self) -> None:
if not self._compatibility_mode: if not self._compatibility_mode:

View File

@ -149,6 +149,9 @@ class SimulationViewProxy(QObject):
self.currentPathChanged.emit() self.currentPathChanged.emit()
self._layerActivityChanged() self._layerActivityChanged()
scene = Application.getInstance().getController().getScene()
scene.sceneChanged.emit(scene.getRoot())
def _onMaxLayersChanged(self): def _onMaxLayersChanged(self):
self.maxLayersChanged.emit() self.maxLayersChanged.emit()

View File

@ -0,0 +1,142 @@
// Copyright (c) 2020 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
import UM 1.1 as UM
import Cura 1.6 as Cura
UM.Dialog{
visible: true
title: catalog.i18nc("@title", "Changes from your account")
width: UM.Theme.getSize("popup_dialog").width
height: UM.Theme.getSize("popup_dialog").height
minimumWidth: width
maximumWidth: minimumWidth
minimumHeight: height
maximumHeight: minimumHeight
margin: 0
Rectangle
{
id: root
anchors.fill: parent
color: UM.Theme.getColor("main_background")
UM.I18nCatalog
{
id: catalog
name: "cura"
}
ScrollView
{
width: parent.width
height: parent.height - nextButton.height - nextButton.anchors.margins * 2 // We want some leftover space for the button at the bottom
clip: true
Column
{
anchors.fill: parent
anchors.margins: UM.Theme.getSize("default_margin").width
// Compatible packages
Label
{
font: UM.Theme.getFont("default")
text: catalog.i18nc("@label", "The following packages will be added:")
color: UM.Theme.getColor("text")
height: contentHeight + UM.Theme.getSize("default_margin").height
}
Repeater
{
model: toolbox.subscribedPackagesModel
Component
{
Item
{
width: parent.width
property var lineHeight: 60
visible: model.is_compatible == "True" ? true : false
height: visible ? (lineHeight + UM.Theme.getSize("default_margin").height) : 0 // We only show the compatible packages here
Image
{
id: packageIcon
source: model.icon_url || "../../images/logobot.svg"
height: lineHeight
width: height
mipmap: true
fillMode: Image.PreserveAspectFit
}
Label
{
text: model.name
font: UM.Theme.getFont("medium_bold")
anchors.left: packageIcon.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: packageIcon.verticalCenter
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
}
}
}
// Incompatible packages
Label
{
font: UM.Theme.getFont("default")
text: catalog.i18nc("@label", "The following packages can not be installed because of incompatible Cura version:")
color: UM.Theme.getColor("text")
height: contentHeight + UM.Theme.getSize("default_margin").height
}
Repeater
{
model: toolbox.subscribedPackagesModel
Component
{
Item
{
width: parent.width
property var lineHeight: 60
visible: model.is_compatible == "True" ? false : true
height: visible ? (lineHeight + UM.Theme.getSize("default_margin").height) : 0 // We only show the incompatible packages here
Image
{
id: packageIcon
source: model.icon_url || "../../images/logobot.svg"
height: lineHeight
width: height
mipmap: true
fillMode: Image.PreserveAspectFit
}
Label
{
text: model.name
font: UM.Theme.getFont("medium_bold")
anchors.left: packageIcon.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: packageIcon.verticalCenter
color: UM.Theme.getColor("text")
elide: Text.ElideRight
}
}
}
}
}
} // End of ScrollView
Cura.ActionButton
{
id: nextButton
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.margins: UM.Theme.getSize("default_margin").height
text: catalog.i18nc("@button", "Next")
}
}
}

View File

@ -0,0 +1,46 @@
# Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt
from UM.Qt.ListModel import ListModel
from cura import ApplicationMetadata
class SubscribedPackagesModel(ListModel):
def __init__(self, parent = None):
super().__init__(parent)
self._metadata = None
self._discrepancies = None
self._sdk_version = ApplicationMetadata.CuraSDKVersion
self.addRoleName(Qt.UserRole + 1, "name")
self.addRoleName(Qt.UserRole + 2, "icon_url")
self.addRoleName(Qt.UserRole + 3, "is_compatible")
def setMetadata(self, data):
if self._metadata != data:
self._metadata = data
def addValue(self, discrepancy):
if self._discrepancies != discrepancy:
self._discrepancies = discrepancy
def update(self):
items = []
for item in self._metadata:
if item["package_id"] not in self._discrepancies:
continue
package = {"name": item["display_name"], "sdk_versions": item["sdk_versions"]}
if self._sdk_version not in item["sdk_versions"]:
package.update({"is_compatible": "False"})
else:
package.update({"is_compatible": "True"})
try:
package.update({"icon_url": item["icon_url"]})
except KeyError: # There is no 'icon_url" in the response payload for this package
package.update({"icon_url": ""})
items.append(package)
self.setItems(items)

View File

@ -15,6 +15,7 @@ from UM.PluginRegistry import PluginRegistry
from UM.Extension import Extension from UM.Extension import Extension
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Version import Version from UM.Version import Version
from UM.Message import Message
from cura import ApplicationMetadata from cura import ApplicationMetadata
from cura import UltimakerCloudAuthentication from cura import UltimakerCloudAuthentication
@ -23,6 +24,7 @@ from cura.Machines.ContainerTree import ContainerTree
from .AuthorsModel import AuthorsModel from .AuthorsModel import AuthorsModel
from .PackagesModel import PackagesModel from .PackagesModel import PackagesModel
from .SubscribedPackagesModel import SubscribedPackagesModel
if TYPE_CHECKING: if TYPE_CHECKING:
from cura.Settings.GlobalStack import GlobalStack from cura.Settings.GlobalStack import GlobalStack
@ -61,6 +63,7 @@ class Toolbox(QObject, Extension):
"authors": [], "authors": [],
"packages": [], "packages": [],
"updates": [], "updates": [],
"subscribed_packages": [],
} # type: Dict[str, List[Any]] } # type: Dict[str, List[Any]]
# Models: # Models:
@ -68,7 +71,8 @@ class Toolbox(QObject, Extension):
"authors": AuthorsModel(self), "authors": AuthorsModel(self),
"packages": PackagesModel(self), "packages": PackagesModel(self),
"updates": PackagesModel(self), "updates": PackagesModel(self),
} # type: Dict[str, Union[AuthorsModel, PackagesModel]] "subscribed_packages": SubscribedPackagesModel(self),
} # type: Dict[str, Union[AuthorsModel, PackagesModel, SubscribedPackagesModel]]
self._plugins_showcase_model = PackagesModel(self) self._plugins_showcase_model = PackagesModel(self)
self._plugins_available_model = PackagesModel(self) self._plugins_available_model = PackagesModel(self)
@ -161,7 +165,7 @@ class Toolbox(QObject, Extension):
@pyqtSlot(str, int) @pyqtSlot(str, int)
def ratePackage(self, package_id: str, rating: int) -> None: def ratePackage(self, package_id: str, rating: int) -> None:
url = QUrl("{base_url}/packages/{package_id}/ratings".format(base_url=self._api_url, package_id = package_id)) url = QUrl("{base_url}/packages/{package_id}/ratings".format(base_url = self._api_url, package_id = package_id))
self._rate_request = QNetworkRequest(url) self._rate_request = QNetworkRequest(url)
for header_name, header_value in self._request_headers: for header_name, header_value in self._request_headers:
@ -197,6 +201,11 @@ class Toolbox(QObject, Extension):
cloud_api_version = self._cloud_api_version, cloud_api_version = self._cloud_api_version,
sdk_version = self._sdk_version sdk_version = self._sdk_version
) )
# https://api.ultimaker.com/cura-packages/v1/user/packages
self._api_url_user_packages = "{cloud_api_root}/cura-packages/v{cloud_api_version}/user/packages".format(
cloud_api_root = self._cloud_api_root,
cloud_api_version = self._cloud_api_version,
)
# We need to construct a query like installed_packages=ID:VERSION&installed_packages=ID:VERSION, etc. # We need to construct a query like installed_packages=ID:VERSION&installed_packages=ID:VERSION, etc.
installed_package_ids_with_versions = [":".join(items) for items in installed_package_ids_with_versions = [":".join(items) for items in
@ -207,15 +216,18 @@ class Toolbox(QObject, Extension):
"authors": QUrl("{base_url}/authors".format(base_url = self._api_url)), "authors": QUrl("{base_url}/authors".format(base_url = self._api_url)),
"packages": QUrl("{base_url}/packages".format(base_url = self._api_url)), "packages": QUrl("{base_url}/packages".format(base_url = self._api_url)),
"updates": QUrl("{base_url}/packages/package-updates?installed_packages={query}".format( "updates": QUrl("{base_url}/packages/package-updates?installed_packages={query}".format(
base_url = self._api_url, query = installed_packages_query)) base_url = self._api_url, query = installed_packages_query)),
"subscribed_packages": QUrl(self._api_url_user_packages)
} }
self._application.getCuraAPI().account.loginStateChanged.connect(self._restart) self._application.getCuraAPI().account.loginStateChanged.connect(self._restart)
self._application.getCuraAPI().account.loginStateChanged.connect(self._fetchUserSubscribedPackages)
# On boot we check which packages have updates. # On boot we check which packages have updates.
if CuraApplication.getInstance().getPreferences().getValue("info/automatic_update_check") and len(installed_package_ids_with_versions) > 0: if CuraApplication.getInstance().getPreferences().getValue("info/automatic_update_check") and len(installed_package_ids_with_versions) > 0:
# Request the latest and greatest! # Request the latest and greatest!
self._fetchPackageUpdates() self._fetchPackageUpdates()
self._fetchUserSubscribedPackages()
def _prepareNetworkManager(self): def _prepareNetworkManager(self):
if self._network_manager is not None: if self._network_manager is not None:
@ -237,6 +249,11 @@ class Toolbox(QObject, Extension):
# Gather installed packages: # Gather installed packages:
self._updateInstalledModels() self._updateInstalledModels()
def _fetchUserSubscribedPackages(self):
if self._application.getCuraAPI().account.isLoggedIn:
self._prepareNetworkManager()
self._makeRequestByType("subscribed_packages")
# Displays the toolbox # Displays the toolbox
@pyqtSlot() @pyqtSlot()
def launch(self) -> None: def launch(self) -> None:
@ -540,9 +557,7 @@ class Toolbox(QObject, Extension):
@pyqtSlot(str, result = bool) @pyqtSlot(str, result = bool)
def isEnabled(self, package_id: str) -> bool: def isEnabled(self, package_id: str) -> bool:
if package_id in self._plugin_registry.getActivePlugins(): return package_id in self._plugin_registry.getActivePlugins()
return True
return False
# Check for plugins that were installed with the old plugin browser # Check for plugins that were installed with the old plugin browser
def isOldPlugin(self, plugin_id: str) -> bool: def isOldPlugin(self, plugin_id: str) -> bool:
@ -561,10 +576,11 @@ class Toolbox(QObject, Extension):
# Make API Calls # Make API Calls
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
def _makeRequestByType(self, request_type: str) -> None: def _makeRequestByType(self, request_type: str) -> None:
Logger.log("d", "Requesting %s metadata from server.", request_type) Logger.log("d", "Requesting '%s' metadata from server.", request_type)
request = QNetworkRequest(self._request_urls[request_type]) request = QNetworkRequest(self._request_urls[request_type])
for header_name, header_value in self._request_headers: for header_name, header_value in self._request_headers:
request.setRawHeader(header_name, header_value) request.setRawHeader(header_name, header_value)
self._updateRequestHeader()
if self._network_manager: if self._network_manager:
self._network_manager.get(request) self._network_manager.get(request)
@ -661,6 +677,8 @@ class Toolbox(QObject, Extension):
# Tell the package manager that there's a new set of updates available. # Tell the package manager that there's a new set of updates available.
packages = set([pkg["package_id"] for pkg in self._server_response_data[response_type]]) packages = set([pkg["package_id"] for pkg in self._server_response_data[response_type]])
self._package_manager.setPackagesWithUpdate(packages) self._package_manager.setPackagesWithUpdate(packages)
elif response_type == "subscribed_packages":
self._checkCompatibilities(json_data["data"])
self.metadataChanged.emit() self.metadataChanged.emit()
@ -674,9 +692,38 @@ class Toolbox(QObject, Extension):
Logger.log("w", "Unable to connect with the server, we got a response code %s while trying to connect to %s", reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url()) Logger.log("w", "Unable to connect with the server, we got a response code %s while trying to connect to %s", reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url())
self.setViewPage("errored") self.setViewPage("errored")
self.resetDownload() self.resetDownload()
elif reply.operation() == QNetworkAccessManager.PutOperation:
# Ignore any operation that is not a get operation def _checkCompatibilities(self, json_data) -> None:
pass user_subscribed_packages = [plugin["package_id"] for plugin in json_data]
user_installed_packages = self._package_manager.getUserInstalledPackages()
# We check if there are packages installed in Cloud Marketplace but not in Cura marketplace (discrepancy)
package_discrepancy = list(set(user_subscribed_packages).difference(user_installed_packages))
if package_discrepancy:
self._models["subscribed_packages"].addValue(package_discrepancy)
self._models["subscribed_packages"].update()
Logger.log("d", "Discrepancy found between Cloud subscribed packages and Cura installed packages")
sync_message = Message(i18n_catalog.i18nc(
"@info:generic",
"\nDo you want to sync material and software packages with your account?"),
lifetime=0,
title=i18n_catalog.i18nc("@info:title", "Changes detected from your Ultimaker account", ))
sync_message.addAction("sync",
name=i18n_catalog.i18nc("@action:button", "Sync"),
icon="",
description="Sync your Cloud subscribed packages to your local environment.",
button_align=Message.ActionButtonAlignment.ALIGN_RIGHT)
sync_message.actionTriggered.connect(self._onSyncButtonClicked)
sync_message.show()
def _onSyncButtonClicked(self, sync_message: Message, sync_message_action: str) -> None:
sync_message.hide()
compatibility_dialog_path = "resources/qml/dialogs/CompatibilityDialog.qml"
plugin_path_prefix = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
if plugin_path_prefix:
path = os.path.join(plugin_path_prefix, compatibility_dialog_path)
self.compatibility_dialog_view = self._application.getInstance().createQmlComponent(path, {"toolbox": self})
# This function goes through all known remote versions of a package and notifies the package manager of this change # This function goes through all known remote versions of a package and notifies the package manager of this change
def _notifyPackageManager(self): def _notifyPackageManager(self):
@ -772,39 +819,43 @@ class Toolbox(QObject, Extension):
# Exposed Models: # Exposed Models:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
@pyqtProperty(QObject, constant=True) @pyqtProperty(QObject, constant = True)
def authorsModel(self) -> AuthorsModel: def authorsModel(self) -> AuthorsModel:
return cast(AuthorsModel, self._models["authors"]) return cast(AuthorsModel, self._models["authors"])
@pyqtProperty(QObject, constant=True) @pyqtProperty(QObject, constant = True)
def subscribedPackagesModel(self) -> SubscribedPackagesModel:
return cast(SubscribedPackagesModel, self._models["subscribed_packages"])
@pyqtProperty(QObject, constant = True)
def packagesModel(self) -> PackagesModel: def packagesModel(self) -> PackagesModel:
return cast(PackagesModel, self._models["packages"]) return cast(PackagesModel, self._models["packages"])
@pyqtProperty(QObject, constant=True) @pyqtProperty(QObject, constant = True)
def pluginsShowcaseModel(self) -> PackagesModel: def pluginsShowcaseModel(self) -> PackagesModel:
return self._plugins_showcase_model return self._plugins_showcase_model
@pyqtProperty(QObject, constant=True) @pyqtProperty(QObject, constant = True)
def pluginsAvailableModel(self) -> PackagesModel: def pluginsAvailableModel(self) -> PackagesModel:
return self._plugins_available_model return self._plugins_available_model
@pyqtProperty(QObject, constant=True) @pyqtProperty(QObject, constant = True)
def pluginsInstalledModel(self) -> PackagesModel: def pluginsInstalledModel(self) -> PackagesModel:
return self._plugins_installed_model return self._plugins_installed_model
@pyqtProperty(QObject, constant=True) @pyqtProperty(QObject, constant = True)
def materialsShowcaseModel(self) -> AuthorsModel: def materialsShowcaseModel(self) -> AuthorsModel:
return self._materials_showcase_model return self._materials_showcase_model
@pyqtProperty(QObject, constant=True) @pyqtProperty(QObject, constant = True)
def materialsAvailableModel(self) -> AuthorsModel: def materialsAvailableModel(self) -> AuthorsModel:
return self._materials_available_model return self._materials_available_model
@pyqtProperty(QObject, constant=True) @pyqtProperty(QObject, constant = True)
def materialsInstalledModel(self) -> PackagesModel: def materialsInstalledModel(self) -> PackagesModel:
return self._materials_installed_model return self._materials_installed_model
@pyqtProperty(QObject, constant=True) @pyqtProperty(QObject, constant = True)
def materialsGenericModel(self) -> PackagesModel: def materialsGenericModel(self) -> PackagesModel:
return self._materials_generic_model return self._materials_generic_model

View File

@ -7650,7 +7650,7 @@
"default_value": 50, "default_value": 50,
"minimum_value": "1", "minimum_value": "1",
"minimum_value_warning": "25", "minimum_value_warning": "25",
"maximum_value": "100", "maximum_value_warning": "100",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"small_feature_speed_factor_0": "small_feature_speed_factor_0":
@ -7663,7 +7663,7 @@
"value": "small_feature_speed_factor", "value": "small_feature_speed_factor",
"minimum_value": "1", "minimum_value": "1",
"minimum_value_warning": "25", "minimum_value_warning": "25",
"maximum_value": "100", "maximum_value_warning": "100",
"settable_per_mesh": true "settable_per_mesh": true
} }
} }

View File

@ -14,7 +14,6 @@ Menu
property QtObject settingVisibilityPresetsModel: CuraApplication.getSettingVisibilityPresetsModel() property QtObject settingVisibilityPresetsModel: CuraApplication.getSettingVisibilityPresetsModel()
signal showAllSettings()
signal collapseAllCategories() signal collapseAllCategories()
Instantiator Instantiator
@ -37,17 +36,6 @@ Menu
onObjectRemoved: menu.removeItem(object) onObjectRemoved: menu.removeItem(object)
} }
MenuSeparator {}
MenuItem
{
text: catalog.i18nc("@action:inmenu", "Show All Settings")
checkable: false
exclusiveGroup: group
onTriggered:
{
showAllSettings();
}
}
MenuSeparator {} MenuSeparator {}
MenuItem MenuItem
{ {

View File

@ -19,7 +19,7 @@ Button
background: Rectangle background: Rectangle
{ {
id: backgroundRectangle id: backgroundRectangle
implicitHeight: UM.Theme.getSize("section").height height: UM.Theme.getSize("section").height
color: color:
{ {
if (base.color) if (base.color)

View File

@ -187,12 +187,6 @@ Item
menu: SettingVisibilityPresetsMenu menu: SettingVisibilityPresetsMenu
{ {
onShowAllSettings:
{
definitionsModel.setAllVisible(true)
filter.updateDefinitionModel()
}
onCollapseAllCategories: onCollapseAllCategories:
{ {
settingsSearchTimer.stop() settingsSearchTimer.stop()
@ -230,7 +224,6 @@ Item
ListView ListView
{ {
id: contents id: contents
spacing: UM.Theme.getSize("default_lining").height
cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item. cacheBuffer: 1000000 // Set a large cache to effectively just cache every list item.
model: UM.SettingDefinitionsModel model: UM.SettingDefinitionsModel
@ -259,7 +252,7 @@ Item
id: delegate id: delegate
width: scrollView.width width: scrollView.width
height: provider.properties.enabled === "True" ? UM.Theme.getSize("section").height : - contents.spacing height: provider.properties.enabled === "True" ? UM.Theme.getSize("section").height + 2 * UM.Theme.getSize("default_lining").height : 0
Behavior on height { NumberAnimation { duration: 100 } } Behavior on height { NumberAnimation { duration: 100 } }
opacity: provider.properties.enabled === "True" ? 1 : 0 opacity: provider.properties.enabled === "True" ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } } Behavior on opacity { NumberAnimation { duration: 100 } }

View File

@ -12,7 +12,6 @@ material = generic_petg
[values] [values]
material_print_temperature = =default_material_print_temperature + 35 material_print_temperature = =default_material_print_temperature + 35
material_bed_temperature = 70
cool_fan_enabled = False cool_fan_enabled = False
speed_print = 30 speed_print = 30

View File

@ -12,7 +12,6 @@ material = generic_petg
[values] [values]
material_print_temperature = =default_material_print_temperature + 35 material_print_temperature = =default_material_print_temperature + 35
material_bed_temperature = 70
cool_fan_enabled = False cool_fan_enabled = False
speed_print = 30 speed_print = 30

View File

@ -12,7 +12,6 @@ material = generic_petg
[values] [values]
material_print_temperature = =default_material_print_temperature + 35 material_print_temperature = =default_material_print_temperature + 35
material_bed_temperature = 70
cool_fan_enabled = False cool_fan_enabled = False
speed_print = 30 speed_print = 30

View File

@ -1,8 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
import os import os
import sys import sys
import subprocess from multiprocessing.dummy import Pool
from functools import partial
from subprocess import call
# A quick Python implementation of unix 'where' command. # A quick Python implementation of unix 'where' command.
def where(exe_name: str, search_path: str = os.getenv("PATH")) -> str: def where(exe_name: str, search_path: str = os.getenv("PATH")) -> str:
@ -62,21 +63,23 @@ def main():
mods = ["cura"] + plugins + findModules("plugins/VersionUpgrade") mods = ["cura"] + plugins + findModules("plugins/VersionUpgrade")
success_code = 0 success_code = 0
for mod in mods:
print("------------- Checking module {mod}".format(**locals())) pool = Pool(2) # Run two commands at once
if sys.platform == "win32": if sys.platform == "win32":
result = subprocess.run([mypy_module, "-p", mod, "--ignore-missing-imports"]) commands = ["%s -p %s --ignore-missing-imports" % (mypy_module, mod) for mod in mods]
else: else:
result = subprocess.run([sys.executable, mypy_module, "-p", mod, "--ignore-missing-imports"]) commands = ["%s %s -p %s --ignore-missing-imports" % (sys.executable, mypy_module, mod) for mod in mods]
if result.returncode != 0:
print("\nModule {mod} failed checking. :(".format(**locals())) for i, returncode in enumerate(pool.imap(partial(call, shell=True), commands)):
if returncode != 0:
print("\nCommand %s failed checking. :(" % commands[i])
success_code = 1 success_code = 1
if success_code: if success_code:
print("\n\nSome modules failed checking!") print("MYPY check was compleded, but did not pass")
else: else:
print("\n\nDone checking. All is good.") print("MYPY check was compleded and passed with flying colors")
return success_code return success_code
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(main()) sys.exit(main())

View File

@ -1,4 +1,4 @@
from unittest.mock import MagicMock from unittest.mock import MagicMock, patch
import os.path import os.path
@ -28,7 +28,7 @@ def test_createVisibilityPresetFromLocalFile():
def test_visibilityFromPrevious(): def test_visibilityFromPrevious():
# This test checks that all settings in basic are in advanced and all settings in advanced are in expert. # This test checks that all settings in basic are in advanced and all settings in advanced are in expert.
with patch("cura.CuraApplication.CuraApplication.getInstance"):
visibility_model = SettingVisibilityPresetsModel(Preferences()) visibility_model = SettingVisibilityPresetsModel(Preferences())
basic_visibility = visibility_model.getVisibilityPresetById("basic") basic_visibility = visibility_model.getVisibilityPresetById("basic")
@ -46,6 +46,7 @@ def test_visibilityFromPrevious():
def test_setActivePreset(): def test_setActivePreset():
preferences = Preferences() preferences = Preferences()
with patch("cura.CuraApplication.CuraApplication.getInstance"):
visibility_model = SettingVisibilityPresetsModel(preferences) visibility_model = SettingVisibilityPresetsModel(preferences)
visibility_model.activePresetChanged = MagicMock() visibility_model.activePresetChanged = MagicMock()
# Ensure that we start off with basic (since we didn't change anyting just yet!) # Ensure that we start off with basic (since we didn't change anyting just yet!)
@ -71,13 +72,13 @@ def test_preferenceChanged():
preferences = Preferences() preferences = Preferences()
# Set the visible_settings to something silly # Set the visible_settings to something silly
preferences.addPreference("general/visible_settings", "omgzomg") preferences.addPreference("general/visible_settings", "omgzomg")
with patch("cura.CuraApplication.CuraApplication.getInstance"):
visibility_model = SettingVisibilityPresetsModel(preferences) visibility_model = SettingVisibilityPresetsModel(preferences)
visibility_model.activePresetChanged = MagicMock() visibility_model.activePresetChanged = MagicMock()
assert visibility_model.activePreset == "custom" # This should make the model start at "custom assert visibility_model.activePreset == "custom" # This should make the model start at "custom
assert visibility_model.activePresetChanged.emit.call_count == 0 assert visibility_model.activePresetChanged.emit.call_count == 0
basic_visibility = visibility_model.getVisibilityPresetById("basic") basic_visibility = visibility_model.getVisibilityPresetById("basic")
new_visibility_string = ";".join(basic_visibility.settings) new_visibility_string = ";".join(basic_visibility.settings)
preferences.setValue("general/visible_settings", new_visibility_string) preferences.setValue("general/visible_settings", new_visibility_string)