Merge branch 'master' of github.com:Ultimaker/cura

This commit is contained in:
Aleksei S 2018-05-04 10:30:03 +02:00
commit 4a26cf0cbd
8 changed files with 147 additions and 151 deletions

View File

@ -270,6 +270,7 @@ class CuraApplication(QtApplication):
"PrepareStage",
"MonitorStage",
"LocalFileOutputDevice",
"LocalContainerProvider",
# Views:
"SimpleView",

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional
from typing import Optional, Dict, Any
import json
import os
import shutil
@ -15,6 +15,7 @@ from UM.Logger import Logger
from UM.Resources import Resources
from UM.Version import Version
class CuraPackageManager(QObject):
Version = 1
@ -25,7 +26,7 @@ class CuraPackageManager(QObject):
def __init__(self, parent = None):
super().__init__(parent)
self._application = parent
self._application = Application.getInstance()
self._container_registry = self._application.getContainerRegistry()
self._plugin_registry = self._application.getPluginRegistry()
@ -190,6 +191,8 @@ class CuraPackageManager(QObject):
try:
# Get package information
package_info = self.getPackageInfo(filename)
if not package_info:
return
package_id = package_info["package_id"]
# Check the delayed installation and removal lists first
@ -282,30 +285,28 @@ class CuraPackageManager(QObject):
self._purgePackage(package_id)
# Install the package
archive = zipfile.ZipFile(filename, "r")
with zipfile.ZipFile(filename, "r") as archive:
temp_dir = tempfile.TemporaryDirectory()
archive.extractall(temp_dir.name)
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.abspath(Resources.getStoragePath(Resources.Plugins)),
}
from cura.CuraApplication import CuraApplication
installation_dirs_dict = {
"materials": Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer),
"quality": Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer),
"plugins": os.path.abspath(Resources.getStoragePath(Resources.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)
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
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()
# 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)
# Remove the file
os.remove(filename)
@ -324,24 +325,22 @@ class CuraPackageManager(QObject):
os.rename(old_file_path, new_file_path)
# Gets package information from the given file.
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" % (filename, e))
finally:
archive.close()
def getPackageInfo(self, filename: str) -> Dict[str, Any]:
with zipfile.ZipFile(filename) as archive:
try:
# All information is in package.json
with archive.open("package.json") as f:
package_info_dict = json.loads(f.read().decode("utf-8"))
return package_info_dict
except Exception as e:
Logger.logException("w", "Could not get package information from file '%s': %s" % (filename, e))
return {}
# 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:
with zipfile.ZipFile(filename) as archive:
# Go through all the files and use the first successful read as the result
for file_info in archive.infolist():
is_dir = lambda file_info: file_info.filename.endswith('/')
@ -351,7 +350,7 @@ class CuraPackageManager(QObject):
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)
Logger.log("d", "Found potential license file '%s'", file_info.filename)
try:
with archive.open(file_info.filename, "r") as f:
data = f.read()
@ -361,8 +360,4 @@ class CuraPackageManager(QObject):
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

View File

@ -7,6 +7,8 @@ import time
from typing import List, Dict, TYPE_CHECKING, Optional
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.Interfaces import ContainerInterface
from UM.Signal import Signal
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
@ -28,6 +30,7 @@ from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.ExtruderStack import ExtruderStack
from .CuraStackBuilder import CuraStackBuilder
@ -38,16 +41,15 @@ if TYPE_CHECKING:
from cura.Settings.CuraContainerStack import CuraContainerStack
from cura.Settings.GlobalStack import GlobalStack
class MachineManager(QObject):
def __init__(self, parent = None):
super().__init__(parent)
self._active_container_stack = None # type: CuraContainerStack
self._global_container_stack = None # type: GlobalStack
self._active_container_stack = None # type: Optional[ExtruderManager]
self._global_container_stack = None # type: Optional[GlobalStack]
self._current_root_material_id = {}
self._current_root_material_id = {} # type: Dict[str, str]
self._current_quality_group = None
self._current_quality_changes_group = None
@ -62,7 +64,7 @@ class MachineManager(QObject):
self._application = Application.getInstance()
self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
self._application.getContainerRegistry().containerLoadComplete.connect(self._onInstanceContainersChanged)
self._application.getContainerRegistry().containerLoadComplete.connect(self._onContainersChanged)
## When the global container is changed, active material probably needs to be updated.
self.globalContainerChanged.connect(self.activeMaterialChanged)
@ -99,7 +101,7 @@ class MachineManager(QObject):
self._global_event_keys = set()
self._printer_output_devices = []
self._printer_output_devices = [] # type: List[PrinterOutputDevice]
Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
# There might already be some output devices by the time the signal is connected
self._onOutputDevicesChanged()
@ -160,7 +162,7 @@ class MachineManager(QObject):
rootMaterialChanged = pyqtSignal()
def setInitialActiveMachine(self):
def setInitialActiveMachine(self) -> None:
active_machine_id = Preferences.getInstance().getValue("cura/active_machine")
if active_machine_id != "" and ContainerRegistry.getInstance().findContainerStacksMetadata(id = active_machine_id):
# An active machine was saved, so restore it.
@ -177,7 +179,7 @@ class MachineManager(QObject):
self.outputDevicesChanged.emit()
@pyqtProperty(QObject, notify = currentConfigurationChanged)
def currentConfiguration(self):
def currentConfiguration(self) -> ConfigurationModel:
return self._current_printer_configuration
def _onCurrentConfigurationChanged(self) -> None:
@ -210,7 +212,7 @@ class MachineManager(QObject):
return self._current_printer_configuration == configuration
@pyqtProperty("QVariantList", notify = outputDevicesChanged)
def printerOutputDevices(self):
def printerOutputDevices(self) -> List[PrinterOutputDevice]:
return self._printer_output_devices
@pyqtProperty(int, constant=True)
@ -224,7 +226,7 @@ class MachineManager(QObject):
except TypeError: # pyQtSignal gives a TypeError when disconnecting from something that was already disconnected.
pass
try:
self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
self._global_container_stack.containersChanged.disconnect(self._onContainersChanged)
except TypeError:
pass
try:
@ -234,7 +236,7 @@ class MachineManager(QObject):
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
extruder_stack.propertyChanged.disconnect(self._onPropertyChanged)
extruder_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
extruder_stack.containersChanged.disconnect(self._onContainersChanged)
# Update the local global container stack reference
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
@ -248,7 +250,7 @@ class MachineManager(QObject):
Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId())
self._global_container_stack.nameChanged.connect(self._onMachineNameChanged)
self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged)
self._global_container_stack.containersChanged.connect(self._onContainersChanged)
self._global_container_stack.propertyChanged.connect(self._onPropertyChanged)
# Global stack can have only a variant if it is a buildplate
@ -265,7 +267,7 @@ class MachineManager(QObject):
# Listen for changes on all extruder stacks
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
extruder_stack.propertyChanged.connect(self._onPropertyChanged)
extruder_stack.containersChanged.connect(self._onInstanceContainersChanged)
extruder_stack.containersChanged.connect(self._onContainersChanged)
if self._global_container_stack.getId() in self.machine_extruder_material_update_dict:
for func in self.machine_extruder_material_update_dict[self._global_container_stack.getId()]:
@ -292,7 +294,7 @@ class MachineManager(QObject):
self.rootMaterialChanged.emit()
def _onInstanceContainersChanged(self, container) -> None:
def _onContainersChanged(self, container: ContainerInterface) -> None:
self._instance_container_timer.start()
def _onPropertyChanged(self, key: str, property_name: str) -> None:
@ -301,7 +303,7 @@ class MachineManager(QObject):
self.activeStackValueChanged.emit()
## Given a global_stack, make sure that it's all valid by searching for this quality group and applying it again
def _initMachineState(self, global_stack):
def _initMachineState(self, global_stack: "CuraContainerStack") -> None:
material_dict = {}
for position, extruder in global_stack.extruders.items():
material_dict[position] = extruder.material.getMetaDataEntry("base_file")
@ -620,7 +622,7 @@ class MachineManager(QObject):
## Copy the value of the setting of the current extruder to all other extruders as well as the global container.
@pyqtSlot(str)
def copyValueToExtruders(self, key: str):
def copyValueToExtruders(self, key: str) -> None:
new_value = self._active_container_stack.getProperty(key, "value")
extruder_stacks = [stack for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())]
@ -631,7 +633,7 @@ class MachineManager(QObject):
## Copy the value of all manually changed settings of the current extruder to all other extruders.
@pyqtSlot()
def copyAllValuesToExtruders(self):
def copyAllValuesToExtruders(self) -> None:
extruder_stacks = list(self._global_container_stack.extruders.values())
for extruder_stack in extruder_stacks:
if extruder_stack != self._active_container_stack:
@ -685,7 +687,7 @@ class MachineManager(QObject):
return fallback_title
@pyqtSlot(str, str)
def renameMachine(self, machine_id: str, new_name: str):
def renameMachine(self, machine_id: str, new_name: str) -> None:
container_registry = ContainerRegistry.getInstance()
machine_stack = container_registry.findContainerStacks(id = machine_id)
if machine_stack:
@ -694,7 +696,7 @@ class MachineManager(QObject):
self.globalContainerChanged.emit()
@pyqtSlot(str)
def removeMachine(self, machine_id: str):
def removeMachine(self, machine_id: str) -> None:
# If the machine that is being removed is the currently active machine, set another machine as the active machine.
activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id)
@ -791,9 +793,9 @@ class MachineManager(QObject):
if containers:
return containers[0].definition.getId()
def getIncompatibleSettingsOnEnabledExtruders(self, container):
def getIncompatibleSettingsOnEnabledExtruders(self, container: InstanceContainer) -> List[str]:
extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
result = []
result = [] # type: List[str]
for setting_instance in container.findInstances():
setting_key = setting_instance.definition.key
setting_enabled = self._global_container_stack.getProperty(setting_key, "enabled")
@ -815,7 +817,7 @@ class MachineManager(QObject):
return result
## Update extruder number to a valid value when the number of extruders are changed, or when an extruder is changed
def correctExtruderSettings(self):
def correctExtruderSettings(self) -> None:
for setting_key in self.getIncompatibleSettingsOnEnabledExtruders(self._global_container_stack.userChanges):
self._global_container_stack.userChanges.removeInstance(setting_key)
add_user_changes = self.getIncompatibleSettingsOnEnabledExtruders(self._global_container_stack.qualityChanges)
@ -832,7 +834,7 @@ class MachineManager(QObject):
## Set the amount of extruders on the active machine (global stack)
# \param extruder_count int the number of extruders to set
def setActiveMachineExtruderCount(self, extruder_count):
def setActiveMachineExtruderCount(self, extruder_count: int) -> None:
extruder_manager = Application.getInstance().getExtruderManager()
definition_changes_container = self._global_container_stack.definitionChanges
@ -887,13 +889,13 @@ class MachineManager(QObject):
self.forceUpdateAllSettings()
@pyqtSlot(int, result = QObject)
def getExtruder(self, position: int):
def getExtruder(self, position: int) -> Optional[ExtruderStack]:
extruder = None
if self._global_container_stack:
extruder = self._global_container_stack.extruders.get(str(position))
return extruder
def updateDefaultExtruder(self):
def updateDefaultExtruder(self) -> None:
extruder_items = sorted(self._global_container_stack.extruders.items())
old_position = self._default_extruder_position
new_default_position = "0"
@ -905,7 +907,7 @@ class MachineManager(QObject):
self._default_extruder_position = new_default_position
self.extruderChanged.emit()
def updateNumberExtrudersEnabled(self):
def updateNumberExtrudersEnabled(self) -> None:
definition_changes_container = self._global_container_stack.definitionChanges
machine_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
extruder_count = 0
@ -917,16 +919,16 @@ class MachineManager(QObject):
self.numberExtrudersEnabledChanged.emit()
@pyqtProperty(int, notify = numberExtrudersEnabledChanged)
def numberExtrudersEnabled(self):
def numberExtrudersEnabled(self) -> int:
return self._global_container_stack.definitionChanges.getProperty("extruders_enabled_count", "value")
@pyqtProperty(str, notify = extruderChanged)
def defaultExtruderPosition(self):
def defaultExtruderPosition(self) -> str:
return self._default_extruder_position
## This will fire the propertiesChanged for all settings so they will be updated in the front-end
@pyqtSlot()
def forceUpdateAllSettings(self):
def forceUpdateAllSettings(self) -> None:
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
property_names = ["value", "resolve", "validationState"]
for container in [self._global_container_stack] + list(self._global_container_stack.extruders.values()):
@ -934,8 +936,11 @@ class MachineManager(QObject):
container.propertiesChanged.emit(setting_key, property_names)
@pyqtSlot(int, bool)
def setExtruderEnabled(self, position: int, enabled) -> None:
def setExtruderEnabled(self, position: int, enabled: bool) -> None:
extruder = self.getExtruder(position)
if not extruder:
Logger.log("w", "Could not find extruder on position %s", position)
extruder.setEnabled(enabled)
self.updateDefaultExtruder()
self.updateNumberExtrudersEnabled()
@ -952,13 +957,13 @@ class MachineManager(QObject):
# Also trigger the build plate compatibility to update
self.activeMaterialChanged.emit()
def _onMachineNameChanged(self):
def _onMachineNameChanged(self) -> None:
self.globalContainerChanged.emit()
def _onMaterialNameChanged(self):
def _onMaterialNameChanged(self) -> None:
self.activeMaterialChanged.emit()
def _onQualityNameChanged(self):
def _onQualityNameChanged(self) -> None:
self.activeQualityChanged.emit()
def _getContainerChangedSignals(self) -> List[Signal]:
@ -969,19 +974,19 @@ class MachineManager(QObject):
return [ s.containersChanged for s in stacks ]
@pyqtSlot(str, str, str)
def setSettingForAllExtruders(self, setting_name: str, property_name: str, property_value: str):
def setSettingForAllExtruders(self, setting_name: str, property_name: str, property_value: str) -> None:
for key, extruder in self._global_container_stack.extruders.items():
container = extruder.userChanges
container.setProperty(setting_name, property_name, property_value)
@pyqtProperty("QVariantList", notify = globalContainerChanged)
def currentExtruderPositions(self):
def currentExtruderPositions(self) -> List[str]:
if self._global_container_stack is None:
return []
return sorted(list(self._global_container_stack.extruders.keys()))
## Update _current_root_material_id when the current root material was changed.
def _onRootMaterialChanged(self):
def _onRootMaterialChanged(self) -> None:
self._current_root_material_id = {}
if self._global_container_stack:
@ -989,13 +994,13 @@ class MachineManager(QObject):
self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file")
@pyqtProperty("QVariant", notify = rootMaterialChanged)
def currentRootMaterialId(self):
def currentRootMaterialId(self) -> Dict[str, str]:
return self._current_root_material_id
## Return the variant names in the extruder stack(s).
## For the variant in the global stack, use activeVariantBuildplateName
@pyqtProperty("QVariant", notify = activeVariantChanged)
def activeVariantNames(self):
def activeVariantNames(self) -> Dict[str, str]:
result = {}
active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
@ -1011,7 +1016,7 @@ class MachineManager(QObject):
# Sets all quality and quality_changes containers to empty_quality and empty_quality_changes containers
# for all stacks in the currently active machine.
#
def _setEmptyQuality(self):
def _setEmptyQuality(self) -> None:
self._current_quality_group = None
self._current_quality_changes_group = None
self._global_container_stack.quality = self._empty_quality_container
@ -1023,7 +1028,7 @@ class MachineManager(QObject):
self.activeQualityGroupChanged.emit()
self.activeQualityChangesGroupChanged.emit()
def _setQualityGroup(self, quality_group, empty_quality_changes = True):
def _setQualityGroup(self, quality_group, empty_quality_changes: bool = True) -> None:
if quality_group.node_for_global.getContainer() is None:
return
for node in quality_group.nodes_for_extruders.values():
@ -1219,7 +1224,7 @@ class MachineManager(QObject):
## Given a printer definition name, select the right machine instance. In case it doesn't exist, create a new
# instance with the same network key.
@pyqtSlot(str)
def switchPrinterType(self, machine_name):
def switchPrinterType(self, machine_name: str):
# Don't switch if the user tries to change to the same type of printer
if self.activeMachineDefinitionName == machine_name:
return
@ -1243,7 +1248,7 @@ class MachineManager(QObject):
self.setActiveMachine(new_machine.getId())
@pyqtSlot(QObject)
def applyRemoteConfiguration(self, configuration: ConfigurationModel):
def applyRemoteConfiguration(self, configuration: ConfigurationModel) -> None:
self.blurSettings.emit()
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
self.switchPrinterType(configuration.printerType)
@ -1273,7 +1278,7 @@ class MachineManager(QObject):
self._updateQualityWithMaterial()
## Find all container stacks that has the pair 'key = value' in its metadata and replaces the value with 'new_value'
def replaceContainersMetadata(self, key: str, value: str, new_value: str):
def replaceContainersMetadata(self, key: str, value: str, new_value: str) -> None:
machines = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
for machine in machines:
if machine.getMetaDataEntry(key) == value:
@ -1282,7 +1287,7 @@ class MachineManager(QObject):
## This method checks if the name of the group stored in the definition container is correct.
# After updating from 3.2 to 3.3 some group names may be temporary. If there is a mismatch in the name of the group
# then all the container stacks are updated, both the current and the hidden ones.
def checkCorrectGroupName(self, device_id: str, group_name: str):
def checkCorrectGroupName(self, device_id: str, group_name: str) -> None:
if self._global_container_stack and device_id == self.activeMachineNetworkKey:
# Check if the connect_group_name is correct. If not, update all the containers connected to the same printer
if self.activeMachineNetworkGroupName != group_name:
@ -1316,7 +1321,7 @@ class MachineManager(QObject):
self.setMaterial(position, material_node)
@pyqtSlot(str, "QVariant")
def setMaterial(self, position, container_node):
def setMaterial(self, position: str, container_node) -> None:
position = str(position)
self.blurSettings.emit()
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
@ -1324,13 +1329,13 @@ class MachineManager(QObject):
self._updateQualityWithMaterial()
@pyqtSlot(str, str)
def setVariantByName(self, position, variant_name):
def setVariantByName(self, position: str, variant_name: str) -> None:
machine_definition_id = self._global_container_stack.definition.id
variant_node = self._variant_manager.getVariantNode(machine_definition_id, variant_name)
self.setVariant(position, variant_node)
@pyqtSlot(str, "QVariant")
def setVariant(self, position, container_node):
def setVariant(self, position: str, container_node):
position = str(position)
self.blurSettings.emit()
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
@ -1339,7 +1344,7 @@ class MachineManager(QObject):
self._updateQualityWithMaterial()
@pyqtSlot(str)
def setQualityGroupByQualityType(self, quality_type):
def setQualityGroupByQualityType(self, quality_type: str) -> None:
if self._global_container_stack is None:
return
# Get all the quality groups for this global stack and filter out by quality_type
@ -1391,7 +1396,7 @@ class MachineManager(QObject):
name = self._current_quality_group.name
return name
def _updateUponMaterialMetadataChange(self):
def _updateUponMaterialMetadataChange(self) -> None:
if self._global_container_stack is None:
return
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V.
# Toolbox is released under the terms of the LGPLv3 or higher.
from typing import Dict
from typing import Dict, Optional, Union, Any
import json
import os
import tempfile
@ -25,9 +25,10 @@ from .ConfigsModel import ConfigsModel
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):
def __init__(self, parent=None) -> None:
super().__init__(parent)
self._application = Application.getInstance()
@ -142,7 +143,7 @@ class Toolbox(QObject, Extension):
def getLicenseDialogLicenseContent(self) -> str:
return self._license_dialog_license_content
def openLicenseDialog(self, plugin_name: str, license_content: str, plugin_file_location: str):
def openLicenseDialog(self, plugin_name: str, license_content: str, plugin_file_location: str) -> None:
self._license_dialog_plugin_name = plugin_name
self._license_dialog_license_content = license_content
self._license_dialog_plugin_file_location = plugin_file_location
@ -150,11 +151,11 @@ class Toolbox(QObject, Extension):
# 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):
def _onAppInitialized(self) -> None:
self._package_manager = Application.getInstance().getCuraPackageManager()
@pyqtSlot()
def browsePackages(self):
def browsePackages(self) -> None:
# 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.
@ -181,14 +182,14 @@ class Toolbox(QObject, Extension):
# Apply enabled/disabled state to installed plugins
self.enabledChanged.emit()
def _createDialog(self, qml_name: str):
def _createDialog(self, qml_name: str) -> Optional[QObject]:
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})
return dialog
@pyqtSlot()
def _updateInstalledModels(self):
def _updateInstalledModels(self) -> None:
all_packages = self._package_manager.getAllInstalledPackagesInfo()
if "plugin" in all_packages:
self._metadata["plugins_installed"] = all_packages["plugin"]
@ -200,7 +201,7 @@ class Toolbox(QObject, Extension):
self.metadataChanged.emit()
@pyqtSlot(str)
def install(self, file_path: str):
def install(self, file_path: str) -> None:
self._package_manager.installPackage(file_path)
self.installChanged.emit()
self._updateInstalledModels()
@ -209,7 +210,7 @@ class Toolbox(QObject, Extension):
self.restartRequiredChanged.emit()
@pyqtSlot(str)
def uninstall(self, plugin_id: str):
def uninstall(self, plugin_id: str) -> None:
self._package_manager.removePackage(plugin_id)
self.installChanged.emit()
self._updateInstalledModels()
@ -218,7 +219,7 @@ class Toolbox(QObject, Extension):
self.restartRequiredChanged.emit()
@pyqtSlot(str)
def enable(self, plugin_id: str):
def enable(self, plugin_id: str) -> None:
self._plugin_registry.enablePlugin(plugin_id)
self.enabledChanged.emit()
Logger.log("i", "%s was set as 'active'.", plugin_id)
@ -226,7 +227,7 @@ class Toolbox(QObject, Extension):
self.restartRequiredChanged.emit()
@pyqtSlot(str)
def disable(self, plugin_id: str):
def disable(self, plugin_id: str) -> None:
self._plugin_registry.disablePlugin(plugin_id)
self.enabledChanged.emit()
Logger.log("i", "%s was set as 'deactive'.", plugin_id)
@ -234,11 +235,11 @@ class Toolbox(QObject, Extension):
self.restartRequiredChanged.emit()
@pyqtProperty(bool, notify = metadataChanged)
def dataReady(self):
def dataReady(self) -> bool:
return self._packages_model is not None
@pyqtProperty(bool, notify = restartRequiredChanged)
def restartRequired(self):
def restartRequired(self) -> bool:
return self._restart_required
@pyqtSlot()
@ -246,8 +247,6 @@ class Toolbox(QObject, Extension):
self._package_manager._removeAllScheduledPackages()
CuraApplication.getInstance().windowClosed()
# Checks
# --------------------------------------------------------------------------
@pyqtSlot(str, result = bool)
@ -286,18 +285,16 @@ class Toolbox(QObject, Extension):
return True
return False
# Make API Calls
# --------------------------------------------------------------------------
def _makeRequestByType(self, type: str):
def _makeRequestByType(self, type: str) -> None:
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)
@pyqtSlot(str)
def startDownload(self, url: str):
def startDownload(self, url: str) -> None:
Logger.log("i", "Toolbox: Attempting to download & install package from %s.", url)
url = QUrl(url)
self._download_request = QNetworkRequest(url)
@ -314,12 +311,11 @@ class Toolbox(QObject, Extension):
self._download_reply.downloadProgress.connect(self._onDownloadProgress)
@pyqtSlot()
def cancelDownload(self):
def cancelDownload(self) -> None:
Logger.log("i", "Toolbox: User cancelled the download of a plugin.")
self.resetDownload()
return
def resetDownload(self):
def resetDownload(self) -> None:
if self._download_reply:
self._download_reply.abort()
self._download_reply.downloadProgress.disconnect(self._onDownloadProgress)
@ -328,15 +324,13 @@ class Toolbox(QObject, Extension):
self.setDownloadProgress(0)
self.setIsDownloading(False)
# Handlers for Network Events
# --------------------------------------------------------------------------
def _onNetworkAccessibleChanged(self, accessible: int):
def _onNetworkAccessibleChanged(self, accessible: int) -> None:
if accessible == 0:
self.resetDownload()
def _onRequestFinished(self, reply: QNetworkReply):
def _onRequestFinished(self, reply: QNetworkReply) -> None:
if reply.error() == QNetworkReply.TimeoutError:
Logger.log("w", "Got a timeout.")
@ -402,28 +396,26 @@ class Toolbox(QObject, Extension):
# Ignore any operation that is not a get operation
pass
def _onDownloadProgress(self, bytes_sent: int, bytes_total: int):
def _onDownloadProgress(self, bytes_sent: int, bytes_total: int) -> None:
if bytes_total > 0:
new_progress = bytes_sent / bytes_total * 100
self.setDownloadProgress(new_progress)
if bytes_sent == bytes_total:
self.setIsDownloading(False)
self._download_reply.downloadProgress.disconnect(self._onDownloadProgress)
# must not delete the temporary file on Windows
# <ust not delete the temporary file on Windows
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
# 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: str):
Logger.log("i", "Toolbox: Download complete.")
try:
package_info = self._package_manager.getPackageInfo(file_path)
except:
Logger.logException("w", "Toolbox: Package file [%s] was not a valid CuraPackage.", file_path)
package_info = self._package_manager.getPackageInfo(file_path)
if not package_info:
Logger.log("w", "Toolbox: Package file [%s] was not a valid CuraPackage.", file_path)
return
license_content = self._package_manager.getPackageLicense(file_path)
@ -434,43 +426,46 @@ class Toolbox(QObject, Extension):
self.install(file_path)
return
# Getter & Setters for Properties:
# --------------------------------------------------------------------------
def setDownloadProgress(self, progress: int):
def setDownloadProgress(self, progress: Union[int, float]) -> None:
if progress != self._download_progress:
self._download_progress = progress
self.onDownloadProgressChanged.emit()
@pyqtProperty(int, fset = setDownloadProgress, notify = onDownloadProgressChanged)
def downloadProgress(self) -> int:
return self._download_progress
def setIsDownloading(self, is_downloading: bool):
def setIsDownloading(self, is_downloading: bool) -> None:
if self._is_downloading != is_downloading:
self._is_downloading = is_downloading
self.onIsDownloadingChanged.emit()
@pyqtProperty(bool, fset = setIsDownloading, notify = onIsDownloadingChanged)
def isDownloading(self) -> bool:
return self._is_downloading
def setActivePackage(self, package: dict):
def setActivePackage(self, package: Dict[str, Any]) -> None:
self._active_package = package
self.activePackageChanged.emit()
@pyqtProperty(QObject, fset = setActivePackage, notify = activePackageChanged)
def activePackage(self) -> dict:
@pyqtProperty("QVariantMap", fset = setActivePackage, notify = activePackageChanged)
def activePackage(self) -> Optional[Dict[str, Any]]:
return self._active_package
def setViewCategory(self, category: str = "plugin"):
def setViewCategory(self, category: str = "plugin") -> None:
self._view_category = category
self.viewChanged.emit()
@pyqtProperty(str, fset = setViewCategory, notify = viewChanged)
def viewCategory(self) -> str:
return self._view_category
def setViewPage(self, page: str = "overview"):
def setViewPage(self, page: str = "overview") -> None:
self._view_page = page
self.viewChanged.emit()
@pyqtProperty(str, fset = setViewPage, notify = viewChanged)
def viewPage(self) -> str:
return self._view_page

View File

@ -25,11 +25,11 @@ jerk_enabled = True
jerk_print = 25
line_width = =machine_nozzle_size * 0.92
machine_min_cool_heat_time_window = 15
material_bed_temperature_layer_0 = 90
material_final_print_temperature = 195
material_initial_print_temperature = 200
material_print_temperature = 205
material_print_temperature_layer_0 = 208
material_bed_temperature_layer_0 = =material_bed_temperature + 5
material_final_print_temperature = =material_print_temperature - 10
material_initial_print_temperature = =material_print_temperature - 5
material_print_temperature = =default_material_print_temperature - 15
material_print_temperature_layer_0 = =material_print_temperature + 3
multiple_mesh_overlap = 0
prime_tower_enable = False
prime_tower_size = 16

View File

@ -30,11 +30,11 @@ line_width = =machine_nozzle_size * 0.95
machine_min_cool_heat_time_window = 15
machine_nozzle_cool_down_speed = 0.85
machine_nozzle_heat_up_speed = 1.5
material_bed_temperature_layer_0 = 90
material_final_print_temperature = 205
material_initial_print_temperature = 210
material_print_temperature = 215
material_print_temperature_layer_0 = 220
material_bed_temperature_layer_0 = =material_bed_temperature + 5
material_final_print_temperature = =material_print_temperature - 10
material_initial_print_temperature = =material_print_temperature - 5
material_print_temperature = =default_material_print_temperature - 5
material_print_temperature_layer_0 = =material_print_temperature + 5
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = False

View File

@ -30,11 +30,11 @@ line_width = =machine_nozzle_size * 0.95
machine_min_cool_heat_time_window = 15
machine_nozzle_cool_down_speed = 0.85
machine_nozzle_heat_up_speed = 1.5
material_bed_temperature_layer_0 = 90
material_final_print_temperature = 195
material_initial_print_temperature = 205
material_print_temperature = 207
material_print_temperature_layer_0 = 210
material_bed_temperature_layer_0 = =material_bed_temperature + 5
material_final_print_temperature = =material_print_temperature - 12
material_initial_print_temperature = =material_print_temperature - 2
material_print_temperature = =default_material_print_temperature - 13
material_print_temperature_layer_0 = =material_print_temperature + 3
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = False

View File

@ -29,11 +29,11 @@ line_width = =machine_nozzle_size * 0.95
machine_min_cool_heat_time_window = 15
machine_nozzle_cool_down_speed = 0.85
machine_nozzle_heat_up_speed = 1.5
material_bed_temperature_layer_0 = 90
material_final_print_temperature = 195
material_initial_print_temperature = 200
material_print_temperature = 205
material_print_temperature_layer_0 = 208
material_bed_temperature_layer_0 = =material_bed_temperature + 5
material_final_print_temperature = =material_print_temperature - 10
material_initial_print_temperature = =material_print_temperature - 5
material_print_temperature = =default_material_print_temperature - 15
material_print_temperature_layer_0 = =material_print_temperature + 3
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = False