mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-19 12:47:49 -06:00
Merge branch 'master' of github.com:Ultimaker/Cura
This commit is contained in:
commit
467e814f88
32 changed files with 287 additions and 247 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -14,6 +14,7 @@ CuraEngine.exe
|
||||||
LC_MESSAGES
|
LC_MESSAGES
|
||||||
.cache
|
.cache
|
||||||
*.qmlc
|
*.qmlc
|
||||||
|
.mypy_cache
|
||||||
|
|
||||||
#MacOS
|
#MacOS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
@ -38,6 +39,7 @@ plugins/cura-god-mode-plugin
|
||||||
plugins/cura-siemensnx-plugin
|
plugins/cura-siemensnx-plugin
|
||||||
plugins/CuraBlenderPlugin
|
plugins/CuraBlenderPlugin
|
||||||
plugins/CuraCloudPlugin
|
plugins/CuraCloudPlugin
|
||||||
|
plugins/CuraDrivePlugin
|
||||||
plugins/CuraLiveScriptingPlugin
|
plugins/CuraLiveScriptingPlugin
|
||||||
plugins/CuraOpenSCADPlugin
|
plugins/CuraOpenSCADPlugin
|
||||||
plugins/CuraPrintProfileCreator
|
plugins/CuraPrintProfileCreator
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2017 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.
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
@ -53,3 +53,9 @@ foreach(_plugin ${_plugins})
|
||||||
cura_add_test(NAME pytest-${_plugin_name} DIRECTORY ${_plugin_directory} PYTHONPATH "${_plugin_directory}|${CMAKE_SOURCE_DIR}|${URANIUM_DIR}")
|
cura_add_test(NAME pytest-${_plugin_name} DIRECTORY ${_plugin_directory} PYTHONPATH "${_plugin_directory}|${CMAKE_SOURCE_DIR}|${URANIUM_DIR}")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
#Add code style test.
|
||||||
|
add_test(
|
||||||
|
NAME "code-style"
|
||||||
|
COMMAND ${PYTHON_EXECUTABLE} run_mypy.py WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
)
|
|
@ -270,6 +270,7 @@ class CuraApplication(QtApplication):
|
||||||
"PrepareStage",
|
"PrepareStage",
|
||||||
"MonitorStage",
|
"MonitorStage",
|
||||||
"LocalFileOutputDevice",
|
"LocalFileOutputDevice",
|
||||||
|
"LocalContainerProvider",
|
||||||
|
|
||||||
# Views:
|
# Views:
|
||||||
"SimpleView",
|
"SimpleView",
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
@ -139,6 +140,9 @@ class CuraPackageManager(QObject):
|
||||||
# Also get all bundled plugins
|
# Also get all bundled plugins
|
||||||
all_metadata = self._plugin_registry.getAllMetaData()
|
all_metadata = self._plugin_registry.getAllMetaData()
|
||||||
for item in all_metadata:
|
for item in all_metadata:
|
||||||
|
if item == {}:
|
||||||
|
continue
|
||||||
|
|
||||||
plugin_package_info = self.__convertPluginMetadataToPackageMetadata(item)
|
plugin_package_info = self.__convertPluginMetadataToPackageMetadata(item)
|
||||||
# Only gather the bundled plugins here.
|
# Only gather the bundled plugins here.
|
||||||
package_id = plugin_package_info["package_id"]
|
package_id = plugin_package_info["package_id"]
|
||||||
|
@ -187,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
|
||||||
|
@ -279,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)
|
||||||
|
@ -321,33 +325,32 @@ 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():
|
||||||
if file_info.is_dir() or not file_info.filename.startswith("files/"):
|
is_dir = lambda file_info: file_info.filename.endswith('/')
|
||||||
|
if is_dir or not file_info.filename.startswith("files/"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
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()
|
||||||
|
@ -357,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
|
||||||
|
|
|
@ -220,7 +220,7 @@ class MaterialManager(QObject):
|
||||||
else:
|
else:
|
||||||
# Add this container id to the wrong containers list in the registry
|
# Add this container id to the wrong containers list in the registry
|
||||||
Logger.log("w", "Not adding {id} to the material manager because the variant does not exist.".format(id = material_metadata["id"]))
|
Logger.log("w", "Not adding {id} to the material manager because the variant does not exist.".format(id = material_metadata["id"]))
|
||||||
self._container_registry.wrong_container_ids.append(material_metadata["id"])
|
self._container_registry.addWrongContainerId(material_metadata["id"])
|
||||||
|
|
||||||
self.materialsUpdated.emit()
|
self.materialsUpdated.emit()
|
||||||
|
|
||||||
|
|
|
@ -337,11 +337,20 @@ class PrintInformation(QObject):
|
||||||
if is_gcode or is_project_file or (is_empty or (self._base_name == "" and self._base_name != name)):
|
if is_gcode or is_project_file or (is_empty or (self._base_name == "" and self._base_name != name)):
|
||||||
# Only take the file name part, Note : file name might have 'dot' in name as well
|
# Only take the file name part, Note : file name might have 'dot' in name as well
|
||||||
if is_project_file:
|
if is_project_file:
|
||||||
|
# This is for .curaproject, loaded as project
|
||||||
self._base_name = ".".join(filename_parts)
|
self._base_name = ".".join(filename_parts)
|
||||||
elif len(filename_parts) > 1:
|
elif len(filename_parts) > 1:
|
||||||
self._base_name = ".".join(filename_parts[0:-1])
|
if "gcode" in filename_parts:
|
||||||
|
gcode_index = filename_parts.index('gcode')
|
||||||
|
self._base_name = ".".join(filename_parts[0:gcode_index])
|
||||||
|
elif "curaproject" in filename_parts:
|
||||||
|
#load a project and import only models
|
||||||
|
curaproject_index = filename_parts.index('curaproject')
|
||||||
|
self._base_name = ".".join(filename_parts[0:curaproject_index])
|
||||||
|
else:
|
||||||
|
self._base_name = name
|
||||||
else:
|
else:
|
||||||
self._base_name = filename_parts[0]
|
self._base_name = name
|
||||||
|
|
||||||
|
|
||||||
self._updateJobName()
|
self._updateJobName()
|
||||||
|
|
|
@ -8,6 +8,8 @@ from typing import List, Dict, TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
|
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
|
||||||
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
|
||||||
|
@ -29,6 +31,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
|
||||||
|
|
||||||
|
@ -39,16 +42,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
|
||||||
|
|
||||||
|
@ -63,7 +65,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)
|
||||||
|
@ -100,7 +102,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()
|
||||||
|
@ -161,7 +163,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.
|
||||||
|
@ -176,7 +178,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:
|
||||||
|
@ -209,7 +211,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)
|
||||||
|
@ -223,7 +225,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:
|
||||||
|
@ -233,7 +235,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()
|
||||||
|
@ -247,7 +249,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
|
||||||
|
@ -264,7 +266,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()]:
|
||||||
|
@ -291,7 +293,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:
|
||||||
|
@ -300,7 +302,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")
|
||||||
|
@ -623,7 +625,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())]
|
||||||
|
|
||||||
|
@ -634,7 +636,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:
|
||||||
|
@ -688,7 +690,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:
|
||||||
|
@ -697,7 +699,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)
|
||||||
|
|
||||||
|
@ -794,9 +796,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")
|
||||||
|
@ -818,7 +820,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)
|
||||||
|
@ -835,7 +837,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
|
||||||
|
@ -890,13 +892,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"
|
||||||
|
@ -908,7 +910,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
|
||||||
|
@ -920,16 +922,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()):
|
||||||
|
@ -937,8 +939,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()
|
||||||
|
@ -955,13 +960,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]:
|
||||||
|
@ -972,19 +977,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:
|
||||||
|
@ -992,13 +997,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()
|
||||||
|
@ -1014,7 +1019,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
|
||||||
|
@ -1026,7 +1031,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():
|
||||||
|
@ -1222,7 +1227,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
|
||||||
|
@ -1246,7 +1251,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)
|
||||||
|
@ -1276,7 +1281,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:
|
||||||
|
@ -1285,7 +1290,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:
|
||||||
|
@ -1319,7 +1324,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):
|
||||||
|
@ -1327,13 +1332,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):
|
||||||
|
@ -1342,7 +1347,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
|
||||||
|
@ -1394,7 +1399,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):
|
||||||
|
|
|
@ -12,6 +12,8 @@ Window
|
||||||
property var selection: null
|
property var selection: null
|
||||||
title: catalog.i18nc("@title", "Toolbox")
|
title: catalog.i18nc("@title", "Toolbox")
|
||||||
modality: Qt.ApplicationModal
|
modality: Qt.ApplicationModal
|
||||||
|
flags: Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint
|
||||||
|
|
||||||
width: 720 * screenScaleFactor
|
width: 720 * screenScaleFactor
|
||||||
height: 640 * screenScaleFactor
|
height: 640 * screenScaleFactor
|
||||||
minimumWidth: 720 * screenScaleFactor
|
minimumWidth: 720 * screenScaleFactor
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
import QtQuick 2.2
|
import QtQuick 2.3
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
import UM 1.1 as UM
|
import UM 1.1 as UM
|
||||||
|
@ -9,7 +9,7 @@ import UM 1.1 as UM
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
id: page
|
id: page
|
||||||
property var details: base.selection
|
property var details: base.selection || {}
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
ToolboxBackColumn
|
ToolboxBackColumn
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,7 @@ Item
|
||||||
height: UM.Theme.getSize("toolbox_thumbnail_medium").height
|
height: UM.Theme.getSize("toolbox_thumbnail_medium").height
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: details.icon_url || "../images/logobot.svg"
|
source: details.icon_url || "../images/logobot.svg"
|
||||||
|
mipmap: true
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
top: parent.top
|
top: parent.top
|
||||||
|
@ -53,7 +54,7 @@ Item
|
||||||
rightMargin: UM.Theme.getSize("wide_margin").width
|
rightMargin: UM.Theme.getSize("wide_margin").width
|
||||||
bottomMargin: UM.Theme.getSize("default_margin").height
|
bottomMargin: UM.Theme.getSize("default_margin").height
|
||||||
}
|
}
|
||||||
text: details.name
|
text: details.name || ""
|
||||||
font: UM.Theme.getFont("large")
|
font: UM.Theme.getFont("large")
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -62,7 +63,7 @@ Item
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: description
|
id: description
|
||||||
text: details.description
|
text: details.description || ""
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
top: title.bottom
|
top: title.bottom
|
||||||
|
@ -114,6 +115,7 @@ Item
|
||||||
}
|
}
|
||||||
font: UM.Theme.getFont("very_small")
|
font: UM.Theme.getFont("very_small")
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
|
linkColor: UM.Theme.getColor("text_link")
|
||||||
onLinkActivated: Qt.openUrlExternally(link)
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import UM 1.1 as UM
|
||||||
|
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
|
property var packageData
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||||
height: visible ? childrenRect.height : 0
|
height: visible ? childrenRect.height : 0
|
||||||
visible: packageData.type == "material" && packageData.has_configs
|
visible: packageData.type == "material" && packageData.has_configs
|
||||||
|
@ -36,8 +37,8 @@ Item
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
elide: styleData.elideMode
|
elide: Text.ElideRight
|
||||||
text: styleData.value
|
text: styleData.value || ""
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
font: UM.Theme.getFont("default_bold")
|
font: UM.Theme.getFont("default_bold")
|
||||||
}
|
}
|
||||||
|
@ -55,8 +56,8 @@ Item
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
elide: styleData.elideMode
|
elide: Text.ElideRight
|
||||||
text: styleData.value
|
text: styleData.value || ""
|
||||||
color: UM.Theme.getColor("text_medium")
|
color: UM.Theme.getColor("text_medium")
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
}
|
}
|
||||||
|
@ -67,8 +68,8 @@ Item
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
elide: styleData.elideMode
|
elide: Text.ElideRight
|
||||||
text: styleData.value
|
text: styleData.value || ""
|
||||||
color: UM.Theme.getColor("text_medium")
|
color: UM.Theme.getColor("text_medium")
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
import QtQuick 2.2
|
import QtQuick 2.3
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
import UM 1.1 as UM
|
import UM 1.1 as UM
|
||||||
|
@ -33,6 +33,7 @@ Item
|
||||||
height: UM.Theme.getSize("toolbox_thumbnail_medium").height
|
height: UM.Theme.getSize("toolbox_thumbnail_medium").height
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: details.icon_url || "../images/logobot.svg"
|
source: details.icon_url || "../images/logobot.svg"
|
||||||
|
mipmap: true
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
top: parent.top
|
top: parent.top
|
||||||
|
@ -54,8 +55,9 @@ Item
|
||||||
rightMargin: UM.Theme.getSize("wide_margin").width
|
rightMargin: UM.Theme.getSize("wide_margin").width
|
||||||
bottomMargin: UM.Theme.getSize("default_margin").height
|
bottomMargin: UM.Theme.getSize("default_margin").height
|
||||||
}
|
}
|
||||||
text: details.name
|
text: details.name || ""
|
||||||
font: UM.Theme.getFont("large")
|
font: UM.Theme.getFont("large")
|
||||||
|
color: UM.Theme.getColor("text")
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: UM.Theme.getSize("toolbox_property_label").height
|
height: UM.Theme.getSize("toolbox_property_label").height
|
||||||
|
@ -133,6 +135,7 @@ Item
|
||||||
}
|
}
|
||||||
font: UM.Theme.getFont("very_small")
|
font: UM.Theme.getFont("very_small")
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
|
linkColor: UM.Theme.getColor("text_link")
|
||||||
onLinkActivated: Qt.openUrlExternally(link)
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,8 @@ Item
|
||||||
{
|
{
|
||||||
id: tile
|
id: tile
|
||||||
property bool installed: toolbox.isInstalled(model.id)
|
property bool installed: toolbox.isInstalled(model.id)
|
||||||
property var packageData: model
|
|
||||||
width: detailList.width - UM.Theme.getSize("wide_margin").width
|
width: detailList.width - UM.Theme.getSize("wide_margin").width
|
||||||
height: Math.max(UM.Theme.getSize("toolbox_detail_tile").height, childrenRect.height + UM.Theme.getSize("default_margin").height)
|
height: normalData.height + compatibilityChart.height + 4 * UM.Theme.getSize("default_margin").height
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
id: normalData
|
id: normalData
|
||||||
|
@ -46,6 +45,7 @@ Item
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
id: controls
|
id: controls
|
||||||
|
@ -76,58 +76,9 @@ Item
|
||||||
}
|
}
|
||||||
enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model) //Don't allow installing while another download is running.
|
enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model) //Don't allow installing while another download is running.
|
||||||
opacity: enabled ? 1.0 : 0.5
|
opacity: enabled ? 1.0 : 0.5
|
||||||
style: ButtonStyle
|
|
||||||
{
|
|
||||||
background: Rectangle
|
|
||||||
{
|
|
||||||
implicitWidth: 96
|
|
||||||
implicitHeight: 30
|
|
||||||
color:
|
|
||||||
{
|
|
||||||
if (installed)
|
|
||||||
{
|
|
||||||
return UM.Theme.getColor("action_button_disabled")
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( control.hovered )
|
|
||||||
{
|
|
||||||
return UM.Theme.getColor("primary_hover")
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return UM.Theme.getColor("primary")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
property alias installed: tile.installed
|
||||||
}
|
style: UM.Theme.styles.toolbox_action_button
|
||||||
label: Label
|
|
||||||
{
|
|
||||||
text: control.text
|
|
||||||
color:
|
|
||||||
{
|
|
||||||
if (installed)
|
|
||||||
{
|
|
||||||
return UM.Theme.getColor("action_button_disabled_text")
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( control.hovered )
|
|
||||||
{
|
|
||||||
return UM.Theme.getColor("button_text_hover")
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return UM.Theme.getColor("button_text")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font: UM.Theme.getFont("default_bold")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
if (installed)
|
if (installed)
|
||||||
|
@ -164,6 +115,7 @@ Item
|
||||||
id: compatibilityChart
|
id: compatibilityChart
|
||||||
anchors.top: normalData.bottom
|
anchors.top: normalData.bottom
|
||||||
width: normalData.width
|
width: normalData.width
|
||||||
|
packageData: model
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle
|
Rectangle
|
||||||
|
|
|
@ -9,9 +9,7 @@ import UM 1.1 as UM
|
||||||
|
|
||||||
Column
|
Column
|
||||||
{
|
{
|
||||||
// HACK: GridLayouts don't render to the correct height with odd numbers of
|
height: childrenRect.height
|
||||||
// items, so if odd, add some extra space.
|
|
||||||
height: grid.model.items.length % 2 == 0 ? childrenRect.height : childrenRect.height + UM.Theme.getSize("toolbox_thumbnail_small").height
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: UM.Theme.getSize("default_margin").height
|
spacing: UM.Theme.getSize("default_margin").height
|
||||||
Label
|
Label
|
||||||
|
@ -36,6 +34,7 @@ Column
|
||||||
delegate: ToolboxDownloadsGridTile
|
delegate: ToolboxDownloadsGridTile
|
||||||
{
|
{
|
||||||
Layout.preferredWidth: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns
|
Layout.preferredWidth: (grid.width - (grid.columns - 1) * grid.columnSpacing) / grid.columns
|
||||||
|
Layout.preferredHeight: UM.Theme.getSize("toolbox_thumbnail_small").height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
import QtQuick 2.2
|
import QtQuick 2.3
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
|
@ -34,10 +34,11 @@ Item
|
||||||
Image
|
Image
|
||||||
{
|
{
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: UM.Theme.getSize("toolbox_thumbnail_small").width - 26
|
width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width
|
||||||
height: UM.Theme.getSize("toolbox_thumbnail_small").height - 26
|
height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: model.icon_url || "../images/logobot.svg"
|
source: model.icon_url || "../images/logobot.svg"
|
||||||
|
mipmap: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column
|
Column
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
import QtQuick 2.2
|
import QtQuick 2.3
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
import UM 1.1 as UM
|
import UM 1.1 as UM
|
||||||
|
@ -9,7 +9,7 @@ import UM 1.1 as UM
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
width: UM.Theme.getSize("toolbox_thumbnail_large").width
|
width: UM.Theme.getSize("toolbox_thumbnail_large").width
|
||||||
height: childrenRect.height
|
height: thumbnail.height + packageName.height
|
||||||
Rectangle
|
Rectangle
|
||||||
{
|
{
|
||||||
id: highlight
|
id: highlight
|
||||||
|
@ -40,14 +40,16 @@ Item
|
||||||
height: UM.Theme.getSize("toolbox_thumbnail_large").height - 2 * UM.Theme.getSize("default_margin").height
|
height: UM.Theme.getSize("toolbox_thumbnail_large").height - 2 * UM.Theme.getSize("default_margin").height
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: model.icon_url || "../images/logobot.svg"
|
source: model.icon_url || "../images/logobot.svg"
|
||||||
|
mipmap: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
|
id: packageName
|
||||||
text: model.name
|
text: model.name
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
bottom: parent.bottom
|
top: thumbnail.bottom
|
||||||
horizontalCenter: parent.horizontalCenter
|
horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
|
@ -49,7 +49,7 @@ Item
|
||||||
implicitHeight: Math.floor(UM.Theme.getSize("toolbox_footer_button").height)
|
implicitHeight: Math.floor(UM.Theme.getSize("toolbox_footer_button").height)
|
||||||
color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary")
|
color: control.hovered ? UM.Theme.getColor("primary_hover") : UM.Theme.getColor("primary")
|
||||||
}
|
}
|
||||||
label: Text
|
label: Label
|
||||||
{
|
{
|
||||||
color: UM.Theme.getColor("button_text")
|
color: UM.Theme.getColor("button_text")
|
||||||
font: UM.Theme.getFont("default_bold")
|
font: UM.Theme.getFont("default_bold")
|
||||||
|
|
|
@ -89,6 +89,7 @@ Item
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
onLinkActivated: Qt.openUrlExternally("mailto:" + model.author_email + "?Subject=Cura: " + model.name + " Plugin")
|
onLinkActivated: Qt.openUrlExternally("mailto:" + model.author_email + "?Subject=Cura: " + model.name + " Plugin")
|
||||||
color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining")
|
color: model.enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("lining")
|
||||||
|
linkColor: UM.Theme.getColor("text_link")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column
|
Column
|
||||||
|
@ -130,7 +131,7 @@ Item
|
||||||
color: UM.Theme.getColor("lining")
|
color: UM.Theme.getColor("lining")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
label: Text
|
label: Label
|
||||||
{
|
{
|
||||||
text: control.text
|
text: control.text
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
|
|
|
@ -42,7 +42,7 @@ UM.Dialog
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||||
readOnly: true
|
readOnly: true
|
||||||
text: licenseDialog.licenseContent
|
text: licenseDialog.licenseContent || ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rightButtons:
|
rightButtons:
|
||||||
|
|
|
@ -25,7 +25,7 @@ Button
|
||||||
height: UM.Theme.getSize("sidebar_header_highlight").height
|
height: UM.Theme.getSize("sidebar_header_highlight").height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
label: Text
|
label: Label
|
||||||
{
|
{
|
||||||
text: control.text
|
text: control.text
|
||||||
color:
|
color:
|
||||||
|
|
|
@ -59,7 +59,7 @@ class PackagesModel(ListModel):
|
||||||
"version": package["package_version"],
|
"version": package["package_version"],
|
||||||
"author_id": package["author"]["author_id"] if "author_id" in package["author"] else package["author"]["name"],
|
"author_id": package["author"]["author_id"] if "author_id" in package["author"] else package["author"]["name"],
|
||||||
"author_name": package["author"]["display_name"] if "display_name" in package["author"] else package["author"]["name"],
|
"author_name": package["author"]["display_name"] if "display_name" in package["author"] else package["author"]["name"],
|
||||||
"author_email": package["author"]["email"] if "email" in package["author"] else "None",
|
"author_email": package["author"]["email"] if "email" in package["author"] else None,
|
||||||
"description": package["description"],
|
"description": package["description"],
|
||||||
"icon_url": package["icon_url"] if "icon_url" in package else None,
|
"icon_url": package["icon_url"] if "icon_url" in package else None,
|
||||||
"image_urls": package["image_urls"] if "image_urls" in package else None,
|
"image_urls": package["image_urls"] if "image_urls" in package else None,
|
||||||
|
|
|
@ -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,22 +285,25 @@ 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)
|
||||||
self._download_request.setAttribute(QNetworkRequest.RedirectPolicyAttribute, QNetworkRequest.NoLessSafeRedirectPolicy)
|
if hasattr(QNetworkRequest, "FollowRedirectsAttribute"):
|
||||||
|
# Patch for Qt 5.6-5.8
|
||||||
|
self._download_request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True)
|
||||||
|
if hasattr(QNetworkRequest, "RedirectPolicyAttribute"):
|
||||||
|
# Patch for Qt 5.9+
|
||||||
|
self._download_request.setAttribute(QNetworkRequest.RedirectPolicyAttribute, True)
|
||||||
self._download_request.setRawHeader(*self._request_header)
|
self._download_request.setRawHeader(*self._request_header)
|
||||||
self._download_reply = self._network_manager.get(self._download_request)
|
self._download_reply = self._network_manager.get(self._download_request)
|
||||||
self.setDownloadProgress(0)
|
self.setDownloadProgress(0)
|
||||||
|
@ -309,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)
|
||||||
|
@ -323,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.")
|
||||||
|
@ -397,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
|
# Must 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)
|
||||||
|
@ -429,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)
|
@pyqtProperty(QObject, fset = setActivePackage, notify = activePackageChanged)
|
||||||
def activePackage(self) -> dict:
|
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
|
||||||
|
|
|
@ -190,7 +190,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
||||||
b"address": address.encode("utf-8"),
|
b"address": address.encode("utf-8"),
|
||||||
b"firmware_version": system_info["firmware"].encode("utf-8"),
|
b"firmware_version": system_info["firmware"].encode("utf-8"),
|
||||||
b"manual": b"true",
|
b"manual": b"true",
|
||||||
b"machine": system_info["variant"].encode("utf-8")
|
b"machine": str(system_info['hardware']["typeid"]).encode("utf-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_cluster_capable_firmware:
|
if has_cluster_capable_firmware:
|
||||||
|
|
|
@ -227,6 +227,7 @@
|
||||||
{
|
{
|
||||||
"label": "Outer nozzle diameter",
|
"label": "Outer nozzle diameter",
|
||||||
"description": "The outer diameter of the tip of the nozzle.",
|
"description": "The outer diameter of the tip of the nozzle.",
|
||||||
|
"unit": "mm",
|
||||||
"default_value": 1,
|
"default_value": 1,
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
|
@ -238,6 +239,7 @@
|
||||||
{
|
{
|
||||||
"label": "Nozzle length",
|
"label": "Nozzle length",
|
||||||
"description": "The height difference between the tip of the nozzle and the lowest part of the print head.",
|
"description": "The height difference between the tip of the nozzle and the lowest part of the print head.",
|
||||||
|
"unit": "mm",
|
||||||
"default_value": 3,
|
"default_value": 3,
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
|
@ -261,6 +263,7 @@
|
||||||
{
|
{
|
||||||
"label": "Heat zone length",
|
"label": "Heat zone length",
|
||||||
"description": "The distance from the tip of the nozzle in which heat from the nozzle is transferred to the filament.",
|
"description": "The distance from the tip of the nozzle in which heat from the nozzle is transferred to the filament.",
|
||||||
|
"unit": "mm",
|
||||||
"default_value": 16,
|
"default_value": 16,
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
|
@ -271,6 +274,7 @@
|
||||||
{
|
{
|
||||||
"label": "Filament Park Distance",
|
"label": "Filament Park Distance",
|
||||||
"description": "The distance from the tip of the nozzle where to park the filament when an extruder is no longer used.",
|
"description": "The distance from the tip of the nozzle where to park the filament when an extruder is no longer used.",
|
||||||
|
"unit": "mm",
|
||||||
"default_value": 16,
|
"default_value": 16,
|
||||||
"value": "machine_heat_zone_length",
|
"value": "machine_heat_zone_length",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"file_formats": "text/x-gcode",
|
"file_formats": "text/x-gcode",
|
||||||
"icon": "icon_ultimaker2",
|
"icon": "icon_ultimaker2",
|
||||||
"platform": "Vertex_build_panel.stl",
|
"platform": "Vertex_build_panel.stl",
|
||||||
"platform_offset": [0, -2, 0],
|
"platform_offset": [0, -3, 0],
|
||||||
"supports_usb_connection": true,
|
"supports_usb_connection": true,
|
||||||
"supported_actions": ["MachineSettingsAction"]
|
"supported_actions": ["MachineSettingsAction"]
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"file_formats": "text/x-gcode",
|
"file_formats": "text/x-gcode",
|
||||||
"icon": "icon_ultimaker2",
|
"icon": "icon_ultimaker2",
|
||||||
"platform": "Vertex_build_panel.stl",
|
"platform": "Vertex_build_panel.stl",
|
||||||
"platform_offset": [0, -2, 0],
|
"platform_offset": [0, -3, 0],
|
||||||
"machine_extruder_trains": {
|
"machine_extruder_trains": {
|
||||||
"0": "vertex_k8400_dual_1st",
|
"0": "vertex_k8400_dual_1st",
|
||||||
"1": "vertex_k8400_dual_2nd"
|
"1": "vertex_k8400_dual_2nd"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1033,4 +1033,59 @@ QtObject {
|
||||||
label: Item { }
|
label: Item { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property Component toolbox_action_button: Component {
|
||||||
|
ButtonStyle
|
||||||
|
{
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
implicitWidth: UM.Theme.getSize("toolbox_action_button").width
|
||||||
|
implicitHeight: UM.Theme.getSize("toolbox_action_button").height
|
||||||
|
color:
|
||||||
|
{
|
||||||
|
if (control.installed)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("action_button_disabled")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (control.hovered)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("primary_hover")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("primary")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label: Label
|
||||||
|
{
|
||||||
|
text: control.text
|
||||||
|
color:
|
||||||
|
{
|
||||||
|
if (control.installed)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("action_button_disabled_text")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (control.hovered)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("button_text_hover")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("button_text")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
font: UM.Theme.getFont("default_bold")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,6 +460,7 @@
|
||||||
"toolbox_header": [1.0, 4.0],
|
"toolbox_header": [1.0, 4.0],
|
||||||
"toolbox_action_button": [8.0, 2.5],
|
"toolbox_action_button": [8.0, 2.5],
|
||||||
"toolbox_progress_bar": [8.0, 0.5],
|
"toolbox_progress_bar": [8.0, 0.5],
|
||||||
"toolbox_chart_row": [1.0, 2.0]
|
"toolbox_chart_row": [1.0, 2.0],
|
||||||
|
"toolbox_action_button": [8.0, 2.5]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
run_mypy.py
11
run_mypy.py
|
@ -46,14 +46,9 @@ def main():
|
||||||
print("------------- Checking module {mod}".format(**locals()))
|
print("------------- Checking module {mod}".format(**locals()))
|
||||||
result = subprocess.run([sys.executable, mypyModule, "-p", mod])
|
result = subprocess.run([sys.executable, mypyModule, "-p", mod])
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
print("""
|
print("\nModule {mod} failed checking. :(".format(**locals()))
|
||||||
Module {mod} failed checking. :(
|
return 1
|
||||||
""".format(**locals()))
|
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
print("""
|
print("\n\nDone checking. All is good.")
|
||||||
|
|
||||||
Done checking. All is good.
|
|
||||||
""")
|
|
||||||
return 0
|
return 0
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue