Merge branch '3.5' into CURA-5682_material_manager_leftovers
13
Jenkinsfile
vendored
@ -12,6 +12,19 @@ parallel_nodes(['linux && cura', 'windows && cura']) {
|
|||||||
|
|
||||||
// If any error occurs during building, we want to catch it and continue with the "finale" stage.
|
// If any error occurs during building, we want to catch it and continue with the "finale" stage.
|
||||||
catchError {
|
catchError {
|
||||||
|
stage('Pre Checks') {
|
||||||
|
if (isUnix()) {
|
||||||
|
try {
|
||||||
|
sh """
|
||||||
|
echo 'Check for duplicate shortcut keys in all translation files.'
|
||||||
|
${env.CURA_ENVIRONMENT_PATH}/master/bin/python3 scripts/check_shortcut_keys.py
|
||||||
|
"""
|
||||||
|
} catch(e) {
|
||||||
|
currentBuild.result = "UNSTABLE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Building and testing should happen in a subdirectory.
|
// Building and testing should happen in a subdirectory.
|
||||||
dir('build') {
|
dir('build') {
|
||||||
// Perform the "build". Since Uranium is Python code, this basically only ensures CMake is setup.
|
// Perform the "build". Since Uranium is Python code, this basically only ensures CMake is setup.
|
||||||
|
@ -528,7 +528,7 @@ class BuildVolume(SceneNode):
|
|||||||
def _onStackChanged(self):
|
def _onStackChanged(self):
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
self._global_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged)
|
self._global_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged)
|
||||||
extruders = ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())
|
extruders = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
for extruder in extruders:
|
for extruder in extruders:
|
||||||
extruder.propertyChanged.disconnect(self._onSettingPropertyChanged)
|
extruder.propertyChanged.disconnect(self._onSettingPropertyChanged)
|
||||||
|
|
||||||
@ -536,7 +536,7 @@ class BuildVolume(SceneNode):
|
|||||||
|
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
self._global_container_stack.propertyChanged.connect(self._onSettingPropertyChanged)
|
self._global_container_stack.propertyChanged.connect(self._onSettingPropertyChanged)
|
||||||
extruders = ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())
|
extruders = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
for extruder in extruders:
|
for extruder in extruders:
|
||||||
extruder.propertyChanged.connect(self._onSettingPropertyChanged)
|
extruder.propertyChanged.connect(self._onSettingPropertyChanged)
|
||||||
|
|
||||||
|
@ -19,5 +19,11 @@ class CameraImageProvider(QQuickImageProvider):
|
|||||||
|
|
||||||
return image, QSize(15, 15)
|
return image, QSize(15, 15)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
try:
|
||||||
|
image = output_device.activeCamera.getImage()
|
||||||
|
|
||||||
|
return image, QSize(15, 15)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
return QImage(), QSize(15, 15)
|
return QImage(), QSize(15, 15)
|
||||||
|
@ -93,6 +93,7 @@ from . import CuraActions
|
|||||||
from cura.Scene import ZOffsetDecorator
|
from cura.Scene import ZOffsetDecorator
|
||||||
from . import CuraSplashScreen
|
from . import CuraSplashScreen
|
||||||
from . import CameraImageProvider
|
from . import CameraImageProvider
|
||||||
|
from . import PrintJobPreviewImageProvider
|
||||||
from . import MachineActionManager
|
from . import MachineActionManager
|
||||||
|
|
||||||
from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
|
from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
|
||||||
@ -428,6 +429,7 @@ class CuraApplication(QtApplication):
|
|||||||
# Readers & Writers:
|
# Readers & Writers:
|
||||||
"GCodeWriter",
|
"GCodeWriter",
|
||||||
"STLReader",
|
"STLReader",
|
||||||
|
"3MFWriter",
|
||||||
|
|
||||||
# Tools:
|
# Tools:
|
||||||
"CameraTool",
|
"CameraTool",
|
||||||
@ -504,6 +506,7 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
def _onEngineCreated(self):
|
def _onEngineCreated(self):
|
||||||
self._qml_engine.addImageProvider("camera", CameraImageProvider.CameraImageProvider())
|
self._qml_engine.addImageProvider("camera", CameraImageProvider.CameraImageProvider())
|
||||||
|
self._qml_engine.addImageProvider("print_job_preview", PrintJobPreviewImageProvider.PrintJobPreviewImageProvider())
|
||||||
|
|
||||||
@pyqtProperty(bool)
|
@pyqtProperty(bool)
|
||||||
def needToShowUserAgreement(self):
|
def needToShowUserAgreement(self):
|
||||||
|
@ -108,6 +108,6 @@ class QualityProfilesDropDownMenuModel(ListModel):
|
|||||||
layer_height = container.getProperty("layer_height", "value")
|
layer_height = container.getProperty("layer_height", "value")
|
||||||
|
|
||||||
if isinstance(layer_height, SettingFunction):
|
if isinstance(layer_height, SettingFunction):
|
||||||
layer_height = layer_height()
|
layer_height = layer_height(global_stack)
|
||||||
|
|
||||||
return float(layer_height)
|
return float(layer_height)
|
||||||
|
@ -200,12 +200,19 @@ class QualityManager(QObject):
|
|||||||
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition)
|
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine.definition)
|
||||||
|
|
||||||
# This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks
|
# This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks
|
||||||
has_variant_materials = parseBool(machine.getMetaDataEntry("has_variant_materials", False))
|
has_machine_specific_qualities = machine.getHasMachineQuality()
|
||||||
|
|
||||||
# To find the quality container for the GlobalStack, check in the following fall-back manner:
|
# To find the quality container for the GlobalStack, check in the following fall-back manner:
|
||||||
# (1) the machine-specific node
|
# (1) the machine-specific node
|
||||||
# (2) the generic node
|
# (2) the generic node
|
||||||
machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(machine_definition_id)
|
machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(machine_definition_id)
|
||||||
|
# Check if this machine has specific quality profiles for its extruders, if so, when looking up extruder
|
||||||
|
# qualities, we should not fall back to use the global qualities.
|
||||||
|
has_extruder_specific_qualities = False
|
||||||
|
if machine_node:
|
||||||
|
if machine_node.children_map:
|
||||||
|
has_extruder_specific_qualities = True
|
||||||
|
|
||||||
default_machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(self._default_machine_definition_id)
|
default_machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(self._default_machine_definition_id)
|
||||||
nodes_to_check = [machine_node, default_machine_node]
|
nodes_to_check = [machine_node, default_machine_node]
|
||||||
|
|
||||||
@ -213,12 +220,10 @@ class QualityManager(QObject):
|
|||||||
quality_group_dict = {}
|
quality_group_dict = {}
|
||||||
for node in nodes_to_check:
|
for node in nodes_to_check:
|
||||||
if node and node.quality_type_map:
|
if node and node.quality_type_map:
|
||||||
# Only include global qualities
|
quality_node = list(node.quality_type_map.values())[0]
|
||||||
if has_variant_materials:
|
is_global_quality = parseBool(quality_node.metadata.get("global_quality", False))
|
||||||
quality_node = list(node.quality_type_map.values())[0]
|
if not is_global_quality:
|
||||||
is_global_quality = parseBool(quality_node.metadata.get("global_quality", False))
|
continue
|
||||||
if not is_global_quality:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for quality_type, quality_node in node.quality_type_map.items():
|
for quality_type, quality_node in node.quality_type_map.items():
|
||||||
quality_group = QualityGroup(quality_node.metadata["name"], quality_type)
|
quality_group = QualityGroup(quality_node.metadata["name"], quality_type)
|
||||||
@ -300,9 +305,9 @@ class QualityManager(QObject):
|
|||||||
else:
|
else:
|
||||||
nodes_to_check += [default_machine_node]
|
nodes_to_check += [default_machine_node]
|
||||||
|
|
||||||
for node in nodes_to_check:
|
for node_idx, node in enumerate(nodes_to_check):
|
||||||
if node and node.quality_type_map:
|
if node and node.quality_type_map:
|
||||||
if has_variant_materials:
|
if has_extruder_specific_qualities:
|
||||||
# Only include variant qualities; skip non global qualities
|
# Only include variant qualities; skip non global qualities
|
||||||
quality_node = list(node.quality_type_map.values())[0]
|
quality_node = list(node.quality_type_map.values())[0]
|
||||||
is_global_quality = parseBool(quality_node.metadata.get("global_quality", False))
|
is_global_quality = parseBool(quality_node.metadata.get("global_quality", False))
|
||||||
@ -318,6 +323,12 @@ class QualityManager(QObject):
|
|||||||
if position not in quality_group.nodes_for_extruders:
|
if position not in quality_group.nodes_for_extruders:
|
||||||
quality_group.nodes_for_extruders[position] = quality_node
|
quality_group.nodes_for_extruders[position] = quality_node
|
||||||
|
|
||||||
|
# If the machine has its own specific qualities, for extruders, it should skip the global qualities
|
||||||
|
# and use the material/variant specific qualities.
|
||||||
|
if has_extruder_specific_qualities:
|
||||||
|
if node_idx == len(nodes_to_check) - 1:
|
||||||
|
break
|
||||||
|
|
||||||
# Update availabilities for each quality group
|
# Update availabilities for each quality group
|
||||||
self._updateQualityGroupsAvailability(machine, quality_group_dict.values())
|
self._updateQualityGroupsAvailability(machine, quality_group_dict.values())
|
||||||
|
|
||||||
|
27
cura/PrintJobPreviewImageProvider.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from PyQt5.QtGui import QImage
|
||||||
|
from PyQt5.QtQuick import QQuickImageProvider
|
||||||
|
from PyQt5.QtCore import QSize
|
||||||
|
|
||||||
|
from UM.Application import Application
|
||||||
|
|
||||||
|
|
||||||
|
class PrintJobPreviewImageProvider(QQuickImageProvider):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(QQuickImageProvider.Image)
|
||||||
|
|
||||||
|
## Request a new image.
|
||||||
|
def requestImage(self, id: str, size: QSize) -> QImage:
|
||||||
|
# The id will have an uuid and an increment separated by a slash. As we don't care about the value of the
|
||||||
|
# increment, we need to strip that first.
|
||||||
|
uuid = id[id.find("/") + 1:]
|
||||||
|
for output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices():
|
||||||
|
if not hasattr(output_device, "printJobs"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for print_job in output_device.printJobs:
|
||||||
|
if print_job.key == uuid:
|
||||||
|
if print_job.getPreviewImage():
|
||||||
|
return print_job.getPreviewImage(), QSize(15, 15)
|
||||||
|
else:
|
||||||
|
return QImage(), QSize(15, 15)
|
||||||
|
return QImage(), QSize(15,15)
|
@ -27,7 +27,13 @@ class ConfigurationModel(QObject):
|
|||||||
return self._printer_type
|
return self._printer_type
|
||||||
|
|
||||||
def setExtruderConfigurations(self, extruder_configurations):
|
def setExtruderConfigurations(self, extruder_configurations):
|
||||||
self._extruder_configurations = extruder_configurations
|
if self._extruder_configurations != extruder_configurations:
|
||||||
|
self._extruder_configurations = extruder_configurations
|
||||||
|
|
||||||
|
for extruder_configuration in self._extruder_configurations:
|
||||||
|
extruder_configuration.extruderConfigurationChanged.connect(self.configurationChanged)
|
||||||
|
|
||||||
|
self.configurationChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty("QVariantList", fset = setExtruderConfigurations, notify = configurationChanged)
|
@pyqtProperty("QVariantList", fset = setExtruderConfigurations, notify = configurationChanged)
|
||||||
def extruderConfigurations(self):
|
def extruderConfigurations(self):
|
||||||
|
@ -1,56 +1,67 @@
|
|||||||
# 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 PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal
|
from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal
|
||||||
|
|
||||||
|
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
|
||||||
|
|
||||||
|
|
||||||
class ExtruderConfigurationModel(QObject):
|
class ExtruderConfigurationModel(QObject):
|
||||||
|
|
||||||
extruderConfigurationChanged = pyqtSignal()
|
extruderConfigurationChanged = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, position: int = -1) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._position = -1
|
self._position = position # type: int
|
||||||
self._material = None
|
self._material = None # type: Optional[MaterialOutputModel]
|
||||||
self._hotend_id = None
|
self._hotend_id = None # type: Optional[str]
|
||||||
|
|
||||||
def setPosition(self, position):
|
def setPosition(self, position: int) -> None:
|
||||||
self._position = position
|
self._position = position
|
||||||
|
|
||||||
@pyqtProperty(int, fset = setPosition, notify = extruderConfigurationChanged)
|
@pyqtProperty(int, fset = setPosition, notify = extruderConfigurationChanged)
|
||||||
def position(self):
|
def position(self) -> int:
|
||||||
return self._position
|
return self._position
|
||||||
|
|
||||||
def setMaterial(self, material):
|
def setMaterial(self, material: Optional[MaterialOutputModel]) -> None:
|
||||||
self._material = material
|
if self._hotend_id != material:
|
||||||
|
self._material = material
|
||||||
|
self.extruderConfigurationChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged)
|
@pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged)
|
||||||
def material(self):
|
def activeMaterial(self) -> Optional[MaterialOutputModel]:
|
||||||
return self._material
|
return self._material
|
||||||
|
|
||||||
def setHotendID(self, hotend_id):
|
@pyqtProperty(QObject, fset=setMaterial, notify=extruderConfigurationChanged)
|
||||||
self._hotend_id = hotend_id
|
def material(self) -> Optional[MaterialOutputModel]:
|
||||||
|
return self._material
|
||||||
|
|
||||||
|
def setHotendID(self, hotend_id: Optional[str]) -> None:
|
||||||
|
if self._hotend_id != hotend_id:
|
||||||
|
self._hotend_id = hotend_id
|
||||||
|
self.extruderConfigurationChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, fset = setHotendID, notify = extruderConfigurationChanged)
|
@pyqtProperty(str, fset = setHotendID, notify = extruderConfigurationChanged)
|
||||||
def hotendID(self):
|
def hotendID(self) -> Optional[str]:
|
||||||
return self._hotend_id
|
return self._hotend_id
|
||||||
|
|
||||||
## This method is intended to indicate whether the configuration is valid or not.
|
## This method is intended to indicate whether the configuration is valid or not.
|
||||||
# The method checks if the mandatory fields are or not set
|
# The method checks if the mandatory fields are or not set
|
||||||
# At this moment is always valid since we allow to have empty material and variants.
|
# At this moment is always valid since we allow to have empty material and variants.
|
||||||
def isValid(self):
|
def isValid(self) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self) -> str:
|
||||||
message_chunks = []
|
message_chunks = []
|
||||||
message_chunks.append("Position: " + str(self._position))
|
message_chunks.append("Position: " + str(self._position))
|
||||||
message_chunks.append("-")
|
message_chunks.append("-")
|
||||||
message_chunks.append("Material: " + self.material.type if self.material else "empty")
|
message_chunks.append("Material: " + self.activeMaterial.type if self.activeMaterial else "empty")
|
||||||
message_chunks.append("-")
|
message_chunks.append("-")
|
||||||
message_chunks.append("HotendID: " + self.hotendID if self.hotendID else "empty")
|
message_chunks.append("HotendID: " + self.hotendID if self.hotendID else "empty")
|
||||||
return " ".join(message_chunks)
|
return " ".join(message_chunks)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other) -> bool:
|
||||||
return hash(self) == hash(other)
|
return hash(self) == hash(other)
|
||||||
|
|
||||||
# Calculating a hash function using the position of the extruder, the material GUID and the hotend id to check if is
|
# Calculating a hash function using the position of the extruder, the material GUID and the hotend id to check if is
|
||||||
|
@ -12,64 +12,61 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
class ExtruderOutputModel(QObject):
|
class ExtruderOutputModel(QObject):
|
||||||
hotendIDChanged = pyqtSignal()
|
|
||||||
targetHotendTemperatureChanged = pyqtSignal()
|
targetHotendTemperatureChanged = pyqtSignal()
|
||||||
hotendTemperatureChanged = pyqtSignal()
|
hotendTemperatureChanged = pyqtSignal()
|
||||||
activeMaterialChanged = pyqtSignal()
|
|
||||||
extruderConfigurationChanged = pyqtSignal()
|
extruderConfigurationChanged = pyqtSignal()
|
||||||
isPreheatingChanged = pyqtSignal()
|
isPreheatingChanged = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, printer: "PrinterOutputModel", position, parent=None) -> None:
|
def __init__(self, printer: "PrinterOutputModel", position: int, parent=None) -> None:
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._printer = printer
|
self._printer = printer # type: PrinterOutputModel
|
||||||
self._position = position
|
self._position = position
|
||||||
self._target_hotend_temperature = 0 # type: float
|
self._target_hotend_temperature = 0.0 # type: float
|
||||||
self._hotend_temperature = 0 # type: float
|
self._hotend_temperature = 0.0 # type: float
|
||||||
self._hotend_id = ""
|
|
||||||
self._active_material = None # type: Optional[MaterialOutputModel]
|
|
||||||
self._extruder_configuration = ExtruderConfigurationModel()
|
|
||||||
self._extruder_configuration.position = self._position
|
|
||||||
|
|
||||||
self._is_preheating = False
|
self._is_preheating = False
|
||||||
|
|
||||||
def getPrinter(self):
|
# The extruder output model wraps the configuration model. This way we can use the same config model for jobs
|
||||||
|
# and extruders alike.
|
||||||
|
self._extruder_configuration = ExtruderConfigurationModel()
|
||||||
|
self._extruder_configuration.position = self._position
|
||||||
|
self._extruder_configuration.extruderConfigurationChanged.connect(self.extruderConfigurationChanged)
|
||||||
|
|
||||||
|
def getPrinter(self) -> "PrinterOutputModel":
|
||||||
return self._printer
|
return self._printer
|
||||||
|
|
||||||
def getPosition(self):
|
def getPosition(self) -> int:
|
||||||
return self._position
|
return self._position
|
||||||
|
|
||||||
# Does the printer support pre-heating the bed at all
|
# Does the printer support pre-heating the bed at all
|
||||||
@pyqtProperty(bool, constant=True)
|
@pyqtProperty(bool, constant=True)
|
||||||
def canPreHeatHotends(self):
|
def canPreHeatHotends(self) -> bool:
|
||||||
if self._printer:
|
if self._printer:
|
||||||
return self._printer.canPreHeatHotends
|
return self._printer.canPreHeatHotends
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@pyqtProperty(QObject, notify = activeMaterialChanged)
|
@pyqtProperty(QObject, notify = extruderConfigurationChanged)
|
||||||
def activeMaterial(self) -> Optional["MaterialOutputModel"]:
|
def activeMaterial(self) -> Optional["MaterialOutputModel"]:
|
||||||
return self._active_material
|
return self._extruder_configuration.activeMaterial
|
||||||
|
|
||||||
def updateActiveMaterial(self, material: Optional["MaterialOutputModel"]):
|
def updateActiveMaterial(self, material: Optional["MaterialOutputModel"]) -> None:
|
||||||
if self._active_material != material:
|
self._extruder_configuration.setMaterial(material)
|
||||||
self._active_material = material
|
|
||||||
self._extruder_configuration.material = self._active_material
|
|
||||||
self.activeMaterialChanged.emit()
|
|
||||||
self.extruderConfigurationChanged.emit()
|
|
||||||
|
|
||||||
## Update the hotend temperature. This only changes it locally.
|
## Update the hotend temperature. This only changes it locally.
|
||||||
def updateHotendTemperature(self, temperature: float):
|
def updateHotendTemperature(self, temperature: float) -> None:
|
||||||
if self._hotend_temperature != temperature:
|
if self._hotend_temperature != temperature:
|
||||||
self._hotend_temperature = temperature
|
self._hotend_temperature = temperature
|
||||||
self.hotendTemperatureChanged.emit()
|
self.hotendTemperatureChanged.emit()
|
||||||
|
|
||||||
def updateTargetHotendTemperature(self, temperature: float):
|
def updateTargetHotendTemperature(self, temperature: float) -> None:
|
||||||
if self._target_hotend_temperature != temperature:
|
if self._target_hotend_temperature != temperature:
|
||||||
self._target_hotend_temperature = temperature
|
self._target_hotend_temperature = temperature
|
||||||
self.targetHotendTemperatureChanged.emit()
|
self.targetHotendTemperatureChanged.emit()
|
||||||
|
|
||||||
## Set the target hotend temperature. This ensures that it's actually sent to the remote.
|
## Set the target hotend temperature. This ensures that it's actually sent to the remote.
|
||||||
@pyqtSlot(float)
|
@pyqtSlot(float)
|
||||||
def setTargetHotendTemperature(self, temperature: float):
|
def setTargetHotendTemperature(self, temperature: float) -> None:
|
||||||
self._printer.getController().setTargetHotendTemperature(self._printer, self, temperature)
|
self._printer.getController().setTargetHotendTemperature(self._printer, self, temperature)
|
||||||
self.updateTargetHotendTemperature(temperature)
|
self.updateTargetHotendTemperature(temperature)
|
||||||
|
|
||||||
@ -81,30 +78,26 @@ class ExtruderOutputModel(QObject):
|
|||||||
def hotendTemperature(self) -> float:
|
def hotendTemperature(self) -> float:
|
||||||
return self._hotend_temperature
|
return self._hotend_temperature
|
||||||
|
|
||||||
@pyqtProperty(str, notify = hotendIDChanged)
|
@pyqtProperty(str, notify = extruderConfigurationChanged)
|
||||||
def hotendID(self) -> str:
|
def hotendID(self) -> str:
|
||||||
return self._hotend_id
|
return self._extruder_configuration.hotendID
|
||||||
|
|
||||||
def updateHotendID(self, id: str):
|
def updateHotendID(self, hotend_id: str) -> None:
|
||||||
if self._hotend_id != id:
|
self._extruder_configuration.setHotendID(hotend_id)
|
||||||
self._hotend_id = id
|
|
||||||
self._extruder_configuration.hotendID = self._hotend_id
|
|
||||||
self.hotendIDChanged.emit()
|
|
||||||
self.extruderConfigurationChanged.emit()
|
|
||||||
|
|
||||||
@pyqtProperty(QObject, notify = extruderConfigurationChanged)
|
@pyqtProperty(QObject, notify = extruderConfigurationChanged)
|
||||||
def extruderConfiguration(self):
|
def extruderConfiguration(self) -> Optional[ExtruderConfigurationModel]:
|
||||||
if self._extruder_configuration.isValid():
|
if self._extruder_configuration.isValid():
|
||||||
return self._extruder_configuration
|
return self._extruder_configuration
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def updateIsPreheating(self, pre_heating):
|
def updateIsPreheating(self, pre_heating: bool) -> None:
|
||||||
if self._is_preheating != pre_heating:
|
if self._is_preheating != pre_heating:
|
||||||
self._is_preheating = pre_heating
|
self._is_preheating = pre_heating
|
||||||
self.isPreheatingChanged.emit()
|
self.isPreheatingChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(bool, notify=isPreheatingChanged)
|
@pyqtProperty(bool, notify=isPreheatingChanged)
|
||||||
def isPreheating(self):
|
def isPreheating(self) -> bool:
|
||||||
return self._is_preheating
|
return self._is_preheating
|
||||||
|
|
||||||
## Pre-heats the extruder before printer.
|
## Pre-heats the extruder before printer.
|
||||||
@ -113,9 +106,9 @@ class ExtruderOutputModel(QObject):
|
|||||||
# Celsius.
|
# Celsius.
|
||||||
# \param duration How long the bed should stay warm, in seconds.
|
# \param duration How long the bed should stay warm, in seconds.
|
||||||
@pyqtSlot(float, float)
|
@pyqtSlot(float, float)
|
||||||
def preheatHotend(self, temperature, duration):
|
def preheatHotend(self, temperature: float, duration: float) -> None:
|
||||||
self._printer._controller.preheatHotend(self, temperature, duration)
|
self._printer._controller.preheatHotend(self, temperature, duration)
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def cancelPreheatHotend(self):
|
def cancelPreheatHotend(self) -> None:
|
||||||
self._printer._controller.cancelPreheatHotend(self)
|
self._printer._controller.cancelPreheatHotend(self)
|
||||||
|
@ -188,40 +188,55 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
if reply in self._kept_alive_multiparts:
|
if reply in self._kept_alive_multiparts:
|
||||||
del self._kept_alive_multiparts[reply]
|
del self._kept_alive_multiparts[reply]
|
||||||
|
|
||||||
def put(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None:
|
def _validateManager(self) -> None:
|
||||||
if self._manager is None:
|
if self._manager is None:
|
||||||
self._createNetworkManager()
|
self._createNetworkManager()
|
||||||
assert (self._manager is not None)
|
assert (self._manager is not None)
|
||||||
|
|
||||||
|
def put(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None:
|
||||||
|
self._validateManager()
|
||||||
request = self._createEmptyRequest(target)
|
request = self._createEmptyRequest(target)
|
||||||
self._last_request_time = time()
|
self._last_request_time = time()
|
||||||
reply = self._manager.put(request, data.encode())
|
if self._manager is not None:
|
||||||
self._registerOnFinishedCallback(reply, on_finished)
|
reply = self._manager.put(request, data.encode())
|
||||||
|
self._registerOnFinishedCallback(reply, on_finished)
|
||||||
|
else:
|
||||||
|
Logger.log("e", "Could not find manager.")
|
||||||
|
|
||||||
|
def delete(self, target: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None:
|
||||||
|
self._validateManager()
|
||||||
|
request = self._createEmptyRequest(target)
|
||||||
|
self._last_request_time = time()
|
||||||
|
if self._manager is not None:
|
||||||
|
reply = self._manager.deleteResource(request)
|
||||||
|
self._registerOnFinishedCallback(reply, on_finished)
|
||||||
|
else:
|
||||||
|
Logger.log("e", "Could not find manager.")
|
||||||
|
|
||||||
def get(self, target: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None:
|
def get(self, target: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None:
|
||||||
if self._manager is None:
|
self._validateManager()
|
||||||
self._createNetworkManager()
|
|
||||||
assert (self._manager is not None)
|
|
||||||
request = self._createEmptyRequest(target)
|
request = self._createEmptyRequest(target)
|
||||||
self._last_request_time = time()
|
self._last_request_time = time()
|
||||||
reply = self._manager.get(request)
|
if self._manager is not None:
|
||||||
self._registerOnFinishedCallback(reply, on_finished)
|
reply = self._manager.get(request)
|
||||||
|
self._registerOnFinishedCallback(reply, on_finished)
|
||||||
|
else:
|
||||||
|
Logger.log("e", "Could not find manager.")
|
||||||
|
|
||||||
def post(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None:
|
def post(self, target: str, data: str, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None:
|
||||||
if self._manager is None:
|
self._validateManager()
|
||||||
self._createNetworkManager()
|
|
||||||
assert (self._manager is not None)
|
|
||||||
request = self._createEmptyRequest(target)
|
request = self._createEmptyRequest(target)
|
||||||
self._last_request_time = time()
|
self._last_request_time = time()
|
||||||
reply = self._manager.post(request, data)
|
if self._manager is not None:
|
||||||
if on_progress is not None:
|
reply = self._manager.post(request, data)
|
||||||
reply.uploadProgress.connect(on_progress)
|
if on_progress is not None:
|
||||||
self._registerOnFinishedCallback(reply, on_finished)
|
reply.uploadProgress.connect(on_progress)
|
||||||
|
self._registerOnFinishedCallback(reply, on_finished)
|
||||||
|
else:
|
||||||
|
Logger.log("e", "Could not find manager.")
|
||||||
|
|
||||||
def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> QNetworkReply:
|
def postFormWithParts(self, target: str, parts: List[QHttpPart], on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> QNetworkReply:
|
||||||
|
self._validateManager()
|
||||||
if self._manager is None:
|
|
||||||
self._createNetworkManager()
|
|
||||||
assert (self._manager is not None)
|
|
||||||
request = self._createEmptyRequest(target, content_type=None)
|
request = self._createEmptyRequest(target, content_type=None)
|
||||||
multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType)
|
multi_post_part = QHttpMultiPart(QHttpMultiPart.FormDataType)
|
||||||
for part in parts:
|
for part in parts:
|
||||||
@ -229,15 +244,18 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
|
|
||||||
self._last_request_time = time()
|
self._last_request_time = time()
|
||||||
|
|
||||||
reply = self._manager.post(request, multi_post_part)
|
if self._manager is not None:
|
||||||
|
reply = self._manager.post(request, multi_post_part)
|
||||||
|
|
||||||
self._kept_alive_multiparts[reply] = multi_post_part
|
self._kept_alive_multiparts[reply] = multi_post_part
|
||||||
|
|
||||||
if on_progress is not None:
|
if on_progress is not None:
|
||||||
reply.uploadProgress.connect(on_progress)
|
reply.uploadProgress.connect(on_progress)
|
||||||
self._registerOnFinishedCallback(reply, on_finished)
|
self._registerOnFinishedCallback(reply, on_finished)
|
||||||
|
|
||||||
return reply
|
return reply
|
||||||
|
else:
|
||||||
|
Logger.log("e", "Could not find manager.")
|
||||||
|
|
||||||
def postForm(self, target: str, header_data: str, body_data: bytes, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None:
|
def postForm(self, target: str, header_data: str, body_data: bytes, on_finished: Optional[Callable[[QNetworkReply], None]], on_progress: Callable = None) -> None:
|
||||||
post_part = QHttpPart()
|
post_part = QHttpPart()
|
||||||
|
@ -2,11 +2,15 @@
|
|||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot
|
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, pyqtSlot
|
||||||
from typing import Optional, TYPE_CHECKING
|
from typing import Optional, TYPE_CHECKING, List
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QUrl
|
||||||
|
from PyQt5.QtGui import QImage
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
||||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||||
|
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||||
|
|
||||||
|
|
||||||
class PrintJobOutputModel(QObject):
|
class PrintJobOutputModel(QObject):
|
||||||
@ -17,6 +21,9 @@ class PrintJobOutputModel(QObject):
|
|||||||
keyChanged = pyqtSignal()
|
keyChanged = pyqtSignal()
|
||||||
assignedPrinterChanged = pyqtSignal()
|
assignedPrinterChanged = pyqtSignal()
|
||||||
ownerChanged = pyqtSignal()
|
ownerChanged = pyqtSignal()
|
||||||
|
configurationChanged = pyqtSignal()
|
||||||
|
previewImageChanged = pyqtSignal()
|
||||||
|
compatibleMachineFamiliesChanged = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, output_controller: "PrinterOutputController", key: str = "", name: str = "", parent=None) -> None:
|
def __init__(self, output_controller: "PrinterOutputController", key: str = "", name: str = "", parent=None) -> None:
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -29,6 +36,48 @@ class PrintJobOutputModel(QObject):
|
|||||||
self._assigned_printer = None # type: Optional[PrinterOutputModel]
|
self._assigned_printer = None # type: Optional[PrinterOutputModel]
|
||||||
self._owner = "" # Who started/owns the print job?
|
self._owner = "" # Who started/owns the print job?
|
||||||
|
|
||||||
|
self._configuration = None # type: Optional[ConfigurationModel]
|
||||||
|
self._compatible_machine_families = [] # type: List[str]
|
||||||
|
self._preview_image_id = 0
|
||||||
|
|
||||||
|
self._preview_image = None # type: Optional[QImage]
|
||||||
|
|
||||||
|
@pyqtProperty("QStringList", notify=compatibleMachineFamiliesChanged)
|
||||||
|
def compatibleMachineFamilies(self):
|
||||||
|
# Hack; Some versions of cluster will return a family more than once...
|
||||||
|
return set(self._compatible_machine_families)
|
||||||
|
|
||||||
|
def setCompatibleMachineFamilies(self, compatible_machine_families: List[str]) -> None:
|
||||||
|
if self._compatible_machine_families != compatible_machine_families:
|
||||||
|
self._compatible_machine_families = compatible_machine_families
|
||||||
|
self.compatibleMachineFamiliesChanged.emit()
|
||||||
|
|
||||||
|
@pyqtProperty(QUrl, notify=previewImageChanged)
|
||||||
|
def previewImageUrl(self):
|
||||||
|
self._preview_image_id += 1
|
||||||
|
# There is an image provider that is called "camera". In order to ensure that the image qml object, that
|
||||||
|
# requires a QUrl to function, updates correctly we add an increasing number. This causes to see the QUrl
|
||||||
|
# as new (instead of relying on cached version and thus forces an update.
|
||||||
|
temp = "image://print_job_preview/" + str(self._preview_image_id) + "/" + self._key
|
||||||
|
return QUrl(temp, QUrl.TolerantMode)
|
||||||
|
|
||||||
|
def getPreviewImage(self) -> Optional[QImage]:
|
||||||
|
return self._preview_image
|
||||||
|
|
||||||
|
def updatePreviewImage(self, preview_image: Optional[QImage]) -> None:
|
||||||
|
if self._preview_image != preview_image:
|
||||||
|
self._preview_image = preview_image
|
||||||
|
self.previewImageChanged.emit()
|
||||||
|
|
||||||
|
@pyqtProperty(QObject, notify=configurationChanged)
|
||||||
|
def configuration(self) -> Optional["ConfigurationModel"]:
|
||||||
|
return self._configuration
|
||||||
|
|
||||||
|
def updateConfiguration(self, configuration: Optional["ConfigurationModel"]) -> None:
|
||||||
|
if self._configuration != configuration:
|
||||||
|
self._configuration = configuration
|
||||||
|
self.configurationChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, notify=ownerChanged)
|
@pyqtProperty(str, notify=ownerChanged)
|
||||||
def owner(self):
|
def owner(self):
|
||||||
return self._owner
|
return self._owner
|
||||||
|
@ -35,7 +35,7 @@ class PrinterOutputModel(QObject):
|
|||||||
self._key = "" # Unique identifier
|
self._key = "" # Unique identifier
|
||||||
self._controller = output_controller
|
self._controller = output_controller
|
||||||
self._extruders = [ExtruderOutputModel(printer = self, position = i) for i in range(number_of_extruders)]
|
self._extruders = [ExtruderOutputModel(printer = self, position = i) for i in range(number_of_extruders)]
|
||||||
self._printer_configuration = ConfigurationModel() # Indicates the current configuration setup in this printer
|
self._printer_configuration = ConfigurationModel() # Indicates the current configuration setup in this printer
|
||||||
self._head_position = Vector(0, 0, 0)
|
self._head_position = Vector(0, 0, 0)
|
||||||
self._active_print_job = None # type: Optional[PrintJobOutputModel]
|
self._active_print_job = None # type: Optional[PrintJobOutputModel]
|
||||||
self._firmware_version = firmware_version
|
self._firmware_version = firmware_version
|
||||||
@ -43,9 +43,9 @@ class PrinterOutputModel(QObject):
|
|||||||
self._is_preheating = False
|
self._is_preheating = False
|
||||||
self._printer_type = ""
|
self._printer_type = ""
|
||||||
self._buildplate_name = None
|
self._buildplate_name = None
|
||||||
# Update the printer configuration every time any of the extruders changes its configuration
|
|
||||||
for extruder in self._extruders:
|
self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in
|
||||||
extruder.extruderConfigurationChanged.connect(self._updateExtruderConfiguration)
|
self._extruders]
|
||||||
|
|
||||||
self._camera = None
|
self._camera = None
|
||||||
|
|
||||||
@ -282,8 +282,4 @@ class PrinterOutputModel(QObject):
|
|||||||
def printerConfiguration(self):
|
def printerConfiguration(self):
|
||||||
if self._printer_configuration.isValid():
|
if self._printer_configuration.isValid():
|
||||||
return self._printer_configuration
|
return self._printer_configuration
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _updateExtruderConfiguration(self):
|
|
||||||
self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in self._extruders]
|
|
||||||
self.configurationChanged.emit()
|
|
@ -304,7 +304,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
|||||||
if self._global_stack:
|
if self._global_stack:
|
||||||
self._global_stack.propertyChanged.disconnect(self._onSettingValueChanged)
|
self._global_stack.propertyChanged.disconnect(self._onSettingValueChanged)
|
||||||
self._global_stack.containersChanged.disconnect(self._onChanged)
|
self._global_stack.containersChanged.disconnect(self._onChanged)
|
||||||
extruders = ExtruderManager.getInstance().getMachineExtruders(self._global_stack.getId())
|
extruders = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
for extruder in extruders:
|
for extruder in extruders:
|
||||||
extruder.propertyChanged.disconnect(self._onSettingValueChanged)
|
extruder.propertyChanged.disconnect(self._onSettingValueChanged)
|
||||||
|
|
||||||
@ -314,7 +314,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
|||||||
self._global_stack.propertyChanged.connect(self._onSettingValueChanged)
|
self._global_stack.propertyChanged.connect(self._onSettingValueChanged)
|
||||||
self._global_stack.containersChanged.connect(self._onChanged)
|
self._global_stack.containersChanged.connect(self._onChanged)
|
||||||
|
|
||||||
extruders = ExtruderManager.getInstance().getMachineExtruders(self._global_stack.getId())
|
extruders = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
for extruder in extruders:
|
for extruder in extruders:
|
||||||
extruder.propertyChanged.connect(self._onSettingValueChanged)
|
extruder.propertyChanged.connect(self._onSettingValueChanged)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt.
|
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt.
|
||||||
from UM.FlameProfiler import pyqtSlot
|
from UM.FlameProfiler import pyqtSlot
|
||||||
|
|
||||||
import cura.CuraApplication #To get the global container stack to find the current machine.
|
import cura.CuraApplication # To get the global container stack to find the current machine.
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
from UM.Scene.SceneNode import SceneNode
|
from UM.Scene.SceneNode import SceneNode
|
||||||
@ -12,15 +12,15 @@ from UM.Scene.Selection import Selection
|
|||||||
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry # Finding containers by ID.
|
from UM.Settings.ContainerRegistry import ContainerRegistry # Finding containers by ID.
|
||||||
from UM.Settings.SettingFunction import SettingFunction
|
from UM.Settings.SettingFunction import SettingFunction
|
||||||
from UM.Settings.SettingInstance import SettingInstance
|
|
||||||
from UM.Settings.ContainerStack import ContainerStack
|
from UM.Settings.ContainerStack import ContainerStack
|
||||||
from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
|
from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
|
||||||
|
|
||||||
from typing import Optional, List, TYPE_CHECKING, Union, Dict
|
from typing import Optional, TYPE_CHECKING, Dict, List, Any
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from cura.Settings.ExtruderStack import ExtruderStack
|
from cura.Settings.ExtruderStack import ExtruderStack
|
||||||
from cura.Settings.GlobalStack import GlobalStack
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
from UM.Scene.SceneNode import SceneNode
|
||||||
|
|
||||||
|
|
||||||
## Manages all existing extruder stacks.
|
## Manages all existing extruder stacks.
|
||||||
@ -38,9 +38,10 @@ class ExtruderManager(QObject):
|
|||||||
|
|
||||||
self._application = cura.CuraApplication.CuraApplication.getInstance()
|
self._application = cura.CuraApplication.CuraApplication.getInstance()
|
||||||
|
|
||||||
self._extruder_trains = {} # Per machine, a dictionary of extruder container stack IDs. Only for separately defined extruders.
|
# Per machine, a dictionary of extruder container stack IDs. Only for separately defined extruders.
|
||||||
|
self._extruder_trains = {} # type: Dict[str, Dict[str, ExtruderStack]]
|
||||||
self._active_extruder_index = -1 # Indicates the index of the active extruder stack. -1 means no active extruder stack
|
self._active_extruder_index = -1 # Indicates the index of the active extruder stack. -1 means no active extruder stack
|
||||||
self._selected_object_extruders = []
|
self._selected_object_extruders = [] # type: List[str]
|
||||||
self._addCurrentMachineExtruders()
|
self._addCurrentMachineExtruders()
|
||||||
|
|
||||||
Selection.selectionChanged.connect(self.resetSelectedObjectExtruders)
|
Selection.selectionChanged.connect(self.resetSelectedObjectExtruders)
|
||||||
@ -68,7 +69,7 @@ class ExtruderManager(QObject):
|
|||||||
|
|
||||||
## Return extruder count according to extruder trains.
|
## Return extruder count according to extruder trains.
|
||||||
@pyqtProperty(int, notify = extrudersChanged)
|
@pyqtProperty(int, notify = extrudersChanged)
|
||||||
def extruderCount(self):
|
def extruderCount(self) -> int:
|
||||||
if not self._application.getGlobalContainerStack():
|
if not self._application.getGlobalContainerStack():
|
||||||
return 0 # No active machine, so no extruders.
|
return 0 # No active machine, so no extruders.
|
||||||
try:
|
try:
|
||||||
@ -79,28 +80,14 @@ class ExtruderManager(QObject):
|
|||||||
## Gets a dict with the extruder stack ids with the extruder number as the key.
|
## Gets a dict with the extruder stack ids with the extruder number as the key.
|
||||||
@pyqtProperty("QVariantMap", notify = extrudersChanged)
|
@pyqtProperty("QVariantMap", notify = extrudersChanged)
|
||||||
def extruderIds(self) -> Dict[str, str]:
|
def extruderIds(self) -> Dict[str, str]:
|
||||||
extruder_stack_ids = {}
|
extruder_stack_ids = {} # type: Dict[str, str]
|
||||||
|
|
||||||
global_container_stack = self._application.getGlobalContainerStack()
|
global_container_stack = self._application.getGlobalContainerStack()
|
||||||
if global_container_stack:
|
if global_container_stack:
|
||||||
global_stack_id = global_container_stack.getId()
|
extruder_stack_ids = {position: extruder.id for position, extruder in global_container_stack.extruders.items()}
|
||||||
|
|
||||||
if global_stack_id in self._extruder_trains:
|
|
||||||
for position in self._extruder_trains[global_stack_id]:
|
|
||||||
extruder_stack_ids[position] = self._extruder_trains[global_stack_id][position].getId()
|
|
||||||
|
|
||||||
return extruder_stack_ids
|
return extruder_stack_ids
|
||||||
|
|
||||||
@pyqtSlot(str, result = str)
|
|
||||||
def getQualityChangesIdByExtruderStackId(self, extruder_stack_id: str) -> str:
|
|
||||||
global_container_stack = self._application.getGlobalContainerStack()
|
|
||||||
if global_container_stack is not None:
|
|
||||||
for position in self._extruder_trains[global_container_stack.getId()]:
|
|
||||||
extruder = self._extruder_trains[global_container_stack.getId()][position]
|
|
||||||
if extruder.getId() == extruder_stack_id:
|
|
||||||
return extruder.qualityChanges.getId()
|
|
||||||
return ""
|
|
||||||
|
|
||||||
## Changes the active extruder by index.
|
## Changes the active extruder by index.
|
||||||
#
|
#
|
||||||
# \param index The index of the new active extruder.
|
# \param index The index of the new active extruder.
|
||||||
@ -117,9 +104,9 @@ class ExtruderManager(QObject):
|
|||||||
#
|
#
|
||||||
# \param index The index of the extruder whose name to get.
|
# \param index The index of the extruder whose name to get.
|
||||||
@pyqtSlot(int, result = str)
|
@pyqtSlot(int, result = str)
|
||||||
def getExtruderName(self, index):
|
def getExtruderName(self, index: int) -> str:
|
||||||
try:
|
try:
|
||||||
return list(self.getActiveExtruderStacks())[index].getName()
|
return self.getActiveExtruderStacks()[index].getName()
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@ -133,7 +120,7 @@ class ExtruderManager(QObject):
|
|||||||
object_extruders = set()
|
object_extruders = set()
|
||||||
|
|
||||||
# First, build a list of the actual selected objects (including children of groups, excluding group nodes)
|
# First, build a list of the actual selected objects (including children of groups, excluding group nodes)
|
||||||
selected_nodes = []
|
selected_nodes = [] # type: List["SceneNode"]
|
||||||
for node in Selection.getAllSelectedObjects():
|
for node in Selection.getAllSelectedObjects():
|
||||||
if node.callDecoration("isGroup"):
|
if node.callDecoration("isGroup"):
|
||||||
for grouped_node in BreadthFirstIterator(node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
for grouped_node in BreadthFirstIterator(node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||||
@ -145,14 +132,13 @@ class ExtruderManager(QObject):
|
|||||||
selected_nodes.append(node)
|
selected_nodes.append(node)
|
||||||
|
|
||||||
# Then, figure out which nodes are used by those selected nodes.
|
# Then, figure out which nodes are used by those selected nodes.
|
||||||
global_stack = self._application.getGlobalContainerStack()
|
current_extruder_trains = self.getActiveExtruderStacks()
|
||||||
current_extruder_trains = self._extruder_trains.get(global_stack.getId())
|
|
||||||
for node in selected_nodes:
|
for node in selected_nodes:
|
||||||
extruder = node.callDecoration("getActiveExtruder")
|
extruder = node.callDecoration("getActiveExtruder")
|
||||||
if extruder:
|
if extruder:
|
||||||
object_extruders.add(extruder)
|
object_extruders.add(extruder)
|
||||||
elif current_extruder_trains:
|
elif current_extruder_trains:
|
||||||
object_extruders.add(current_extruder_trains["0"].getId())
|
object_extruders.add(current_extruder_trains[0].getId())
|
||||||
|
|
||||||
self._selected_object_extruders = list(object_extruders)
|
self._selected_object_extruders = list(object_extruders)
|
||||||
|
|
||||||
@ -168,14 +154,7 @@ class ExtruderManager(QObject):
|
|||||||
|
|
||||||
@pyqtSlot(result = QObject)
|
@pyqtSlot(result = QObject)
|
||||||
def getActiveExtruderStack(self) -> Optional["ExtruderStack"]:
|
def getActiveExtruderStack(self) -> Optional["ExtruderStack"]:
|
||||||
global_container_stack = self._application.getGlobalContainerStack()
|
return self.getExtruderStack(self._active_extruder_index)
|
||||||
|
|
||||||
if global_container_stack:
|
|
||||||
if global_container_stack.getId() in self._extruder_trains:
|
|
||||||
if str(self._active_extruder_index) in self._extruder_trains[global_container_stack.getId()]:
|
|
||||||
return self._extruder_trains[global_container_stack.getId()][str(self._active_extruder_index)]
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
## Get an extruder stack by index
|
## Get an extruder stack by index
|
||||||
def getExtruderStack(self, index) -> Optional["ExtruderStack"]:
|
def getExtruderStack(self, index) -> Optional["ExtruderStack"]:
|
||||||
@ -186,16 +165,7 @@ class ExtruderManager(QObject):
|
|||||||
return self._extruder_trains[global_container_stack.getId()][str(index)]
|
return self._extruder_trains[global_container_stack.getId()][str(index)]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
## Get all extruder stacks
|
def registerExtruder(self, extruder_train: "ExtruderStack", machine_id: str) -> None:
|
||||||
def getExtruderStacks(self) -> List["ExtruderStack"]:
|
|
||||||
result = []
|
|
||||||
for i in range(self.extruderCount):
|
|
||||||
stack = self.getExtruderStack(i)
|
|
||||||
if stack:
|
|
||||||
result.append(stack)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def registerExtruder(self, extruder_train, machine_id):
|
|
||||||
changed = False
|
changed = False
|
||||||
|
|
||||||
if machine_id not in self._extruder_trains:
|
if machine_id not in self._extruder_trains:
|
||||||
@ -214,23 +184,20 @@ class ExtruderManager(QObject):
|
|||||||
if changed:
|
if changed:
|
||||||
self.extrudersChanged.emit(machine_id)
|
self.extrudersChanged.emit(machine_id)
|
||||||
|
|
||||||
def getAllExtruderValues(self, setting_key):
|
|
||||||
return self.getAllExtruderSettings(setting_key, "value")
|
|
||||||
|
|
||||||
## Gets a property of a setting for all extruders.
|
## Gets a property of a setting for all extruders.
|
||||||
#
|
#
|
||||||
# \param setting_key \type{str} The setting to get the property of.
|
# \param setting_key \type{str} The setting to get the property of.
|
||||||
# \param property \type{str} The property to get.
|
# \param property \type{str} The property to get.
|
||||||
# \return \type{List} the list of results
|
# \return \type{List} the list of results
|
||||||
def getAllExtruderSettings(self, setting_key: str, prop: str):
|
def getAllExtruderSettings(self, setting_key: str, prop: str) -> List:
|
||||||
result = []
|
result = []
|
||||||
for index in self.extruderIds:
|
|
||||||
extruder_stack_id = self.extruderIds[str(index)]
|
for extruder_stack in self.getActiveExtruderStacks():
|
||||||
extruder_stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
|
||||||
result.append(extruder_stack.getProperty(setting_key, prop))
|
result.append(extruder_stack.getProperty(setting_key, prop))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def extruderValueWithDefault(self, value):
|
def extruderValueWithDefault(self, value: str) -> str:
|
||||||
machine_manager = self._application.getMachineManager()
|
machine_manager = self._application.getMachineManager()
|
||||||
if value == "-1":
|
if value == "-1":
|
||||||
return machine_manager.defaultExtruderPosition
|
return machine_manager.defaultExtruderPosition
|
||||||
@ -321,7 +288,7 @@ class ExtruderManager(QObject):
|
|||||||
## Removes the container stack and user profile for the extruders for a specific machine.
|
## Removes the container stack and user profile for the extruders for a specific machine.
|
||||||
#
|
#
|
||||||
# \param machine_id The machine to remove the extruders for.
|
# \param machine_id The machine to remove the extruders for.
|
||||||
def removeMachineExtruders(self, machine_id: str):
|
def removeMachineExtruders(self, machine_id: str) -> None:
|
||||||
for extruder in self.getMachineExtruders(machine_id):
|
for extruder in self.getMachineExtruders(machine_id):
|
||||||
ContainerRegistry.getInstance().removeContainer(extruder.userChanges.getId())
|
ContainerRegistry.getInstance().removeContainer(extruder.userChanges.getId())
|
||||||
ContainerRegistry.getInstance().removeContainer(extruder.getId())
|
ContainerRegistry.getInstance().removeContainer(extruder.getId())
|
||||||
@ -331,24 +298,11 @@ class ExtruderManager(QObject):
|
|||||||
## Returns extruders for a specific machine.
|
## Returns extruders for a specific machine.
|
||||||
#
|
#
|
||||||
# \param machine_id The machine to get the extruders of.
|
# \param machine_id The machine to get the extruders of.
|
||||||
def getMachineExtruders(self, machine_id: str):
|
def getMachineExtruders(self, machine_id: str) -> List["ExtruderStack"]:
|
||||||
if machine_id not in self._extruder_trains:
|
if machine_id not in self._extruder_trains:
|
||||||
return []
|
return []
|
||||||
return [self._extruder_trains[machine_id][name] for name in self._extruder_trains[machine_id]]
|
return [self._extruder_trains[machine_id][name] for name in self._extruder_trains[machine_id]]
|
||||||
|
|
||||||
## Returns a list containing the global stack and active extruder stacks.
|
|
||||||
#
|
|
||||||
# The first element is the global container stack, followed by any extruder stacks.
|
|
||||||
# \return \type{List[ContainerStack]}
|
|
||||||
def getActiveGlobalAndExtruderStacks(self) -> Optional[List[Union["ExtruderStack", "GlobalStack"]]]:
|
|
||||||
global_stack = self._application.getGlobalContainerStack()
|
|
||||||
if not global_stack:
|
|
||||||
return None
|
|
||||||
|
|
||||||
result = [global_stack]
|
|
||||||
result.extend(self.getActiveExtruderStacks())
|
|
||||||
return result
|
|
||||||
|
|
||||||
## Returns the list of active extruder stacks, taking into account the machine extruder count.
|
## Returns the list of active extruder stacks, taking into account the machine extruder count.
|
||||||
#
|
#
|
||||||
# \return \type{List[ContainerStack]} a list of
|
# \return \type{List[ContainerStack]} a list of
|
||||||
@ -357,14 +311,11 @@ class ExtruderManager(QObject):
|
|||||||
if not global_stack:
|
if not global_stack:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
result = []
|
result_tuple_list = sorted(list(global_stack.extruders.items()), key = lambda x: int(x[0]))
|
||||||
if global_stack.getId() in self._extruder_trains:
|
result_list = [item[1] for item in result_tuple_list]
|
||||||
for extruder in sorted(self._extruder_trains[global_stack.getId()]):
|
|
||||||
result.append(self._extruder_trains[global_stack.getId()][extruder])
|
|
||||||
|
|
||||||
machine_extruder_count = global_stack.getProperty("machine_extruder_count", "value")
|
machine_extruder_count = global_stack.getProperty("machine_extruder_count", "value")
|
||||||
|
return result_list[:machine_extruder_count]
|
||||||
return result[:machine_extruder_count]
|
|
||||||
|
|
||||||
def _globalContainerStackChanged(self) -> None:
|
def _globalContainerStackChanged(self) -> None:
|
||||||
# If the global container changed, the machine changed and might have extruders that were not registered yet
|
# If the global container changed, the machine changed and might have extruders that were not registered yet
|
||||||
@ -406,7 +357,7 @@ class ExtruderManager(QObject):
|
|||||||
|
|
||||||
# After 3.4, all single-extrusion machines have their own extruder definition files instead of reusing
|
# After 3.4, all single-extrusion machines have their own extruder definition files instead of reusing
|
||||||
# "fdmextruder". We need to check a machine here so its extruder definition is correct according to this.
|
# "fdmextruder". We need to check a machine here so its extruder definition is correct according to this.
|
||||||
def _fixSingleExtrusionMachineExtruderDefinition(self, global_stack):
|
def _fixSingleExtrusionMachineExtruderDefinition(self, global_stack: "GlobalStack") -> None:
|
||||||
expected_extruder_definition_0_id = global_stack.getMetaDataEntry("machine_extruder_trains")["0"]
|
expected_extruder_definition_0_id = global_stack.getMetaDataEntry("machine_extruder_trains")["0"]
|
||||||
extruder_stack_0 = global_stack.extruders["0"]
|
extruder_stack_0 = global_stack.extruders["0"]
|
||||||
if extruder_stack_0.definition.getId() != expected_extruder_definition_0_id:
|
if extruder_stack_0.definition.getId() != expected_extruder_definition_0_id:
|
||||||
@ -425,11 +376,11 @@ class ExtruderManager(QObject):
|
|||||||
# \return A list of values for all extruders. If an extruder does not have a value, it will not be in the list.
|
# \return A list of values for all extruders. If an extruder does not have a value, it will not be in the list.
|
||||||
# If no extruder has the value, the list will contain the global value.
|
# If no extruder has the value, the list will contain the global value.
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getExtruderValues(key):
|
def getExtruderValues(key: str) -> List[Any]:
|
||||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
|
for extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
if not extruder.isEnabled:
|
if not extruder.isEnabled:
|
||||||
continue
|
continue
|
||||||
# only include values from extruders that are "active" for the current machine instance
|
# only include values from extruders that are "active" for the current machine instance
|
||||||
@ -460,7 +411,7 @@ class ExtruderManager(QObject):
|
|||||||
# \return A list of values for all extruders. If an extruder does not have a value, it will not be in the list.
|
# \return A list of values for all extruders. If an extruder does not have a value, it will not be in the list.
|
||||||
# If no extruder has the value, the list will contain the global value.
|
# If no extruder has the value, the list will contain the global value.
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getDefaultExtruderValues(key):
|
def getDefaultExtruderValues(key: str) -> List[Any]:
|
||||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||||
context = PropertyEvaluationContext(global_stack)
|
context = PropertyEvaluationContext(global_stack)
|
||||||
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
|
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
|
||||||
@ -471,7 +422,7 @@ class ExtruderManager(QObject):
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
|
for extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
# only include values from extruders that are "active" for the current machine instance
|
# only include values from extruders that are "active" for the current machine instance
|
||||||
if int(extruder.getMetaDataEntry("position")) >= global_stack.getProperty("machine_extruder_count", "value", context = context):
|
if int(extruder.getMetaDataEntry("position")) >= global_stack.getProperty("machine_extruder_count", "value", context = context):
|
||||||
continue
|
continue
|
||||||
@ -504,7 +455,7 @@ class ExtruderManager(QObject):
|
|||||||
#
|
#
|
||||||
# \return String representing the extruder values
|
# \return String representing the extruder values
|
||||||
@pyqtSlot(str, result="QVariant")
|
@pyqtSlot(str, result="QVariant")
|
||||||
def getInstanceExtruderValues(self, key):
|
def getInstanceExtruderValues(self, key) -> List:
|
||||||
return ExtruderManager.getExtruderValues(key)
|
return ExtruderManager.getExtruderValues(key)
|
||||||
|
|
||||||
## Get the value for a setting from a specific extruder.
|
## Get the value for a setting from a specific extruder.
|
||||||
@ -517,7 +468,7 @@ class ExtruderManager(QObject):
|
|||||||
# \return The value of the setting for the specified extruder or for the
|
# \return The value of the setting for the specified extruder or for the
|
||||||
# global stack if not found.
|
# global stack if not found.
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getExtruderValue(extruder_index, key):
|
def getExtruderValue(extruder_index: int, key: str) -> Any:
|
||||||
if extruder_index == -1:
|
if extruder_index == -1:
|
||||||
extruder_index = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition)
|
extruder_index = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition)
|
||||||
extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
|
extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
|
||||||
@ -542,7 +493,7 @@ class ExtruderManager(QObject):
|
|||||||
# \return The value of the setting for the specified extruder or for the
|
# \return The value of the setting for the specified extruder or for the
|
||||||
# global stack if not found.
|
# global stack if not found.
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getDefaultExtruderValue(extruder_index, key):
|
def getDefaultExtruderValue(extruder_index: int, key: str) -> Any:
|
||||||
extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
|
extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
|
||||||
context = PropertyEvaluationContext(extruder)
|
context = PropertyEvaluationContext(extruder)
|
||||||
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
|
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
|
||||||
@ -569,7 +520,7 @@ class ExtruderManager(QObject):
|
|||||||
#
|
#
|
||||||
# \return The effective value
|
# \return The effective value
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getResolveOrValue(key):
|
def getResolveOrValue(key: str) -> Any:
|
||||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||||
resolved_value = global_stack.getProperty(key, "value")
|
resolved_value = global_stack.getProperty(key, "value")
|
||||||
|
|
||||||
@ -583,7 +534,7 @@ class ExtruderManager(QObject):
|
|||||||
#
|
#
|
||||||
# \return The effective value
|
# \return The effective value
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getDefaultResolveOrValue(key):
|
def getDefaultResolveOrValue(key: str) -> Any:
|
||||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||||
context = PropertyEvaluationContext(global_stack)
|
context = PropertyEvaluationContext(global_stack)
|
||||||
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
|
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
|
||||||
|
@ -134,7 +134,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
|||||||
# Link to new extruders
|
# Link to new extruders
|
||||||
self._active_machine_extruders = []
|
self._active_machine_extruders = []
|
||||||
extruder_manager = Application.getInstance().getExtruderManager()
|
extruder_manager = Application.getInstance().getExtruderManager()
|
||||||
for extruder in extruder_manager.getExtruderStacks():
|
for extruder in extruder_manager.getActiveExtruderStacks():
|
||||||
if extruder is None: #This extruder wasn't loaded yet. This happens asynchronously while this model is constructed from QML.
|
if extruder is None: #This extruder wasn't loaded yet. This happens asynchronously while this model is constructed from QML.
|
||||||
continue
|
continue
|
||||||
extruder.containersChanged.connect(self._onExtruderStackContainersChanged)
|
extruder.containersChanged.connect(self._onExtruderStackContainersChanged)
|
||||||
@ -171,7 +171,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
|||||||
# get machine extruder count for verification
|
# get machine extruder count for verification
|
||||||
machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value")
|
machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value")
|
||||||
|
|
||||||
for extruder in Application.getInstance().getExtruderManager().getMachineExtruders(global_container_stack.getId()):
|
for extruder in Application.getInstance().getExtruderManager().getActiveExtruderStacks():
|
||||||
position = extruder.getMetaDataEntry("position", default = "0") # Get the position
|
position = extruder.getMetaDataEntry("position", default = "0") # Get the position
|
||||||
try:
|
try:
|
||||||
position = int(position)
|
position = int(position)
|
||||||
|
@ -13,6 +13,8 @@ from UM.Settings.SettingInstance import InstanceState
|
|||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
from UM.Settings.Interfaces import PropertyEvaluationContext
|
from UM.Settings.Interfaces import PropertyEvaluationContext
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
|
from UM.Util import parseBool
|
||||||
|
|
||||||
import cura.CuraApplication
|
import cura.CuraApplication
|
||||||
|
|
||||||
from . import Exceptions
|
from . import Exceptions
|
||||||
@ -188,6 +190,15 @@ class GlobalStack(CuraContainerStack):
|
|||||||
def getHeadAndFansCoordinates(self):
|
def getHeadAndFansCoordinates(self):
|
||||||
return self.getProperty("machine_head_with_fans_polygon", "value")
|
return self.getProperty("machine_head_with_fans_polygon", "value")
|
||||||
|
|
||||||
|
def getHasMaterials(self) -> bool:
|
||||||
|
return parseBool(self.getMetaDataEntry("has_materials", False))
|
||||||
|
|
||||||
|
def getHasVariants(self) -> bool:
|
||||||
|
return parseBool(self.getMetaDataEntry("has_variants", False))
|
||||||
|
|
||||||
|
def getHasMachineQuality(self) -> bool:
|
||||||
|
return parseBool(self.getMetaDataEntry("has_machine_quality", False))
|
||||||
|
|
||||||
|
|
||||||
## private:
|
## private:
|
||||||
global_stack_mime = MimeType(
|
global_stack_mime = MimeType(
|
||||||
|
@ -385,7 +385,9 @@ class MachineManager(QObject):
|
|||||||
# \param definition_id \type{str} definition id that needs to look for
|
# \param definition_id \type{str} definition id that needs to look for
|
||||||
# \param metadata_filter \type{dict} list of metadata keys and values used for filtering
|
# \param metadata_filter \type{dict} list of metadata keys and values used for filtering
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getMachine(definition_id: str, metadata_filter: Dict[str, str] = None) -> Optional["GlobalStack"]:
|
def getMachine(definition_id: str, metadata_filter: Optional[Dict[str, str]] = None) -> Optional["GlobalStack"]:
|
||||||
|
if metadata_filter is None:
|
||||||
|
metadata_filter = {}
|
||||||
machines = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
machines = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||||
for machine in machines:
|
for machine in machines:
|
||||||
if machine.definition.getId() == definition_id:
|
if machine.definition.getId() == definition_id:
|
||||||
@ -412,7 +414,7 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
# Not a very pretty solution, but the extruder manager doesn't really know how many extruders there are
|
# Not a very pretty solution, but the extruder manager doesn't really know how many extruders there are
|
||||||
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_stacks = ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())
|
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
count = 1 # we start with the global stack
|
count = 1 # we start with the global stack
|
||||||
for stack in extruder_stacks:
|
for stack in extruder_stacks:
|
||||||
md = stack.getMetaData()
|
md = stack.getMetaData()
|
||||||
@ -435,7 +437,7 @@ class MachineManager(QObject):
|
|||||||
if self._global_container_stack.getTop().findInstances():
|
if self._global_container_stack.getTop().findInstances():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
|
stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
for stack in stacks:
|
for stack in stacks:
|
||||||
if stack.getTop().findInstances():
|
if stack.getTop().findInstances():
|
||||||
return True
|
return True
|
||||||
@ -448,7 +450,7 @@ class MachineManager(QObject):
|
|||||||
return 0
|
return 0
|
||||||
num_user_settings = 0
|
num_user_settings = 0
|
||||||
num_user_settings += len(self._global_container_stack.getTop().findInstances())
|
num_user_settings += len(self._global_container_stack.getTop().findInstances())
|
||||||
stacks = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
|
stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
for stack in stacks:
|
for stack in stacks:
|
||||||
num_user_settings += len(stack.getTop().findInstances())
|
num_user_settings += len(stack.getTop().findInstances())
|
||||||
return num_user_settings
|
return num_user_settings
|
||||||
@ -473,7 +475,7 @@ class MachineManager(QObject):
|
|||||||
stack = ExtruderManager.getInstance().getActiveExtruderStack()
|
stack = ExtruderManager.getInstance().getActiveExtruderStack()
|
||||||
stacks = [stack]
|
stacks = [stack]
|
||||||
else:
|
else:
|
||||||
stacks = ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())
|
stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
|
|
||||||
for stack in stacks:
|
for stack in stacks:
|
||||||
if stack is not None:
|
if stack is not None:
|
||||||
@ -638,7 +640,7 @@ class MachineManager(QObject):
|
|||||||
if self._active_container_stack is None or self._global_container_stack is None:
|
if self._active_container_stack is None or self._global_container_stack is None:
|
||||||
return
|
return
|
||||||
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().getActiveExtruderStacks()]
|
||||||
|
|
||||||
# check in which stack the value has to be replaced
|
# check in which stack the value has to be replaced
|
||||||
for extruder_stack in extruder_stacks:
|
for extruder_stack in extruder_stacks:
|
||||||
|
@ -43,7 +43,9 @@ class UserChangesModel(ListModel):
|
|||||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if not global_stack:
|
if not global_stack:
|
||||||
return
|
return
|
||||||
stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
|
|
||||||
|
stacks = [global_stack]
|
||||||
|
stacks.extend(global_stack.extruders.values())
|
||||||
|
|
||||||
# Check if the definition container has a translation file and ensure it's loaded.
|
# Check if the definition container has a translation file and ensure it's loaded.
|
||||||
definition = global_stack.getBottom()
|
definition = global_stack.getBottom()
|
||||||
|
@ -225,7 +225,7 @@ class ThreeMFReader(MeshReader):
|
|||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
Logger.logException("e", "An exception occurred in 3mf reader.")
|
Logger.logException("e", "An exception occurred in 3mf reader.")
|
||||||
return []
|
return None
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||||||
if not self._global_container_stack:
|
if not self._global_container_stack:
|
||||||
Logger.log("w", "Global container stack not assigned to CuraEngineBackend!")
|
Logger.log("w", "Global container stack not assigned to CuraEngineBackend!")
|
||||||
return
|
return
|
||||||
extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
|
extruders = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
error_keys = [] #type: List[str]
|
error_keys = [] #type: List[str]
|
||||||
for extruder in extruders:
|
for extruder in extruders:
|
||||||
error_keys.extend(extruder.getErrorKeys())
|
error_keys.extend(extruder.getErrorKeys())
|
||||||
|
@ -178,7 +178,7 @@ class ProcessSlicedLayersJob(Job):
|
|||||||
# Find out colors per extruder
|
# Find out colors per extruder
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
manager = ExtruderManager.getInstance()
|
manager = ExtruderManager.getInstance()
|
||||||
extruders = list(manager.getMachineExtruders(global_container_stack.getId()))
|
extruders = manager.getActiveExtruderStacks()
|
||||||
if extruders:
|
if extruders:
|
||||||
material_color_map = numpy.zeros((len(extruders), 4), dtype=numpy.float32)
|
material_color_map = numpy.zeros((len(extruders), 4), dtype=numpy.float32)
|
||||||
for extruder in extruders:
|
for extruder in extruders:
|
||||||
|
@ -333,7 +333,7 @@ class StartSliceJob(Job):
|
|||||||
"-1": self._buildReplacementTokens(global_stack)
|
"-1": self._buildReplacementTokens(global_stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
for extruder_stack in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
|
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
extruder_nr = extruder_stack.getProperty("extruder_nr", "value")
|
extruder_nr = extruder_stack.getProperty("extruder_nr", "value")
|
||||||
self._all_extruders_settings[str(extruder_nr)] = self._buildReplacementTokens(extruder_stack)
|
self._all_extruders_settings[str(extruder_nr)] = self._buildReplacementTokens(extruder_stack)
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ class FlavorParser:
|
|||||||
## For showing correct x, y offsets for each extruder
|
## For showing correct x, y offsets for each extruder
|
||||||
def _extruderOffsets(self) -> Dict[int, List[float]]:
|
def _extruderOffsets(self) -> Dict[int, List[float]]:
|
||||||
result = {}
|
result = {}
|
||||||
for extruder in ExtruderManager.getInstance().getExtruderStacks():
|
for extruder in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
result[int(extruder.getMetaData().get("position", "0"))] = [
|
result[int(extruder.getMetaData().get("position", "0"))] = [
|
||||||
extruder.getProperty("machine_nozzle_offset_x", "value"),
|
extruder.getProperty("machine_nozzle_offset_x", "value"),
|
||||||
extruder.getProperty("machine_nozzle_offset_y", "value")]
|
extruder.getProperty("machine_nozzle_offset_y", "value")]
|
||||||
|
@ -16,6 +16,8 @@ Cura.MachineAction
|
|||||||
property var extrudersModel: Cura.ExtrudersModel{}
|
property var extrudersModel: Cura.ExtrudersModel{}
|
||||||
property int extruderTabsCount: 0
|
property int extruderTabsCount: 0
|
||||||
|
|
||||||
|
property var activeMachineId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.id : ""
|
||||||
|
|
||||||
Connections
|
Connections
|
||||||
{
|
{
|
||||||
target: base.extrudersModel
|
target: base.extrudersModel
|
||||||
@ -511,7 +513,7 @@ Cura.MachineAction
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return Cura.MachineManager.activeMachineId;
|
return base.activeMachineId
|
||||||
}
|
}
|
||||||
key: settingKey
|
key: settingKey
|
||||||
watchedProperties: [ "value", "description" ]
|
watchedProperties: [ "value", "description" ]
|
||||||
@ -564,7 +566,7 @@ Cura.MachineAction
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return Cura.MachineManager.activeMachineId;
|
return base.activeMachineId
|
||||||
}
|
}
|
||||||
key: settingKey
|
key: settingKey
|
||||||
watchedProperties: [ "value", "description" ]
|
watchedProperties: [ "value", "description" ]
|
||||||
@ -655,7 +657,7 @@ Cura.MachineAction
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return Cura.MachineManager.activeMachineId;
|
return base.activeMachineId
|
||||||
}
|
}
|
||||||
key: settingKey
|
key: settingKey
|
||||||
watchedProperties: [ "value", "options", "description" ]
|
watchedProperties: [ "value", "options", "description" ]
|
||||||
@ -754,7 +756,7 @@ Cura.MachineAction
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return Cura.MachineManager.activeMachineId;
|
return base.activeMachineId
|
||||||
}
|
}
|
||||||
key: settingKey
|
key: settingKey
|
||||||
watchedProperties: [ "value", "description" ]
|
watchedProperties: [ "value", "description" ]
|
||||||
@ -879,7 +881,7 @@ Cura.MachineAction
|
|||||||
{
|
{
|
||||||
id: machineExtruderCountProvider
|
id: machineExtruderCountProvider
|
||||||
|
|
||||||
containerStackId: Cura.MachineManager.activeMachineId
|
containerStackId: base.activeMachineId
|
||||||
key: "machine_extruder_count"
|
key: "machine_extruder_count"
|
||||||
watchedProperties: [ "value", "description" ]
|
watchedProperties: [ "value", "description" ]
|
||||||
storeIndex: manager.containerIndex
|
storeIndex: manager.containerIndex
|
||||||
@ -889,7 +891,7 @@ Cura.MachineAction
|
|||||||
{
|
{
|
||||||
id: machineHeadPolygonProvider
|
id: machineHeadPolygonProvider
|
||||||
|
|
||||||
containerStackId: Cura.MachineManager.activeMachineId
|
containerStackId: base.activeMachineId
|
||||||
key: "machine_head_with_fans_polygon"
|
key: "machine_head_with_fans_polygon"
|
||||||
watchedProperties: [ "value" ]
|
watchedProperties: [ "value" ]
|
||||||
storeIndex: manager.containerIndex
|
storeIndex: manager.containerIndex
|
||||||
|
@ -17,7 +17,6 @@ Item {
|
|||||||
|
|
||||||
width: childrenRect.width;
|
width: childrenRect.width;
|
||||||
height: childrenRect.height;
|
height: childrenRect.height;
|
||||||
|
|
||||||
property var all_categories_except_support: [ "machine_settings", "resolution", "shell", "infill", "material", "speed",
|
property var all_categories_except_support: [ "machine_settings", "resolution", "shell", "infill", "material", "speed",
|
||||||
"travel", "cooling", "platform_adhesion", "dual", "meshfix", "blackmagic", "experimental"]
|
"travel", "cooling", "platform_adhesion", "dual", "meshfix", "blackmagic", "experimental"]
|
||||||
|
|
||||||
@ -45,7 +44,7 @@ Item {
|
|||||||
UM.SettingPropertyProvider
|
UM.SettingPropertyProvider
|
||||||
{
|
{
|
||||||
id: meshTypePropertyProvider
|
id: meshTypePropertyProvider
|
||||||
containerStackId: Cura.MachineManager.activeMachineId
|
containerStack: Cura.MachineManager.activeMachine
|
||||||
watchedProperties: [ "enabled" ]
|
watchedProperties: [ "enabled" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +517,7 @@ Item {
|
|||||||
{
|
{
|
||||||
id: machineExtruderCount
|
id: machineExtruderCount
|
||||||
|
|
||||||
containerStackId: Cura.MachineManager.activeMachineId
|
containerStack: Cura.MachineManager.activeMachine
|
||||||
key: "machine_extruder_count"
|
key: "machine_extruder_count"
|
||||||
watchedProperties: [ "value" ]
|
watchedProperties: [ "value" ]
|
||||||
storeIndex: 0
|
storeIndex: 0
|
||||||
@ -528,7 +527,7 @@ Item {
|
|||||||
{
|
{
|
||||||
id: printSequencePropertyProvider
|
id: printSequencePropertyProvider
|
||||||
|
|
||||||
containerStackId: Cura.MachineManager.activeMachineId
|
containerStack: Cura.MachineManager.activeMachine
|
||||||
key: "print_sequence"
|
key: "print_sequence"
|
||||||
watchedProperties: [ "value" ]
|
watchedProperties: [ "value" ]
|
||||||
storeIndex: 0
|
storeIndex: 0
|
||||||
|
@ -384,7 +384,7 @@ UM.Dialog
|
|||||||
UM.SettingPropertyProvider
|
UM.SettingPropertyProvider
|
||||||
{
|
{
|
||||||
id: inheritStackProvider
|
id: inheritStackProvider
|
||||||
containerStackId: Cura.MachineManager.activeMachineId
|
containerStack: Cura.MachineManager.activeMachine
|
||||||
key: model.key ? model.key : "None"
|
key: model.key ? model.key : "None"
|
||||||
watchedProperties: [ "limit_to_extruder" ]
|
watchedProperties: [ "limit_to_extruder" ]
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,11 @@ UM.PointingRectangle {
|
|||||||
id: valueLabel
|
id: valueLabel
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: parent.left
|
|
||||||
leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
|
|
||||||
verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
width: maximumValue.toString().length * 12 * screenScaleFactor
|
width: (maximumValue.toString().length + 1) * 10 * screenScaleFactor
|
||||||
text: sliderLabelRoot.value + startFrom // the current handle value, add 1 because layers is an array
|
text: sliderLabelRoot.value + startFrom // the current handle value, add 1 because layers is an array
|
||||||
horizontalAlignment: TextInput.AlignRight
|
horizontalAlignment: TextInput.AlignRight
|
||||||
|
|
||||||
|
@ -667,8 +667,12 @@ Item
|
|||||||
{
|
{
|
||||||
target: UM.SimulationView
|
target: UM.SimulationView
|
||||||
onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer)
|
onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer)
|
||||||
onMinimumLayerChanged: layerSlider.setLowerValue(UM.SimulationView.minimumLayer)
|
onCurrentLayerChanged:
|
||||||
onCurrentLayerChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer)
|
{
|
||||||
|
playButton.pauseSimulation()
|
||||||
|
pathSlider.setHandleValue(0) // After updating the layer set Path slider to 0
|
||||||
|
layerSlider.setUpperValue(UM.SimulationView.currentLayer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the slider handlers show the correct value after switching views
|
// make sure the slider handlers show the correct value after switching views
|
||||||
@ -723,6 +727,7 @@ Item
|
|||||||
UM.SimulationView.setSimulationRunning(true)
|
UM.SimulationView.setSimulationRunning(true)
|
||||||
iconSource = "./resources/simulation_pause.svg"
|
iconSource = "./resources/simulation_pause.svg"
|
||||||
simulationTimer.start()
|
simulationTimer.start()
|
||||||
|
status = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -766,6 +771,7 @@ Item
|
|||||||
{
|
{
|
||||||
UM.SimulationView.setCurrentLayer(currentLayer+1)
|
UM.SimulationView.setCurrentLayer(currentLayer+1)
|
||||||
UM.SimulationView.setCurrentPath(0)
|
UM.SimulationView.setCurrentPath(0)
|
||||||
|
playButton.resumeSimulation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -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.7
|
||||||
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
|
||||||
|
@ -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.7
|
||||||
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
|
||||||
|
@ -32,7 +32,7 @@ Item
|
|||||||
width: UM.Theme.getSize("toolbox_thumbnail_medium").width
|
width: UM.Theme.getSize("toolbox_thumbnail_medium").width
|
||||||
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 === null ? "" : (details.icon_url || "../images/logobot.svg")
|
||||||
mipmap: true
|
mipmap: true
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
@ -55,7 +55,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 === null ? "" : (details.name || "")
|
||||||
font: UM.Theme.getFont("large")
|
font: UM.Theme.getFont("large")
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
@ -114,7 +114,7 @@ Item
|
|||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
text: details.version || catalog.i18nc("@label", "Unknown")
|
text: details === null ? "" : (details.version || catalog.i18nc("@label", "Unknown"))
|
||||||
font: UM.Theme.getFont("very_small")
|
font: UM.Theme.getFont("very_small")
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
}
|
}
|
||||||
@ -122,6 +122,10 @@ Item
|
|||||||
{
|
{
|
||||||
text:
|
text:
|
||||||
{
|
{
|
||||||
|
if (details === null)
|
||||||
|
{
|
||||||
|
return ""
|
||||||
|
}
|
||||||
var date = new Date(details.last_updated)
|
var date = new Date(details.last_updated)
|
||||||
return date.toLocaleString(UM.Preferences.getValue("general/language"))
|
return date.toLocaleString(UM.Preferences.getValue("general/language"))
|
||||||
}
|
}
|
||||||
@ -132,6 +136,10 @@ Item
|
|||||||
{
|
{
|
||||||
text:
|
text:
|
||||||
{
|
{
|
||||||
|
if (details === null)
|
||||||
|
{
|
||||||
|
return ""
|
||||||
|
}
|
||||||
if (details.author_email)
|
if (details.author_email)
|
||||||
{
|
{
|
||||||
return "<a href=\"mailto:" + details.author_email+"?Subject=Cura: " + details.name + "\">" + details.author_name + "</a>"
|
return "<a href=\"mailto:" + details.author_email+"?Subject=Cura: " + details.name + "\">" + details.author_name + "</a>"
|
||||||
@ -148,7 +156,7 @@ Item
|
|||||||
}
|
}
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
text: details.download_count || catalog.i18nc("@label", "Unknown")
|
text: details === null ? "" : (details.download_count || catalog.i18nc("@label", "Unknown"))
|
||||||
font: UM.Theme.getFont("very_small")
|
font: UM.Theme.getFont("very_small")
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
}
|
}
|
||||||
|
@ -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.7
|
||||||
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
|
||||||
{
|
{
|
||||||
property int packageCount: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getTotalNumberOfPackagesByAuthor(model.id) : 1
|
property int packageCount: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getTotalNumberOfMaterialPackagesByAuthor(model.id) : 1
|
||||||
property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
|
property int installedPackages: (toolbox.viewCategory == "material" && model.type === undefined) ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
||||||
|
@ -12,7 +12,9 @@ ScrollView
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
style: UM.Theme.styles.scrollview
|
style: UM.Theme.styles.scrollview
|
||||||
|
|
||||||
flickableItem.flickableDirection: Flickable.VerticalFlick
|
flickableItem.flickableDirection: Flickable.VerticalFlick
|
||||||
|
|
||||||
Column
|
Column
|
||||||
{
|
{
|
||||||
width: base.width
|
width: base.width
|
||||||
@ -30,7 +32,7 @@ ScrollView
|
|||||||
id: allPlugins
|
id: allPlugins
|
||||||
width: parent.width
|
width: parent.width
|
||||||
heading: toolbox.viewCategory == "material" ? catalog.i18nc("@label", "Community Contributions") : catalog.i18nc("@label", "Community Plugins")
|
heading: toolbox.viewCategory == "material" ? catalog.i18nc("@label", "Community Contributions") : catalog.i18nc("@label", "Community Plugins")
|
||||||
model: toolbox.viewCategory == "material" ? toolbox.authorsModel : toolbox.packagesModel
|
model: toolbox.viewCategory == "material" ? toolbox.materialsAvailableModel : toolbox.pluginsAvailableModel
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolboxDownloadsGrid
|
ToolboxDownloadsGrid
|
||||||
|
@ -9,7 +9,7 @@ import UM 1.1 as UM
|
|||||||
|
|
||||||
Rectangle
|
Rectangle
|
||||||
{
|
{
|
||||||
property int packageCount: toolbox.viewCategory == "material" ? toolbox.getTotalNumberOfPackagesByAuthor(model.id) : 1
|
property int packageCount: toolbox.viewCategory == "material" ? toolbox.getTotalNumberOfMaterialPackagesByAuthor(model.id) : 1
|
||||||
property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
|
property int installedPackages: toolbox.viewCategory == "material" ? toolbox.getNumberOfInstalledPackagesByAuthor(model.id) : (toolbox.isInstalled(model.id) ? 1 : 0)
|
||||||
id: tileBase
|
id: tileBase
|
||||||
width: UM.Theme.getSize("toolbox_thumbnail_large").width + (2 * UM.Theme.getSize("default_lining").width)
|
width: UM.Theme.getSize("toolbox_thumbnail_large").width + (2 * UM.Theme.getSize("default_lining").width)
|
||||||
|
@ -34,6 +34,7 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* // NOTE: Remember to re-enable for v3.6!
|
||||||
ToolboxTabButton
|
ToolboxTabButton
|
||||||
{
|
{
|
||||||
text: catalog.i18nc("@title:tab", "Materials")
|
text: catalog.i18nc("@title:tab", "Materials")
|
||||||
@ -46,6 +47,7 @@ Item
|
|||||||
toolbox.viewPage = "overview"
|
toolbox.viewPage = "overview"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
ToolboxTabButton
|
ToolboxTabButton
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ import QtQuick.Dialogs 1.1
|
|||||||
import QtQuick.Window 2.2
|
import QtQuick.Window 2.2
|
||||||
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
|
||||||
|
|
||||||
ScrollView
|
ScrollView
|
||||||
@ -16,6 +17,7 @@ ScrollView
|
|||||||
height: parent.height
|
height: parent.height
|
||||||
style: UM.Theme.styles.scrollview
|
style: UM.Theme.styles.scrollview
|
||||||
flickableItem.flickableDirection: Flickable.VerticalFlick
|
flickableItem.flickableDirection: Flickable.VerticalFlick
|
||||||
|
|
||||||
Column
|
Column
|
||||||
{
|
{
|
||||||
spacing: UM.Theme.getSize("default_margin").height
|
spacing: UM.Theme.getSize("default_margin").height
|
||||||
|
@ -33,6 +33,9 @@ class AuthorsModel(ListModel):
|
|||||||
|
|
||||||
def _update(self):
|
def _update(self):
|
||||||
items = []
|
items = []
|
||||||
|
if not self._metadata:
|
||||||
|
self.setItems([])
|
||||||
|
return
|
||||||
|
|
||||||
for author in self._metadata:
|
for author in self._metadata:
|
||||||
items.append({
|
items.append({
|
||||||
|
@ -76,7 +76,6 @@ class PackagesModel(ListModel):
|
|||||||
if "author_id" not in package["author"] or "display_name" not in package["author"]:
|
if "author_id" not in package["author"] or "display_name" not in package["author"]:
|
||||||
package["author"]["author_id"] = ""
|
package["author"]["author_id"] = ""
|
||||||
package["author"]["display_name"] = ""
|
package["author"]["display_name"] = ""
|
||||||
# raise Exception("Detected a package with malformed author data.")
|
|
||||||
|
|
||||||
items.append({
|
items.append({
|
||||||
"id": package["package_id"],
|
"id": package["package_id"],
|
||||||
|
@ -6,7 +6,7 @@ import json
|
|||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
import platform
|
import platform
|
||||||
from typing import cast, List
|
from typing import cast, List, TYPE_CHECKING, Tuple, Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import QUrl, QObject, pyqtProperty, pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import QUrl, QObject, pyqtProperty, pyqtSignal, pyqtSlot
|
||||||
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
||||||
@ -20,9 +20,13 @@ from UM.Version import Version
|
|||||||
|
|
||||||
import cura
|
import cura
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
from .AuthorsModel import AuthorsModel
|
from .AuthorsModel import AuthorsModel
|
||||||
from .PackagesModel import PackagesModel
|
from .PackagesModel import PackagesModel
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
|
||||||
i18n_catalog = i18nCatalog("cura")
|
i18n_catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
@ -34,19 +38,19 @@ class Toolbox(QObject, Extension):
|
|||||||
def __init__(self, application: CuraApplication) -> None:
|
def __init__(self, application: CuraApplication) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self._application = application #type: CuraApplication
|
self._application = application # type: CuraApplication
|
||||||
|
|
||||||
self._sdk_version = None # type: Optional[int]
|
self._sdk_version = None # type: Optional[int]
|
||||||
self._cloud_api_version = None # type: Optional[int]
|
self._cloud_api_version = None # type: Optional[int]
|
||||||
self._cloud_api_root = None # type: Optional[str]
|
self._cloud_api_root = None # type: Optional[str]
|
||||||
self._api_url = None # type: Optional[str]
|
self._api_url = None # type: Optional[str]
|
||||||
|
|
||||||
# Network:
|
# Network:
|
||||||
self._download_request = None #type: Optional[QNetworkRequest]
|
self._download_request = None # type: Optional[QNetworkRequest]
|
||||||
self._download_reply = None #type: Optional[QNetworkReply]
|
self._download_reply = None # type: Optional[QNetworkReply]
|
||||||
self._download_progress = 0 #type: float
|
self._download_progress = 0 # type: float
|
||||||
self._is_downloading = False #type: bool
|
self._is_downloading = False # type: bool
|
||||||
self._network_manager = None #type: Optional[QNetworkAccessManager]
|
self._network_manager = None # type: Optional[QNetworkAccessManager]
|
||||||
self._request_header = [
|
self._request_header = [
|
||||||
b"User-Agent",
|
b"User-Agent",
|
||||||
str.encode(
|
str.encode(
|
||||||
@ -58,9 +62,9 @@ class Toolbox(QObject, Extension):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self._request_urls = {} # type: Dict[str, QUrl]
|
self._request_urls = {} # type: Dict[str, QUrl]
|
||||||
self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated
|
self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated
|
||||||
self._old_plugin_ids = [] # type: List[str]
|
self._old_plugin_ids = [] # type: List[str]
|
||||||
|
|
||||||
# Data:
|
# Data:
|
||||||
self._metadata = {
|
self._metadata = {
|
||||||
@ -73,7 +77,7 @@ class Toolbox(QObject, Extension):
|
|||||||
"materials_available": [],
|
"materials_available": [],
|
||||||
"materials_installed": [],
|
"materials_installed": [],
|
||||||
"materials_generic": []
|
"materials_generic": []
|
||||||
} # type: Dict[str, List[Any]]
|
} # type: Dict[str, List[Any]]
|
||||||
|
|
||||||
# Models:
|
# Models:
|
||||||
self._models = {
|
self._models = {
|
||||||
@ -83,42 +87,40 @@ class Toolbox(QObject, Extension):
|
|||||||
"plugins_available": PackagesModel(self),
|
"plugins_available": PackagesModel(self),
|
||||||
"plugins_installed": PackagesModel(self),
|
"plugins_installed": PackagesModel(self),
|
||||||
"materials_showcase": AuthorsModel(self),
|
"materials_showcase": AuthorsModel(self),
|
||||||
"materials_available": PackagesModel(self),
|
"materials_available": AuthorsModel(self),
|
||||||
"materials_installed": PackagesModel(self),
|
"materials_installed": PackagesModel(self),
|
||||||
"materials_generic": PackagesModel(self)
|
"materials_generic": PackagesModel(self)
|
||||||
} # type: Dict[str, ListModel]
|
} # type: Dict[str, ListModel]
|
||||||
|
|
||||||
# These properties are for keeping track of the UI state:
|
# These properties are for keeping track of the UI state:
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
# View category defines which filter to use, and therefore effectively
|
# View category defines which filter to use, and therefore effectively
|
||||||
# which category is currently being displayed. For example, possible
|
# which category is currently being displayed. For example, possible
|
||||||
# values include "plugin" or "material", but also "installed".
|
# values include "plugin" or "material", but also "installed".
|
||||||
self._view_category = "plugin" #type: str
|
self._view_category = "plugin" # type: str
|
||||||
|
|
||||||
# View page defines which type of page layout to use. For example,
|
# View page defines which type of page layout to use. For example,
|
||||||
# possible values include "overview", "detail" or "author".
|
# possible values include "overview", "detail" or "author".
|
||||||
self._view_page = "loading" #type: str
|
self._view_page = "loading" # type: str
|
||||||
|
|
||||||
# Active package refers to which package is currently being downloaded,
|
# Active package refers to which package is currently being downloaded,
|
||||||
# installed, or otherwise modified.
|
# installed, or otherwise modified.
|
||||||
self._active_package = None # type: Optional[Dict[str, Any]]
|
self._active_package = None # type: Optional[Dict[str, Any]]
|
||||||
|
|
||||||
self._dialog = None #type: Optional[QObject]
|
self._dialog = None # type: Optional[QObject]
|
||||||
self._confirm_reset_dialog = None #type: Optional[QObject]
|
self._confirm_reset_dialog = None # type: Optional[QObject]
|
||||||
self._resetUninstallVariables()
|
self._resetUninstallVariables()
|
||||||
|
|
||||||
self._restart_required = False #type: bool
|
self._restart_required = False # type: bool
|
||||||
|
|
||||||
# variables for the license agreement dialog
|
# variables for the license agreement dialog
|
||||||
self._license_dialog_plugin_name = "" #type: str
|
self._license_dialog_plugin_name = "" # type: str
|
||||||
self._license_dialog_license_content = "" #type: str
|
self._license_dialog_license_content = "" # type: str
|
||||||
self._license_dialog_plugin_file_location = "" #type: str
|
self._license_dialog_plugin_file_location = "" # type: str
|
||||||
self._restart_dialog_message = "" #type: str
|
self._restart_dialog_message = "" # type: str
|
||||||
|
|
||||||
self._application.initializationFinished.connect(self._onAppInitialized)
|
self._application.initializationFinished.connect(self._onAppInitialized)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Signals:
|
# Signals:
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# Downloading changes
|
# Downloading changes
|
||||||
@ -137,11 +139,11 @@ class Toolbox(QObject, Extension):
|
|||||||
showLicenseDialog = pyqtSignal()
|
showLicenseDialog = pyqtSignal()
|
||||||
uninstallVariablesChanged = pyqtSignal()
|
uninstallVariablesChanged = pyqtSignal()
|
||||||
|
|
||||||
def _resetUninstallVariables(self):
|
def _resetUninstallVariables(self) -> None:
|
||||||
self._package_id_to_uninstall = None
|
self._package_id_to_uninstall = None # type: Optional[str]
|
||||||
self._package_name_to_uninstall = ""
|
self._package_name_to_uninstall = ""
|
||||||
self._package_used_materials = []
|
self._package_used_materials = [] # type: List[Tuple[GlobalStack, str, str]]
|
||||||
self._package_used_qualities = []
|
self._package_used_qualities = [] # type: List[Tuple[GlobalStack, str, str]]
|
||||||
|
|
||||||
@pyqtSlot(result = str)
|
@pyqtSlot(result = str)
|
||||||
def getLicenseDialogPluginName(self) -> str:
|
def getLicenseDialogPluginName(self) -> str:
|
||||||
@ -229,10 +231,12 @@ class Toolbox(QObject, Extension):
|
|||||||
# Make remote requests:
|
# Make remote requests:
|
||||||
self._makeRequestByType("packages")
|
self._makeRequestByType("packages")
|
||||||
self._makeRequestByType("authors")
|
self._makeRequestByType("authors")
|
||||||
self._makeRequestByType("plugins_showcase")
|
# TODO: Uncomment in the future when the tag-filtered api calls work in the cloud server
|
||||||
self._makeRequestByType("materials_showcase")
|
# self._makeRequestByType("plugins_showcase")
|
||||||
self._makeRequestByType("materials_available")
|
# self._makeRequestByType("plugins_available")
|
||||||
self._makeRequestByType("materials_generic")
|
# self._makeRequestByType("materials_showcase")
|
||||||
|
# self._makeRequestByType("materials_available")
|
||||||
|
# self._makeRequestByType("materials_generic")
|
||||||
|
|
||||||
# Gather installed packages:
|
# Gather installed packages:
|
||||||
self._updateInstalledModels()
|
self._updateInstalledModels()
|
||||||
@ -344,26 +348,26 @@ class Toolbox(QObject, Extension):
|
|||||||
self.uninstall(package_id)
|
self.uninstall(package_id)
|
||||||
|
|
||||||
@pyqtProperty(str, notify = uninstallVariablesChanged)
|
@pyqtProperty(str, notify = uninstallVariablesChanged)
|
||||||
def pluginToUninstall(self):
|
def pluginToUninstall(self) -> str:
|
||||||
return self._package_name_to_uninstall
|
return self._package_name_to_uninstall
|
||||||
|
|
||||||
@pyqtProperty(str, notify = uninstallVariablesChanged)
|
@pyqtProperty(str, notify = uninstallVariablesChanged)
|
||||||
def uninstallUsedMaterials(self):
|
def uninstallUsedMaterials(self) -> str:
|
||||||
return "\n".join(["%s (%s)" % (str(global_stack.getName()), material) for global_stack, extruder_nr, material in self._package_used_materials])
|
return "\n".join(["%s (%s)" % (str(global_stack.getName()), material) for global_stack, extruder_nr, material in self._package_used_materials])
|
||||||
|
|
||||||
@pyqtProperty(str, notify = uninstallVariablesChanged)
|
@pyqtProperty(str, notify = uninstallVariablesChanged)
|
||||||
def uninstallUsedQualities(self):
|
def uninstallUsedQualities(self) -> str:
|
||||||
return "\n".join(["%s (%s)" % (str(global_stack.getName()), quality) for global_stack, extruder_nr, quality in self._package_used_qualities])
|
return "\n".join(["%s (%s)" % (str(global_stack.getName()), quality) for global_stack, extruder_nr, quality in self._package_used_qualities])
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def closeConfirmResetDialog(self):
|
def closeConfirmResetDialog(self) -> None:
|
||||||
if self._confirm_reset_dialog is not None:
|
if self._confirm_reset_dialog is not None:
|
||||||
self._confirm_reset_dialog.close()
|
self._confirm_reset_dialog.close()
|
||||||
|
|
||||||
## Uses "uninstall variables" to reset qualities and materials, then uninstall
|
## Uses "uninstall variables" to reset qualities and materials, then uninstall
|
||||||
# It's used as an action on Confirm reset on Uninstall
|
# It's used as an action on Confirm reset on Uninstall
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def resetMaterialsQualitiesAndUninstall(self):
|
def resetMaterialsQualitiesAndUninstall(self) -> None:
|
||||||
application = CuraApplication.getInstance()
|
application = CuraApplication.getInstance()
|
||||||
material_manager = application.getMaterialManager()
|
material_manager = application.getMaterialManager()
|
||||||
quality_manager = application.getQualityManager()
|
quality_manager = application.getQualityManager()
|
||||||
@ -376,9 +380,9 @@ class Toolbox(QObject, Extension):
|
|||||||
default_quality_group = quality_manager.getDefaultQualityType(global_stack)
|
default_quality_group = quality_manager.getDefaultQualityType(global_stack)
|
||||||
machine_manager.setQualityGroup(default_quality_group, global_stack = global_stack)
|
machine_manager.setQualityGroup(default_quality_group, global_stack = global_stack)
|
||||||
|
|
||||||
self._markPackageMaterialsAsToBeUninstalled(self._package_id_to_uninstall)
|
if self._package_id_to_uninstall is not None:
|
||||||
|
self._markPackageMaterialsAsToBeUninstalled(self._package_id_to_uninstall)
|
||||||
self.uninstall(self._package_id_to_uninstall)
|
self.uninstall(self._package_id_to_uninstall)
|
||||||
self._resetUninstallVariables()
|
self._resetUninstallVariables()
|
||||||
self.closeConfirmResetDialog()
|
self.closeConfirmResetDialog()
|
||||||
|
|
||||||
@ -514,12 +518,14 @@ class Toolbox(QObject, Extension):
|
|||||||
count += 1
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
# This slot is only used to get the number of material packages by author, not any other type of packages.
|
||||||
@pyqtSlot(str, result = int)
|
@pyqtSlot(str, result = int)
|
||||||
def getTotalNumberOfPackagesByAuthor(self, author_id: str) -> int:
|
def getTotalNumberOfMaterialPackagesByAuthor(self, author_id: str) -> int:
|
||||||
count = 0
|
count = 0
|
||||||
for package in self._metadata["materials_available"]:
|
for package in self._metadata["packages"]:
|
||||||
if package["author"]["author_id"] == author_id:
|
if package["package_type"] == "material":
|
||||||
count += 1
|
if package["author"]["author_id"] == author_id:
|
||||||
|
count += 1
|
||||||
return count
|
return count
|
||||||
|
|
||||||
@pyqtSlot(str, result = bool)
|
@pyqtSlot(str, result = bool)
|
||||||
@ -606,8 +612,22 @@ class Toolbox(QObject, Extension):
|
|||||||
self.resetDownload()
|
self.resetDownload()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# HACK: These request are not handled independently at this moment, but together from the "packages" call
|
||||||
|
do_not_handle = [
|
||||||
|
"materials_available",
|
||||||
|
"materials_showcase",
|
||||||
|
"materials_generic",
|
||||||
|
"plugins_available",
|
||||||
|
"plugins_showcase",
|
||||||
|
]
|
||||||
|
|
||||||
if reply.operation() == QNetworkAccessManager.GetOperation:
|
if reply.operation() == QNetworkAccessManager.GetOperation:
|
||||||
for type, url in self._request_urls.items():
|
for type, url in self._request_urls.items():
|
||||||
|
|
||||||
|
# HACK: Do nothing because we'll handle these from the "packages" call
|
||||||
|
if type in do_not_handle:
|
||||||
|
continue
|
||||||
|
|
||||||
if reply.url() == url:
|
if reply.url() == url:
|
||||||
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200:
|
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200:
|
||||||
try:
|
try:
|
||||||
@ -623,25 +643,16 @@ class Toolbox(QObject, Extension):
|
|||||||
if not self._models[type]:
|
if not self._models[type]:
|
||||||
Logger.log("e", "Could not find the %s model.", type)
|
Logger.log("e", "Could not find the %s model.", type)
|
||||||
break
|
break
|
||||||
|
|
||||||
# HACK: Eventually get rid of the code from here...
|
self._metadata[type] = json_data["data"]
|
||||||
if type is "plugins_showcase" or type is "materials_showcase":
|
self._models[type].setMetadata(self._metadata[type])
|
||||||
self._metadata["plugins_showcase"] = json_data["data"]["plugin"]["packages"]
|
|
||||||
self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"])
|
|
||||||
self._metadata["materials_showcase"] = json_data["data"]["material"]["authors"]
|
|
||||||
self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"])
|
|
||||||
else:
|
|
||||||
# ...until here.
|
|
||||||
# This hack arises for multiple reasons but the main
|
|
||||||
# one is because there are not separate API calls
|
|
||||||
# for different kinds of showcases.
|
|
||||||
self._metadata[type] = json_data["data"]
|
|
||||||
self._models[type].setMetadata(self._metadata[type])
|
|
||||||
|
|
||||||
# Do some auto filtering
|
# Do some auto filtering
|
||||||
# TODO: Make multiple API calls in the future to handle this
|
# TODO: Make multiple API calls in the future to handle this
|
||||||
if type is "packages":
|
if type is "packages":
|
||||||
self._models[type].setFilter({"type": "plugin"})
|
self._models[type].setFilter({"type": "plugin"})
|
||||||
|
self.buildMaterialsModels()
|
||||||
|
self.buildPluginsModels()
|
||||||
if type is "authors":
|
if type is "authors":
|
||||||
self._models[type].setFilter({"package_types": "material"})
|
self._models[type].setFilter({"package_types": "material"})
|
||||||
if type is "materials_generic":
|
if type is "materials_generic":
|
||||||
@ -680,7 +691,7 @@ class Toolbox(QObject, Extension):
|
|||||||
self._temp_plugin_file.close()
|
self._temp_plugin_file.close()
|
||||||
self._onDownloadComplete(file_path)
|
self._onDownloadComplete(file_path)
|
||||||
|
|
||||||
def _onDownloadComplete(self, file_path: str):
|
def _onDownloadComplete(self, file_path: str) -> None:
|
||||||
Logger.log("i", "Toolbox: Download complete.")
|
Logger.log("i", "Toolbox: Download complete.")
|
||||||
package_info = self._package_manager.getPackageInfo(file_path)
|
package_info = self._package_manager.getPackageInfo(file_path)
|
||||||
if not package_info:
|
if not package_info:
|
||||||
@ -739,9 +750,7 @@ class Toolbox(QObject, Extension):
|
|||||||
def viewPage(self) -> str:
|
def viewPage(self) -> str:
|
||||||
return self._view_page
|
return self._view_page
|
||||||
|
|
||||||
|
# Exposed Models:
|
||||||
|
|
||||||
# Expose Models:
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
@pyqtProperty(QObject, notify = metadataChanged)
|
@pyqtProperty(QObject, notify = metadataChanged)
|
||||||
def authorsModel(self) -> AuthorsModel:
|
def authorsModel(self) -> AuthorsModel:
|
||||||
@ -755,6 +764,10 @@ class Toolbox(QObject, Extension):
|
|||||||
def pluginsShowcaseModel(self) -> PackagesModel:
|
def pluginsShowcaseModel(self) -> PackagesModel:
|
||||||
return cast(PackagesModel, self._models["plugins_showcase"])
|
return cast(PackagesModel, self._models["plugins_showcase"])
|
||||||
|
|
||||||
|
@pyqtProperty(QObject, notify = metadataChanged)
|
||||||
|
def pluginsAvailableModel(self) -> PackagesModel:
|
||||||
|
return cast(PackagesModel, self._models["plugins_available"])
|
||||||
|
|
||||||
@pyqtProperty(QObject, notify = metadataChanged)
|
@pyqtProperty(QObject, notify = metadataChanged)
|
||||||
def pluginsInstalledModel(self) -> PackagesModel:
|
def pluginsInstalledModel(self) -> PackagesModel:
|
||||||
return cast(PackagesModel, self._models["plugins_installed"])
|
return cast(PackagesModel, self._models["plugins_installed"])
|
||||||
@ -763,6 +776,10 @@ class Toolbox(QObject, Extension):
|
|||||||
def materialsShowcaseModel(self) -> AuthorsModel:
|
def materialsShowcaseModel(self) -> AuthorsModel:
|
||||||
return cast(AuthorsModel, self._models["materials_showcase"])
|
return cast(AuthorsModel, self._models["materials_showcase"])
|
||||||
|
|
||||||
|
@pyqtProperty(QObject, notify = metadataChanged)
|
||||||
|
def materialsAvailableModel(self) -> AuthorsModel:
|
||||||
|
return cast(AuthorsModel, self._models["materials_available"])
|
||||||
|
|
||||||
@pyqtProperty(QObject, notify = metadataChanged)
|
@pyqtProperty(QObject, notify = metadataChanged)
|
||||||
def materialsInstalledModel(self) -> PackagesModel:
|
def materialsInstalledModel(self) -> PackagesModel:
|
||||||
return cast(PackagesModel, self._models["materials_installed"])
|
return cast(PackagesModel, self._models["materials_installed"])
|
||||||
@ -771,8 +788,6 @@ class Toolbox(QObject, Extension):
|
|||||||
def materialsGenericModel(self) -> PackagesModel:
|
def materialsGenericModel(self) -> PackagesModel:
|
||||||
return cast(PackagesModel, self._models["materials_generic"])
|
return cast(PackagesModel, self._models["materials_generic"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Filter Models:
|
# Filter Models:
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
@pyqtSlot(str, str, str)
|
@pyqtSlot(str, str, str)
|
||||||
@ -798,3 +813,48 @@ class Toolbox(QObject, Extension):
|
|||||||
return
|
return
|
||||||
self._models[model_type].setFilter({})
|
self._models[model_type].setFilter({})
|
||||||
self.filterChanged.emit()
|
self.filterChanged.emit()
|
||||||
|
|
||||||
|
# HACK(S):
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
def buildMaterialsModels(self) -> None:
|
||||||
|
self._metadata["materials_showcase"] = []
|
||||||
|
self._metadata["materials_available"] = []
|
||||||
|
|
||||||
|
processed_authors = [] # type: List[str]
|
||||||
|
|
||||||
|
for item in self._metadata["packages"]:
|
||||||
|
if item["package_type"] == "material":
|
||||||
|
|
||||||
|
author = item["author"]
|
||||||
|
if author["author_id"] in processed_authors:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Generic materials to be in the same section
|
||||||
|
if "generic" in item["tags"]:
|
||||||
|
self._metadata["materials_generic"].append(item)
|
||||||
|
else:
|
||||||
|
if "showcase" in item["tags"]:
|
||||||
|
self._metadata["materials_showcase"].append(author)
|
||||||
|
else:
|
||||||
|
self._metadata["materials_available"].append(author)
|
||||||
|
|
||||||
|
processed_authors.append(author["author_id"])
|
||||||
|
|
||||||
|
self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"])
|
||||||
|
self._models["materials_available"].setMetadata(self._metadata["materials_available"])
|
||||||
|
self._models["materials_generic"].setMetadata(self._metadata["materials_generic"])
|
||||||
|
|
||||||
|
def buildPluginsModels(self) -> None:
|
||||||
|
self._metadata["plugins_showcase"] = []
|
||||||
|
self._metadata["plugins_available"] = []
|
||||||
|
|
||||||
|
for item in self._metadata["packages"]:
|
||||||
|
if item["package_type"] == "plugin":
|
||||||
|
|
||||||
|
if "showcase" in item["tags"]:
|
||||||
|
self._metadata["plugins_showcase"].append(item)
|
||||||
|
else:
|
||||||
|
self._metadata["plugins_available"].append(item)
|
||||||
|
|
||||||
|
self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"])
|
||||||
|
self._models["plugins_available"].setMetadata(self._metadata["plugins_available"])
|
||||||
|
@ -1,241 +0,0 @@
|
|||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Controls 1.4
|
|
||||||
|
|
||||||
import UM 1.3 as UM
|
|
||||||
import Cura 1.0 as Cura
|
|
||||||
|
|
||||||
Component
|
|
||||||
{
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
id: base
|
|
||||||
property var manager: Cura.MachineManager.printerOutputDevices[0]
|
|
||||||
property var lineColor: "#DCDCDC" // TODO: Should be linked to theme.
|
|
||||||
property var cornerRadius: 4 * screenScaleFactor // TODO: Should be linked to theme.
|
|
||||||
|
|
||||||
visible: manager != null
|
|
||||||
anchors.fill: parent
|
|
||||||
color: UM.Theme.getColor("viewport_background")
|
|
||||||
|
|
||||||
UM.I18nCatalog
|
|
||||||
{
|
|
||||||
id: catalog
|
|
||||||
name: "cura"
|
|
||||||
}
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: activePrintersLabel
|
|
||||||
font: UM.Theme.getFont("large")
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.right:parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
text: Cura.MachineManager.printerOutputDevices[0].name
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
id: printJobArea
|
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
|
||||||
border.color: lineColor
|
|
||||||
anchors.top: activePrintersLabel.bottom
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin:UM.Theme.getSize("default_margin").width
|
|
||||||
radius: cornerRadius
|
|
||||||
height: childrenRect.height
|
|
||||||
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
id: printJobTitleBar
|
|
||||||
width: parent.width
|
|
||||||
height: printJobTitleLabel.height + 2 * UM.Theme.getSize("default_margin").height
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: printJobTitleLabel
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
text: catalog.i18nc("@title", "Print jobs")
|
|
||||||
font: UM.Theme.getFont("default")
|
|
||||||
opacity: 0.75
|
|
||||||
}
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
height: UM.Theme.getSize("default_lining").width
|
|
||||||
color: lineColor
|
|
||||||
width: parent.width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column
|
|
||||||
{
|
|
||||||
id: printJobColumn
|
|
||||||
anchors.top: printJobTitleBar.bottom
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
width: parent.width
|
|
||||||
height: childrenRect.height
|
|
||||||
opacity: 0.65
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
text: catalog.i18nc("@label", "Printing")
|
|
||||||
font: UM.Theme.getFont("very_small")
|
|
||||||
|
|
||||||
}
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
text: manager.activePrintJobs.length
|
|
||||||
font: UM.Theme.getFont("small")
|
|
||||||
anchors.right: parent.right
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
width: parent.width
|
|
||||||
height: childrenRect.height
|
|
||||||
opacity: 0.65
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
text: catalog.i18nc("@label", "Queued")
|
|
||||||
font: UM.Theme.getFont("very_small")
|
|
||||||
}
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
text: manager.queuedPrintJobs.length
|
|
||||||
font: UM.Theme.getFont("small")
|
|
||||||
anchors.right: parent.right
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OpenPanelButton
|
|
||||||
{
|
|
||||||
anchors.top: printJobColumn.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.margins: UM.Theme.getSize("default_margin").height
|
|
||||||
id: configButton
|
|
||||||
onClicked: base.manager.openPrintJobControlPanel()
|
|
||||||
text: catalog.i18nc("@action:button", "View print jobs")
|
|
||||||
}
|
|
||||||
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
// spacer
|
|
||||||
anchors.top: configButton.bottom
|
|
||||||
width: UM.Theme.getSize("default_margin").width
|
|
||||||
height: UM.Theme.getSize("default_margin").height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
id: printersArea
|
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
|
||||||
border.color: lineColor
|
|
||||||
anchors.top: printJobArea.bottom
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin:UM.Theme.getSize("default_margin").width
|
|
||||||
radius: cornerRadius
|
|
||||||
height: childrenRect.height
|
|
||||||
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
id: printersTitleBar
|
|
||||||
width: parent.width
|
|
||||||
height: printJobTitleLabel.height + 2 * UM.Theme.getSize("default_margin").height
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: printersTitleLabel
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
text: catalog.i18nc("@label:title", "Printers")
|
|
||||||
font: UM.Theme.getFont("default")
|
|
||||||
opacity: 0.75
|
|
||||||
}
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
height: UM.Theme.getSize("default_lining").width
|
|
||||||
color: lineColor
|
|
||||||
width: parent.width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Column
|
|
||||||
{
|
|
||||||
id: printersColumn
|
|
||||||
anchors.top: printersTitleBar.bottom
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
|
|
||||||
Repeater
|
|
||||||
{
|
|
||||||
model: manager.connectedPrintersTypeCount
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
width: parent.width
|
|
||||||
height: childrenRect.height
|
|
||||||
opacity: 0.65
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
text: modelData.machine_type
|
|
||||||
font: UM.Theme.getFont("very_small")
|
|
||||||
}
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
text: modelData.count
|
|
||||||
font: UM.Theme.getFont("small")
|
|
||||||
anchors.right: parent.right
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OpenPanelButton
|
|
||||||
{
|
|
||||||
anchors.top: printersColumn.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.margins: UM.Theme.getSize("default_margin").height
|
|
||||||
id: printerConfigButton
|
|
||||||
onClicked: base.manager.openPrinterControlPanel()
|
|
||||||
|
|
||||||
text: catalog.i18nc("@action:button", "View printers")
|
|
||||||
}
|
|
||||||
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
// spacer
|
|
||||||
anchors.top: printerConfigButton.bottom
|
|
||||||
width: UM.Theme.getSize("default_margin").width
|
|
||||||
height: UM.Theme.getSize("default_margin").height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Controls 1.4
|
|
||||||
import QtQuick.Controls.Styles 1.4
|
|
||||||
|
|
||||||
import UM 1.3 as UM
|
|
||||||
import Cura 1.0 as Cura
|
|
||||||
|
|
||||||
Component
|
|
||||||
{
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
id: monitorFrame
|
|
||||||
width: maximumWidth
|
|
||||||
height: maximumHeight
|
|
||||||
color: UM.Theme.getColor("viewport_background")
|
|
||||||
property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight")
|
|
||||||
property var lineColor: "#DCDCDC" // TODO: Should be linked to theme.
|
|
||||||
property var cornerRadius: 4 * screenScaleFactor // TODO: Should be linked to theme.
|
|
||||||
|
|
||||||
UM.I18nCatalog
|
|
||||||
{
|
|
||||||
id: catalog
|
|
||||||
name: "cura"
|
|
||||||
}
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: activePrintersLabel
|
|
||||||
font: UM.Theme.getFont("large")
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
topMargin: UM.Theme.getSize("default_margin").height * 2 // a bit more spacing to give it some breathing room
|
|
||||||
horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
text: OutputDevice.printers.length == 0 ? catalog.i18nc("@label: arg 1 is group name", "%1 is not set up to host a group of connected Ultimaker 3 printers").arg(Cura.MachineManager.printerOutputDevices[0].name) : ""
|
|
||||||
|
|
||||||
visible: OutputDevice.printers.length == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
width: Math.min(800 * screenScaleFactor, maximumWidth)
|
|
||||||
height: children.height
|
|
||||||
visible: OutputDevice.printers.length != 0
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: addRemovePrintersLabel
|
|
||||||
anchors.right: parent.right
|
|
||||||
text: catalog.i18nc("@label link to connect manager", "Add/Remove printers")
|
|
||||||
font: UM.Theme.getFont("default")
|
|
||||||
color: UM.Theme.getColor("text")
|
|
||||||
linkColor: UM.Theme.getColor("text_link")
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea
|
|
||||||
{
|
|
||||||
anchors.fill: addRemovePrintersLabel
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrinterControlPanel()
|
|
||||||
onEntered: addRemovePrintersLabel.font.underline = true
|
|
||||||
onExited: addRemovePrintersLabel.font.underline = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollView
|
|
||||||
{
|
|
||||||
id: printerScrollView
|
|
||||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.top: activePrintersLabel.bottom
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_lining").width // To ensure border can be drawn.
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_lining").width
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
ListView
|
|
||||||
{
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: -UM.Theme.getSize("default_lining").height
|
|
||||||
|
|
||||||
model: OutputDevice.printers
|
|
||||||
|
|
||||||
delegate: PrinterInfoBlock
|
|
||||||
{
|
|
||||||
printer: modelData
|
|
||||||
width: Math.min(800 * screenScaleFactor, maximumWidth)
|
|
||||||
height: 125 * screenScaleFactor
|
|
||||||
|
|
||||||
// Add a 1 pix margin, as the border is sometimes cut off otherwise.
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PrinterVideoStream
|
|
||||||
{
|
|
||||||
visible: OutputDevice.activePrinter != null
|
|
||||||
anchors.fill:parent
|
|
||||||
}
|
|
||||||
|
|
||||||
onVisibleChanged:
|
|
||||||
{
|
|
||||||
if (!monitorFrame.visible)
|
|
||||||
{
|
|
||||||
// After switching the Tab ensure that active printer is Null, the video stream image
|
|
||||||
// might be active
|
|
||||||
OutputDevice.setActivePrinter(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Controls 1.1
|
|
||||||
import QtQuick.Controls.Styles 1.1
|
|
||||||
|
|
||||||
import UM 1.1 as UM
|
|
||||||
|
|
||||||
Button {
|
|
||||||
objectName: "openPanelSaveAreaButton"
|
|
||||||
id: openPanelSaveAreaButton
|
|
||||||
|
|
||||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
|
||||||
|
|
||||||
height: UM.Theme.getSize("save_button_save_to_button").height
|
|
||||||
tooltip: catalog.i18nc("@info:tooltip", "Opens the print jobs page with your default web browser.")
|
|
||||||
text: catalog.i18nc("@action:button", "View print jobs")
|
|
||||||
|
|
||||||
// FIXME: This button style is copied and duplicated from SaveButton.qml
|
|
||||||
style: ButtonStyle {
|
|
||||||
background: Rectangle
|
|
||||||
{
|
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
|
||||||
border.color:
|
|
||||||
{
|
|
||||||
if(!control.enabled)
|
|
||||||
return UM.Theme.getColor("action_button_disabled_border");
|
|
||||||
else if(control.pressed)
|
|
||||||
return UM.Theme.getColor("print_button_ready_pressed_border");
|
|
||||||
else if(control.hovered)
|
|
||||||
return UM.Theme.getColor("print_button_ready_hovered_border");
|
|
||||||
else
|
|
||||||
return UM.Theme.getColor("print_button_ready_border");
|
|
||||||
}
|
|
||||||
color:
|
|
||||||
{
|
|
||||||
if(!control.enabled)
|
|
||||||
return UM.Theme.getColor("action_button_disabled");
|
|
||||||
else if(control.pressed)
|
|
||||||
return UM.Theme.getColor("print_button_ready_pressed");
|
|
||||||
else if(control.hovered)
|
|
||||||
return UM.Theme.getColor("print_button_ready_hovered");
|
|
||||||
else
|
|
||||||
return UM.Theme.getColor("print_button_ready");
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on color { ColorAnimation { duration: 50; } }
|
|
||||||
|
|
||||||
implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("sidebar_margin").width * 2)
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: actualLabel
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color:
|
|
||||||
{
|
|
||||||
if(!control.enabled)
|
|
||||||
return UM.Theme.getColor("action_button_disabled_text");
|
|
||||||
else if(control.pressed)
|
|
||||||
return UM.Theme.getColor("print_button_ready_text");
|
|
||||||
else if(control.hovered)
|
|
||||||
return UM.Theme.getColor("print_button_ready_text");
|
|
||||||
else
|
|
||||||
return UM.Theme.getColor("print_button_ready_text");
|
|
||||||
}
|
|
||||||
font: UM.Theme.getFont("action_button")
|
|
||||||
text: control.text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
label: Item { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Controls 1.4
|
|
||||||
import QtQuick.Controls.Styles 1.4
|
|
||||||
|
|
||||||
import UM 1.2 as UM
|
|
||||||
|
|
||||||
|
|
||||||
Item
|
|
||||||
{
|
|
||||||
id: extruderInfo
|
|
||||||
property var printCoreConfiguration
|
|
||||||
|
|
||||||
width: Math.round(parent.width / 2)
|
|
||||||
height: childrenRect.height
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: materialLabel
|
|
||||||
text: printCoreConfiguration.activeMaterial != null ? printCoreConfiguration.activeMaterial.name : ""
|
|
||||||
elide: Text.ElideRight
|
|
||||||
width: parent.width
|
|
||||||
font: UM.Theme.getFont("very_small")
|
|
||||||
}
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: printCoreLabel
|
|
||||||
text: printCoreConfiguration.hotendID
|
|
||||||
anchors.top: materialLabel.bottom
|
|
||||||
elide: Text.ElideRight
|
|
||||||
width: parent.width
|
|
||||||
font: UM.Theme.getFont("very_small")
|
|
||||||
opacity: 0.5
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,431 +0,0 @@
|
|||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Controls 1.4
|
|
||||||
import QtQuick.Controls.Styles 1.4
|
|
||||||
|
|
||||||
import UM 1.3 as UM
|
|
||||||
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
function strPadLeft(string, pad, length)
|
|
||||||
{
|
|
||||||
return (new Array(length + 1).join(pad) + string).slice(-length);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPrettyTime(time)
|
|
||||||
{
|
|
||||||
return OutputDevice.formatDuration(time)
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatPrintJobPercent(printJob)
|
|
||||||
{
|
|
||||||
if (printJob == null)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (printJob.timeTotal === 0)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return Math.min(100, Math.round(printJob.timeElapsed / printJob.timeTotal * 100)) + "%";
|
|
||||||
}
|
|
||||||
|
|
||||||
function printerStatusText(printer)
|
|
||||||
{
|
|
||||||
switch (printer.state)
|
|
||||||
{
|
|
||||||
case "pre_print":
|
|
||||||
return catalog.i18nc("@label:status", "Preparing to print")
|
|
||||||
case "printing":
|
|
||||||
return catalog.i18nc("@label:status", "Printing");
|
|
||||||
case "idle":
|
|
||||||
return catalog.i18nc("@label:status", "Available");
|
|
||||||
case "unreachable":
|
|
||||||
return catalog.i18nc("@label:status", "Lost connection with the printer");
|
|
||||||
case "maintenance":
|
|
||||||
return catalog.i18nc("@label:status", "Unavailable");
|
|
||||||
default:
|
|
||||||
return catalog.i18nc("@label:status", "Unknown");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
id: printerDelegate
|
|
||||||
|
|
||||||
property var printer: null
|
|
||||||
property var printJob: printer != null ? printer.activePrintJob: null
|
|
||||||
|
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
|
||||||
border.color: mouse.containsMouse ? emphasisColor : lineColor
|
|
||||||
z: mouse.containsMouse ? 1 : 0 // Push this item up a bit on mouse over to ensure that the highlighted bottom border is visible.
|
|
||||||
|
|
||||||
MouseArea
|
|
||||||
{
|
|
||||||
id: mouse
|
|
||||||
anchors.fill:parent
|
|
||||||
onClicked: OutputDevice.setActivePrinter(printer)
|
|
||||||
hoverEnabled: true;
|
|
||||||
|
|
||||||
// Only clickable if no printer is selected
|
|
||||||
enabled: OutputDevice.activePrinter == null && printer.state !== "unreachable"
|
|
||||||
}
|
|
||||||
|
|
||||||
Row
|
|
||||||
{
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
|
||||||
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
width: Math.round(parent.width / 3)
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
Label // Print job name
|
|
||||||
{
|
|
||||||
id: jobNameLabel
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
|
|
||||||
text: printJob != null ? printJob.name : ""
|
|
||||||
font: UM.Theme.getFont("default_bold")
|
|
||||||
elide: Text.ElideRight
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: jobOwnerLabel
|
|
||||||
anchors.top: jobNameLabel.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
text: printJob != null ? printJob.owner : ""
|
|
||||||
opacity: 0.50
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: totalTimeLabel
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
text: printJob != null ? getPrettyTime(printJob.timeTotal) : ""
|
|
||||||
opacity: 0.65
|
|
||||||
font: UM.Theme.getFont("default")
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
width: Math.round(parent.width / 3 * 2)
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
Label // Friendly machine name
|
|
||||||
{
|
|
||||||
id: printerNameLabel
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
width: Math.round(parent.width / 2 - UM.Theme.getSize("default_margin").width - showCameraIcon.width)
|
|
||||||
text: printer.name
|
|
||||||
font: UM.Theme.getFont("default_bold")
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
|
|
||||||
Label // Machine variant
|
|
||||||
{
|
|
||||||
id: printerTypeLabel
|
|
||||||
anchors.top: printerNameLabel.bottom
|
|
||||||
width: Math.round(parent.width / 2 - UM.Theme.getSize("default_margin").width)
|
|
||||||
text: printer.type
|
|
||||||
anchors.left: parent.left
|
|
||||||
elide: Text.ElideRight
|
|
||||||
font: UM.Theme.getFont("very_small")
|
|
||||||
opacity: 0.50
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle // Camera icon
|
|
||||||
{
|
|
||||||
id: showCameraIcon
|
|
||||||
width: 40 * screenScaleFactor
|
|
||||||
height: width
|
|
||||||
radius: width
|
|
||||||
anchors.right: printProgressArea.left
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
color: emphasisColor
|
|
||||||
opacity: printer != null && printer.state === "unreachable" ? 0.3 : 1
|
|
||||||
|
|
||||||
Image
|
|
||||||
{
|
|
||||||
width: parent.width
|
|
||||||
height: width
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: parent.rightMargin
|
|
||||||
source: "camera-icon.svg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row // PrintCore config
|
|
||||||
{
|
|
||||||
id: extruderInfo
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
|
|
||||||
width: Math.round(parent.width / 2 - UM.Theme.getSize("default_margin").width)
|
|
||||||
height: childrenRect.height
|
|
||||||
|
|
||||||
spacing: UM.Theme.getSize("default_margin").width
|
|
||||||
|
|
||||||
PrintCoreConfiguration
|
|
||||||
{
|
|
||||||
id: leftExtruderInfo
|
|
||||||
width: Math.round((parent.width - extruderSeperator.width) / 2)
|
|
||||||
printCoreConfiguration: printer.extruders[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
id: extruderSeperator
|
|
||||||
width: UM.Theme.getSize("default_lining").width
|
|
||||||
height: parent.height
|
|
||||||
color: lineColor
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintCoreConfiguration
|
|
||||||
{
|
|
||||||
id: rightExtruderInfo
|
|
||||||
width: Math.round((parent.width - extruderSeperator.width) / 2)
|
|
||||||
printCoreConfiguration: printer.extruders[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle // Print progress
|
|
||||||
{
|
|
||||||
id: printProgressArea
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
height: showExtended ? parent.height: printProgressTitleBar.height
|
|
||||||
width: Math.round(parent.width / 2 - UM.Theme.getSize("default_margin").width)
|
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
|
||||||
border.color: lineColor
|
|
||||||
radius: cornerRadius
|
|
||||||
property var showExtended: {
|
|
||||||
if(printJob != null)
|
|
||||||
{
|
|
||||||
var extendStates = ["sent_to_printer", "wait_for_configuration", "printing", "pre_print", "post_print", "wait_cleanup", "queued"];
|
|
||||||
return extendStates.indexOf(printJob.state) !== -1;
|
|
||||||
}
|
|
||||||
return printer.state == "disabled"
|
|
||||||
}
|
|
||||||
|
|
||||||
Item // Status and Percent
|
|
||||||
{
|
|
||||||
id: printProgressTitleBar
|
|
||||||
|
|
||||||
property var showPercent: {
|
|
||||||
return printJob != null && (["printing", "post_print", "pre_print", "sent_to_printer"].indexOf(printJob.state) !== -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
//TODO: hardcoded value
|
|
||||||
height: 40 * screenScaleFactor
|
|
||||||
anchors.left: parent.left
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: statusText
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.right: progressText.left
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: {
|
|
||||||
if (printer.state == "disabled")
|
|
||||||
{
|
|
||||||
return catalog.i18nc("@label:status", "Disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (printer.state === "unreachable")
|
|
||||||
{
|
|
||||||
return printerStatusText(printer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (printJob != null)
|
|
||||||
{
|
|
||||||
switch (printJob.state)
|
|
||||||
{
|
|
||||||
case "printing":
|
|
||||||
case "post_print":
|
|
||||||
return catalog.i18nc("@label:status", "Printing")
|
|
||||||
case "wait_for_configuration":
|
|
||||||
return catalog.i18nc("@label:status", "Reserved")
|
|
||||||
case "wait_cleanup":
|
|
||||||
case "wait_user_action":
|
|
||||||
return catalog.i18nc("@label:status", "Finished")
|
|
||||||
case "pre_print":
|
|
||||||
case "sent_to_printer":
|
|
||||||
return catalog.i18nc("@label", "Preparing to print")
|
|
||||||
case "queued":
|
|
||||||
return catalog.i18nc("@label:status", "Action required");
|
|
||||||
case "pausing":
|
|
||||||
case "paused":
|
|
||||||
return catalog.i18nc("@label:status", "Paused");
|
|
||||||
case "resuming":
|
|
||||||
return catalog.i18nc("@label:status", "Resuming");
|
|
||||||
case "aborted":
|
|
||||||
return catalog.i18nc("@label:status", "Print aborted");
|
|
||||||
default:
|
|
||||||
// If print job has unknown status show printer.status
|
|
||||||
return printerStatusText(printer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return printerStatusText(printer);
|
|
||||||
}
|
|
||||||
|
|
||||||
elide: Text.ElideRight
|
|
||||||
font: UM.Theme.getFont("small")
|
|
||||||
}
|
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: progressText
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.top: statusText.top
|
|
||||||
|
|
||||||
text: formatPrintJobPercent(printJob)
|
|
||||||
visible: printProgressTitleBar.showPercent
|
|
||||||
//TODO: Hardcoded value
|
|
||||||
opacity: 0.65
|
|
||||||
font: UM.Theme.getFont("very_small")
|
|
||||||
}
|
|
||||||
|
|
||||||
Image
|
|
||||||
{
|
|
||||||
width: statusText.height
|
|
||||||
height: width
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.top: statusText.top
|
|
||||||
|
|
||||||
visible: !printProgressTitleBar.showPercent
|
|
||||||
|
|
||||||
source: {
|
|
||||||
if (printer.state == "disabled")
|
|
||||||
{
|
|
||||||
return "blocked-icon.svg";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (printer.state === "unreachable")
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (printJob != null)
|
|
||||||
{
|
|
||||||
if(printJob.state === "queued")
|
|
||||||
{
|
|
||||||
return "action-required-icon.svg";
|
|
||||||
}
|
|
||||||
else if (printJob.state === "wait_cleanup")
|
|
||||||
{
|
|
||||||
return "checkmark-icon.svg";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""; // We're not going to show it, so it will not be resolved as a url.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
//TODO: This will become a progress bar in the future
|
|
||||||
width: parent.width
|
|
||||||
height: UM.Theme.getSize("default_lining").height
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
visible: printProgressArea.showExtended
|
|
||||||
color: lineColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column
|
|
||||||
{
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
|
|
||||||
anchors.top: printProgressTitleBar.bottom
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
|
|
||||||
width: parent.width - 2 * UM.Theme.getSize("default_margin").width
|
|
||||||
|
|
||||||
visible: printProgressArea.showExtended
|
|
||||||
|
|
||||||
Label // Status detail
|
|
||||||
{
|
|
||||||
text:
|
|
||||||
{
|
|
||||||
if (printer.state == "disabled")
|
|
||||||
{
|
|
||||||
return catalog.i18nc("@label", "Not accepting print jobs");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (printer.state === "unreachable")
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(printJob != null)
|
|
||||||
{
|
|
||||||
switch (printJob.state)
|
|
||||||
{
|
|
||||||
case "printing":
|
|
||||||
case "post_print":
|
|
||||||
return catalog.i18nc("@label", "Finishes at: ") + OutputDevice.getTimeCompleted(printJob.timeTotal - printJob.timeElapsed)
|
|
||||||
case "wait_cleanup":
|
|
||||||
return catalog.i18nc("@label", "Clear build plate")
|
|
||||||
case "sent_to_printer":
|
|
||||||
case "pre_print":
|
|
||||||
return catalog.i18nc("@label", "Preparing to print")
|
|
||||||
case "wait_for_configuration":
|
|
||||||
return catalog.i18nc("@label", "Not accepting print jobs")
|
|
||||||
case "queued":
|
|
||||||
return catalog.i18nc("@label", "Waiting for configuration change");
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
elide: Text.ElideRight
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
|
|
||||||
font: UM.Theme.getFont("default")
|
|
||||||
}
|
|
||||||
|
|
||||||
Label // Status 2nd row
|
|
||||||
{
|
|
||||||
text: {
|
|
||||||
if(printJob != null)
|
|
||||||
{
|
|
||||||
if(printJob.state == "printing" || printJob.state == "post_print")
|
|
||||||
{
|
|
||||||
return OutputDevice.getDateCompleted(printJob.timeTotal - printJob.timeElapsed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
elide: Text.ElideRight
|
|
||||||
font: UM.Theme.getFont("default")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Controls 1.4
|
|
||||||
import QtQuick.Controls.Styles 1.4
|
|
||||||
|
|
||||||
import UM 1.3 as UM
|
|
||||||
import Cura 1.0 as Cura
|
|
||||||
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
id: base
|
|
||||||
width: 250 * screenScaleFactor
|
|
||||||
height: 250 * screenScaleFactor
|
|
||||||
signal clicked()
|
|
||||||
MouseArea
|
|
||||||
{
|
|
||||||
anchors.fill:parent
|
|
||||||
onClicked: base.clicked()
|
|
||||||
}
|
|
||||||
Rectangle
|
|
||||||
{
|
|
||||||
// TODO: Actually add UM icon / picture
|
|
||||||
width: 100 * screenScaleFactor
|
|
||||||
height: 100 * screenScaleFactor
|
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
}
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: nameLabel
|
|
||||||
anchors.bottom: ipLabel.top
|
|
||||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
text: modelData.friendly_name.toString()
|
|
||||||
font: UM.Theme.getFont("large")
|
|
||||||
elide: Text.ElideMiddle;
|
|
||||||
height: UM.Theme.getSize("section").height;
|
|
||||||
}
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
id: ipLabel
|
|
||||||
text: modelData.ip_address.toString()
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
font: UM.Theme.getFont("default")
|
|
||||||
height:10 * screenScaleFactor
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
|||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 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 . import DiscoverUM3Action
|
from .src import DiscoverUM3Action
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
from . import UM3OutputDevicePlugin
|
from .src import UM3OutputDevicePlugin
|
||||||
|
|
||||||
def getMetaData():
|
def getMetaData():
|
||||||
return {}
|
return {}
|
||||||
|
717
plugins/UM3NetworkPrinting/resources/qml/ClusterControlItem.qml
Normal file
@ -0,0 +1,717 @@
|
|||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Controls.Styles 1.3
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import QtQuick.Controls 2.0 as Controls2
|
||||||
|
|
||||||
|
import UM 1.3 as UM
|
||||||
|
import Cura 1.0 as Cura
|
||||||
|
|
||||||
|
|
||||||
|
Component
|
||||||
|
{
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: base
|
||||||
|
property var lineColor: "#DCDCDC" // TODO: Should be linked to theme.
|
||||||
|
|
||||||
|
property var cornerRadius: 4 * screenScaleFactor // TODO: Should be linked to theme.
|
||||||
|
visible: OutputDevice != null
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "white"
|
||||||
|
|
||||||
|
UM.I18nCatalog
|
||||||
|
{
|
||||||
|
id: catalog
|
||||||
|
name: "cura"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: printingLabel
|
||||||
|
font: UM.Theme.getFont("large")
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
margins: 2 * UM.Theme.getSize("default_margin").width
|
||||||
|
leftMargin: 4 * UM.Theme.getSize("default_margin").width
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
|
||||||
|
text: catalog.i18nc("@label", "Printing")
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: managePrintersLabel
|
||||||
|
anchors.rightMargin: 4 * UM.Theme.getSize("default_margin").width
|
||||||
|
anchors.right: printerScrollView.right
|
||||||
|
anchors.bottom: printingLabel.bottom
|
||||||
|
text: catalog.i18nc("@label link to connect manager", "Manage printers")
|
||||||
|
font: UM.Theme.getFont("default")
|
||||||
|
color: UM.Theme.getColor("primary")
|
||||||
|
linkColor: UM.Theme.getColor("primary")
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
anchors.fill: managePrintersLabel
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrinterControlPanel()
|
||||||
|
onEntered: managePrintersLabel.font.underline = true
|
||||||
|
onExited: managePrintersLabel.font.underline = false
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView
|
||||||
|
{
|
||||||
|
id: printerScrollView
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: printingLabel.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
topMargin: UM.Theme.getSize("default_margin").height
|
||||||
|
bottom: parent.bottom
|
||||||
|
bottomMargin: UM.Theme.getSize("default_margin").height
|
||||||
|
}
|
||||||
|
|
||||||
|
style: UM.Theme.styles.scrollview
|
||||||
|
|
||||||
|
ListView
|
||||||
|
{
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
leftMargin: 2 * UM.Theme.getSize("default_margin").width
|
||||||
|
rightMargin: 2 * UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
spacing: UM.Theme.getSize("default_margin").height -10
|
||||||
|
model: OutputDevice.printers
|
||||||
|
|
||||||
|
delegate: Item
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
height: base.height + 2 * base.shadowRadius // To ensure that the shadow doesn't get cut off.
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
width: parent.width - 2 * shadowRadius
|
||||||
|
height: childrenRect.height + UM.Theme.getSize("default_margin").height
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
id: base
|
||||||
|
property var shadowRadius: 5
|
||||||
|
property var collapsed: true
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow
|
||||||
|
{
|
||||||
|
radius: base.shadowRadius
|
||||||
|
verticalOffset: 2
|
||||||
|
color: "#3F000000" // 25% shadow
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: printerInfo
|
||||||
|
height: machineIcon.height
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
margins: UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: base.collapsed = !base.collapsed
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: machineIcon
|
||||||
|
// Yeah, this is hardcoded now, but I can't think of a good way to fix this.
|
||||||
|
// The UI is going to get another update soon, so it's probably not worth the effort...
|
||||||
|
width: 58
|
||||||
|
height: 58
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
anchors.left: parent.left
|
||||||
|
|
||||||
|
UM.RecolorImage
|
||||||
|
{
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source:
|
||||||
|
{
|
||||||
|
switch(modelData.type)
|
||||||
|
{
|
||||||
|
case "Ultimaker 3":
|
||||||
|
return "../svg/UM3-icon.svg"
|
||||||
|
case "Ultimaker 3 Extended":
|
||||||
|
return "../svg/UM3x-icon.svg"
|
||||||
|
case "Ultimaker S5":
|
||||||
|
return "../svg/UMs5-icon.svg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width: sourceSize.width
|
||||||
|
height: sourceSize.height
|
||||||
|
|
||||||
|
color:
|
||||||
|
{
|
||||||
|
if(modelData.state == "disabled")
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("setting_control_disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
if(modelData.activePrintJob != undefined)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("primary")
|
||||||
|
}
|
||||||
|
|
||||||
|
return UM.Theme.getColor("setting_control_disabled")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
height: childrenRect.height
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
right: collapseIcon.left
|
||||||
|
rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
left: machineIcon.right
|
||||||
|
leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
|
||||||
|
verticalCenter: machineIcon.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: machineNameLabel
|
||||||
|
text: modelData.name
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font: UM.Theme.getFont("default_bold")
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: activeJobLabel
|
||||||
|
text:
|
||||||
|
{
|
||||||
|
if (modelData.state == "disabled")
|
||||||
|
{
|
||||||
|
return catalog.i18nc("@label", "Not available")
|
||||||
|
} else if (modelData.state == "unreachable")
|
||||||
|
{
|
||||||
|
return catalog.i18nc("@label", "Unreachable")
|
||||||
|
}
|
||||||
|
if (modelData.activePrintJob != null)
|
||||||
|
{
|
||||||
|
return modelData.activePrintJob.name
|
||||||
|
}
|
||||||
|
return catalog.i18nc("@label", "Available")
|
||||||
|
}
|
||||||
|
anchors.top: machineNameLabel.bottom
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font: UM.Theme.getFont("default")
|
||||||
|
opacity: 0.6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.RecolorImage
|
||||||
|
{
|
||||||
|
id: collapseIcon
|
||||||
|
width: 15
|
||||||
|
height: 15
|
||||||
|
sourceSize.width: width
|
||||||
|
sourceSize.height: height
|
||||||
|
source: base.collapsed ? UM.Theme.getIcon("arrow_left") : UM.Theme.getIcon("arrow_bottom")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: detailedInfo
|
||||||
|
property var printJob: modelData.activePrintJob
|
||||||
|
visible: height == childrenRect.height
|
||||||
|
anchors.top: printerInfo.bottom
|
||||||
|
width: parent.width
|
||||||
|
height: !base.collapsed ? childrenRect.height : 0
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on height { NumberAnimation { duration: 100 } }
|
||||||
|
Behavior on opacity { NumberAnimation { duration: 100 } }
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: topSpacer
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
height: 2
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
margins: UM.Theme.getSize("default_margin").width
|
||||||
|
top: parent.top
|
||||||
|
topMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PrinterFamilyPill
|
||||||
|
{
|
||||||
|
id: printerFamilyPill
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
anchors.top: topSpacer.bottom
|
||||||
|
anchors.topMargin: 2 * UM.Theme.getSize("default_margin").height
|
||||||
|
text: modelData.type
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
padding: 3
|
||||||
|
}
|
||||||
|
Row
|
||||||
|
{
|
||||||
|
id: extrudersInfo
|
||||||
|
anchors.top: printerFamilyPill.bottom
|
||||||
|
anchors.topMargin: 2 * UM.Theme.getSize("default_margin").height
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 2 * UM.Theme.getSize("default_margin").width
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 2 * UM.Theme.getSize("default_margin").width
|
||||||
|
height: childrenRect.height
|
||||||
|
spacing: UM.Theme.getSize("default_margin").width
|
||||||
|
|
||||||
|
PrintCoreConfiguration
|
||||||
|
{
|
||||||
|
id: leftExtruderInfo
|
||||||
|
width: Math.round(parent.width / 2)
|
||||||
|
printCoreConfiguration: modelData.printerConfiguration.extruderConfigurations[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintCoreConfiguration
|
||||||
|
{
|
||||||
|
id: rightExtruderInfo
|
||||||
|
width: Math.round(parent.width / 2)
|
||||||
|
printCoreConfiguration: modelData.printerConfiguration.extruderConfigurations[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: jobSpacer
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
height: 2
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
margins: UM.Theme.getSize("default_margin").width
|
||||||
|
top: extrudersInfo.bottom
|
||||||
|
topMargin: 2 * UM.Theme.getSize("default_margin").height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: jobInfo
|
||||||
|
property var showJobInfo: modelData.activePrintJob != null && modelData.activePrintJob.state != "queued"
|
||||||
|
|
||||||
|
anchors.top: jobSpacer.bottom
|
||||||
|
anchors.topMargin: 2 * UM.Theme.getSize("default_margin").height
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||||
|
anchors.leftMargin: 2 * UM.Theme.getSize("default_margin").width
|
||||||
|
height: showJobInfo ? childrenRect.height + 2 * UM.Theme.getSize("default_margin").height: 0
|
||||||
|
visible: showJobInfo
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: printJobName
|
||||||
|
text: modelData.activePrintJob != null ? modelData.activePrintJob.name : ""
|
||||||
|
font: UM.Theme.getFont("default_bold")
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: contextButton.left
|
||||||
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: ownerName
|
||||||
|
anchors.top: printJobName.bottom
|
||||||
|
text: modelData.activePrintJob != null ? modelData.activePrintJob.owner : ""
|
||||||
|
font: UM.Theme.getFont("default")
|
||||||
|
opacity: 0.6
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchPopupState()
|
||||||
|
{
|
||||||
|
if (popup.visible)
|
||||||
|
{
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
popup.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls2.Button
|
||||||
|
{
|
||||||
|
id: contextButton
|
||||||
|
text: "\u22EE" //Unicode; Three stacked points.
|
||||||
|
font.pixelSize: 25
|
||||||
|
width: 35
|
||||||
|
height: width
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
opacity: contextButton.down || contextButton.hovered ? 1 : 0
|
||||||
|
width: contextButton.width
|
||||||
|
height: contextButton.height
|
||||||
|
radius: 0.5 * width
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: parent.switchPopupState()
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls2.Popup
|
||||||
|
{
|
||||||
|
// TODO Change once updating to Qt5.10 - The 'opened' property is in 5.10 but the behavior is now implemented with the visible property
|
||||||
|
id: popup
|
||||||
|
clip: true
|
||||||
|
closePolicy: Controls2.Popup.CloseOnPressOutsideParent
|
||||||
|
x: parent.width - width
|
||||||
|
y: contextButton.height
|
||||||
|
width: 160
|
||||||
|
height: contentItem.height + 2 * padding
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
transformOrigin: Controls2.Popup.Top
|
||||||
|
contentItem: Item
|
||||||
|
{
|
||||||
|
width: popup.width - 2 * popup.padding
|
||||||
|
height: childrenRect.height + 15
|
||||||
|
Controls2.Button
|
||||||
|
{
|
||||||
|
id: pauseButton
|
||||||
|
text: modelData.activePrintJob != null && modelData.activePrintJob.state == "paused" ? catalog.i18nc("@label", "Resume") : catalog.i18nc("@label", "Pause")
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
if(modelData.activePrintJob.state == "paused")
|
||||||
|
{
|
||||||
|
modelData.activePrintJob.setState("print")
|
||||||
|
}
|
||||||
|
else if(modelData.activePrintJob.state == "printing")
|
||||||
|
{
|
||||||
|
modelData.activePrintJob.setState("pause")
|
||||||
|
}
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
enabled: modelData.activePrintJob != null && ["paused", "printing"].indexOf(modelData.activePrintJob.state) >= 0
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 10
|
||||||
|
hoverEnabled: true
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
opacity: pauseButton.down || pauseButton.hovered ? 1 : 0
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls2.Button
|
||||||
|
{
|
||||||
|
id: abortButton
|
||||||
|
text: catalog.i18nc("@label", "Abort")
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
modelData.activePrintJob.setState("abort")
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: pauseButton.bottom
|
||||||
|
hoverEnabled: true
|
||||||
|
enabled: modelData.activePrintJob != null && ["paused", "printing", "pre_print"].indexOf(modelData.activePrintJob.state) >= 0
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
opacity: abortButton.down || abortButton.hovered ? 1 : 0
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Item
|
||||||
|
{
|
||||||
|
width: popup.width
|
||||||
|
height: popup.height
|
||||||
|
|
||||||
|
DropShadow
|
||||||
|
{
|
||||||
|
anchors.fill: pointedRectangle
|
||||||
|
radius: 5
|
||||||
|
color: "#3F000000" // 25% shadow
|
||||||
|
source: pointedRectangle
|
||||||
|
transparentBorder: true
|
||||||
|
verticalOffset: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: pointedRectangle
|
||||||
|
width: parent.width -10
|
||||||
|
height: parent.height -10
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: point
|
||||||
|
height: 13
|
||||||
|
width: 13
|
||||||
|
color: UM.Theme.getColor("setting_control")
|
||||||
|
transform: Rotation { angle: 45}
|
||||||
|
anchors.right: bloop.right
|
||||||
|
y: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: bloop
|
||||||
|
color: UM.Theme.getColor("setting_control")
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 10
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit: Transition
|
||||||
|
{
|
||||||
|
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
|
||||||
|
NumberAnimation { property: "visible"; duration: 75; }
|
||||||
|
}
|
||||||
|
enter: Transition
|
||||||
|
{
|
||||||
|
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
|
||||||
|
NumberAnimation { property: "visible"; duration: 75; }
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: visible = false
|
||||||
|
onOpened: visible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Image
|
||||||
|
{
|
||||||
|
id: printJobPreview
|
||||||
|
source: modelData.activePrintJob != null ? modelData.activePrintJob.previewImageUrl : ""
|
||||||
|
anchors.top: ownerName.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: parent.width / 2
|
||||||
|
height: width
|
||||||
|
opacity:
|
||||||
|
{
|
||||||
|
if(modelData.activePrintJob == null)
|
||||||
|
{
|
||||||
|
return 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(modelData.activePrintJob.state)
|
||||||
|
{
|
||||||
|
case "wait_cleanup":
|
||||||
|
case "wait_user_action":
|
||||||
|
case "paused":
|
||||||
|
return 0.5
|
||||||
|
default:
|
||||||
|
return 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.RecolorImage
|
||||||
|
{
|
||||||
|
id: statusImage
|
||||||
|
anchors.centerIn: printJobPreview
|
||||||
|
source:
|
||||||
|
{
|
||||||
|
if(modelData.activePrintJob == null)
|
||||||
|
{
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
switch(modelData.activePrintJob.state)
|
||||||
|
{
|
||||||
|
case "paused":
|
||||||
|
return "../svg/paused-icon.svg"
|
||||||
|
case "wait_cleanup":
|
||||||
|
if(modelData.activePrintJob.timeElapsed < modelData.activePrintJob.timeTotal)
|
||||||
|
{
|
||||||
|
return "../svg/aborted-icon.svg"
|
||||||
|
}
|
||||||
|
return "../svg/approved-icon.svg"
|
||||||
|
case "wait_user_action":
|
||||||
|
return "../svg/aborted-icon.svg"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visible: source != ""
|
||||||
|
width: 0.5 * printJobPreview.width
|
||||||
|
height: 0.5 * printJobPreview.height
|
||||||
|
sourceSize.width: width
|
||||||
|
sourceSize.height: height
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: showCameraIcon
|
||||||
|
width: 35 * screenScaleFactor
|
||||||
|
height: width
|
||||||
|
radius: 0.5 * width
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.bottom: printJobPreview.bottom
|
||||||
|
color: UM.Theme.getColor("setting_control_border_highlight")
|
||||||
|
Image
|
||||||
|
{
|
||||||
|
width: parent.width
|
||||||
|
height: width
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: parent.rightMargin
|
||||||
|
source: "../svg/camera-icon.svg"
|
||||||
|
}
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
anchors.fill:parent
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
OutputDevice.setActiveCamera(modelData.camera)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressBar
|
||||||
|
{
|
||||||
|
property var progress:
|
||||||
|
{
|
||||||
|
if(modelData.activePrintJob == null)
|
||||||
|
{
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var result = modelData.activePrintJob.timeElapsed / modelData.activePrintJob.timeTotal
|
||||||
|
if(result > 1.0)
|
||||||
|
{
|
||||||
|
result = 1.0
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
id: jobProgressBar
|
||||||
|
width: parent.width
|
||||||
|
value: progress
|
||||||
|
anchors.top: detailedInfo.bottom
|
||||||
|
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||||
|
|
||||||
|
visible: modelData.activePrintJob != null && modelData.activePrintJob != undefined
|
||||||
|
|
||||||
|
style: ProgressBarStyle
|
||||||
|
{
|
||||||
|
property var progressText:
|
||||||
|
{
|
||||||
|
if(modelData.activePrintJob == null)
|
||||||
|
{
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(modelData.activePrintJob.state)
|
||||||
|
{
|
||||||
|
case "wait_cleanup":
|
||||||
|
if(modelData.activePrintJob.timeTotal > modelData.activePrintJob.timeElapsed)
|
||||||
|
{
|
||||||
|
return catalog.i18nc("@label:status", "Aborted")
|
||||||
|
}
|
||||||
|
return catalog.i18nc("@label:status", "Finished")
|
||||||
|
case "pre_print":
|
||||||
|
case "sent_to_printer":
|
||||||
|
return catalog.i18nc("@label:status", "Preparing")
|
||||||
|
case "aborted":
|
||||||
|
case "wait_user_action":
|
||||||
|
return catalog.i18nc("@label:status", "Aborted")
|
||||||
|
case "pausing":
|
||||||
|
return catalog.i18nc("@label:status", "Pausing")
|
||||||
|
case "paused":
|
||||||
|
return catalog.i18nc("@label:status", "Paused")
|
||||||
|
case "resuming":
|
||||||
|
return catalog.i18nc("@label:status", "Resuming")
|
||||||
|
case "queued":
|
||||||
|
return catalog.i18nc("@label:status", "Action required")
|
||||||
|
default:
|
||||||
|
OutputDevice.formatDuration(modelData.activePrintJob.timeTotal - modelData.activePrintJob.timeElapsed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
implicitWidth: 100
|
||||||
|
implicitHeight: visible ? 24 : 0
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
}
|
||||||
|
|
||||||
|
progress: Rectangle
|
||||||
|
{
|
||||||
|
color: UM.Theme.getColor("primary")
|
||||||
|
id: progressItem
|
||||||
|
function getTextOffset()
|
||||||
|
{
|
||||||
|
if(progressItem.width + progressLabel.width < control.width)
|
||||||
|
{
|
||||||
|
return progressItem.width + UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return progressItem.width - progressLabel.width - UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: progressLabel
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: getTextOffset()
|
||||||
|
text: progressText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: progressItem.width + progressLabel.width < control.width ? "black" : "white"
|
||||||
|
width: contentWidth
|
||||||
|
font: UM.Theme.getFont("default")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
108
plugins/UM3NetworkPrinting/resources/qml/ClusterMonitorItem.qml
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
|
||||||
|
import UM 1.3 as UM
|
||||||
|
import Cura 1.0 as Cura
|
||||||
|
|
||||||
|
Component
|
||||||
|
{
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: monitorFrame
|
||||||
|
width: maximumWidth
|
||||||
|
height: maximumHeight
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
property var emphasisColor: UM.Theme.getColor("setting_control_border_highlight")
|
||||||
|
property var lineColor: "#DCDCDC" // TODO: Should be linked to theme.
|
||||||
|
property var cornerRadius: 4 * screenScaleFactor // TODO: Should be linked to theme.
|
||||||
|
|
||||||
|
UM.I18nCatalog
|
||||||
|
{
|
||||||
|
id: catalog
|
||||||
|
name: "cura"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: manageQueueLabel
|
||||||
|
anchors.rightMargin: 4 * UM.Theme.getSize("default_margin").width
|
||||||
|
anchors.right: queuedPrintJobs.right
|
||||||
|
anchors.bottom: queuedLabel.bottom
|
||||||
|
text: catalog.i18nc("@label link to connect manager", "Manage queue")
|
||||||
|
font: UM.Theme.getFont("default")
|
||||||
|
color: UM.Theme.getColor("primary")
|
||||||
|
linkColor: UM.Theme.getColor("primary")
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
anchors.fill: manageQueueLabel
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel()
|
||||||
|
onEntered: manageQueueLabel.font.underline = true
|
||||||
|
onExited: manageQueueLabel.font.underline = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: queuedLabel
|
||||||
|
anchors.left: queuedPrintJobs.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 2 * UM.Theme.getSize("default_margin").height
|
||||||
|
anchors.leftMargin: 3 * UM.Theme.getSize("default_margin").width
|
||||||
|
text: catalog.i18nc("@label", "Queued")
|
||||||
|
font: UM.Theme.getFont("large")
|
||||||
|
color: UM.Theme.getColor("text")
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView
|
||||||
|
{
|
||||||
|
id: queuedPrintJobs
|
||||||
|
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: queuedLabel.bottom
|
||||||
|
topMargin: UM.Theme.getSize("default_margin").height
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
bottomMargin: 0
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
style: UM.Theme.styles.scrollview
|
||||||
|
width: Math.min(800 * screenScaleFactor, maximumWidth)
|
||||||
|
ListView
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
//anchors.margins: UM.Theme.getSize("default_margin").height
|
||||||
|
spacing: UM.Theme.getSize("default_margin").height - 10 // 2x the shadow radius
|
||||||
|
|
||||||
|
model: OutputDevice.queuedPrintJobs
|
||||||
|
|
||||||
|
delegate: PrintJobInfoBlock
|
||||||
|
{
|
||||||
|
printJob: modelData
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: UM.Theme.getSize("default_margin").height
|
||||||
|
anchors.leftMargin: UM.Theme.getSize("default_margin").height
|
||||||
|
height: 175 * screenScaleFactor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PrinterVideoStream
|
||||||
|
{
|
||||||
|
visible: OutputDevice.activeCamera != null
|
||||||
|
anchors.fill: parent
|
||||||
|
camera: OutputDevice.activeCamera
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged:
|
||||||
|
{
|
||||||
|
if (monitorFrame != null && !monitorFrame.visible)
|
||||||
|
{
|
||||||
|
OutputDevice.setActiveCamera(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
|
||||||
|
import UM 1.2 as UM
|
||||||
|
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: extruderInfo
|
||||||
|
property var printCoreConfiguration
|
||||||
|
|
||||||
|
width: Math.round(parent.width / 2)
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: extruderCircle
|
||||||
|
width: 30
|
||||||
|
height: 30
|
||||||
|
|
||||||
|
anchors.verticalCenter: printAndMaterialLabel.verticalCenter
|
||||||
|
opacity:
|
||||||
|
{
|
||||||
|
if(printCoreConfiguration == null || printCoreConfiguration.activeMaterial == null || printCoreConfiguration.hotendID == null)
|
||||||
|
{
|
||||||
|
return 0.5
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Math.round(width / 2)
|
||||||
|
border.width: 2
|
||||||
|
border.color: "black"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font: UM.Theme.getFont("default_bold")
|
||||||
|
text: printCoreConfiguration.position + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: printAndMaterialLabel
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
right: parent.right
|
||||||
|
left: extruderCircle.right
|
||||||
|
margins: UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: materialLabel
|
||||||
|
text:
|
||||||
|
{
|
||||||
|
if(printCoreConfiguration != undefined && printCoreConfiguration.activeMaterial != undefined)
|
||||||
|
{
|
||||||
|
return printCoreConfiguration.activeMaterial.name
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
font: UM.Theme.getFont("default_bold")
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: printCoreLabel
|
||||||
|
text:
|
||||||
|
{
|
||||||
|
if(printCoreConfiguration != undefined && printCoreConfiguration.hotendID != undefined)
|
||||||
|
{
|
||||||
|
return printCoreConfiguration.hotendID
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
anchors.top: materialLabel.bottom
|
||||||
|
elide: Text.ElideRight
|
||||||
|
width: parent.width
|
||||||
|
opacity: 0.6
|
||||||
|
font: UM.Theme.getFont("default")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
378
plugins/UM3NetworkPrinting/resources/qml/PrintJobInfoBlock.qml
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import UM 1.3 as UM
|
||||||
|
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: base
|
||||||
|
property var printJob: null
|
||||||
|
property var shadowRadius: 5
|
||||||
|
function getPrettyTime(time)
|
||||||
|
{
|
||||||
|
return OutputDevice.formatDuration(time)
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.I18nCatalog
|
||||||
|
{
|
||||||
|
id: catalog
|
||||||
|
name: "cura"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: background
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
topMargin: 3
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: base.shadowRadius
|
||||||
|
rightMargin: base.shadowRadius
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
bottomMargin: base.shadowRadius
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow
|
||||||
|
{
|
||||||
|
radius: base.shadowRadius
|
||||||
|
verticalOffset: 2
|
||||||
|
color: "#3F000000" // 25% shadow
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
// Content on the left of the infobox
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.horizontalCenter
|
||||||
|
margins: 2 * UM.Theme.getSize("default_margin").width
|
||||||
|
rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: printJobName
|
||||||
|
text: printJob.name
|
||||||
|
font: UM.Theme.getFont("default_bold")
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: ownerName
|
||||||
|
anchors.top: printJobName.bottom
|
||||||
|
text: printJob.owner
|
||||||
|
font: UM.Theme.getFont("default")
|
||||||
|
opacity: 0.6
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
Image
|
||||||
|
{
|
||||||
|
id: printJobPreview
|
||||||
|
source: printJob.previewImageUrl
|
||||||
|
anchors.top: ownerName.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: totalTimeLabel.bottom
|
||||||
|
width: height
|
||||||
|
opacity: printJob.state == "error" ? 0.5 : 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
UM.RecolorImage
|
||||||
|
{
|
||||||
|
id: statusImage
|
||||||
|
anchors.centerIn: printJobPreview
|
||||||
|
source: printJob.state == "error" ? "../svg/aborted-icon.svg" : ""
|
||||||
|
visible: source != ""
|
||||||
|
width: 0.5 * printJobPreview.width
|
||||||
|
height: 0.5 * printJobPreview.height
|
||||||
|
sourceSize.width: width
|
||||||
|
sourceSize.height: height
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: totalTimeLabel
|
||||||
|
opacity: 0.6
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
|
font: UM.Theme.getFont("default")
|
||||||
|
text: printJob != null ? getPrettyTime(printJob.timeTotal) : ""
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
// Content on the right side of the infobox.
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.horizontalCenter
|
||||||
|
right: parent.right
|
||||||
|
margins: 2 * UM.Theme.getSize("default_margin").width
|
||||||
|
leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: targetPrinterLabel
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font: UM.Theme.getFont("default_bold")
|
||||||
|
text:
|
||||||
|
{
|
||||||
|
if(printJob.assignedPrinter == null)
|
||||||
|
{
|
||||||
|
if(printJob.state == "error")
|
||||||
|
{
|
||||||
|
return catalog.i18nc("@label", "Waiting for: Unavailable printer")
|
||||||
|
}
|
||||||
|
return catalog.i18nc("@label", "Waiting for: First available")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return catalog.i18nc("@label", "Waiting for: ") + printJob.assignedPrinter.name
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
left: parent.left
|
||||||
|
right: contextButton.left
|
||||||
|
rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function switchPopupState()
|
||||||
|
{
|
||||||
|
popup.visible ? popup.close() : popup.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: contextButton
|
||||||
|
text: "\u22EE" //Unicode; Three stacked points.
|
||||||
|
font.pixelSize: 25
|
||||||
|
width: 35
|
||||||
|
height: width
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
opacity: contextButton.down || contextButton.hovered ? 1 : 0
|
||||||
|
width: contextButton.width
|
||||||
|
height: contextButton.height
|
||||||
|
radius: 0.5 * width
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: parent.switchPopupState()
|
||||||
|
}
|
||||||
|
|
||||||
|
Popup
|
||||||
|
{
|
||||||
|
// TODO Change once updating to Qt5.10 - The 'opened' property is in 5.10 but the behavior is now implemented with the visible property
|
||||||
|
id: popup
|
||||||
|
clip: true
|
||||||
|
closePolicy: Popup.CloseOnPressOutsideParent
|
||||||
|
x: parent.width - width
|
||||||
|
y: contextButton.height
|
||||||
|
width: 160
|
||||||
|
height: contentItem.height + 2 * padding
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
transformOrigin: Popup.Top
|
||||||
|
contentItem: Item
|
||||||
|
{
|
||||||
|
width: popup.width - 2 * popup.padding
|
||||||
|
height: childrenRect.height + 15
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: sendToTopButton
|
||||||
|
text: catalog.i18nc("@label", "Move to top")
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
OutputDevice.sendJobToTop(printJob.key)
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
enabled: OutputDevice.queuedPrintJobs[0].key != printJob.key
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 10
|
||||||
|
hoverEnabled: true
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
opacity: sendToTopButton.down || sendToTopButton.hovered ? 1 : 0
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: deleteButton
|
||||||
|
text: catalog.i18nc("@label", "Delete")
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
OutputDevice.deleteJobFromQueue(printJob.key)
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: sendToTopButton.bottom
|
||||||
|
hoverEnabled: true
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
opacity: deleteButton.down || deleteButton.hovered ? 1 : 0
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Item
|
||||||
|
{
|
||||||
|
width: popup.width
|
||||||
|
height: popup.height
|
||||||
|
|
||||||
|
DropShadow
|
||||||
|
{
|
||||||
|
anchors.fill: pointedRectangle
|
||||||
|
radius: 5
|
||||||
|
color: "#3F000000" // 25% shadow
|
||||||
|
source: pointedRectangle
|
||||||
|
transparentBorder: true
|
||||||
|
verticalOffset: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: pointedRectangle
|
||||||
|
width: parent.width -10
|
||||||
|
height: parent.height -10
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: point
|
||||||
|
height: 13
|
||||||
|
width: 13
|
||||||
|
color: UM.Theme.getColor("setting_control")
|
||||||
|
transform: Rotation { angle: 45}
|
||||||
|
anchors.right: bloop.right
|
||||||
|
y: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: bloop
|
||||||
|
color: UM.Theme.getColor("setting_control")
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 10
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit: Transition
|
||||||
|
{
|
||||||
|
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
|
||||||
|
NumberAnimation { property: "visible"; duration: 75; }
|
||||||
|
}
|
||||||
|
enter: Transition
|
||||||
|
{
|
||||||
|
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
|
||||||
|
NumberAnimation { property: "visible"; duration: 75; }
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: visible = false
|
||||||
|
onOpened: visible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Row
|
||||||
|
{
|
||||||
|
id: printerFamilyPills
|
||||||
|
spacing: 0.5 * UM.Theme.getSize("default_margin").width
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: extrudersInfo.top
|
||||||
|
bottomMargin: UM.Theme.getSize("default_margin").height
|
||||||
|
}
|
||||||
|
height: childrenRect.height
|
||||||
|
Repeater
|
||||||
|
{
|
||||||
|
model: printJob.compatibleMachineFamilies
|
||||||
|
|
||||||
|
delegate: PrinterFamilyPill
|
||||||
|
{
|
||||||
|
text: modelData
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
padding: 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// PrintCore && Material config
|
||||||
|
Row
|
||||||
|
{
|
||||||
|
id: extrudersInfo
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
height: childrenRect.height
|
||||||
|
|
||||||
|
spacing: UM.Theme.getSize("default_margin").width
|
||||||
|
|
||||||
|
PrintCoreConfiguration
|
||||||
|
{
|
||||||
|
id: leftExtruderInfo
|
||||||
|
width: Math.round(parent.width / 2)
|
||||||
|
printCoreConfiguration: printJob.configuration.extruderConfigurations[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintCoreConfiguration
|
||||||
|
{
|
||||||
|
id: rightExtruderInfo
|
||||||
|
width: Math.round(parent.width / 2)
|
||||||
|
printCoreConfiguration: printJob.configuration.extruderConfigurations[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
color: UM.Theme.getColor("viewport_background")
|
||||||
|
width: 2
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.margins: UM.Theme.getSize("default_margin").height
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
import QtQuick 2.2
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import UM 1.2 as UM
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
property alias color: background.color
|
||||||
|
property alias text: familyNameLabel.text
|
||||||
|
property var padding: 0
|
||||||
|
implicitHeight: familyNameLabel.contentHeight + 2 * padding // Apply the padding to top and bottom.
|
||||||
|
implicitWidth: familyNameLabel.contentWidth + implicitHeight // The extra height is added to ensure the radius doesn't cut something off.
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: background
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width
|
||||||
|
color: parent.color
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
radius: 0.5 * height
|
||||||
|
}
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: familyNameLabel
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,8 @@ import UM 1.3 as UM
|
|||||||
|
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
|
property var camera: null
|
||||||
|
|
||||||
Rectangle
|
Rectangle
|
||||||
{
|
{
|
||||||
anchors.fill:parent
|
anchors.fill:parent
|
||||||
@ -17,7 +19,7 @@ Item
|
|||||||
MouseArea
|
MouseArea
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: OutputDevice.setActivePrinter(null)
|
onClicked: OutputDevice.setActiveCamera(null)
|
||||||
z: 0
|
z: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +34,7 @@ Item
|
|||||||
width: 20 * screenScaleFactor
|
width: 20 * screenScaleFactor
|
||||||
height: 20 * screenScaleFactor
|
height: 20 * screenScaleFactor
|
||||||
|
|
||||||
onClicked: OutputDevice.setActivePrinter(null)
|
onClicked: OutputDevice.setActiveCamera(null)
|
||||||
|
|
||||||
style: ButtonStyle
|
style: ButtonStyle
|
||||||
{
|
{
|
||||||
@ -65,23 +67,24 @@ Item
|
|||||||
{
|
{
|
||||||
if(visible)
|
if(visible)
|
||||||
{
|
{
|
||||||
if(OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null)
|
if(camera != null)
|
||||||
{
|
{
|
||||||
OutputDevice.activePrinter.camera.start()
|
camera.start()
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
if(OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null)
|
if(camera != null)
|
||||||
{
|
{
|
||||||
OutputDevice.activePrinter.camera.stop()
|
camera.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source:
|
source:
|
||||||
{
|
{
|
||||||
if(OutputDevice.activePrinter != null && OutputDevice.activePrinter.camera != null && OutputDevice.activePrinter.camera.latestImage)
|
if(camera != null && camera.latestImage != null)
|
||||||
{
|
{
|
||||||
return OutputDevice.activePrinter.camera.latestImage;
|
return camera.latestImage;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -92,7 +95,7 @@ Item
|
|||||||
anchors.fill: cameraImage
|
anchors.fill: cameraImage
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
OutputDevice.setActivePrinter(null)
|
OutputDevice.setActiveCamera(null)
|
||||||
}
|
}
|
||||||
z: 1
|
z: 1
|
||||||
}
|
}
|
1
plugins/UM3NetworkPrinting/resources/svg/UM3-icon.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 46.16 48"><defs><style>.cls-1{fill:#9a9a9a;}</style></defs><title>UM3-icon</title><g id="Symbols"><g id="system_overview_inactive" data-name="system overview inactive"><path id="Shape" class="cls-1" d="M18.4,12.2h9.26c.1,0,.1,0,.2-.2l1.73-4.27a.22.22,0,0,0-.2-.2H16.67a.22.22,0,0,0-.2.2L18.2,12C18.3,12.2,18.3,12.2,18.4,12.2Z"/><path id="Shape-2" data-name="Shape" class="cls-1" d="M38.33,35.08H7.72a.48.48,0,0,0-.5.51V37a.48.48,0,0,0,.5.51H38.44a.48.48,0,0,0,.5-.51V35.59A.64.64,0,0,0,38.33,35.08Z"/><path id="Shape-3" data-name="Shape" class="cls-1" d="M0,0V48H3.76a2.86,2.86,0,0,1,2.13-1H40.27a2.86,2.86,0,0,1,2.13,1h3.76V0ZM41.28,37a2.83,2.83,0,0,1-2.84,2.84H7.72A2.84,2.84,0,0,1,4.88,37V5.49a.65.65,0,0,1,.61-.61H40.67a.65.65,0,0,1,.61.61Z"/></g></g></svg>
|
After Width: | Height: | Size: 847 B |
1
plugins/UM3NetworkPrinting/resources/svg/UM3x-icon.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 46.16 58"><defs><style>.cls-1{fill:#9a9a9a;}</style></defs><title>UM3x-icon</title><g id="Symbols"><g id="system_overview_inactive" data-name="system overview inactive"><path id="Shape" class="cls-1" d="M18.4,12.2h9.26c.1,0,.1,0,.2-.2l1.73-4.27a.22.22,0,0,0-.2-.2H16.67a.22.22,0,0,0-.2.2L18.2,12C18.3,12.2,18.3,12.2,18.4,12.2Z"/><path id="Shape-2" data-name="Shape" class="cls-1" d="M38.33,45.08H7.72a.48.48,0,0,0-.5.51V47a.48.48,0,0,0,.5.51H38.44a.48.48,0,0,0,.5-.51V45.59A.64.64,0,0,0,38.33,45.08Z"/><path id="Shape-3" data-name="Shape" class="cls-1" d="M0,0V58H3.76a2.86,2.86,0,0,1,2.13-1H40.27a2.86,2.86,0,0,1,2.13,1h3.76V0ZM41.28,35.32V47a2.83,2.83,0,0,1-2.84,2.84H7.72A2.84,2.84,0,0,1,4.88,47V5.49a.65.65,0,0,1,.61-.61H40.67a.65.65,0,0,1,.61.61Z"/></g></g></svg>
|
After Width: | Height: | Size: 854 B |
1
plugins/UM3NetworkPrinting/resources/svg/UMs5-icon.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 58 58"><defs><style>.cls-1{fill:none;}.cls-2{fill:#9a9a9a;}</style></defs><title>UMs5-icon</title><path class="cls-1" d="M33.83,12.33c-.1.2-.1.2-.2.2H24.37c-.1,0-.1,0-.2-.2L22.44,8.06a.22.22,0,0,1,.2-.2H35.36a.22.22,0,0,1,.2.2Z"/><path class="cls-2" d="M35.36,7.86H22.64a.22.22,0,0,0-.2.2l1.73,4.27c.1.2.1.2.2.2h9.26c.1,0,.1,0,.2-.2l1.73-4.27A.22.22,0,0,0,35.36,7.86Z"/><path class="cls-2" d="M0,0V58H3.75a2.85,2.85,0,0,1,2.12-1H52.13a2.85,2.85,0,0,1,2.12,1H58V0ZM37.5,53.82a1.5,1.5,0,0,1-1.5,1.5H22a1.5,1.5,0,0,1-1.5-1.5v-4a1.5,1.5,0,0,1,1.5-1.5H36a1.5,1.5,0,0,1,1.5,1.5Zm15.63-18.5V47a2.83,2.83,0,0,1-2.83,2.84H38.5v0a2.5,2.5,0,0,0-2.5-2.5H22a2.5,2.5,0,0,0-2.5,2.5v0H7.7A2.83,2.83,0,0,1,4.87,47V5.49a.65.65,0,0,1,.6-.61H52.53a.65.65,0,0,1,.6.61Z"/></svg>
|
After Width: | Height: | Size: 842 B |
@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><title>aborted-icon</title><path d="M16,0A16,16,0,1,0,32,16,16,16,0,0,0,16,0Zm1.69,28.89a13,13,0,1,1,11.2-11.2A13,13,0,0,1,17.69,28.89Z"/><polygon points="20.6 9.28 16 13.88 11.4 9.28 9.28 11.4 13.88 16 9.28 20.6 11.4 22.72 16 18.12 20.6 22.72 22.72 20.6 18.12 16 22.72 11.4 20.6 9.28"/></svg>
|
After Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 844 B |
@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><title>approved-icon</title><path d="M16,29A13,13,0,1,0,3,16,13,13,0,0,0,16,29ZM8,14.59l6,5.3L23.89,9l2.22,2L14.18,24.11,6,16.83Z" fill="none"/><path d="M16,32A16,16,0,1,0,0,16,16,16,0,0,0,16,32ZM16,3A13,13,0,1,1,3,16,13,13,0,0,1,16,3Z"/><polygon points="26.11 11.01 23.89 8.99 13.96 19.89 8 14.59 6 16.83 14.18 24.11 26.11 11.01"/></svg>
|
After Width: | Height: | Size: 431 B |
Before Width: | Height: | Size: 311 B After Width: | Height: | Size: 311 B |
Before Width: | Height: | Size: 438 B After Width: | Height: | Size: 438 B |
Before Width: | Height: | Size: 194 B After Width: | Height: | Size: 194 B |
1
plugins/UM3NetworkPrinting/resources/svg/paused-icon.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><title>paused-icon</title><path d="M16,0A16,16,0,1,0,32,16,16,16,0,0,0,16,0Zm0,29A13,13,0,1,1,29,16,13,13,0,0,1,16,29Z"/><rect x="11.5" y="9" width="3" height="14"/><rect x="17.5" y="9" width="3" height="14"/></svg>
|
After Width: | Height: | Size: 308 B |
@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><title>warning-icon</title><path d="M18.09,1.31A2.35,2.35,0,0,0,16,0a2.31,2.31,0,0,0-2.09,1.31L.27,28.44A2.49,2.49,0,0,0,.11,30.3a2.38,2.38,0,0,0,1.16,1.42A2.33,2.33,0,0,0,2.36,32H29.64A2.4,2.4,0,0,0,32,29.57a2.55,2.55,0,0,0-.27-1.14ZM3.34,29,16,3.83,28.66,29Z"/><polygon points="13.94 25.19 13.94 25.19 13.94 25.19 13.94 25.19"/><polygon points="14.39 21.68 17.61 21.68 18.11 11.85 13.89 11.85 14.39 21.68"/><path d="M16.06,23.08a2.19,2.19,0,0,0-1.56,3.66,2.14,2.14,0,0,0,1.56.55,2.06,2.06,0,0,0,1.54-.55,2.1,2.1,0,0,0,.55-1.55,2.17,2.17,0,0,0-.53-1.55A2.05,2.05,0,0,0,16.06,23.08Z"/></svg>
|
After Width: | Height: | Size: 684 B |
@ -4,19 +4,21 @@
|
|||||||
from typing import Any, cast, Optional, Set, Tuple, Union
|
from typing import Any, cast, Optional, Set, Tuple, Union
|
||||||
|
|
||||||
from UM.FileHandler.FileHandler import FileHandler
|
from UM.FileHandler.FileHandler import FileHandler
|
||||||
from UM.FileHandler.FileWriter import FileWriter #To choose based on the output file mode (text vs. binary).
|
from UM.FileHandler.FileWriter import FileWriter # To choose based on the output file mode (text vs. binary).
|
||||||
from UM.FileHandler.WriteFileJob import WriteFileJob #To call the file writer asynchronously.
|
from UM.FileHandler.WriteFileJob import WriteFileJob # To call the file writer asynchronously.
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
from UM.Mesh.MeshWriter import MeshWriter # For typing
|
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
from UM.Qt.Duration import Duration, DurationFormat
|
from UM.Qt.Duration import Duration, DurationFormat
|
||||||
from UM.OutputDevice import OutputDeviceError #To show that something went wrong when writing.
|
from UM.OutputDevice import OutputDeviceError # To show that something went wrong when writing.
|
||||||
from UM.Scene.SceneNode import SceneNode #For typing.
|
from UM.Scene.SceneNode import SceneNode # For typing.
|
||||||
from UM.Version import Version #To check against firmware versions for support.
|
from UM.Version import Version # To check against firmware versions for support.
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||||
|
from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
|
||||||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
|
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
|
||||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||||
@ -27,14 +29,14 @@ from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController
|
|||||||
from .SendMaterialJob import SendMaterialJob
|
from .SendMaterialJob import SendMaterialJob
|
||||||
|
|
||||||
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
|
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
|
||||||
from PyQt5.QtGui import QDesktopServices
|
from PyQt5.QtGui import QDesktopServices, QImage
|
||||||
from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject
|
from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject
|
||||||
|
|
||||||
from time import time
|
from time import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Optional, Dict, List, Set
|
from typing import Optional, Dict, List
|
||||||
|
|
||||||
import io #To create the correct buffers for sending data to the printer.
|
import io # To create the correct buffers for sending data to the printer.
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -44,6 +46,7 @@ i18n_catalog = i18nCatalog("cura")
|
|||||||
class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
||||||
printJobsChanged = pyqtSignal()
|
printJobsChanged = pyqtSignal()
|
||||||
activePrinterChanged = pyqtSignal()
|
activePrinterChanged = pyqtSignal()
|
||||||
|
activeCameraChanged = pyqtSignal()
|
||||||
|
|
||||||
# This is a bit of a hack, as the notify can only use signals that are defined by the class that they are in.
|
# This is a bit of a hack, as the notify can only use signals that are defined by the class that they are in.
|
||||||
# Inheritance doesn't seem to work. Tying them together does work, but i'm open for better suggestions.
|
# Inheritance doesn't seem to work. Tying them together does work, but i'm open for better suggestions.
|
||||||
@ -59,24 +62,24 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
|
|
||||||
self._print_jobs = [] # type: List[PrintJobOutputModel]
|
self._print_jobs = [] # type: List[PrintJobOutputModel]
|
||||||
|
|
||||||
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ClusterMonitorItem.qml")
|
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/ClusterMonitorItem.qml")
|
||||||
self._control_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ClusterControlItem.qml")
|
self._control_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/ClusterControlItem.qml")
|
||||||
|
|
||||||
# See comments about this hack with the clusterPrintersChanged signal
|
# See comments about this hack with the clusterPrintersChanged signal
|
||||||
self.printersChanged.connect(self.clusterPrintersChanged)
|
self.printersChanged.connect(self.clusterPrintersChanged)
|
||||||
|
|
||||||
self._accepts_commands = True #type: bool
|
self._accepts_commands = True # type: bool
|
||||||
|
|
||||||
# Cluster does not have authentication, so default to authenticated
|
# Cluster does not have authentication, so default to authenticated
|
||||||
self._authentication_state = AuthState.Authenticated
|
self._authentication_state = AuthState.Authenticated
|
||||||
|
|
||||||
self._error_message = None #type: Optional[Message]
|
self._error_message = None # type: Optional[Message]
|
||||||
self._write_job_progress_message = None #type: Optional[Message]
|
self._write_job_progress_message = None # type: Optional[Message]
|
||||||
self._progress_message = None #type: Optional[Message]
|
self._progress_message = None # type: Optional[Message]
|
||||||
|
|
||||||
self._active_printer = None # type: Optional[PrinterOutputModel]
|
self._active_printer = None # type: Optional[PrinterOutputModel]
|
||||||
|
|
||||||
self._printer_selection_dialog = None #type: QObject
|
self._printer_selection_dialog = None # type: QObject
|
||||||
|
|
||||||
self.setPriority(3) # Make sure the output device gets selected above local file output
|
self.setPriority(3) # Make sure the output device gets selected above local file output
|
||||||
self.setName(self._id)
|
self.setName(self._id)
|
||||||
@ -87,32 +90,35 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
|
|
||||||
self._printer_uuid_to_unique_name_mapping = {} # type: Dict[str, str]
|
self._printer_uuid_to_unique_name_mapping = {} # type: Dict[str, str]
|
||||||
|
|
||||||
self._finished_jobs = [] # type: List[PrintJobOutputModel]
|
self._finished_jobs = [] # type: List[PrintJobOutputModel]
|
||||||
|
|
||||||
self._cluster_size = int(properties.get(b"cluster_size", 0))
|
self._cluster_size = int(properties.get(b"cluster_size", 0)) # type: int
|
||||||
|
|
||||||
self._latest_reply_handler = None #type: Optional[QNetworkReply]
|
self._latest_reply_handler = None # type: Optional[QNetworkReply]
|
||||||
|
self._sending_job = None
|
||||||
|
|
||||||
|
self._active_camera = None # type: Optional[NetworkCamera]
|
||||||
|
|
||||||
def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None:
|
def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional[FileHandler] = None, **kwargs: str) -> None:
|
||||||
self.writeStarted.emit(self)
|
self.writeStarted.emit(self)
|
||||||
|
|
||||||
self.sendMaterialProfiles()
|
self.sendMaterialProfiles()
|
||||||
|
|
||||||
#Formats supported by this application (file types that we can actually write).
|
# Formats supported by this application (file types that we can actually write).
|
||||||
if file_handler:
|
if file_handler:
|
||||||
file_formats = file_handler.getSupportedFileTypesWrite()
|
file_formats = file_handler.getSupportedFileTypesWrite()
|
||||||
else:
|
else:
|
||||||
file_formats = CuraApplication.getInstance().getMeshFileHandler().getSupportedFileTypesWrite()
|
file_formats = CuraApplication.getInstance().getMeshFileHandler().getSupportedFileTypesWrite()
|
||||||
|
|
||||||
global_stack = CuraApplication.getInstance().getGlobalContainerStack()
|
global_stack = CuraApplication.getInstance().getGlobalContainerStack()
|
||||||
#Create a list from the supported file formats string.
|
# Create a list from the supported file formats string.
|
||||||
if not global_stack:
|
if not global_stack:
|
||||||
Logger.log("e", "Missing global stack!")
|
Logger.log("e", "Missing global stack!")
|
||||||
return
|
return
|
||||||
|
|
||||||
machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";")
|
machine_file_formats = global_stack.getMetaDataEntry("file_formats").split(";")
|
||||||
machine_file_formats = [file_type.strip() for file_type in machine_file_formats]
|
machine_file_formats = [file_type.strip() for file_type in machine_file_formats]
|
||||||
#Exception for UM3 firmware version >=4.4: UFP is now supported and should be the preferred file format.
|
# Exception for UM3 firmware version >=4.4: UFP is now supported and should be the preferred file format.
|
||||||
if "application/x-ufp" not in machine_file_formats and Version(self.firmwareVersion) >= Version("4.4"):
|
if "application/x-ufp" not in machine_file_formats and Version(self.firmwareVersion) >= Version("4.4"):
|
||||||
machine_file_formats = ["application/x-ufp"] + machine_file_formats
|
machine_file_formats = ["application/x-ufp"] + machine_file_formats
|
||||||
|
|
||||||
@ -125,7 +131,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
raise OutputDeviceError.WriteRequestFailedError(i18n_catalog.i18nc("@info:status", "There are no file formats available to write with!"))
|
raise OutputDeviceError.WriteRequestFailedError(i18n_catalog.i18nc("@info:status", "There are no file formats available to write with!"))
|
||||||
preferred_format = file_formats[0]
|
preferred_format = file_formats[0]
|
||||||
|
|
||||||
#Just take the first file format available.
|
# Just take the first file format available.
|
||||||
if file_handler is not None:
|
if file_handler is not None:
|
||||||
writer = file_handler.getWriterByMimeType(cast(str, preferred_format["mime_type"]))
|
writer = file_handler.getWriterByMimeType(cast(str, preferred_format["mime_type"]))
|
||||||
else:
|
else:
|
||||||
@ -135,29 +141,30 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
Logger.log("e", "Unexpected error when trying to get the FileWriter")
|
Logger.log("e", "Unexpected error when trying to get the FileWriter")
|
||||||
return
|
return
|
||||||
|
|
||||||
#This function pauses with the yield, waiting on instructions on which printer it needs to print with.
|
# This function pauses with the yield, waiting on instructions on which printer it needs to print with.
|
||||||
if not writer:
|
if not writer:
|
||||||
Logger.log("e", "Missing file or mesh writer!")
|
Logger.log("e", "Missing file or mesh writer!")
|
||||||
return
|
return
|
||||||
self._sending_job = self._sendPrintJob(writer, preferred_format, nodes)
|
self._sending_job = self._sendPrintJob(writer, preferred_format, nodes)
|
||||||
self._sending_job.send(None) #Start the generator.
|
if self._sending_job is not None:
|
||||||
|
self._sending_job.send(None) # Start the generator.
|
||||||
|
|
||||||
if len(self._printers) > 1: #We need to ask the user.
|
if len(self._printers) > 1: # We need to ask the user.
|
||||||
self._spawnPrinterSelectionDialog()
|
self._spawnPrinterSelectionDialog()
|
||||||
is_job_sent = True
|
is_job_sent = True
|
||||||
else: #Just immediately continue.
|
else: # Just immediately continue.
|
||||||
self._sending_job.send("") #No specifically selected printer.
|
self._sending_job.send("") # No specifically selected printer.
|
||||||
is_job_sent = self._sending_job.send(None)
|
is_job_sent = self._sending_job.send(None)
|
||||||
|
|
||||||
def _spawnPrinterSelectionDialog(self):
|
def _spawnPrinterSelectionDialog(self):
|
||||||
if self._printer_selection_dialog is None:
|
if self._printer_selection_dialog is None:
|
||||||
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "PrintWindow.qml")
|
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/PrintWindow.qml")
|
||||||
self._printer_selection_dialog = CuraApplication.getInstance().createQmlComponent(path, {"OutputDevice": self})
|
self._printer_selection_dialog = CuraApplication.getInstance().createQmlComponent(path, {"OutputDevice": self})
|
||||||
if self._printer_selection_dialog is not None:
|
if self._printer_selection_dialog is not None:
|
||||||
self._printer_selection_dialog.show()
|
self._printer_selection_dialog.show()
|
||||||
|
|
||||||
@pyqtProperty(int, constant=True)
|
@pyqtProperty(int, constant=True)
|
||||||
def clusterSize(self):
|
def clusterSize(self) -> int:
|
||||||
return self._cluster_size
|
return self._cluster_size
|
||||||
|
|
||||||
## Allows the user to choose a printer to print with from the printer
|
## Allows the user to choose a printer to print with from the printer
|
||||||
@ -165,7 +172,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
# \param target_printer The name of the printer to target.
|
# \param target_printer The name of the printer to target.
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def selectPrinter(self, target_printer: str = "") -> None:
|
def selectPrinter(self, target_printer: str = "") -> None:
|
||||||
self._sending_job.send(target_printer)
|
if self._sending_job is not None:
|
||||||
|
self._sending_job.send(target_printer)
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def cancelPrintSelection(self) -> None:
|
def cancelPrintSelection(self) -> None:
|
||||||
@ -214,8 +222,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
|
|
||||||
job.start()
|
job.start()
|
||||||
|
|
||||||
yield True #Return that we had success!
|
yield True # Return that we had success!
|
||||||
yield #To prevent having to catch the StopIteration exception.
|
yield # To prevent having to catch the StopIteration exception.
|
||||||
|
|
||||||
def _sendPrintJobWaitOnWriteJobFinished(self, job: WriteFileJob) -> None:
|
def _sendPrintJobWaitOnWriteJobFinished(self, job: WriteFileJob) -> None:
|
||||||
if self._write_job_progress_message:
|
if self._write_job_progress_message:
|
||||||
@ -240,7 +248,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
|
|
||||||
file_name = CuraApplication.getInstance().getPrintInformation().jobName + "." + preferred_format["extension"]
|
file_name = CuraApplication.getInstance().getPrintInformation().jobName + "." + preferred_format["extension"]
|
||||||
|
|
||||||
output = stream.getvalue() #Either str or bytes depending on the output mode.
|
output = stream.getvalue() # Either str or bytes depending on the output mode.
|
||||||
if isinstance(stream, io.StringIO):
|
if isinstance(stream, io.StringIO):
|
||||||
output = cast(str, output).encode("utf-8")
|
output = cast(str, output).encode("utf-8")
|
||||||
output = cast(bytes, output)
|
output = cast(bytes, output)
|
||||||
@ -253,6 +261,10 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
def activePrinter(self) -> Optional[PrinterOutputModel]:
|
def activePrinter(self) -> Optional[PrinterOutputModel]:
|
||||||
return self._active_printer
|
return self._active_printer
|
||||||
|
|
||||||
|
@pyqtProperty(QObject, notify=activeCameraChanged)
|
||||||
|
def activeCamera(self) -> Optional[NetworkCamera]:
|
||||||
|
return self._active_camera
|
||||||
|
|
||||||
@pyqtSlot(QObject)
|
@pyqtSlot(QObject)
|
||||||
def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None:
|
def setActivePrinter(self, printer: Optional[PrinterOutputModel]) -> None:
|
||||||
if self._active_printer != printer:
|
if self._active_printer != printer:
|
||||||
@ -261,6 +273,19 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
self._active_printer = printer
|
self._active_printer = printer
|
||||||
self.activePrinterChanged.emit()
|
self.activePrinterChanged.emit()
|
||||||
|
|
||||||
|
@pyqtSlot(QObject)
|
||||||
|
def setActiveCamera(self, camera: Optional[NetworkCamera]) -> None:
|
||||||
|
if self._active_camera != camera:
|
||||||
|
if self._active_camera:
|
||||||
|
self._active_camera.stop()
|
||||||
|
|
||||||
|
self._active_camera = camera
|
||||||
|
|
||||||
|
if self._active_camera:
|
||||||
|
self._active_camera.start()
|
||||||
|
|
||||||
|
self.activeCameraChanged.emit()
|
||||||
|
|
||||||
def _onPostPrintJobFinished(self, reply: QNetworkReply) -> None:
|
def _onPostPrintJobFinished(self, reply: QNetworkReply) -> None:
|
||||||
if self._progress_message:
|
if self._progress_message:
|
||||||
self._progress_message.hide()
|
self._progress_message.hide()
|
||||||
@ -279,8 +304,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
|
|
||||||
# If successfully sent:
|
# If successfully sent:
|
||||||
if bytes_sent == bytes_total:
|
if bytes_sent == bytes_total:
|
||||||
# Show a confirmation to the user so they know the job was sucessful and provide the option to switch to the
|
# Show a confirmation to the user so they know the job was sucessful and provide the option to switch to
|
||||||
# monitor tab.
|
# the monitor tab.
|
||||||
self._success_message = Message(
|
self._success_message = Message(
|
||||||
i18n_catalog.i18nc("@info:status", "Print job was successfully sent to the printer."),
|
i18n_catalog.i18nc("@info:status", "Print job was successfully sent to the printer."),
|
||||||
lifetime=5, dismissable=True,
|
lifetime=5, dismissable=True,
|
||||||
@ -329,7 +354,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
|
|
||||||
@pyqtProperty("QVariantList", notify = printJobsChanged)
|
@pyqtProperty("QVariantList", notify = printJobsChanged)
|
||||||
def queuedPrintJobs(self) -> List[PrintJobOutputModel]:
|
def queuedPrintJobs(self) -> List[PrintJobOutputModel]:
|
||||||
return [print_job for print_job in self._print_jobs if print_job.state == "queued"]
|
return [print_job for print_job in self._print_jobs if print_job.state == "queued" or print_job.state == "error"]
|
||||||
|
|
||||||
@pyqtProperty("QVariantList", notify = printJobsChanged)
|
@pyqtProperty("QVariantList", notify = printJobsChanged)
|
||||||
def activePrintJobs(self) -> List[PrintJobOutputModel]:
|
def activePrintJobs(self) -> List[PrintJobOutputModel]:
|
||||||
@ -348,6 +373,10 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
result.append({"machine_type": machine_type, "count": str(printer_count[machine_type])})
|
result.append({"machine_type": machine_type, "count": str(printer_count[machine_type])})
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@pyqtProperty("QVariantList", notify=clusterPrintersChanged)
|
||||||
|
def printers(self):
|
||||||
|
return self._printers
|
||||||
|
|
||||||
@pyqtSlot(int, result = str)
|
@pyqtSlot(int, result = str)
|
||||||
def formatDuration(self, seconds: int) -> str:
|
def formatDuration(self, seconds: int) -> str:
|
||||||
return Duration(seconds).getDisplayString(DurationFormat.Format.Short)
|
return Duration(seconds).getDisplayString(DurationFormat.Format.Short)
|
||||||
@ -364,6 +393,19 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
datetime_completed = datetime.fromtimestamp(current_time + time_remaining)
|
datetime_completed = datetime.fromtimestamp(current_time + time_remaining)
|
||||||
return (datetime_completed.strftime("%a %b ") + "{day}".format(day=datetime_completed.day)).upper()
|
return (datetime_completed.strftime("%a %b ") + "{day}".format(day=datetime_completed.day)).upper()
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def sendJobToTop(self, print_job_uuid: str) -> None:
|
||||||
|
# This function is part of the output device (and not of the printjob output model) as this type of operation
|
||||||
|
# is a modification of the cluster queue and not of the actual job.
|
||||||
|
data = "{\"to_position\": 0}"
|
||||||
|
self.put("print_jobs/{uuid}/move_to_position".format(uuid = print_job_uuid), data, on_finished=None)
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def deleteJobFromQueue(self, print_job_uuid: str) -> None:
|
||||||
|
# This function is part of the output device (and not of the printjob output model) as this type of operation
|
||||||
|
# is a modification of the cluster queue and not of the actual job.
|
||||||
|
self.delete("print_jobs/{uuid}".format(uuid = print_job_uuid), on_finished=None)
|
||||||
|
|
||||||
def _printJobStateChanged(self) -> None:
|
def _printJobStateChanged(self) -> None:
|
||||||
username = self._getUserName()
|
username = self._getUserName()
|
||||||
|
|
||||||
@ -392,11 +434,26 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
super().connect()
|
super().connect()
|
||||||
self.sendMaterialProfiles()
|
self.sendMaterialProfiles()
|
||||||
|
|
||||||
|
def _onGetPreviewImageFinished(self, reply: QNetworkReply) -> None:
|
||||||
|
reply_url = reply.url().toString()
|
||||||
|
|
||||||
|
uuid = reply_url[reply_url.find("print_jobs/")+len("print_jobs/"):reply_url.rfind("/preview_image")]
|
||||||
|
|
||||||
|
print_job = findByKey(self._print_jobs, uuid)
|
||||||
|
if print_job:
|
||||||
|
image = QImage()
|
||||||
|
image.loadFromData(reply.readAll())
|
||||||
|
print_job.updatePreviewImage(image)
|
||||||
|
|
||||||
def _update(self) -> None:
|
def _update(self) -> None:
|
||||||
super()._update()
|
super()._update()
|
||||||
self.get("printers/", on_finished = self._onGetPrintersDataFinished)
|
self.get("printers/", on_finished = self._onGetPrintersDataFinished)
|
||||||
self.get("print_jobs/", on_finished = self._onGetPrintJobsFinished)
|
self.get("print_jobs/", on_finished = self._onGetPrintJobsFinished)
|
||||||
|
|
||||||
|
for print_job in self._print_jobs:
|
||||||
|
if print_job.getPreviewImage() is None:
|
||||||
|
self.get("print_jobs/{uuid}/preview_image".format(uuid=print_job.key), on_finished=self._onGetPreviewImageFinished)
|
||||||
|
|
||||||
def _onGetPrintJobsFinished(self, reply: QNetworkReply) -> None:
|
def _onGetPrintJobsFinished(self, reply: QNetworkReply) -> None:
|
||||||
if not checkValidGetReply(reply):
|
if not checkValidGetReply(reply):
|
||||||
return
|
return
|
||||||
@ -407,16 +464,19 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
|
|
||||||
print_jobs_seen = []
|
print_jobs_seen = []
|
||||||
job_list_changed = False
|
job_list_changed = False
|
||||||
for print_job_data in result:
|
for idx, print_job_data in enumerate(result):
|
||||||
print_job = findByKey(self._print_jobs, print_job_data["uuid"])
|
print_job = findByKey(self._print_jobs, print_job_data["uuid"])
|
||||||
|
|
||||||
if print_job is None:
|
if print_job is None:
|
||||||
print_job = self._createPrintJobModel(print_job_data)
|
print_job = self._createPrintJobModel(print_job_data)
|
||||||
job_list_changed = True
|
job_list_changed = True
|
||||||
|
elif not job_list_changed:
|
||||||
|
# Check if the order of the jobs has changed since the last check
|
||||||
|
if self._print_jobs.index(print_job) != idx:
|
||||||
|
job_list_changed = True
|
||||||
|
|
||||||
self._updatePrintJob(print_job, print_job_data)
|
self._updatePrintJob(print_job, print_job_data)
|
||||||
|
|
||||||
if print_job.state != "queued": # Print job should be assigned to a printer.
|
if print_job.state != "queued" and print_job.state != "error": # Print job should be assigned to a printer.
|
||||||
if print_job.state in ["failed", "finished", "aborted", "none"]:
|
if print_job.state in ["failed", "finished", "aborted", "none"]:
|
||||||
# Print job was already completed, so don't attach it to a printer.
|
# Print job was already completed, so don't attach it to a printer.
|
||||||
printer = None
|
printer = None
|
||||||
@ -437,6 +497,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
job_list_changed = job_list_changed or self._removeJob(removed_job)
|
job_list_changed = job_list_changed or self._removeJob(removed_job)
|
||||||
|
|
||||||
if job_list_changed:
|
if job_list_changed:
|
||||||
|
# Override the old list with the new list (either because jobs were removed / added or order changed)
|
||||||
|
self._print_jobs = print_jobs_seen
|
||||||
self.printJobsChanged.emit() # Do a single emit for all print job changes.
|
self.printJobsChanged.emit() # Do a single emit for all print job changes.
|
||||||
|
|
||||||
def _onGetPrintersDataFinished(self, reply: QNetworkReply) -> None:
|
def _onGetPrintersDataFinished(self, reply: QNetworkReply) -> None:
|
||||||
@ -478,16 +540,59 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
def _createPrintJobModel(self, data: Dict[str, Any]) -> PrintJobOutputModel:
|
def _createPrintJobModel(self, data: Dict[str, Any]) -> PrintJobOutputModel:
|
||||||
print_job = PrintJobOutputModel(output_controller=ClusterUM3PrinterOutputController(self),
|
print_job = PrintJobOutputModel(output_controller=ClusterUM3PrinterOutputController(self),
|
||||||
key=data["uuid"], name= data["name"])
|
key=data["uuid"], name= data["name"])
|
||||||
|
|
||||||
|
configuration = ConfigurationModel()
|
||||||
|
extruders = [ExtruderConfigurationModel(position = idx) for idx in range(0, self._number_of_extruders)]
|
||||||
|
for index in range(0, self._number_of_extruders):
|
||||||
|
try:
|
||||||
|
extruder_data = data["configuration"][index]
|
||||||
|
except IndexError:
|
||||||
|
continue
|
||||||
|
extruder = extruders[int(data["configuration"][index]["extruder_index"])]
|
||||||
|
extruder.setHotendID(extruder_data.get("print_core_id", ""))
|
||||||
|
extruder.setMaterial(self._createMaterialOutputModel(extruder_data.get("material", {})))
|
||||||
|
|
||||||
|
configuration.setExtruderConfigurations(extruders)
|
||||||
|
print_job.updateConfiguration(configuration)
|
||||||
|
print_job.setCompatibleMachineFamilies(data.get("compatible_machine_families", []))
|
||||||
print_job.stateChanged.connect(self._printJobStateChanged)
|
print_job.stateChanged.connect(self._printJobStateChanged)
|
||||||
self._print_jobs.append(print_job)
|
|
||||||
return print_job
|
return print_job
|
||||||
|
|
||||||
def _updatePrintJob(self, print_job: PrintJobOutputModel, data: Dict[str, Any]) -> None:
|
def _updatePrintJob(self, print_job: PrintJobOutputModel, data: Dict[str, Any]) -> None:
|
||||||
print_job.updateTimeTotal(data["time_total"])
|
print_job.updateTimeTotal(data["time_total"])
|
||||||
print_job.updateTimeElapsed(data["time_elapsed"])
|
print_job.updateTimeElapsed(data["time_elapsed"])
|
||||||
print_job.updateState(data["status"])
|
impediments_to_printing = data.get("impediments_to_printing", [])
|
||||||
print_job.updateOwner(data["owner"])
|
print_job.updateOwner(data["owner"])
|
||||||
|
|
||||||
|
status_set_by_impediment = False
|
||||||
|
for impediment in impediments_to_printing:
|
||||||
|
if impediment["severity"] == "UNFIXABLE":
|
||||||
|
status_set_by_impediment = True
|
||||||
|
print_job.updateState("error")
|
||||||
|
break
|
||||||
|
|
||||||
|
if not status_set_by_impediment:
|
||||||
|
print_job.updateState(data["status"])
|
||||||
|
|
||||||
|
|
||||||
|
def _createMaterialOutputModel(self, material_data) -> MaterialOutputModel:
|
||||||
|
containers = ContainerRegistry.getInstance().findInstanceContainers(type="material", GUID=material_data["guid"])
|
||||||
|
if containers:
|
||||||
|
color = containers[0].getMetaDataEntry("color_code")
|
||||||
|
brand = containers[0].getMetaDataEntry("brand")
|
||||||
|
material_type = containers[0].getMetaDataEntry("material")
|
||||||
|
name = containers[0].getName()
|
||||||
|
else:
|
||||||
|
Logger.log("w",
|
||||||
|
"Unable to find material with guid {guid}. Using data as provided by cluster".format(
|
||||||
|
guid=material_data["guid"]))
|
||||||
|
color = material_data["color"]
|
||||||
|
brand = material_data["brand"]
|
||||||
|
material_type = material_data["material"]
|
||||||
|
name = "Empty" if material_data["material"] == "empty" else "Unknown"
|
||||||
|
return MaterialOutputModel(guid=material_data["guid"], type=material_type,
|
||||||
|
brand=brand, color=color, name=name)
|
||||||
|
|
||||||
def _updatePrinter(self, printer: PrinterOutputModel, data: Dict[str, Any]) -> None:
|
def _updatePrinter(self, printer: PrinterOutputModel, data: Dict[str, Any]) -> None:
|
||||||
# For some unknown reason the cluster wants UUID for everything, except for sending a job directly to a printer.
|
# For some unknown reason the cluster wants UUID for everything, except for sending a job directly to a printer.
|
||||||
# Then we suddenly need the unique name. So in order to not have to mess up all the other code, we save a mapping.
|
# Then we suddenly need the unique name. So in order to not have to mess up all the other code, we save a mapping.
|
||||||
@ -523,24 +628,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
|
|
||||||
material_data = extruder_data["material"]
|
material_data = extruder_data["material"]
|
||||||
if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_data["guid"]:
|
if extruder.activeMaterial is None or extruder.activeMaterial.guid != material_data["guid"]:
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type="material",
|
material = self._createMaterialOutputModel(material_data)
|
||||||
GUID=material_data["guid"])
|
|
||||||
if containers:
|
|
||||||
color = containers[0].getMetaDataEntry("color_code")
|
|
||||||
brand = containers[0].getMetaDataEntry("brand")
|
|
||||||
material_type = containers[0].getMetaDataEntry("material")
|
|
||||||
name = containers[0].getName()
|
|
||||||
else:
|
|
||||||
Logger.log("w",
|
|
||||||
"Unable to find material with guid {guid}. Using data as provided by cluster".format(
|
|
||||||
guid=material_data["guid"]))
|
|
||||||
color = material_data["color"]
|
|
||||||
brand = material_data["brand"]
|
|
||||||
material_type = material_data["material"]
|
|
||||||
name = "Empty" if material_data["material"] == "empty" else "Unknown"
|
|
||||||
|
|
||||||
material = MaterialOutputModel(guid=material_data["guid"], type=material_type,
|
|
||||||
brand=brand, color=color, name=name)
|
|
||||||
extruder.updateActiveMaterial(material)
|
extruder.updateActiveMaterial(material)
|
||||||
|
|
||||||
def _removeJob(self, job: PrintJobOutputModel) -> bool:
|
def _removeJob(self, job: PrintJobOutputModel) -> bool:
|
||||||
@ -568,6 +656,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
job = SendMaterialJob(device = self)
|
job = SendMaterialJob(device = self)
|
||||||
job.run()
|
job.run()
|
||||||
|
|
||||||
|
|
||||||
def loadJsonFromReply(reply: QNetworkReply) -> Optional[List[Dict[str, Any]]]:
|
def loadJsonFromReply(reply: QNetworkReply) -> Optional[List[Dict[str, Any]]]:
|
||||||
try:
|
try:
|
||||||
result = json.loads(bytes(reply.readAll()).decode("utf-8"))
|
result = json.loads(bytes(reply.readAll()).decode("utf-8"))
|
||||||
@ -586,8 +675,8 @@ def checkValidGetReply(reply: QNetworkReply) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def findByKey(list: List[Union[PrintJobOutputModel, PrinterOutputModel]], key: str) -> Optional[PrintJobOutputModel]:
|
def findByKey(lst: List[Union[PrintJobOutputModel, PrinterOutputModel]], key: str) -> Optional[PrintJobOutputModel]:
|
||||||
for item in list:
|
for item in lst:
|
||||||
if item.key == key:
|
if item.key == key:
|
||||||
return item
|
return item
|
||||||
return None
|
return None
|
@ -6,8 +6,6 @@ from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
|||||||
MYPY = False
|
MYPY = False
|
||||||
if MYPY:
|
if MYPY:
|
||||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
|
||||||
|
|
||||||
|
|
||||||
class ClusterUM3PrinterOutputController(PrinterOutputController):
|
class ClusterUM3PrinterOutputController(PrinterOutputController):
|
||||||
def __init__(self, output_device):
|
def __init__(self, output_device):
|
@ -24,7 +24,7 @@ class DiscoverUM3Action(MachineAction):
|
|||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__("DiscoverUM3Action", catalog.i18nc("@action","Connect via Network"))
|
super().__init__("DiscoverUM3Action", catalog.i18nc("@action","Connect via Network"))
|
||||||
self._qml_url = "DiscoverUM3Action.qml"
|
self._qml_url = "resources/qml/DiscoverUM3Action.qml"
|
||||||
|
|
||||||
self._network_plugin = None #type: Optional[UM3OutputDevicePlugin]
|
self._network_plugin = None #type: Optional[UM3OutputDevicePlugin]
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ class DiscoverUM3Action(MachineAction):
|
|||||||
plugin_path = PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting")
|
plugin_path = PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting")
|
||||||
if not plugin_path:
|
if not plugin_path:
|
||||||
return
|
return
|
||||||
path = os.path.join(plugin_path, "UM3InfoComponents.qml")
|
path = os.path.join(plugin_path, "resources/qml/UM3InfoComponents.qml")
|
||||||
self.__additional_components_view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
|
self.__additional_components_view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
|
||||||
if not self.__additional_components_view:
|
if not self.__additional_components_view:
|
||||||
Logger.log("w", "Could not create ui components for UM3.")
|
Logger.log("w", "Could not create ui components for UM3.")
|
@ -76,7 +76,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
|
|
||||||
self.setIconName("print")
|
self.setIconName("print")
|
||||||
|
|
||||||
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "MonitorItem.qml")
|
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorItem.qml")
|
||||||
|
|
||||||
self._output_controller = LegacyUM3PrinterOutputController(self)
|
self._output_controller = LegacyUM3PrinterOutputController(self)
|
||||||
|
|
@ -60,8 +60,8 @@ _RENAMED_MATERIAL_PROFILES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
## Upgrades configurations from the state they were in at version 3.4 to the
|
## Upgrades configurations from the state they were in at version 3.4 to the
|
||||||
# state they should be in at version 4.0.
|
# state they should be in at version 3.5.
|
||||||
class VersionUpgrade34to40(VersionUpgrade):
|
class VersionUpgrade34to35(VersionUpgrade):
|
||||||
|
|
||||||
## Gets the version number from a CFG file in Uranium's 3.3 format.
|
## Gets the version number from a CFG file in Uranium's 3.3 format.
|
||||||
#
|
#
|
@ -1,9 +1,9 @@
|
|||||||
# 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 . import VersionUpgrade34to40
|
from . import VersionUpgrade34to35
|
||||||
|
|
||||||
upgrade = VersionUpgrade34to40.VersionUpgrade34to40()
|
upgrade = VersionUpgrade34to35.VersionUpgrade34to35()
|
||||||
|
|
||||||
|
|
||||||
def getMetaData():
|
def getMetaData():
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "Version Upgrade 3.4 to 4.0",
|
"name": "Version Upgrade 3.4 to 3.5",
|
||||||
"author": "Ultimaker B.V.",
|
"author": "Ultimaker B.V.",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Upgrades configurations from Cura 3.4 to Cura 4.0.",
|
"description": "Upgrades configurations from Cura 3.4 to Cura 3.5.",
|
||||||
"api": 5,
|
"api": 5,
|
||||||
"i18n-catalog": "cura"
|
"i18n-catalog": "cura"
|
||||||
}
|
}
|
@ -4,12 +4,12 @@
|
|||||||
import configparser #To parse the resulting config files.
|
import configparser #To parse the resulting config files.
|
||||||
import pytest #To register tests with.
|
import pytest #To register tests with.
|
||||||
|
|
||||||
import VersionUpgrade34to40 #The module we're testing.
|
import VersionUpgrade34to35 #The module we're testing.
|
||||||
|
|
||||||
## Creates an instance of the upgrader to test with.
|
## Creates an instance of the upgrader to test with.
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def upgrader():
|
def upgrader():
|
||||||
return VersionUpgrade34to40.VersionUpgrade34to40()
|
return VersionUpgrade34to35.VersionUpgrade34to35()
|
||||||
|
|
||||||
test_upgrade_version_nr_data = [
|
test_upgrade_version_nr_data = [
|
||||||
("Empty config file",
|
("Empty config file",
|
@ -269,7 +269,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
# Find all hotend sub-profiles corresponding to this material and machine and add them to this profile.
|
# Find all hotend sub-profiles corresponding to this material and machine and add them to this profile.
|
||||||
buildplate_dict = {} # type: Dict[str, Any]
|
buildplate_dict = {} # type: Dict[str, Any]
|
||||||
for variant_name, variant_dict in machine_variant_map[definition_id].items():
|
for variant_name, variant_dict in machine_variant_map[definition_id].items():
|
||||||
variant_type = variant_dict["variant_node"].metadata["hardware_type"]
|
variant_type = variant_dict["variant_node"].getMetaDataEntry("hardware_type", str(VariantType.NOZZLE))
|
||||||
variant_type = VariantType(variant_type)
|
variant_type = VariantType(variant_type)
|
||||||
if variant_type == VariantType.NOZZLE:
|
if variant_type == VariantType.NOZZLE:
|
||||||
# The hotend identifier is not the containers name, but its "name".
|
# The hotend identifier is not the containers name, but its "name".
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"display_name": "3MF Reader",
|
"display_name": "3MF Reader",
|
||||||
"description": "Provides support for reading 3MF files.",
|
"description": "Provides support for reading 3MF files.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -23,7 +23,7 @@
|
|||||||
"display_name": "3MF Writer",
|
"display_name": "3MF Writer",
|
||||||
"description": "Provides support for writing 3MF files.",
|
"description": "Provides support for writing 3MF files.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -40,7 +40,7 @@
|
|||||||
"display_name": "Change Log",
|
"display_name": "Change Log",
|
||||||
"description": "Shows changes since latest checked version.",
|
"description": "Shows changes since latest checked version.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -57,7 +57,7 @@
|
|||||||
"display_name": "CuraEngine Backend",
|
"display_name": "CuraEngine Backend",
|
||||||
"description": "Provides the link to the CuraEngine slicing backend.",
|
"description": "Provides the link to the CuraEngine slicing backend.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -74,7 +74,7 @@
|
|||||||
"display_name": "Cura Profile Reader",
|
"display_name": "Cura Profile Reader",
|
||||||
"description": "Provides support for importing Cura profiles.",
|
"description": "Provides support for importing Cura profiles.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -91,7 +91,7 @@
|
|||||||
"display_name": "Cura Profile Writer",
|
"display_name": "Cura Profile Writer",
|
||||||
"description": "Provides support for exporting Cura profiles.",
|
"description": "Provides support for exporting Cura profiles.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -108,7 +108,7 @@
|
|||||||
"display_name": "Firmware Update Checker",
|
"display_name": "Firmware Update Checker",
|
||||||
"description": "Checks for firmware updates.",
|
"description": "Checks for firmware updates.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -125,7 +125,7 @@
|
|||||||
"display_name": "Compressed G-code Reader",
|
"display_name": "Compressed G-code Reader",
|
||||||
"description": "Reads g-code from a compressed archive.",
|
"description": "Reads g-code from a compressed archive.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -142,7 +142,7 @@
|
|||||||
"display_name": "Compressed G-code Writer",
|
"display_name": "Compressed G-code Writer",
|
||||||
"description": "Writes g-code to a compressed archive.",
|
"description": "Writes g-code to a compressed archive.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -159,7 +159,7 @@
|
|||||||
"display_name": "G-Code Profile Reader",
|
"display_name": "G-Code Profile Reader",
|
||||||
"description": "Provides support for importing profiles from g-code files.",
|
"description": "Provides support for importing profiles from g-code files.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -176,7 +176,7 @@
|
|||||||
"display_name": "G-Code Reader",
|
"display_name": "G-Code Reader",
|
||||||
"description": "Allows loading and displaying G-code files.",
|
"description": "Allows loading and displaying G-code files.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "VictorLarchenko",
|
"author_id": "VictorLarchenko",
|
||||||
@ -193,7 +193,7 @@
|
|||||||
"display_name": "G-Code Writer",
|
"display_name": "G-Code Writer",
|
||||||
"description": "Writes g-code to a file.",
|
"description": "Writes g-code to a file.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -210,7 +210,7 @@
|
|||||||
"display_name": "Image Reader",
|
"display_name": "Image Reader",
|
||||||
"description": "Enables ability to generate printable geometry from 2D image files.",
|
"description": "Enables ability to generate printable geometry from 2D image files.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -227,7 +227,7 @@
|
|||||||
"display_name": "Legacy Cura Profile Reader",
|
"display_name": "Legacy Cura Profile Reader",
|
||||||
"description": "Provides support for importing profiles from legacy Cura versions.",
|
"description": "Provides support for importing profiles from legacy Cura versions.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -244,7 +244,7 @@
|
|||||||
"display_name": "Machine Settings Action",
|
"display_name": "Machine Settings Action",
|
||||||
"description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).",
|
"description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "fieldOfView",
|
"author_id": "fieldOfView",
|
||||||
@ -261,7 +261,7 @@
|
|||||||
"display_name": "Model Checker",
|
"display_name": "Model Checker",
|
||||||
"description": "Checks models and print configuration for possible printing issues and give suggestions.",
|
"description": "Checks models and print configuration for possible printing issues and give suggestions.",
|
||||||
"package_version": "0.1.0",
|
"package_version": "0.1.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -278,7 +278,7 @@
|
|||||||
"display_name": "Monitor Stage",
|
"display_name": "Monitor Stage",
|
||||||
"description": "Provides a monitor stage in Cura.",
|
"description": "Provides a monitor stage in Cura.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -295,7 +295,7 @@
|
|||||||
"display_name": "Per-Object Settings Tool",
|
"display_name": "Per-Object Settings Tool",
|
||||||
"description": "Provides the per-model settings.",
|
"description": "Provides the per-model settings.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -312,7 +312,7 @@
|
|||||||
"display_name": "Post Processing",
|
"display_name": "Post Processing",
|
||||||
"description": "Extension that allows for user created scripts for post processing.",
|
"description": "Extension that allows for user created scripts for post processing.",
|
||||||
"package_version": "2.2.0",
|
"package_version": "2.2.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -329,7 +329,7 @@
|
|||||||
"display_name": "Prepare Stage",
|
"display_name": "Prepare Stage",
|
||||||
"description": "Provides a prepare stage in Cura.",
|
"description": "Provides a prepare stage in Cura.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -346,7 +346,7 @@
|
|||||||
"display_name": "Removable Drive Output Device",
|
"display_name": "Removable Drive Output Device",
|
||||||
"description": "Provides removable drive hotplugging and writing support.",
|
"description": "Provides removable drive hotplugging and writing support.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -363,7 +363,7 @@
|
|||||||
"display_name": "Simulation View",
|
"display_name": "Simulation View",
|
||||||
"description": "Provides the Simulation view.",
|
"description": "Provides the Simulation view.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -380,7 +380,7 @@
|
|||||||
"display_name": "Slice Info",
|
"display_name": "Slice Info",
|
||||||
"description": "Submits anonymous slice info. Can be disabled through preferences.",
|
"description": "Submits anonymous slice info. Can be disabled through preferences.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -397,7 +397,7 @@
|
|||||||
"display_name": "Solid View",
|
"display_name": "Solid View",
|
||||||
"description": "Provides a normal solid mesh view.",
|
"description": "Provides a normal solid mesh view.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -414,7 +414,7 @@
|
|||||||
"display_name": "Support Eraser Tool",
|
"display_name": "Support Eraser Tool",
|
||||||
"description": "Creates an eraser mesh to block the printing of support in certain places.",
|
"description": "Creates an eraser mesh to block the printing of support in certain places.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -431,7 +431,7 @@
|
|||||||
"display_name": "Toolbox",
|
"display_name": "Toolbox",
|
||||||
"description": "Find, manage and install new Cura packages.",
|
"description": "Find, manage and install new Cura packages.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -448,7 +448,7 @@
|
|||||||
"display_name": "UFP Writer",
|
"display_name": "UFP Writer",
|
||||||
"description": "Provides support for writing Ultimaker Format Packages.",
|
"description": "Provides support for writing Ultimaker Format Packages.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -465,7 +465,7 @@
|
|||||||
"display_name": "Ultimaker Machine Actions",
|
"display_name": "Ultimaker Machine Actions",
|
||||||
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).",
|
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -482,7 +482,7 @@
|
|||||||
"display_name": "UM3 Network Printing",
|
"display_name": "UM3 Network Printing",
|
||||||
"description": "Manages network connections to Ultimaker 3 printers.",
|
"description": "Manages network connections to Ultimaker 3 printers.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -499,7 +499,7 @@
|
|||||||
"display_name": "USB Printing",
|
"display_name": "USB Printing",
|
||||||
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
|
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -516,7 +516,7 @@
|
|||||||
"display_name": "User Agreement",
|
"display_name": "User Agreement",
|
||||||
"description": "Ask the user once if he/she agrees with our license.",
|
"description": "Ask the user once if he/she agrees with our license.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -533,7 +533,7 @@
|
|||||||
"display_name": "Version Upgrade 2.1 to 2.2",
|
"display_name": "Version Upgrade 2.1 to 2.2",
|
||||||
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
|
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -550,7 +550,7 @@
|
|||||||
"display_name": "Version Upgrade 2.2 to 2.4",
|
"display_name": "Version Upgrade 2.2 to 2.4",
|
||||||
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
|
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -567,7 +567,7 @@
|
|||||||
"display_name": "Version Upgrade 2.5 to 2.6",
|
"display_name": "Version Upgrade 2.5 to 2.6",
|
||||||
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
|
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -584,7 +584,7 @@
|
|||||||
"display_name": "Version Upgrade 2.6 to 2.7",
|
"display_name": "Version Upgrade 2.6 to 2.7",
|
||||||
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
|
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -601,7 +601,7 @@
|
|||||||
"display_name": "Version Upgrade 2.7 to 3.0",
|
"display_name": "Version Upgrade 2.7 to 3.0",
|
||||||
"description": "Upgrades configurations from Cura 2.7 to Cura 3.0.",
|
"description": "Upgrades configurations from Cura 2.7 to Cura 3.0.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -618,7 +618,7 @@
|
|||||||
"display_name": "Version Upgrade 3.0 to 3.1",
|
"display_name": "Version Upgrade 3.0 to 3.1",
|
||||||
"description": "Upgrades configurations from Cura 3.0 to Cura 3.1.",
|
"description": "Upgrades configurations from Cura 3.0 to Cura 3.1.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -635,7 +635,7 @@
|
|||||||
"display_name": "Version Upgrade 3.2 to 3.3",
|
"display_name": "Version Upgrade 3.2 to 3.3",
|
||||||
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
|
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -652,7 +652,7 @@
|
|||||||
"display_name": "Version Upgrade 3.3 to 3.4",
|
"display_name": "Version Upgrade 3.3 to 3.4",
|
||||||
"description": "Upgrades configurations from Cura 3.3 to Cura 3.4.",
|
"description": "Upgrades configurations from Cura 3.3 to Cura 3.4.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -662,14 +662,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"VersionUpgrade34to40": {
|
"VersionUpgrade34to35": {
|
||||||
"package_info": {
|
"package_info": {
|
||||||
"package_id": "VersionUpgrade34to40",
|
"package_id": "VersionUpgrade34to35",
|
||||||
"package_type": "plugin",
|
"package_type": "plugin",
|
||||||
"display_name": "Version Upgrade 3.4 to 4.0",
|
"display_name": "Version Upgrade 3.4 to 3.5",
|
||||||
"description": "Upgrades configurations from Cura 3.4 to Cura 4.0.",
|
"description": "Upgrades configurations from Cura 3.4 to Cura 3.5.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -686,7 +686,7 @@
|
|||||||
"display_name": "X3D Reader",
|
"display_name": "X3D Reader",
|
||||||
"description": "Provides support for reading X3D files.",
|
"description": "Provides support for reading X3D files.",
|
||||||
"package_version": "0.5.0",
|
"package_version": "0.5.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "SevaAlekseyev",
|
"author_id": "SevaAlekseyev",
|
||||||
@ -703,7 +703,7 @@
|
|||||||
"display_name": "XML Material Profiles",
|
"display_name": "XML Material Profiles",
|
||||||
"description": "Provides capabilities to read and write XML-based material profiles.",
|
"description": "Provides capabilities to read and write XML-based material profiles.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -720,7 +720,7 @@
|
|||||||
"display_name": "X-Ray View",
|
"display_name": "X-Ray View",
|
||||||
"description": "Provides the X-Ray view.",
|
"description": "Provides the X-Ray view.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com",
|
"website": "https://ultimaker.com",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -971,7 +971,7 @@
|
|||||||
"display_name": "Dagoma Chromatik PLA",
|
"display_name": "Dagoma Chromatik PLA",
|
||||||
"description": "Filament testé et approuvé pour les imprimantes 3D Dagoma. Chromatik est l'idéal pour débuter et suivre les tutoriels premiers pas. Il vous offre qualité et résistance pour chacune de vos impressions.",
|
"description": "Filament testé et approuvé pour les imprimantes 3D Dagoma. Chromatik est l'idéal pour débuter et suivre les tutoriels premiers pas. Il vous offre qualité et résistance pour chacune de vos impressions.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://dagoma.fr/boutique/filaments.html",
|
"website": "https://dagoma.fr/boutique/filaments.html",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Dagoma",
|
"author_id": "Dagoma",
|
||||||
@ -988,7 +988,7 @@
|
|||||||
"display_name": "FABtotum ABS",
|
"display_name": "FABtotum ABS",
|
||||||
"description": "This material is easy to be extruded but it is not the simplest to use. It is one of the most used in 3D printing to get very well finished objects. It is not sustainable and its smoke can be dangerous if inhaled. The reason to prefer this filament to PLA is mainly because of its precision and mechanical specs. ABS (for plastic) stands for Acrylonitrile Butadiene Styrene and it is a thermoplastic which is widely used in everyday objects. It can be printed with any FFF 3D printer which can get to high temperatures as it must be extruded in a range between 220° and 245°, so it’s compatible with all versions of the FABtotum Personal fabricator.",
|
"description": "This material is easy to be extruded but it is not the simplest to use. It is one of the most used in 3D printing to get very well finished objects. It is not sustainable and its smoke can be dangerous if inhaled. The reason to prefer this filament to PLA is mainly because of its precision and mechanical specs. ABS (for plastic) stands for Acrylonitrile Butadiene Styrene and it is a thermoplastic which is widely used in everyday objects. It can be printed with any FFF 3D printer which can get to high temperatures as it must be extruded in a range between 220° and 245°, so it’s compatible with all versions of the FABtotum Personal fabricator.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=40",
|
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=40",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "FABtotum",
|
"author_id": "FABtotum",
|
||||||
@ -1005,7 +1005,7 @@
|
|||||||
"display_name": "FABtotum Nylon",
|
"display_name": "FABtotum Nylon",
|
||||||
"description": "When 3D printing started this material was not listed among the extrudable filaments. It is flexible as well as resistant to tractions. It is well known for its uses in textile but also in industries which require a strong and flexible material. There are different kinds of Nylon: 3D printing mostly uses Nylon 6 and Nylon 6.6, which are the most common. It requires higher temperatures to be printed, so a 3D printer must be able to reach them (around 240°C): the FABtotum, of course, can.",
|
"description": "When 3D printing started this material was not listed among the extrudable filaments. It is flexible as well as resistant to tractions. It is well known for its uses in textile but also in industries which require a strong and flexible material. There are different kinds of Nylon: 3D printing mostly uses Nylon 6 and Nylon 6.6, which are the most common. It requires higher temperatures to be printed, so a 3D printer must be able to reach them (around 240°C): the FABtotum, of course, can.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=53",
|
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=53",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "FABtotum",
|
"author_id": "FABtotum",
|
||||||
@ -1022,7 +1022,7 @@
|
|||||||
"display_name": "FABtotum PLA",
|
"display_name": "FABtotum PLA",
|
||||||
"description": "It is the most common filament used for 3D printing. It is studied to be bio-degradable as it comes from corn starch’s sugar mainly. It is completely made of renewable sources and has no footprint on polluting. PLA stands for PolyLactic Acid and it is a thermoplastic that today is still considered the easiest material to be 3D printed. It can be extruded at lower temperatures: the standard range of FABtotum’s one is between 185° and 195°.",
|
"description": "It is the most common filament used for 3D printing. It is studied to be bio-degradable as it comes from corn starch’s sugar mainly. It is completely made of renewable sources and has no footprint on polluting. PLA stands for PolyLactic Acid and it is a thermoplastic that today is still considered the easiest material to be 3D printed. It can be extruded at lower temperatures: the standard range of FABtotum’s one is between 185° and 195°.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=39",
|
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=39",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "FABtotum",
|
"author_id": "FABtotum",
|
||||||
@ -1039,7 +1039,7 @@
|
|||||||
"display_name": "FABtotum TPU Shore 98A",
|
"display_name": "FABtotum TPU Shore 98A",
|
||||||
"description": "",
|
"description": "",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=66",
|
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=66",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "FABtotum",
|
"author_id": "FABtotum",
|
||||||
@ -1056,7 +1056,7 @@
|
|||||||
"display_name": "Fiberlogy HD PLA",
|
"display_name": "Fiberlogy HD PLA",
|
||||||
"description": "With our HD PLA you have many more options. You can use this material in two ways. Choose the one you like best. You can use it as a normal PLA and get prints characterized by a very good adhesion between the layers and high precision. You can also make your prints acquire similar properties to that of ABS – better impact resistance and high temperature resistance. All you need is an oven. Yes, an oven! By annealing our HD PLA in an oven, in accordance with the manual, you will avoid all the inconveniences of printing with ABS, such as unpleasant odour or hazardous fumes.",
|
"description": "With our HD PLA you have many more options. You can use this material in two ways. Choose the one you like best. You can use it as a normal PLA and get prints characterized by a very good adhesion between the layers and high precision. You can also make your prints acquire similar properties to that of ABS – better impact resistance and high temperature resistance. All you need is an oven. Yes, an oven! By annealing our HD PLA in an oven, in accordance with the manual, you will avoid all the inconveniences of printing with ABS, such as unpleasant odour or hazardous fumes.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "http://fiberlogy.com/en/fiberlogy-filaments/filament-hd-pla/",
|
"website": "http://fiberlogy.com/en/fiberlogy-filaments/filament-hd-pla/",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Fiberlogy",
|
"author_id": "Fiberlogy",
|
||||||
@ -1073,7 +1073,7 @@
|
|||||||
"display_name": "Filo3D PLA",
|
"display_name": "Filo3D PLA",
|
||||||
"description": "Fast, safe and reliable printing. PLA is ideal for the fast and reliable printing of parts and prototypes with a great surface quality.",
|
"description": "Fast, safe and reliable printing. PLA is ideal for the fast and reliable printing of parts and prototypes with a great surface quality.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://dagoma.fr",
|
"website": "https://dagoma.fr",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Dagoma",
|
"author_id": "Dagoma",
|
||||||
@ -1090,7 +1090,7 @@
|
|||||||
"display_name": "IMADE3D JellyBOX PETG",
|
"display_name": "IMADE3D JellyBOX PETG",
|
||||||
"description": "",
|
"description": "",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "http://shop.imade3d.com/filament.html",
|
"website": "http://shop.imade3d.com/filament.html",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "IMADE3D",
|
"author_id": "IMADE3D",
|
||||||
@ -1107,7 +1107,7 @@
|
|||||||
"display_name": "IMADE3D JellyBOX PLA",
|
"display_name": "IMADE3D JellyBOX PLA",
|
||||||
"description": "",
|
"description": "",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "http://shop.imade3d.com/filament.html",
|
"website": "http://shop.imade3d.com/filament.html",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "IMADE3D",
|
"author_id": "IMADE3D",
|
||||||
@ -1124,7 +1124,7 @@
|
|||||||
"display_name": "Octofiber PLA",
|
"display_name": "Octofiber PLA",
|
||||||
"description": "PLA material from Octofiber.",
|
"description": "PLA material from Octofiber.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://nl.octofiber.com/3d-printing-filament/pla.html",
|
"website": "https://nl.octofiber.com/3d-printing-filament/pla.html",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Octofiber",
|
"author_id": "Octofiber",
|
||||||
@ -1141,7 +1141,7 @@
|
|||||||
"display_name": "PolyFlex™ PLA",
|
"display_name": "PolyFlex™ PLA",
|
||||||
"description": "PolyFlex™ is a highly flexible yet easy to print 3D printing material. Featuring good elasticity and a large strain-to- failure, PolyFlex™ opens up a completely new realm of applications.",
|
"description": "PolyFlex™ is a highly flexible yet easy to print 3D printing material. Featuring good elasticity and a large strain-to- failure, PolyFlex™ opens up a completely new realm of applications.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "http://www.polymaker.com/shop/polyflex/",
|
"website": "http://www.polymaker.com/shop/polyflex/",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Polymaker",
|
"author_id": "Polymaker",
|
||||||
@ -1158,7 +1158,7 @@
|
|||||||
"display_name": "PolyMax™ PLA",
|
"display_name": "PolyMax™ PLA",
|
||||||
"description": "PolyMax™ PLA is a 3D printing material with excellent mechanical properties and printing quality. PolyMax™ PLA has an impact resistance of up to nine times that of regular PLA, and better overall mechanical properties than ABS.",
|
"description": "PolyMax™ PLA is a 3D printing material with excellent mechanical properties and printing quality. PolyMax™ PLA has an impact resistance of up to nine times that of regular PLA, and better overall mechanical properties than ABS.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "http://www.polymaker.com/shop/polymax/",
|
"website": "http://www.polymaker.com/shop/polymax/",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Polymaker",
|
"author_id": "Polymaker",
|
||||||
@ -1175,7 +1175,7 @@
|
|||||||
"display_name": "PolyPlus™ PLA True Colour",
|
"display_name": "PolyPlus™ PLA True Colour",
|
||||||
"description": "PolyPlus™ PLA is a premium PLA designed for all desktop FDM/FFF 3D printers. It is produced with our patented Jam-Free™ technology that ensures consistent extrusion and prevents jams.",
|
"description": "PolyPlus™ PLA is a premium PLA designed for all desktop FDM/FFF 3D printers. It is produced with our patented Jam-Free™ technology that ensures consistent extrusion and prevents jams.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "http://www.polymaker.com/shop/polyplus-true-colour/",
|
"website": "http://www.polymaker.com/shop/polyplus-true-colour/",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Polymaker",
|
"author_id": "Polymaker",
|
||||||
@ -1192,7 +1192,7 @@
|
|||||||
"display_name": "PolyWood™ PLA",
|
"display_name": "PolyWood™ PLA",
|
||||||
"description": "PolyWood™ is a wood mimic printing material that contains no actual wood ensuring a clean Jam-Free™ printing experience.",
|
"description": "PolyWood™ is a wood mimic printing material that contains no actual wood ensuring a clean Jam-Free™ printing experience.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "http://www.polymaker.com/shop/polywood/",
|
"website": "http://www.polymaker.com/shop/polywood/",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Polymaker",
|
"author_id": "Polymaker",
|
||||||
@ -1209,7 +1209,7 @@
|
|||||||
"display_name": "Ultimaker ABS",
|
"display_name": "Ultimaker ABS",
|
||||||
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com/products/materials/abs",
|
"website": "https://ultimaker.com/products/materials/abs",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -1228,7 +1228,7 @@
|
|||||||
"display_name": "Ultimaker CPE",
|
"display_name": "Ultimaker CPE",
|
||||||
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com/products/materials/abs",
|
"website": "https://ultimaker.com/products/materials/abs",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -1247,7 +1247,7 @@
|
|||||||
"display_name": "Ultimaker Nylon",
|
"display_name": "Ultimaker Nylon",
|
||||||
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com/products/materials/abs",
|
"website": "https://ultimaker.com/products/materials/abs",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -1266,7 +1266,7 @@
|
|||||||
"display_name": "Ultimaker PC",
|
"display_name": "Ultimaker PC",
|
||||||
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com/products/materials/pc",
|
"website": "https://ultimaker.com/products/materials/pc",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -1285,7 +1285,7 @@
|
|||||||
"display_name": "Ultimaker PLA",
|
"display_name": "Ultimaker PLA",
|
||||||
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com/products/materials/abs",
|
"website": "https://ultimaker.com/products/materials/abs",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -1304,7 +1304,7 @@
|
|||||||
"display_name": "Ultimaker PVA",
|
"display_name": "Ultimaker PVA",
|
||||||
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
"description": "Example package for material and quality profiles for Ultimaker materials.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://ultimaker.com/products/materials/abs",
|
"website": "https://ultimaker.com/products/materials/abs",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Ultimaker",
|
"author_id": "Ultimaker",
|
||||||
@ -1323,7 +1323,7 @@
|
|||||||
"display_name": "Vertex Delta ABS",
|
"display_name": "Vertex Delta ABS",
|
||||||
"description": "ABS material and quality files for the Delta Vertex K8800.",
|
"description": "ABS material and quality files for the Delta Vertex K8800.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://vertex3dprinter.eu",
|
"website": "https://vertex3dprinter.eu",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Velleman",
|
"author_id": "Velleman",
|
||||||
@ -1340,7 +1340,7 @@
|
|||||||
"display_name": "Vertex Delta PET",
|
"display_name": "Vertex Delta PET",
|
||||||
"description": "ABS material and quality files for the Delta Vertex K8800.",
|
"description": "ABS material and quality files for the Delta Vertex K8800.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://vertex3dprinter.eu",
|
"website": "https://vertex3dprinter.eu",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Velleman",
|
"author_id": "Velleman",
|
||||||
@ -1357,7 +1357,7 @@
|
|||||||
"display_name": "Vertex Delta PLA",
|
"display_name": "Vertex Delta PLA",
|
||||||
"description": "ABS material and quality files for the Delta Vertex K8800.",
|
"description": "ABS material and quality files for the Delta Vertex K8800.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://vertex3dprinter.eu",
|
"website": "https://vertex3dprinter.eu",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Velleman",
|
"author_id": "Velleman",
|
||||||
@ -1374,7 +1374,7 @@
|
|||||||
"display_name": "Vertex Delta TPU",
|
"display_name": "Vertex Delta TPU",
|
||||||
"description": "ABS material and quality files for the Delta Vertex K8800.",
|
"description": "ABS material and quality files for the Delta Vertex K8800.",
|
||||||
"package_version": "1.0.0",
|
"package_version": "1.0.0",
|
||||||
"sdk_version": 4,
|
"sdk_version": 5,
|
||||||
"website": "https://vertex3dprinter.eu",
|
"website": "https://vertex3dprinter.eu",
|
||||||
"author": {
|
"author": {
|
||||||
"author_id": "Velleman",
|
"author_id": "Velleman",
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
"has_machine_quality": true,
|
"has_machine_quality": true,
|
||||||
"has_materials": true,
|
"has_materials": true,
|
||||||
"has_machine_materials": true,
|
"has_machine_materials": true,
|
||||||
"has_variant_materials": true,
|
|
||||||
"has_variants": true,
|
"has_variants": true,
|
||||||
|
|
||||||
"variants_name": "Tool",
|
"variants_name": "Tool",
|
||||||
|
92
resources/definitions/creality_ender3.def.json
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"name": "Creality Ender-3",
|
||||||
|
"version": 2,
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"visible": true,
|
||||||
|
"author": "Sacha Telgenhof",
|
||||||
|
"manufacturer": "Creality3D",
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"platform": "creality_ender3_platform.stl",
|
||||||
|
"preferred_quality_type": "draft"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": {
|
||||||
|
"default_value": "Creality Ender-3"
|
||||||
|
},
|
||||||
|
"machine_width": {
|
||||||
|
"default_value": 220
|
||||||
|
},
|
||||||
|
"machine_height": {
|
||||||
|
"default_value": 250
|
||||||
|
},
|
||||||
|
"machine_depth": {
|
||||||
|
"default_value": 220
|
||||||
|
},
|
||||||
|
"machine_heated_bed": {
|
||||||
|
"default_value": true
|
||||||
|
},
|
||||||
|
"gantry_height": {
|
||||||
|
"default_value": 30
|
||||||
|
},
|
||||||
|
"machine_head_polygon": {
|
||||||
|
"default_value": [
|
||||||
|
[-30, 34],
|
||||||
|
[-30, -32],
|
||||||
|
[30, -32],
|
||||||
|
[30, 34]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"material_diameter": {
|
||||||
|
"default_value": 1.75
|
||||||
|
},
|
||||||
|
"acceleration_enabled": {
|
||||||
|
"default_value": true
|
||||||
|
},
|
||||||
|
"acceleration_print": {
|
||||||
|
"default_value": 500
|
||||||
|
},
|
||||||
|
"acceleration_travel": {
|
||||||
|
"default_value": 500
|
||||||
|
},
|
||||||
|
"jerk_enabled": {
|
||||||
|
"default_value": true
|
||||||
|
},
|
||||||
|
"jerk_travel": {
|
||||||
|
"default_value": 20
|
||||||
|
},
|
||||||
|
"layer_height": {
|
||||||
|
"default_value": 0.15
|
||||||
|
},
|
||||||
|
"layer_height_0": {
|
||||||
|
"default_value": 0.2
|
||||||
|
},
|
||||||
|
"adhesion_type": {
|
||||||
|
"default_value": "skirt"
|
||||||
|
},
|
||||||
|
"top_bottom_thickness": {
|
||||||
|
"default_value": 0.6
|
||||||
|
},
|
||||||
|
"retraction_amount": {
|
||||||
|
"default_value": 5
|
||||||
|
},
|
||||||
|
"retraction_speed": {
|
||||||
|
"default_value": 40
|
||||||
|
},
|
||||||
|
"cool_min_layer_time": {
|
||||||
|
"default_value": 10
|
||||||
|
},
|
||||||
|
"skirt_line_count": {
|
||||||
|
"default_value": 4
|
||||||
|
},
|
||||||
|
"skirt_gap": {
|
||||||
|
"default_value": 5
|
||||||
|
},
|
||||||
|
"machine_start_gcode": {
|
||||||
|
"default_value": "; Ender 3 Custom Start G-code\nM104 S{material_print_temperature_layer_0} ; Set Extruder temperature\nM140 S{material_bed_temperature_layer_0} ; Set Heat Bed temperature\nM190 S{material_bed_temperature_layer_0} ; Wait for Heat Bed temperature\nM109 S{material_print_temperature_layer_0} ; Wait for Extruder temperature\nG28 ; Home all axes\nG92 E0 ; Reset Extruder\nG1 Z5.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 X0.1 Y20 Z0.3 F5000.0 ; Move to start position\nG1 X0.1 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line\nG1 X0.4 Y200.0 Z0.3 F5000.0 ; Move to side a little\nG1 X0.4 Y20 Z0.3 F1500.0 E30 ; Draw the second line\nG92 E0 ; Reset Extruder\nG1 Z5.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed"
|
||||||
|
},
|
||||||
|
"machine_end_gcode": {
|
||||||
|
"default_value": "; Ender 3 Custom End G-code\nG4 ; Wait\nM220 S100 ; Reset Speed factor override percentage to default (100%)\nM221 S100 ; Reset Extrude factor override percentage to default (100%)\nG91 ; Set coordinates to relative\nG1 F1800 E-3 ; Retract filament 3 mm to prevent oozing\nG1 F3000 Z10 ; Move Z Axis up 10 mm to allow filament ooze freely\nG90 ; Set coordinates to absolute\nG1 X0 Y{machine_depth} F1000 ; Move Heat Bed to the front for easy print removal\nM104 S0 ; Turn off Extruder temperature\nM140 S0 ; Turn off Heat Bed\nM106 S0 ; Turn off Cooling Fan\nM107 ; Turn off Fan\nM84 ; Disable stepper motors"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1297,8 +1297,8 @@
|
|||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"enabled": "travel_compensate_overlapping_walls_0_enabled or travel_compensate_overlapping_walls_x_enabled",
|
"enabled": "travel_compensate_overlapping_walls_0_enabled or travel_compensate_overlapping_walls_x_enabled",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": true,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": false
|
||||||
},
|
},
|
||||||
"wall_min_flow_retract":
|
"wall_min_flow_retract":
|
||||||
{
|
{
|
||||||
@ -1307,8 +1307,8 @@
|
|||||||
"type": "bool",
|
"type": "bool",
|
||||||
"default_value": false,
|
"default_value": false,
|
||||||
"enabled": "(travel_compensate_overlapping_walls_0_enabled or travel_compensate_overlapping_walls_x_enabled) and wall_min_flow > 0",
|
"enabled": "(travel_compensate_overlapping_walls_0_enabled or travel_compensate_overlapping_walls_x_enabled) and wall_min_flow > 0",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": true,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": false
|
||||||
},
|
},
|
||||||
"fill_perimeter_gaps":
|
"fill_perimeter_gaps":
|
||||||
{
|
{
|
||||||
@ -6496,6 +6496,30 @@
|
|||||||
"settable_per_extruder": false,
|
"settable_per_extruder": false,
|
||||||
"settable_per_meshgroup": false
|
"settable_per_meshgroup": false
|
||||||
},
|
},
|
||||||
|
"wall_overhang_angle":
|
||||||
|
{
|
||||||
|
"label": "Overhanging Wall Angle",
|
||||||
|
"description": "Walls that overhang more than this angle will be printed using overhanging wall settings. When the value is 90, no walls will be treated as overhanging.",
|
||||||
|
"unit": "°",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0",
|
||||||
|
"minimum_value_warning": "2",
|
||||||
|
"maximum_value": "90",
|
||||||
|
"default_value": 90,
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"wall_overhang_speed_factor":
|
||||||
|
{
|
||||||
|
"label": "Overhanging Wall Speed",
|
||||||
|
"description": "Overhanging walls will be printed at this percentage of their normal print speed.",
|
||||||
|
"unit": "%",
|
||||||
|
"type": "float",
|
||||||
|
"default_value": 100,
|
||||||
|
"minimum_value": "10",
|
||||||
|
"minimum_value_warning": "25",
|
||||||
|
"maximum_value": "100",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
"bridge_settings_enabled":
|
"bridge_settings_enabled":
|
||||||
{
|
{
|
||||||
"label": "Enable Bridge Settings",
|
"label": "Enable Bridge Settings",
|
||||||
@ -6515,8 +6539,8 @@
|
|||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"default_value": 5,
|
"default_value": 5,
|
||||||
"enabled": "bridge_settings_enabled",
|
"enabled": "bridge_settings_enabled",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": true,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": false
|
||||||
},
|
},
|
||||||
"bridge_skin_support_threshold":
|
"bridge_skin_support_threshold":
|
||||||
{
|
{
|
||||||
@ -6530,18 +6554,6 @@
|
|||||||
"enabled": "bridge_settings_enabled",
|
"enabled": "bridge_settings_enabled",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"bridge_wall_max_overhang":
|
|
||||||
{
|
|
||||||
"label": "Bridge Wall Max Overhang",
|
|
||||||
"description": "The maximum allowed width of the region of air below a wall line before the wall is printed using bridge settings. Expressed as a percentage of the wall line width. When the air gap is wider than this, the wall line is printed using the bridge settings. Otherwise, the wall line is printed using the normal settings. The lower the value, the more likely it is that overhung wall lines will be printed using bridge settings.",
|
|
||||||
"unit": "%",
|
|
||||||
"default_value": 100,
|
|
||||||
"type": "float",
|
|
||||||
"minimum_value": "0",
|
|
||||||
"maximum_value": "100",
|
|
||||||
"enabled": "bridge_settings_enabled",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"bridge_wall_coast":
|
"bridge_wall_coast":
|
||||||
{
|
{
|
||||||
"label": "Bridge Wall Coasting",
|
"label": "Bridge Wall Coasting",
|
||||||
@ -6552,7 +6564,7 @@
|
|||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value": "500",
|
"maximum_value": "500",
|
||||||
"enabled": "bridge_settings_enabled",
|
"enabled": "bridge_settings_enabled",
|
||||||
"settable_per_mesh": false
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"bridge_wall_speed":
|
"bridge_wall_speed":
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
"has_machine_quality": true,
|
"has_machine_quality": true,
|
||||||
"has_materials": true,
|
"has_materials": true,
|
||||||
"has_machine_materials": true,
|
"has_machine_materials": true,
|
||||||
"has_variant_materials": true,
|
|
||||||
"has_variants": true,
|
"has_variants": true,
|
||||||
"preferred_variant_name": "AA 0.4",
|
"preferred_variant_name": "AA 0.4",
|
||||||
"preferred_quality_type": "normal",
|
"preferred_quality_type": "normal",
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
"platform_offset": [0, 0, 0],
|
"platform_offset": [0, 0, 0],
|
||||||
"has_machine_quality": true,
|
"has_machine_quality": true,
|
||||||
"has_machine_materials": true,
|
"has_machine_materials": true,
|
||||||
"has_variant_materials": true,
|
|
||||||
"has_materials": true,
|
"has_materials": true,
|
||||||
"has_variants": true,
|
"has_variants": true,
|
||||||
"preferred_variant_name": "AA 0.4",
|
"preferred_variant_name": "AA 0.4",
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
"has_machine_quality": true,
|
"has_machine_quality": true,
|
||||||
"has_materials": true,
|
"has_materials": true,
|
||||||
"has_machine_materials": true,
|
"has_machine_materials": true,
|
||||||
"has_variant_materials": true,
|
|
||||||
"has_variant_buildplates": true,
|
"has_variant_buildplates": true,
|
||||||
"has_variants": true,
|
"has_variants": true,
|
||||||
"preferred_variant_name": "AA 0.4",
|
"preferred_variant_name": "AA 0.4",
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
"machine_nozzle_offset_y": { "default_value": 0 },
|
"machine_nozzle_offset_y": { "default_value": 0 },
|
||||||
|
|
||||||
"machine_extruder_start_pos_abs": { "default_value": true },
|
"machine_extruder_start_pos_abs": { "default_value": true },
|
||||||
"machine_extruder_start_pos_x": { "default_value": 310 },
|
"machine_extruder_start_pos_x": { "default_value": 330 },
|
||||||
"machine_extruder_start_pos_y": { "default_value": 237 },
|
"machine_extruder_start_pos_y": { "default_value": 237 },
|
||||||
"machine_extruder_end_pos_abs": { "default_value": true },
|
"machine_extruder_end_pos_abs": { "default_value": true },
|
||||||
"machine_extruder_end_pos_x": { "default_value": 310 },
|
"machine_extruder_end_pos_x": { "default_value": 330 },
|
||||||
"machine_extruder_end_pos_y": { "default_value": 237 },
|
"machine_extruder_end_pos_y": { "default_value": 237 },
|
||||||
"machine_nozzle_head_distance": { "default_value": 2.7 },
|
"machine_nozzle_head_distance": { "default_value": 2.7 },
|
||||||
"extruder_prime_pos_x": { "default_value": -3 },
|
"extruder_prime_pos_x": { "default_value": -3 },
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
"machine_nozzle_offset_y": { "default_value": 0 },
|
"machine_nozzle_offset_y": { "default_value": 0 },
|
||||||
|
|
||||||
"machine_extruder_start_pos_abs": { "default_value": true },
|
"machine_extruder_start_pos_abs": { "default_value": true },
|
||||||
"machine_extruder_start_pos_x": { "default_value": 310 },
|
"machine_extruder_start_pos_x": { "default_value": 330 },
|
||||||
"machine_extruder_start_pos_y": { "default_value": 219 },
|
"machine_extruder_start_pos_y": { "default_value": 219 },
|
||||||
"machine_extruder_end_pos_abs": { "default_value": true },
|
"machine_extruder_end_pos_abs": { "default_value": true },
|
||||||
"machine_extruder_end_pos_x": { "default_value": 310 },
|
"machine_extruder_end_pos_x": { "default_value": 330 },
|
||||||
"machine_extruder_end_pos_y": { "default_value": 219 },
|
"machine_extruder_end_pos_y": { "default_value": 219 },
|
||||||
"machine_nozzle_head_distance": { "default_value": 4.2 },
|
"machine_nozzle_head_distance": { "default_value": 4.2 },
|
||||||
"extruder_prime_pos_x": { "default_value": 333 },
|
"extruder_prime_pos_x": { "default_value": 333 },
|
||||||
|
@ -3860,7 +3860,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
@ -3880,27 +3880,27 @@ msgstr ""
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
@ -3961,8 +3961,8 @@ msgstr ""
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
@ -4012,17 +4012,17 @@ msgstr ""
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
@ -4047,7 +4047,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
@ -4195,7 +4195,7 @@ msgid "&Settings"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -4222,7 +4222,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3707,8 +3707,8 @@ msgstr "Geschätzte verbleibende Zeit"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr "Umschalten auf Vo&llbild-Modus"
|
msgstr "Umschalten auf Vollbild-Modus"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3727,28 +3727,28 @@ msgstr "&Beenden"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr "&3D-Ansicht"
|
msgstr "3D-Ansicht"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr "&Vorderansicht"
|
msgstr "Vorderansicht"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr "&Draufsicht"
|
msgstr "Draufsicht"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr "&Ansicht von links"
|
msgstr "Ansicht von links"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr "&Ansicht von rechts"
|
msgstr "Ansicht von rechts"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3783,7 +3783,7 @@ msgstr "&Aktuelle Änderungen verwerfen"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:196
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:196
|
||||||
msgctxt "@action:inmenu menubar:profile"
|
msgctxt "@action:inmenu menubar:profile"
|
||||||
msgid "&Create profile from current settings/overrides..."
|
msgid "&Create profile from current settings/overrides..."
|
||||||
msgstr "&Profil von aktuellen Einstellungen/Überschreibungen erstellen..."
|
msgstr "P&rofil von aktuellen Einstellungen/Überschreibungen erstellen..."
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:202
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:202
|
||||||
msgctxt "@action:inmenu menubar:profile"
|
msgctxt "@action:inmenu menubar:profile"
|
||||||
@ -3808,10 +3808,10 @@ msgstr "&Über..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] "&Ausgewähltes Modell löschen"
|
msgstr[0] "Ausgewähltes Modell löschen"
|
||||||
msgstr[1] "&Ausgewählte Modelle löschen"
|
msgstr[1] "Ausgewählte Modelle löschen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3859,18 +3859,18 @@ msgstr "Modell &multiplizieren"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr "Alle Modelle &wählen"
|
msgstr "Alle Modelle wählen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr "Druckplatte &reinigen"
|
msgstr "Druckplatte reinigen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr "Alle Modelle neu &laden"
|
msgstr "Alle Modelle neu laden"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3894,8 +3894,8 @@ msgstr "Alle Modellpositionen zurücksetzen"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr "Alle Modell&transformationen zurücksetzen"
|
msgstr "Alle Modelltransformationen zurücksetzen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
@ -4039,7 +4039,7 @@ msgid "&Settings"
|
|||||||
msgstr "&Konfiguration"
|
msgstr "&Konfiguration"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr "Dr&ucker"
|
msgstr "Dr&ucker"
|
||||||
|
|
||||||
@ -4066,7 +4066,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr "Extruder deaktivieren"
|
msgstr "Extruder deaktivieren"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr "&Profil"
|
msgstr "&Profil"
|
||||||
|
|
||||||
|
@ -3582,7 +3582,7 @@ msgstr "&Posición de la cámara"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:54
|
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:54
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Build plate"
|
msgid "&Build plate"
|
||||||
msgstr "&Placa de impresión"
|
msgstr "P&laca de impresión"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingVisibilityPresetsMenu.qml:13
|
#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingVisibilityPresetsMenu.qml:13
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3719,8 +3719,8 @@ msgstr "Tiempo restante estimado"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr "A<ernar pantalla completa"
|
msgstr "Alternar pantalla completa"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3739,28 +3739,28 @@ msgstr "&Salir"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr "&Vista en 3D"
|
msgstr "Vista en 3D"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr "&Vista frontal"
|
msgstr "Vista frontal"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr "&Vista superior"
|
msgstr "Vista superior"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr "&Vista del lado izquierdo"
|
msgstr "Vista del lado izquierdo"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr "&Vista del lado derecho"
|
msgstr "Vista del lado derecho"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3820,10 +3820,10 @@ msgstr "&Acerca de..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] "Eliminar modelo &seleccionado"
|
msgstr[0] "Eliminar modelo seleccionado"
|
||||||
msgstr[1] "Eliminar modelos &seleccionados"
|
msgstr[1] "Eliminar modelos seleccionados"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3871,18 +3871,18 @@ msgstr "&Multiplicar modelo..."
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr "&Seleccionar todos los modelos"
|
msgstr "Seleccionar todos los modelos"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr "&Borrar placa de impresión"
|
msgstr "Borrar placa de impresión"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr "&Recargar todos los modelos"
|
msgstr "Recargar todos los modelos"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3906,8 +3906,8 @@ msgstr "Restablecer las posiciones de todos los modelos"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr "Restablecer las &transformaciones de todos los modelos"
|
msgstr "Restablecer las transformaciones de todos los modelos"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
@ -4023,7 +4023,7 @@ msgstr "&Archivo"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:119
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:119
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "&Save Selection to File"
|
msgid "&Save Selection to File"
|
||||||
msgstr "Guardar &selección en archivo"
|
msgstr "&Guardar selección en archivo"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:128
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:128
|
||||||
msgctxt "@title:menu menubar:file"
|
msgctxt "@title:menu menubar:file"
|
||||||
@ -4051,7 +4051,7 @@ msgid "&Settings"
|
|||||||
msgstr "A&justes"
|
msgstr "A&justes"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr "&Impresora"
|
msgstr "&Impresora"
|
||||||
|
|
||||||
@ -4078,7 +4078,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr "Deshabilitar extrusor"
|
msgstr "Deshabilitar extrusor"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr "&Perfil"
|
msgstr "&Perfil"
|
||||||
|
|
||||||
|
@ -3726,8 +3726,8 @@ msgstr "Aikaa jäljellä arviolta"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr "Vaihda &koko näyttöön"
|
msgstr "Vaihda koko näyttöön"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3746,27 +3746,27 @@ msgstr "&Lopeta"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
@ -3827,10 +3827,10 @@ msgstr "Ti&etoja..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] "Poista &valittu malli"
|
msgstr[0] "Poista valittu malli"
|
||||||
msgstr[1] "Poista &valitut mallit"
|
msgstr[1] "Poista valitut mallit"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3878,18 +3878,18 @@ msgstr "&Kerro malli..."
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr "&Valitse kaikki mallit"
|
msgstr "Valitse kaikki mallit"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr "&Tyhjennä tulostusalusta"
|
msgstr "Tyhjennä tulostusalusta"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr "&Lataa kaikki mallit uudelleen"
|
msgstr "Lataa kaikki mallit uudelleen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3913,8 +3913,8 @@ msgstr "Määritä kaikkien mallien positiot uudelleen"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr "Määritä kaikkien mallien &muutokset uudelleen"
|
msgstr "Määritä kaikkien mallien muutokset uudelleen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
@ -4025,7 +4025,7 @@ msgstr ""
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:102
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:102
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:toplevel"
|
||||||
msgid "&File"
|
msgid "&File"
|
||||||
msgstr "&Tiedosto"
|
msgstr "Tie&dosto"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:119
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:119
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
@ -4058,7 +4058,7 @@ msgid "&Settings"
|
|||||||
msgstr "&Asetukset"
|
msgstr "&Asetukset"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr "&Tulostin"
|
msgstr "&Tulostin"
|
||||||
|
|
||||||
@ -4085,7 +4085,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr "&Profiili"
|
msgstr "&Profiili"
|
||||||
|
|
||||||
|
@ -3707,8 +3707,8 @@ msgstr "Durée restante estimée"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr "Passer en P&lein écran"
|
msgstr "Passer en Plein écran"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3727,28 +3727,28 @@ msgstr "&Quitter"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr "Vue &3D"
|
msgstr "Vue 3D"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr "Vue de &face"
|
msgstr "Vue de face"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr "Vue du dess&us"
|
msgstr "Vue du dessus"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr "Vue latérale &gauche"
|
msgstr "Vue latérale gauche"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr "Vue latérale &droite"
|
msgstr "Vue latérale droite"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3808,10 +3808,10 @@ msgstr "&À propos de..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] "Supprimer le modèle &sélectionné"
|
msgstr[0] "Supprimer le modèle sélectionné"
|
||||||
msgstr[1] "Supprimer les modèles &sélectionnés"
|
msgstr[1] "Supprimer les modèles sélectionnés"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3859,18 +3859,18 @@ msgstr "&Multiplier le modèle..."
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr "&Sélectionner tous les modèles"
|
msgstr "Sélectionner tous les modèles"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr "&Supprimer les objets du plateau"
|
msgstr "Supprimer les objets du plateau"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr "Rechar&ger tous les modèles"
|
msgstr "Recharger tous les modèles"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3894,7 +3894,7 @@ msgstr "Réinitialiser toutes les positions des modèles"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr "Réinitialiser tous les modèles et transformations"
|
msgstr "Réinitialiser tous les modèles et transformations"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
@ -4039,7 +4039,7 @@ msgid "&Settings"
|
|||||||
msgstr "&Paramètres"
|
msgstr "&Paramètres"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr "Im&primante"
|
msgstr "Im&primante"
|
||||||
|
|
||||||
@ -4066,7 +4066,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr "Désactiver l'extrudeuse"
|
msgstr "Désactiver l'extrudeuse"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr "&Profil"
|
msgstr "&Profil"
|
||||||
|
|
||||||
|
@ -3568,7 +3568,7 @@ msgstr "&Posizione fotocamera"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:54
|
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:54
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Build plate"
|
msgid "&Build plate"
|
||||||
msgstr "&Piano di stampa"
|
msgstr "P&iano di stampa"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingVisibilityPresetsMenu.qml:13
|
#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingVisibilityPresetsMenu.qml:13
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3705,8 +3705,8 @@ msgstr "Tempo residuo stimato"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr "Att&iva/disattiva schermo intero"
|
msgstr "Attiva/disattiva schermo intero"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3721,32 +3721,32 @@ msgstr "Ri&peti"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:105
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:105
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "&Quit"
|
msgid "&Quit"
|
||||||
msgstr "E&sci"
|
msgstr "&Esci"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr "&Visualizzazione 3D"
|
msgstr "Visualizzazione 3D"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr "&Visualizzazione frontale"
|
msgstr "Visualizzazione frontale"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr "&Visualizzazione superiore"
|
msgstr "Visualizzazione superiore"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr "&Visualizzazione lato sinistro"
|
msgstr "Visualizzazione lato sinistro"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr "&Visualizzazione lato destro"
|
msgstr "Visualizzazione lato destro"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3756,12 +3756,12 @@ msgstr "Configura Cura..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:155
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:155
|
||||||
msgctxt "@action:inmenu menubar:printer"
|
msgctxt "@action:inmenu menubar:printer"
|
||||||
msgid "&Add Printer..."
|
msgid "&Add Printer..."
|
||||||
msgstr "A&ggiungi stampante..."
|
msgstr "&Aggiungi stampante..."
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:161
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:161
|
||||||
msgctxt "@action:inmenu menubar:printer"
|
msgctxt "@action:inmenu menubar:printer"
|
||||||
msgid "Manage Pr&inters..."
|
msgid "Manage Pr&inters..."
|
||||||
msgstr "&Gestione stampanti..."
|
msgstr "Gestione stampanti..."
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:168
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:168
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3806,10 +3806,10 @@ msgstr "I&nformazioni..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] "Cancella &modello selezionato"
|
msgstr[0] "Cancella modello selezionato"
|
||||||
msgstr[1] "Cancella modelli &selezionati"
|
msgstr[1] "Cancella modelli selezionati"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3857,18 +3857,18 @@ msgstr "Mo<iplica modello"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr "Sel&eziona tutti i modelli"
|
msgstr "Seleziona tutti i modelli"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr "&Cancellare piano di stampa"
|
msgstr "Cancellare piano di stampa"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr "R&icarica tutti i modelli"
|
msgstr "Ricarica tutti i modelli"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3892,8 +3892,8 @@ msgstr "Reimposta tutte le posizioni dei modelli"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr "Reimposta tutte le &trasformazioni dei modelli"
|
msgstr "Reimposta tutte le trasformazioni dei modelli"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
@ -3908,7 +3908,7 @@ msgstr "&Nuovo Progetto..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:411
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:411
|
||||||
msgctxt "@action:inmenu menubar:help"
|
msgctxt "@action:inmenu menubar:help"
|
||||||
msgid "Show Engine &Log..."
|
msgid "Show Engine &Log..."
|
||||||
msgstr "M&ostra log motore..."
|
msgstr "Mostra &log motore..."
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:419
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:419
|
||||||
msgctxt "@action:inmenu menubar:help"
|
msgctxt "@action:inmenu menubar:help"
|
||||||
@ -4037,7 +4037,7 @@ msgid "&Settings"
|
|||||||
msgstr "&Impostazioni"
|
msgstr "&Impostazioni"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr "S&tampante"
|
msgstr "S&tampante"
|
||||||
|
|
||||||
@ -4064,7 +4064,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr "Disabilita estrusore"
|
msgstr "Disabilita estrusore"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr "&Profilo"
|
msgstr "&Profilo"
|
||||||
|
|
||||||
|
@ -3711,7 +3711,7 @@ msgstr "残り時間"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr "留め金 フルスクリーン"
|
msgstr "留め金 フルスクリーン"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
@ -3731,28 +3731,28 @@ msgstr "&やめる"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr "3Dビュー (&3)"
|
msgstr "3Dビュー "
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr "フロントビュー (&F)"
|
msgstr "フロントビュー"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr "トップビュー (&T)"
|
msgstr "トップビュー"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr "左サイドビュー (&L)"
|
msgstr "左サイドビュー"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr "右サイドビュー (&R)"
|
msgstr "右サイドビュー"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3813,8 +3813,8 @@ msgstr "アバウト..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] "&選択したモデルを削除"
|
msgstr[0] "&選択したモデルを削除"
|
||||||
|
|
||||||
# can’t enter japanese text
|
# can’t enter japanese text
|
||||||
@ -3854,7 +3854,7 @@ msgstr "モデルを非グループ化"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:314
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:314
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Merge Models"
|
msgid "&Merge Models"
|
||||||
msgstr "&モデルの合体"
|
msgstr "モ&デルの合体"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:324
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:324
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3863,17 +3863,17 @@ msgstr "&モデルを増倍する…"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr "&すべてのモデル選択"
|
msgstr "すべてのモデル選択"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr "&ビルドプレート上のクリア"
|
msgstr "ビルドプレート上のクリア"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr "すべてのモデルを読み込む"
|
msgstr "すべてのモデルを読み込む"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
@ -3898,7 +3898,7 @@ msgstr "すべてのモデルのポジションをリセットする"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr "すべてのモデル&変更点をリセットする"
|
msgstr "すべてのモデル&変更点をリセットする"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
@ -4015,7 +4015,7 @@ msgstr "&ファイル"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:119
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:119
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "&Save Selection to File"
|
msgid "&Save Selection to File"
|
||||||
msgstr "&ファイルに選択したものを保存"
|
msgstr "フ&ァイルに選択したものを保存"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:128
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:128
|
||||||
msgctxt "@title:menu menubar:file"
|
msgctxt "@title:menu menubar:file"
|
||||||
@ -4043,7 +4043,7 @@ msgid "&Settings"
|
|||||||
msgstr "&設定"
|
msgstr "&設定"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr "&プリンター"
|
msgstr "&プリンター"
|
||||||
|
|
||||||
@ -4070,7 +4070,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr "エクストルーダーを無効にする"
|
msgstr "エクストルーダーを無効にする"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr "&プロファイル"
|
msgstr "&プロファイル"
|
||||||
|
|
||||||
|
@ -3703,7 +3703,7 @@ msgstr "예상 남은 시간"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr "전채 화면 전환"
|
msgstr "전채 화면 전환"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
@ -3723,28 +3723,28 @@ msgstr "종료(&Q)"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr "3D 보기(&3)"
|
msgstr "3D 보기"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr "앞에서 보기(&F)"
|
msgstr "앞에서 보기"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr "위에서 보기(&T)"
|
msgstr "위에서 보기"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr "왼쪽에서 보기(&L)"
|
msgstr "왼쪽에서 보기"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr "오른쪽에서 보기(&R)"
|
msgstr "오른쪽에서 보기"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3804,8 +3804,8 @@ msgstr "소개..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] "선택한 모델 삭제"
|
msgstr[0] "선택한 모델 삭제"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
||||||
@ -3852,17 +3852,17 @@ msgstr "모델 복제..."
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr "모든 모델 선택"
|
msgstr "모든 모델 선택"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr "빌드 플레이트 지우기"
|
msgstr "빌드 플레이트 지우기"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr "모든 모델 다시 로드"
|
msgstr "모든 모델 다시 로드"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
@ -3887,7 +3887,7 @@ msgstr "모든 모델의 위치 재설정"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr "모든 모델의 변환 재설정"
|
msgstr "모든 모델의 변환 재설정"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
@ -4032,7 +4032,7 @@ msgid "&Settings"
|
|||||||
msgstr "설정"
|
msgstr "설정"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr "프린터"
|
msgstr "프린터"
|
||||||
|
|
||||||
@ -4059,7 +4059,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr "익스트루더 사용하지 않음"
|
msgstr "익스트루더 사용하지 않음"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr "프로파일"
|
msgstr "프로파일"
|
||||||
|
|
||||||
|
@ -3705,8 +3705,8 @@ msgstr "Geschatte resterende tijd"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr "Vo&lledig Scherm In-/Uitschakelen"
|
msgstr "Volledig Scherm In-/Uitschakelen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3725,28 +3725,28 @@ msgstr "&Afsluiten"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr "&3D-weergave"
|
msgstr "3D-weergave"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr "Weergave &voorzijde"
|
msgstr "Weergave voorzijde"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr "Weergave &bovenzijde"
|
msgstr "Weergave bovenzijde"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr "Weergave &linkerzijde"
|
msgstr "Weergave linkerzijde"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr "Weergave &rechterzijde"
|
msgstr "Weergave rechterzijde"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3806,10 +3806,10 @@ msgstr "&Over..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] "Ge&selecteerd model verwijderen"
|
msgstr[0] "Geselecteerd model verwijderen"
|
||||||
msgstr[1] "Ge&selecteerde modellen verwijderen"
|
msgstr[1] "Geselecteerde modellen verwijderen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3857,18 +3857,18 @@ msgstr "&Model verveelvoudigen..."
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr "Alle Modellen &Selecteren"
|
msgstr "Alle Modellen Selecteren"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr "&Platform Leegmaken"
|
msgstr "Platform Leegmaken"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr "Alle Modellen Opnieuw &Laden"
|
msgstr "Alle Modellen Opnieuw Laden"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3892,8 +3892,8 @@ msgstr "Alle Modelposities Herstellen"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr "Alle Model&transformaties Herstellen"
|
msgstr "Alle Modeltransformaties Herstellen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
@ -4037,7 +4037,7 @@ msgid "&Settings"
|
|||||||
msgstr "In&stellingen"
|
msgstr "In&stellingen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr "&Printer"
|
msgstr "&Printer"
|
||||||
|
|
||||||
@ -4064,7 +4064,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr "Extruder uitschakelen"
|
msgstr "Extruder uitschakelen"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr "&Profiel"
|
msgstr "&Profiel"
|
||||||
|
|
||||||
|
@ -3602,7 +3602,7 @@ msgstr "&Pozycja kamery"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:54
|
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:54
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Build plate"
|
msgid "&Build plate"
|
||||||
msgstr "&Pole robocze"
|
msgstr "P&ole robocze"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingVisibilityPresetsMenu.qml:13
|
#: /home/ruben/Projects/Cura/resources/qml/Menus/SettingVisibilityPresetsMenu.qml:13
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3741,7 +3741,7 @@ msgstr "Szacowany czas pozostały"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:78
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
msgid "Toggle Fu&ll Screen"
|
msgid "Toggle Full Screen"
|
||||||
msgstr "Przełącz tryb pełnoekranowy"
|
msgstr "Przełącz tryb pełnoekranowy"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:85
|
||||||
@ -3761,28 +3761,28 @@ msgstr "&Zamknij"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:113
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&3D View"
|
msgid "3D View"
|
||||||
msgstr "&Widok 3D"
|
msgstr "Widok 3D"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:120
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Front View"
|
msgid "Front View"
|
||||||
msgstr "&Widok z przodu"
|
msgstr "Widok z przodu"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:127
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Top View"
|
msgid "Top View"
|
||||||
msgstr "&Widok z góry"
|
msgstr "Widok z góry"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:134
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Left Side View"
|
msgid "Left Side View"
|
||||||
msgstr "&Widok z lewej strony"
|
msgstr "Widok z lewej strony"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:141
|
||||||
msgctxt "@action:inmenu menubar:view"
|
msgctxt "@action:inmenu menubar:view"
|
||||||
msgid "&Right Side View"
|
msgid "Right Side View"
|
||||||
msgstr "&Widok z prawej strony"
|
msgstr "Widok z prawej strony"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:148
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3842,10 +3842,10 @@ msgstr "&O..."
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:232
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:242
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Delete &Selected Model"
|
msgid "Delete Selected Model"
|
||||||
msgid_plural "Delete &Selected Models"
|
msgid_plural "Delete Selected Models"
|
||||||
msgstr[0] "Usuń &wybrany model"
|
msgstr[0] "Usuń wybrany model"
|
||||||
msgstr[1] "Usuń &wybrane modele"
|
msgstr[1] "Usuń wybrane modele"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:252
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
@ -3884,7 +3884,7 @@ msgstr "Rozgrupuj modele "
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:314
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:314
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Merge Models"
|
msgid "&Merge Models"
|
||||||
msgstr "&Połącz modele"
|
msgstr "Połącz modele"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:324
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:324
|
||||||
msgctxt "@action:inmenu"
|
msgctxt "@action:inmenu"
|
||||||
@ -3893,17 +3893,17 @@ msgstr "&Powiel model..."
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:331
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Select All Models"
|
msgid "Select All Models"
|
||||||
msgstr "&Wybierz wszystkie modele"
|
msgstr "Wybierz wszystkie modele"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:341
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "&Clear Build Plate"
|
msgid "Clear Build Plate"
|
||||||
msgstr "&Wyczyść stół"
|
msgstr "Wyczyść stół"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "Re&load All Models"
|
msgid "Reload All Models"
|
||||||
msgstr "Przeładuj wszystkie modele"
|
msgstr "Przeładuj wszystkie modele"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:360
|
||||||
@ -3928,7 +3928,7 @@ msgstr "Zresetuj wszystkie pozycje modelu"
|
|||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:389
|
||||||
msgctxt "@action:inmenu menubar:edit"
|
msgctxt "@action:inmenu menubar:edit"
|
||||||
msgid "Reset All Model &Transformations"
|
msgid "Reset All Model Transformations"
|
||||||
msgstr "Zresetuj wszystkie przekształcenia modelu"
|
msgstr "Zresetuj wszystkie przekształcenia modelu"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:396
|
||||||
@ -4045,7 +4045,7 @@ msgstr "&Plik"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:119
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:119
|
||||||
msgctxt "@action:inmenu menubar:file"
|
msgctxt "@action:inmenu menubar:file"
|
||||||
msgid "&Save Selection to File"
|
msgid "&Save Selection to File"
|
||||||
msgstr "&Zapisz wybór w pliku"
|
msgstr "Z&apisz wybór w pliku"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:128
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:128
|
||||||
msgctxt "@title:menu menubar:file"
|
msgctxt "@title:menu menubar:file"
|
||||||
@ -4073,7 +4073,7 @@ msgid "&Settings"
|
|||||||
msgstr "&Ustawienia"
|
msgstr "&Ustawienia"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:186
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:settings"
|
||||||
msgid "&Printer"
|
msgid "&Printer"
|
||||||
msgstr "&Drukarka"
|
msgstr "&Drukarka"
|
||||||
|
|
||||||
@ -4100,7 +4100,7 @@ msgid "Disable Extruder"
|
|||||||
msgstr "Wyłącz Ekstruder"
|
msgstr "Wyłącz Ekstruder"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:230
|
||||||
msgctxt "@title:menu"
|
msgctxt "@title:settings"
|
||||||
msgid "&Profile"
|
msgid "&Profile"
|
||||||
msgstr "&Profil"
|
msgstr "&Profil"
|
||||||
|
|
||||||
@ -4122,7 +4122,7 @@ msgstr "Preferencje"
|
|||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:289
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:289
|
||||||
msgctxt "@title:menu menubar:toplevel"
|
msgctxt "@title:menu menubar:toplevel"
|
||||||
msgid "&Help"
|
msgid "&Help"
|
||||||
msgstr "&Pomoc"
|
msgstr "P&omoc"
|
||||||
|
|
||||||
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:335
|
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:335
|
||||||
msgctxt "@label"
|
msgctxt "@label"
|
||||||
|