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", "PrepareStage",
"MonitorStage", "MonitorStage",
"LocalFileOutputDevice", "LocalFileOutputDevice",
"LocalContainerProvider",
# Views: # Views:
"SimpleView", "SimpleView",

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional from typing import Optional, Dict, Any
import json import json
import os import os
import shutil import shutil
@ -15,6 +15,7 @@ from UM.Logger import Logger
from UM.Resources import Resources from UM.Resources import Resources
from UM.Version import Version from UM.Version import Version
class CuraPackageManager(QObject): class CuraPackageManager(QObject):
Version = 1 Version = 1
@ -25,7 +26,7 @@ class CuraPackageManager(QObject):
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
self._application = parent self._application = Application.getInstance()
self._container_registry = self._application.getContainerRegistry() self._container_registry = self._application.getContainerRegistry()
self._plugin_registry = self._application.getPluginRegistry() self._plugin_registry = self._application.getPluginRegistry()
@ -190,6 +191,8 @@ class CuraPackageManager(QObject):
try: try:
# Get package information # Get package information
package_info = self.getPackageInfo(filename) package_info = self.getPackageInfo(filename)
if not package_info:
return
package_id = package_info["package_id"] package_id = package_info["package_id"]
# Check the delayed installation and removal lists first # Check the delayed installation and removal lists first
@ -282,30 +285,28 @@ class CuraPackageManager(QObject):
self._purgePackage(package_id) self._purgePackage(package_id)
# Install the package # Install the package
archive = zipfile.ZipFile(filename, "r") with zipfile.ZipFile(filename, "r") as archive:
temp_dir = tempfile.TemporaryDirectory() temp_dir = tempfile.TemporaryDirectory()
archive.extractall(temp_dir.name) archive.extractall(temp_dir.name)
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
installation_dirs_dict = { installation_dirs_dict = {
"materials": Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer), "materials": Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer),
"quality": Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer), "quality": Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer),
"plugins": os.path.abspath(Resources.getStoragePath(Resources.Plugins)), "plugins": os.path.abspath(Resources.getStoragePath(Resources.Plugins)),
} }
for sub_dir_name, installation_root_dir in installation_dirs_dict.items(): 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) src_dir_path = os.path.join(temp_dir.name, "files", sub_dir_name)
dst_dir_path = os.path.join(installation_root_dir, package_id) dst_dir_path = os.path.join(installation_root_dir, package_id)
if not os.path.exists(src_dir_path): if not os.path.exists(src_dir_path):
continue continue
# Need to rename the container files so they don't get ID conflicts # Need to rename the container files so they don't get ID conflicts
to_rename_files = sub_dir_name not in ("plugins",) 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) self.__installPackageFiles(package_id, src_dir_path, dst_dir_path, need_to_rename_files= to_rename_files)
archive.close()
# Remove the file # Remove the file
os.remove(filename) os.remove(filename)
@ -324,24 +325,22 @@ class CuraPackageManager(QObject):
os.rename(old_file_path, new_file_path) os.rename(old_file_path, new_file_path)
# Gets package information from the given file. # Gets package information from the given file.
def getPackageInfo(self, filename: str) -> dict: def getPackageInfo(self, filename: str) -> Dict[str, Any]:
archive = zipfile.ZipFile(filename, "r") with zipfile.ZipFile(filename) as archive:
try: try:
# All information is in package.json # All information is in package.json
with archive.open("package.json", "r") as f: with archive.open("package.json") as f:
package_info_dict = json.loads(f.read().decode("utf-8")) package_info_dict = json.loads(f.read().decode("utf-8"))
return package_info_dict return package_info_dict
except Exception as e: except Exception as e:
raise RuntimeError("Could not get package information from file '%s': %s" % (filename, e)) Logger.logException("w", "Could not get package information from file '%s': %s" % (filename, e))
finally: return {}
archive.close()
# Gets the license file content if present in the given package file. # Gets the license file content if present in the given package file.
# Returns None if there is no license file found. # Returns None if there is no license file found.
def getPackageLicense(self, filename: str) -> Optional[str]: def getPackageLicense(self, filename: str) -> Optional[str]:
license_string = None license_string = None
archive = zipfile.ZipFile(filename) with zipfile.ZipFile(filename) as archive:
try:
# Go through all the files and use the first successful read as the result # Go through all the files and use the first successful read as the result
for file_info in archive.infolist(): for file_info in archive.infolist():
is_dir = lambda file_info: file_info.filename.endswith('/') 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(".") filename_parts = os.path.basename(file_info.filename.lower()).split(".")
stripped_filename = filename_parts[0] stripped_filename = filename_parts[0]
if stripped_filename in ("license", "licence"): 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: try:
with archive.open(file_info.filename, "r") as f: with archive.open(file_info.filename, "r") as f:
data = f.read() data = f.read()
@ -361,8 +360,4 @@ class CuraPackageManager(QObject):
Logger.logException("e", "Failed to load potential license file '%s' as text file.", Logger.logException("e", "Failed to load potential license file '%s' as text file.",
file_info.filename) file_info.filename)
license_string = None 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 return license_string

View File

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

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Toolbox is released under the terms of the LGPLv3 or higher. # 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 json
import os import os
import tempfile import tempfile
@ -25,9 +25,10 @@ from .ConfigsModel import ConfigsModel
i18n_catalog = i18nCatalog("cura") i18n_catalog = i18nCatalog("cura")
## The Toolbox class is responsible of communicating with the server through the API ## The Toolbox class is responsible of communicating with the server through the API
class Toolbox(QObject, Extension): class Toolbox(QObject, Extension):
def __init__(self, parent=None): def __init__(self, parent=None) -> None:
super().__init__(parent) super().__init__(parent)
self._application = Application.getInstance() self._application = Application.getInstance()
@ -142,7 +143,7 @@ class Toolbox(QObject, Extension):
def getLicenseDialogLicenseContent(self) -> str: def getLicenseDialogLicenseContent(self) -> str:
return self._license_dialog_license_content 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_plugin_name = plugin_name
self._license_dialog_license_content = license_content self._license_dialog_license_content = license_content
self._license_dialog_plugin_file_location = plugin_file_location 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 a plugin, so most of the components required are not ready when
# this is initialized. Therefore, we wait until the application is ready. # this is initialized. Therefore, we wait until the application is ready.
def _onAppInitialized(self): def _onAppInitialized(self) -> None:
self._package_manager = Application.getInstance().getCuraPackageManager() self._package_manager = Application.getInstance().getCuraPackageManager()
@pyqtSlot() @pyqtSlot()
def browsePackages(self): def browsePackages(self) -> None:
# Create the network manager: # Create the network manager:
# This was formerly its own function but really had no reason to be as # This was formerly its own function but really had no reason to be as
# it was never called more than once ever. # it was never called more than once ever.
@ -181,14 +182,14 @@ class Toolbox(QObject, Extension):
# Apply enabled/disabled state to installed plugins # Apply enabled/disabled state to installed plugins
self.enabledChanged.emit() 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) Logger.log("d", "Toolbox: Creating dialog [%s].", qml_name)
path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name) path = os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "resources", "qml", qml_name)
dialog = Application.getInstance().createQmlComponent(path, {"toolbox": self}) dialog = Application.getInstance().createQmlComponent(path, {"toolbox": self})
return dialog return dialog
@pyqtSlot() @pyqtSlot()
def _updateInstalledModels(self): def _updateInstalledModels(self) -> None:
all_packages = self._package_manager.getAllInstalledPackagesInfo() all_packages = self._package_manager.getAllInstalledPackagesInfo()
if "plugin" in all_packages: if "plugin" in all_packages:
self._metadata["plugins_installed"] = all_packages["plugin"] self._metadata["plugins_installed"] = all_packages["plugin"]
@ -200,7 +201,7 @@ class Toolbox(QObject, Extension):
self.metadataChanged.emit() self.metadataChanged.emit()
@pyqtSlot(str) @pyqtSlot(str)
def install(self, file_path: str): def install(self, file_path: str) -> None:
self._package_manager.installPackage(file_path) self._package_manager.installPackage(file_path)
self.installChanged.emit() self.installChanged.emit()
self._updateInstalledModels() self._updateInstalledModels()
@ -209,7 +210,7 @@ class Toolbox(QObject, Extension):
self.restartRequiredChanged.emit() self.restartRequiredChanged.emit()
@pyqtSlot(str) @pyqtSlot(str)
def uninstall(self, plugin_id: str): def uninstall(self, plugin_id: str) -> None:
self._package_manager.removePackage(plugin_id) self._package_manager.removePackage(plugin_id)
self.installChanged.emit() self.installChanged.emit()
self._updateInstalledModels() self._updateInstalledModels()
@ -218,7 +219,7 @@ class Toolbox(QObject, Extension):
self.restartRequiredChanged.emit() self.restartRequiredChanged.emit()
@pyqtSlot(str) @pyqtSlot(str)
def enable(self, plugin_id: str): def enable(self, plugin_id: str) -> None:
self._plugin_registry.enablePlugin(plugin_id) self._plugin_registry.enablePlugin(plugin_id)
self.enabledChanged.emit() self.enabledChanged.emit()
Logger.log("i", "%s was set as 'active'.", plugin_id) Logger.log("i", "%s was set as 'active'.", plugin_id)
@ -226,7 +227,7 @@ class Toolbox(QObject, Extension):
self.restartRequiredChanged.emit() self.restartRequiredChanged.emit()
@pyqtSlot(str) @pyqtSlot(str)
def disable(self, plugin_id: str): def disable(self, plugin_id: str) -> None:
self._plugin_registry.disablePlugin(plugin_id) self._plugin_registry.disablePlugin(plugin_id)
self.enabledChanged.emit() self.enabledChanged.emit()
Logger.log("i", "%s was set as 'deactive'.", plugin_id) Logger.log("i", "%s was set as 'deactive'.", plugin_id)
@ -234,11 +235,11 @@ class Toolbox(QObject, Extension):
self.restartRequiredChanged.emit() self.restartRequiredChanged.emit()
@pyqtProperty(bool, notify = metadataChanged) @pyqtProperty(bool, notify = metadataChanged)
def dataReady(self): def dataReady(self) -> bool:
return self._packages_model is not None return self._packages_model is not None
@pyqtProperty(bool, notify = restartRequiredChanged) @pyqtProperty(bool, notify = restartRequiredChanged)
def restartRequired(self): def restartRequired(self) -> bool:
return self._restart_required return self._restart_required
@pyqtSlot() @pyqtSlot()
@ -246,8 +247,6 @@ class Toolbox(QObject, Extension):
self._package_manager._removeAllScheduledPackages() self._package_manager._removeAllScheduledPackages()
CuraApplication.getInstance().windowClosed() CuraApplication.getInstance().windowClosed()
# Checks # Checks
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
@pyqtSlot(str, result = bool) @pyqtSlot(str, result = bool)
@ -286,18 +285,16 @@ class Toolbox(QObject, Extension):
return True return True
return False return False
# Make API Calls # Make API Calls
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
def _makeRequestByType(self, type: str): def _makeRequestByType(self, type: str) -> None:
Logger.log("i", "Toolbox: Requesting %s metadata from server.", type) Logger.log("i", "Toolbox: Requesting %s metadata from server.", type)
request = QNetworkRequest(self._request_urls[type]) request = QNetworkRequest(self._request_urls[type])
request.setRawHeader(*self._request_header) request.setRawHeader(*self._request_header)
self._network_manager.get(request) self._network_manager.get(request)
@pyqtSlot(str) @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) Logger.log("i", "Toolbox: Attempting to download & install package from %s.", url)
url = QUrl(url) url = QUrl(url)
self._download_request = QNetworkRequest(url) self._download_request = QNetworkRequest(url)
@ -314,12 +311,11 @@ class Toolbox(QObject, Extension):
self._download_reply.downloadProgress.connect(self._onDownloadProgress) self._download_reply.downloadProgress.connect(self._onDownloadProgress)
@pyqtSlot() @pyqtSlot()
def cancelDownload(self): def cancelDownload(self) -> None:
Logger.log("i", "Toolbox: User cancelled the download of a plugin.") Logger.log("i", "Toolbox: User cancelled the download of a plugin.")
self.resetDownload() self.resetDownload()
return
def resetDownload(self): def resetDownload(self) -> None:
if self._download_reply: if self._download_reply:
self._download_reply.abort() self._download_reply.abort()
self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) self._download_reply.downloadProgress.disconnect(self._onDownloadProgress)
@ -328,15 +324,13 @@ class Toolbox(QObject, Extension):
self.setDownloadProgress(0) self.setDownloadProgress(0)
self.setIsDownloading(False) self.setIsDownloading(False)
# Handlers for Network Events # Handlers for Network Events
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
def _onNetworkAccessibleChanged(self, accessible: int): def _onNetworkAccessibleChanged(self, accessible: int) -> None:
if accessible == 0: if accessible == 0:
self.resetDownload() self.resetDownload()
def _onRequestFinished(self, reply: QNetworkReply): def _onRequestFinished(self, reply: QNetworkReply) -> None:
if reply.error() == QNetworkReply.TimeoutError: if reply.error() == QNetworkReply.TimeoutError:
Logger.log("w", "Got a timeout.") Logger.log("w", "Got a timeout.")
@ -402,28 +396,26 @@ class Toolbox(QObject, Extension):
# Ignore any operation that is not a get operation # Ignore any operation that is not a get operation
pass pass
def _onDownloadProgress(self, bytes_sent: int, bytes_total: int): def _onDownloadProgress(self, bytes_sent: int, bytes_total: int) -> None:
if bytes_total > 0: if bytes_total > 0:
new_progress = bytes_sent / bytes_total * 100 new_progress = bytes_sent / bytes_total * 100
self.setDownloadProgress(new_progress) self.setDownloadProgress(new_progress)
if bytes_sent == bytes_total: if bytes_sent == bytes_total:
self.setIsDownloading(False) self.setIsDownloading(False)
self._download_reply.downloadProgress.disconnect(self._onDownloadProgress) 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) self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curapackage", delete = False)
file_path = self._temp_plugin_file.name 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.write(self._download_reply.readAll())
self._temp_plugin_file.close() self._temp_plugin_file.close()
self._onDownloadComplete(file_path) self._onDownloadComplete(file_path)
return
def _onDownloadComplete(self, file_path: str): def _onDownloadComplete(self, file_path: str):
Logger.log("i", "Toolbox: Download complete.") Logger.log("i", "Toolbox: Download complete.")
try: package_info = self._package_manager.getPackageInfo(file_path)
package_info = self._package_manager.getPackageInfo(file_path) if not package_info:
except: Logger.log("w", "Toolbox: Package file [%s] was not a valid CuraPackage.", file_path)
Logger.logException("w", "Toolbox: Package file [%s] was not a valid CuraPackage.", file_path)
return return
license_content = self._package_manager.getPackageLicense(file_path) license_content = self._package_manager.getPackageLicense(file_path)
@ -434,43 +426,46 @@ class Toolbox(QObject, Extension):
self.install(file_path) self.install(file_path)
return return
# Getter & Setters for Properties: # Getter & Setters for Properties:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
def setDownloadProgress(self, progress: int): def setDownloadProgress(self, progress: Union[int, float]) -> None:
if progress != self._download_progress: if progress != self._download_progress:
self._download_progress = progress self._download_progress = progress
self.onDownloadProgressChanged.emit() self.onDownloadProgressChanged.emit()
@pyqtProperty(int, fset = setDownloadProgress, notify = onDownloadProgressChanged) @pyqtProperty(int, fset = setDownloadProgress, notify = onDownloadProgressChanged)
def downloadProgress(self) -> int: def downloadProgress(self) -> int:
return self._download_progress return self._download_progress
def setIsDownloading(self, is_downloading: bool): def setIsDownloading(self, is_downloading: bool) -> None:
if self._is_downloading != is_downloading: if self._is_downloading != is_downloading:
self._is_downloading = is_downloading self._is_downloading = is_downloading
self.onIsDownloadingChanged.emit() self.onIsDownloadingChanged.emit()
@pyqtProperty(bool, fset = setIsDownloading, notify = onIsDownloadingChanged) @pyqtProperty(bool, fset = setIsDownloading, notify = onIsDownloadingChanged)
def isDownloading(self) -> bool: def isDownloading(self) -> bool:
return self._is_downloading return self._is_downloading
def setActivePackage(self, package: dict): def setActivePackage(self, package: Dict[str, Any]) -> None:
self._active_package = package self._active_package = package
self.activePackageChanged.emit() 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 return self._active_package
def setViewCategory(self, category: str = "plugin"): def setViewCategory(self, category: str = "plugin") -> None:
self._view_category = category self._view_category = category
self.viewChanged.emit() self.viewChanged.emit()
@pyqtProperty(str, fset = setViewCategory, notify = viewChanged) @pyqtProperty(str, fset = setViewCategory, notify = viewChanged)
def viewCategory(self) -> str: def viewCategory(self) -> str:
return self._view_category return self._view_category
def setViewPage(self, page: str = "overview"): def setViewPage(self, page: str = "overview") -> None:
self._view_page = page self._view_page = page
self.viewChanged.emit() self.viewChanged.emit()
@pyqtProperty(str, fset = setViewPage, notify = viewChanged) @pyqtProperty(str, fset = setViewPage, notify = viewChanged)
def viewPage(self) -> str: def viewPage(self) -> str:
return self._view_page return self._view_page

View File

@ -25,11 +25,11 @@ jerk_enabled = True
jerk_print = 25 jerk_print = 25
line_width = =machine_nozzle_size * 0.92 line_width = =machine_nozzle_size * 0.92
machine_min_cool_heat_time_window = 15 machine_min_cool_heat_time_window = 15
material_bed_temperature_layer_0 = 90 material_bed_temperature_layer_0 = =material_bed_temperature + 5
material_final_print_temperature = 195 material_final_print_temperature = =material_print_temperature - 10
material_initial_print_temperature = 200 material_initial_print_temperature = =material_print_temperature - 5
material_print_temperature = 205 material_print_temperature = =default_material_print_temperature - 15
material_print_temperature_layer_0 = 208 material_print_temperature_layer_0 = =material_print_temperature + 3
multiple_mesh_overlap = 0 multiple_mesh_overlap = 0
prime_tower_enable = False prime_tower_enable = False
prime_tower_size = 16 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_min_cool_heat_time_window = 15
machine_nozzle_cool_down_speed = 0.85 machine_nozzle_cool_down_speed = 0.85
machine_nozzle_heat_up_speed = 1.5 machine_nozzle_heat_up_speed = 1.5
material_bed_temperature_layer_0 = 90 material_bed_temperature_layer_0 = =material_bed_temperature + 5
material_final_print_temperature = 205 material_final_print_temperature = =material_print_temperature - 10
material_initial_print_temperature = 210 material_initial_print_temperature = =material_print_temperature - 5
material_print_temperature = 215 material_print_temperature = =default_material_print_temperature - 5
material_print_temperature_layer_0 = 220 material_print_temperature_layer_0 = =material_print_temperature + 5
material_standby_temperature = 100 material_standby_temperature = 100
multiple_mesh_overlap = 0 multiple_mesh_overlap = 0
prime_tower_enable = False 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_min_cool_heat_time_window = 15
machine_nozzle_cool_down_speed = 0.85 machine_nozzle_cool_down_speed = 0.85
machine_nozzle_heat_up_speed = 1.5 machine_nozzle_heat_up_speed = 1.5
material_bed_temperature_layer_0 = 90 material_bed_temperature_layer_0 = =material_bed_temperature + 5
material_final_print_temperature = 195 material_final_print_temperature = =material_print_temperature - 12
material_initial_print_temperature = 205 material_initial_print_temperature = =material_print_temperature - 2
material_print_temperature = 207 material_print_temperature = =default_material_print_temperature - 13
material_print_temperature_layer_0 = 210 material_print_temperature_layer_0 = =material_print_temperature + 3
material_standby_temperature = 100 material_standby_temperature = 100
multiple_mesh_overlap = 0 multiple_mesh_overlap = 0
prime_tower_enable = False 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_min_cool_heat_time_window = 15
machine_nozzle_cool_down_speed = 0.85 machine_nozzle_cool_down_speed = 0.85
machine_nozzle_heat_up_speed = 1.5 machine_nozzle_heat_up_speed = 1.5
material_bed_temperature_layer_0 = 90 material_bed_temperature_layer_0 = =material_bed_temperature + 5
material_final_print_temperature = 195 material_final_print_temperature = =material_print_temperature - 10
material_initial_print_temperature = 200 material_initial_print_temperature = =material_print_temperature - 5
material_print_temperature = 205 material_print_temperature = =default_material_print_temperature - 15
material_print_temperature_layer_0 = 208 material_print_temperature_layer_0 = =material_print_temperature + 3
material_standby_temperature = 100 material_standby_temperature = 100
multiple_mesh_overlap = 0 multiple_mesh_overlap = 0
prime_tower_enable = False prime_tower_enable = False