mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-08 22:35:03 -06:00
Merge branch 'WIP_onboarding' of github.com:Ultimaker/Cura
This commit is contained in:
commit
932a5c8fc9
146 changed files with 4594 additions and 3972 deletions
|
@ -1,20 +1,20 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import os.path
|
||||
|
||||
from PyQt5.QtCore import QObject
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Extension import Extension
|
||||
from UM.Application import Application
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Version import Version
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QObject
|
||||
|
||||
import os.path
|
||||
import collections
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
class ChangeLog(Extension, QObject,):
|
||||
|
||||
class ChangeLog(Extension, QObject):
|
||||
def __init__(self, parent = None):
|
||||
QObject.__init__(self, parent)
|
||||
Extension.__init__(self)
|
||||
|
@ -26,55 +26,11 @@ class ChangeLog(Extension, QObject,):
|
|||
else:
|
||||
self._current_app_version = None
|
||||
|
||||
self._change_logs = None
|
||||
Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
|
||||
Application.getInstance().getPreferences().addPreference("general/latest_version_changelog_shown", "2.0.0") #First version of CURA with uranium
|
||||
self.setMenuName(catalog.i18nc("@item:inmenu", "Changelog"))
|
||||
self.addMenuItem(catalog.i18nc("@item:inmenu", "Show Changelog"), self.showChangelog)
|
||||
|
||||
def getChangeLogs(self):
|
||||
if not self._change_logs:
|
||||
self.loadChangeLogs()
|
||||
return self._change_logs
|
||||
|
||||
@pyqtSlot(result = str)
|
||||
def getChangeLogString(self):
|
||||
logs = self.getChangeLogs()
|
||||
result = ""
|
||||
for version in logs:
|
||||
result += "<h1>" + str(version) + "</h1><br>"
|
||||
result += ""
|
||||
for change in logs[version]:
|
||||
if str(change) != "":
|
||||
result += "<b>" + str(change) + "</b><br>"
|
||||
for line in logs[version][change]:
|
||||
result += str(line) + "<br>"
|
||||
result += "<br>"
|
||||
|
||||
pass
|
||||
return result
|
||||
|
||||
def loadChangeLogs(self):
|
||||
self._change_logs = collections.OrderedDict()
|
||||
with open(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "ChangeLog.txt"), "r", encoding = "utf-8") as f:
|
||||
open_version = None
|
||||
open_header = "" # Initialise to an empty header in case there is no "*" in the first line of the changelog
|
||||
for line in f:
|
||||
line = line.replace("\n","")
|
||||
if "[" in line and "]" in line:
|
||||
line = line.replace("[","")
|
||||
line = line.replace("]","")
|
||||
open_version = Version(line)
|
||||
open_header = ""
|
||||
self._change_logs[open_version] = collections.OrderedDict()
|
||||
elif line.startswith("*"):
|
||||
open_header = line.replace("*","")
|
||||
self._change_logs[open_version][open_header] = []
|
||||
elif line != "":
|
||||
if open_header not in self._change_logs[open_version]:
|
||||
self._change_logs[open_version][open_header] = []
|
||||
self._change_logs[open_version][open_header].append(line)
|
||||
|
||||
def _onEngineCreated(self):
|
||||
if not self._current_app_version:
|
||||
return #We're on dev branch.
|
||||
|
|
|
@ -6,7 +6,9 @@ import QtQuick.Controls 1.3
|
|||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.1 as UM
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
|
||||
UM.Dialog
|
||||
{
|
||||
|
@ -20,7 +22,7 @@ UM.Dialog
|
|||
TextArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
text: manager.getChangeLogString()
|
||||
text: CuraApplication.getTextManager().getChangeLogText()
|
||||
readOnly: true;
|
||||
textFormat: TextEdit.RichText
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,20 +10,17 @@ from time import time
|
|||
from typing import Any, cast, Dict, List, Optional, Set, TYPE_CHECKING
|
||||
|
||||
from UM.Backend.Backend import Backend, BackendState
|
||||
from UM.Scene.Camera import Camera
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from UM.Signal import Signal
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Resources import Resources
|
||||
from UM.Platform import Platform
|
||||
from UM.Qt.Duration import DurationFormat
|
||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||
from UM.Settings.Interfaces import DefinitionContainerInterface
|
||||
from UM.Settings.SettingInstance import SettingInstance #For typing.
|
||||
from UM.Tool import Tool #For typing.
|
||||
from UM.Mesh.MeshData import MeshData #For typing.
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
|
|
@ -24,7 +24,7 @@ from cura import LayerPolygon
|
|||
|
||||
import numpy
|
||||
from time import time
|
||||
from cura.Settings.ExtrudersModel import ExtrudersModel
|
||||
from cura.Machines.Models.ExtrudersModel import ExtrudersModel
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtCore import pyqtProperty
|
||||
|
||||
import UM.i18n
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
from UM.Application import Application
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
|
||||
from cura.MachineAction import MachineAction
|
||||
from cura.Settings.CuraStackBuilder import CuraStackBuilder
|
||||
from cura.Settings.cura_empty_instance_containers import isEmptyContainer
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from PyQt5.QtCore import QObject
|
||||
|
||||
catalog = UM.i18n.i18nCatalog("cura")
|
||||
|
||||
|
@ -18,139 +23,102 @@ catalog = UM.i18n.i18nCatalog("cura")
|
|||
## This action allows for certain settings that are "machine only") to be modified.
|
||||
# It automatically detects machine definitions that it knows how to change and attaches itself to those.
|
||||
class MachineSettingsAction(MachineAction):
|
||||
def __init__(self, parent = None):
|
||||
def __init__(self, parent: Optional["QObject"] = None) -> None:
|
||||
super().__init__("MachineSettingsAction", catalog.i18nc("@action", "Machine Settings"))
|
||||
self._qml_url = "MachineSettingsAction.qml"
|
||||
|
||||
self._application = Application.getInstance()
|
||||
|
||||
self._global_container_stack = None
|
||||
from cura.CuraApplication import CuraApplication
|
||||
self._application = CuraApplication.getInstance()
|
||||
|
||||
from cura.Settings.CuraContainerStack import _ContainerIndexes
|
||||
self._container_index = _ContainerIndexes.DefinitionChanges
|
||||
self._store_container_index = _ContainerIndexes.DefinitionChanges
|
||||
|
||||
self._container_registry = ContainerRegistry.getInstance()
|
||||
self._container_registry.containerAdded.connect(self._onContainerAdded)
|
||||
self._container_registry.containerRemoved.connect(self._onContainerRemoved)
|
||||
self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
|
||||
|
||||
# The machine settings dialog blocks auto-slicing when it's shown, and re-enables it when it's finished.
|
||||
self._backend = self._application.getBackend()
|
||||
self.onFinished.connect(self._onFinished)
|
||||
|
||||
self._empty_definition_container_id_list = []
|
||||
|
||||
def _isEmptyDefinitionChanges(self, container_id: str):
|
||||
if not self._empty_definition_container_id_list:
|
||||
self._empty_definition_container_id_list = [self._application.empty_container.getId(),
|
||||
self._application.empty_definition_changes_container.getId()]
|
||||
return container_id in self._empty_definition_container_id_list
|
||||
# Which container index in a stack to store machine setting changes.
|
||||
@pyqtProperty(int, constant = True)
|
||||
def storeContainerIndex(self) -> int:
|
||||
return self._store_container_index
|
||||
|
||||
def _onContainerAdded(self, container):
|
||||
# Add this action as a supported action to all machine definitions
|
||||
if isinstance(container, DefinitionContainer) and container.getMetaDataEntry("type") == "machine":
|
||||
self._application.getMachineActionManager().addSupportedAction(container.getId(), self.getKey())
|
||||
|
||||
def _onContainerRemoved(self, container):
|
||||
# Remove definition_changes containers when a stack is removed
|
||||
if container.getMetaDataEntry("type") in ["machine", "extruder_train"]:
|
||||
definition_changes_id = container.definitionChanges.getId()
|
||||
if self._isEmptyDefinitionChanges(definition_changes_id):
|
||||
return
|
||||
|
||||
def _reset(self):
|
||||
if not self._global_container_stack:
|
||||
global_stack = self._application.getMachineManager().activeMachine
|
||||
if not global_stack:
|
||||
return
|
||||
|
||||
# Make sure there is a definition_changes container to store the machine settings
|
||||
definition_changes_id = self._global_container_stack.definitionChanges.getId()
|
||||
if self._isEmptyDefinitionChanges(definition_changes_id):
|
||||
CuraStackBuilder.createDefinitionChangesContainer(self._global_container_stack,
|
||||
self._global_container_stack.getName() + "_settings")
|
||||
|
||||
# Notify the UI in which container to store the machine settings data
|
||||
from cura.Settings.CuraContainerStack import _ContainerIndexes
|
||||
|
||||
container_index = _ContainerIndexes.DefinitionChanges
|
||||
if container_index != self._container_index:
|
||||
self._container_index = container_index
|
||||
self.containerIndexChanged.emit()
|
||||
definition_changes_id = global_stack.definitionChanges.getId()
|
||||
if isEmptyContainer(definition_changes_id):
|
||||
CuraStackBuilder.createDefinitionChangesContainer(global_stack,
|
||||
global_stack.getName() + "_settings")
|
||||
|
||||
# Disable auto-slicing while the MachineAction is showing
|
||||
if self._backend: # This sometimes triggers before backend is loaded.
|
||||
self._backend.disableTimer()
|
||||
|
||||
@pyqtSlot()
|
||||
def onFinishAction(self):
|
||||
# Restore autoslicing when the machineaction is dismissed
|
||||
def _onFinished(self):
|
||||
# Restore auto-slicing when the machine action is dismissed
|
||||
if self._backend and self._backend.determineAutoSlicing():
|
||||
self._backend.enableTimer()
|
||||
self._backend.tickle()
|
||||
|
||||
containerIndexChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty(int, notify = containerIndexChanged)
|
||||
def containerIndex(self):
|
||||
return self._container_index
|
||||
|
||||
def _onGlobalContainerChanged(self):
|
||||
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
# This additional emit is needed because we cannot connect a UM.Signal directly to a pyqtSignal
|
||||
self.globalContainerChanged.emit()
|
||||
|
||||
globalContainerChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty(int, notify = globalContainerChanged)
|
||||
def definedExtruderCount(self):
|
||||
if not self._global_container_stack:
|
||||
return 0
|
||||
|
||||
return len(self._global_container_stack.getMetaDataEntry("machine_extruder_trains"))
|
||||
|
||||
@pyqtSlot(int)
|
||||
def setMachineExtruderCount(self, extruder_count):
|
||||
def setMachineExtruderCount(self, extruder_count: int) -> None:
|
||||
# Note: this method was in this class before, but since it's quite generic and other plugins also need it
|
||||
# it was moved to the machine manager instead. Now this method just calls the machine manager.
|
||||
self._application.getMachineManager().setActiveMachineExtruderCount(extruder_count)
|
||||
|
||||
@pyqtSlot()
|
||||
def forceUpdate(self):
|
||||
def forceUpdate(self) -> None:
|
||||
# Force rebuilding the build volume by reloading the global container stack.
|
||||
# This is a bit of a hack, but it seems quick enough.
|
||||
self._application.globalContainerStackChanged.emit()
|
||||
self._application.getMachineManager().globalContainerChanged.emit()
|
||||
|
||||
@pyqtSlot()
|
||||
def updateHasMaterialsMetadata(self):
|
||||
def updateHasMaterialsMetadata(self) -> None:
|
||||
global_stack = self._application.getMachineManager().activeMachine
|
||||
|
||||
# Updates the has_materials metadata flag after switching gcode flavor
|
||||
if not self._global_container_stack:
|
||||
if not global_stack:
|
||||
return
|
||||
|
||||
definition = self._global_container_stack.getBottom()
|
||||
definition = global_stack.getDefinition()
|
||||
if definition.getProperty("machine_gcode_flavor", "value") != "UltiGCode" or definition.getMetaDataEntry("has_materials", False):
|
||||
# In other words: only continue for the UM2 (extended), but not for the UM2+
|
||||
return
|
||||
|
||||
machine_manager = self._application.getMachineManager()
|
||||
material_manager = self._application.getMaterialManager()
|
||||
extruder_positions = list(self._global_container_stack.extruders.keys())
|
||||
has_materials = self._global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
|
||||
extruder_positions = list(global_stack.extruders.keys())
|
||||
has_materials = global_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
|
||||
|
||||
material_node = None
|
||||
if has_materials:
|
||||
self._global_container_stack.setMetaDataEntry("has_materials", True)
|
||||
global_stack.setMetaDataEntry("has_materials", True)
|
||||
else:
|
||||
# The metadata entry is stored in an ini, and ini files are parsed as strings only.
|
||||
# Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
|
||||
if "has_materials" in self._global_container_stack.getMetaData():
|
||||
self._global_container_stack.removeMetaDataEntry("has_materials")
|
||||
if "has_materials" in global_stack.getMetaData():
|
||||
global_stack.removeMetaDataEntry("has_materials")
|
||||
|
||||
# set materials
|
||||
for position in extruder_positions:
|
||||
if has_materials:
|
||||
material_node = material_manager.getDefaultMaterial(self._global_container_stack, position, None)
|
||||
material_node = material_manager.getDefaultMaterial(global_stack, position, None)
|
||||
machine_manager.setMaterial(position, material_node)
|
||||
|
||||
self._application.globalContainerStackChanged.emit()
|
||||
|
||||
@pyqtSlot(int)
|
||||
def updateMaterialForDiameter(self, extruder_position: int):
|
||||
def updateMaterialForDiameter(self, extruder_position: int) -> None:
|
||||
# Updates the material container to a material that matches the material diameter set for the printer
|
||||
self._application.getMachineManager().updateMaterialWithVariant(str(extruder_position))
|
||||
|
|
File diff suppressed because it is too large
Load diff
180
plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml
Normal file
180
plugins/MachineSettingsAction/MachineSettingsExtruderTab.qml
Normal file
|
@ -0,0 +1,180 @@
|
|||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
|
||||
//
|
||||
// This component contains the content for the "Welcome" page of the welcome on-boarding process.
|
||||
//
|
||||
Item
|
||||
{
|
||||
id: base
|
||||
UM.I18nCatalog { id: catalog; name: "cura" }
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
|
||||
property int labelWidth: 180
|
||||
property int controlWidth: UM.Theme.getSize("setting_control").width * 3 / 4
|
||||
property var labelFont: UM.Theme.getFont("medium")
|
||||
|
||||
property int columnWidth: (parent.width - 2 * UM.Theme.getSize("default_margin").width) / 2
|
||||
property int columnSpacing: 3
|
||||
property int propertyStoreIndex: manager.storeContainerIndex // definition_changes
|
||||
|
||||
property string extruderStackId: ""
|
||||
property int extruderPosition: 0
|
||||
property var forceUpdateFunction: manager.forceUpdate
|
||||
|
||||
function updateMaterialDiameter()
|
||||
{
|
||||
manager.updateMaterialForDiameter(extruderPosition)
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: upperBlock
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
|
||||
height: childrenRect.height
|
||||
|
||||
// =======================================
|
||||
// Left-side column "Nozzle Settings"
|
||||
// =======================================
|
||||
Column
|
||||
{
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
width: parent.width * 2 / 3
|
||||
|
||||
spacing: base.columnSpacing
|
||||
|
||||
Label // Title Label
|
||||
{
|
||||
text: catalog.i18nc("@title:label", "Nozzle Settings")
|
||||
font: UM.Theme.getFont("medium_bold")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Cura.NumericTextFieldWithUnit // "Nozzle size"
|
||||
{
|
||||
id: extruderNozzleSizeField
|
||||
visible: !Cura.MachineManager.hasVariants
|
||||
containerStackId: base.extruderStackId
|
||||
settingKey: "machine_nozzle_size"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Nozzle size")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.NumericTextFieldWithUnit // "Compatible material diameter"
|
||||
{
|
||||
id: extruderCompatibleMaterialDiameterField
|
||||
containerStackId: base.extruderStackId
|
||||
settingKey: "material_diameter"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Compatible material diameter")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
// Other modules won't automatically respond after the user changes the value, so we need to force it.
|
||||
afterOnEditingFinishedFunction: updateMaterialDiameter
|
||||
}
|
||||
|
||||
Cura.NumericTextFieldWithUnit // "Nozzle offset X"
|
||||
{
|
||||
id: extruderNozzleOffsetXField
|
||||
containerStackId: base.extruderStackId
|
||||
settingKey: "machine_nozzle_offset_x"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Nozzle offset X")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.NumericTextFieldWithUnit // "Nozzle offset Y"
|
||||
{
|
||||
id: extruderNozzleOffsetYField
|
||||
containerStackId: base.extruderStackId
|
||||
settingKey: "machine_nozzle_offset_y"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Nozzle offset Y")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.NumericTextFieldWithUnit // "Cooling Fan Number"
|
||||
{
|
||||
id: extruderNozzleCoolingFanNumberField
|
||||
containerStackId: base.extruderStackId
|
||||
settingKey: "machine_extruder_cooling_fan_number"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Cooling Fan Number")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: ""
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item // Extruder Start and End G-code
|
||||
{
|
||||
id: lowerBlock
|
||||
anchors.top: upperBlock.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Cura.GcodeTextArea // "Extruder Start G-code"
|
||||
{
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.left: parent.left
|
||||
width: base.columnWidth - UM.Theme.getSize("default_margin").width
|
||||
|
||||
labelText: catalog.i18nc("@title:label", "Extruder Start G-code")
|
||||
containerStackId: base.extruderStackId
|
||||
settingKey: "machine_extruder_start_code"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
}
|
||||
|
||||
Cura.GcodeTextArea // "Extruder End G-code"
|
||||
{
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.right: parent.right
|
||||
width: base.columnWidth - UM.Theme.getSize("default_margin").width
|
||||
|
||||
labelText: catalog.i18nc("@title:label", "Extruder End G-code")
|
||||
containerStackId: base.extruderStackId
|
||||
settingKey: "machine_extruder_end_code"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
}
|
||||
}
|
||||
}
|
339
plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml
Normal file
339
plugins/MachineSettingsAction/MachineSettingsPrinterTab.qml
Normal file
|
@ -0,0 +1,339 @@
|
|||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
|
||||
//
|
||||
// This the content in the "Printer" tab in the Machine Settings dialog.
|
||||
//
|
||||
Item
|
||||
{
|
||||
id: base
|
||||
UM.I18nCatalog { id: catalog; name: "cura" }
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
|
||||
property int labelWidth: 130
|
||||
property int controlWidth: UM.Theme.getSize("setting_control").width * 3 / 4
|
||||
property var labelFont: UM.Theme.getFont("default")
|
||||
|
||||
property int columnWidth: (parent.width - 2 * UM.Theme.getSize("default_margin").width) / 2
|
||||
property int columnSpacing: 3
|
||||
property int propertyStoreIndex: manager.storeContainerIndex // definition_changes
|
||||
|
||||
property string machineStackId: Cura.MachineManager.activeMachineId
|
||||
|
||||
property var forceUpdateFunction: manager.forceUpdate
|
||||
|
||||
Item
|
||||
{
|
||||
id: upperBlock
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
|
||||
height: childrenRect.height
|
||||
|
||||
// =======================================
|
||||
// Left-side column for "Printer Settings"
|
||||
// =======================================
|
||||
Column
|
||||
{
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
width: base.columnWidth
|
||||
|
||||
spacing: base.columnSpacing
|
||||
|
||||
Label // Title Label
|
||||
{
|
||||
text: catalog.i18nc("@title:label", "Printer Settings")
|
||||
font: UM.Theme.getFont("medium_bold")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Cura.NumericTextFieldWithUnit // "X (Width)"
|
||||
{
|
||||
id: machineXWidthField
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_width"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "X (Width)")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.NumericTextFieldWithUnit // "Y (Depth)"
|
||||
{
|
||||
id: machineYDepthField
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_depth"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Y (Depth)")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.NumericTextFieldWithUnit // "Z (Height)"
|
||||
{
|
||||
id: machineZHeightField
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_height"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Z (Height)")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.ComboBoxWithOptions // "Build plate shape"
|
||||
{
|
||||
id: buildPlateShapeComboBox
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_shape"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Build plate shape")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.SimpleCheckBox // "Origin at center"
|
||||
{
|
||||
id: originAtCenterCheckBox
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_center_is_zero"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Origin at center")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.SimpleCheckBox // "Heated bed"
|
||||
{
|
||||
id: heatedBedCheckBox
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_heated_bed"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Heated bed")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.ComboBoxWithOptions // "G-code flavor"
|
||||
{
|
||||
id: gcodeFlavorComboBox
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_gcode_flavor"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "G-code flavor")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
// FIXME(Lipu): better document this.
|
||||
// This has something to do with UM2 and UM2+ regarding "has_material" and the gcode flavor settings.
|
||||
// I don't remember exactly what.
|
||||
afterOnEditingFinishedFunction: manager.updateHasMaterialsMetadata
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// Right-side column for "Printhead Settings"
|
||||
// =======================================
|
||||
Column
|
||||
{
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
width: base.columnWidth
|
||||
|
||||
spacing: base.columnSpacing
|
||||
|
||||
Label // Title Label
|
||||
{
|
||||
text: catalog.i18nc("@title:label", "Printhead Settings")
|
||||
font: UM.Theme.getFont("medium_bold")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Cura.PrintHeadMinMaxTextField // "X min"
|
||||
{
|
||||
id: machineXMinField
|
||||
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
|
||||
labelText: catalog.i18nc("@label", "X min")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
|
||||
axisName: "x"
|
||||
axisMinOrMax: "min"
|
||||
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.PrintHeadMinMaxTextField // "Y min"
|
||||
{
|
||||
id: machineYMinField
|
||||
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
|
||||
labelText: catalog.i18nc("@label", "Y min")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
|
||||
axisName: "y"
|
||||
axisMinOrMax: "min"
|
||||
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.PrintHeadMinMaxTextField // "X max"
|
||||
{
|
||||
id: machineXMaxField
|
||||
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
|
||||
labelText: catalog.i18nc("@label", "X max")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
|
||||
axisName: "x"
|
||||
axisMinOrMax: "max"
|
||||
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.PrintHeadMinMaxTextField // "Y max"
|
||||
{
|
||||
id: machineYMaxField
|
||||
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_head_with_fans_polygon"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
|
||||
labelText: catalog.i18nc("@label", "Y max")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
|
||||
axisName: "y"
|
||||
axisMinOrMax: "max"
|
||||
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.NumericTextFieldWithUnit // "Gantry Height"
|
||||
{
|
||||
id: machineGantryHeightField
|
||||
containerStackId: machineStackId
|
||||
settingKey: "gantry_height"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Gantry Height")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
unitText: catalog.i18nc("@label", "mm")
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
|
||||
Cura.ComboBoxWithOptions // "Number of Extruders"
|
||||
{
|
||||
id: numberOfExtrudersComboBox
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_extruder_count"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Number of Extruders")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
controlWidth: base.controlWidth
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
// FIXME(Lipu): better document this.
|
||||
// This has something to do with UM2 and UM2+ regarding "has_material" and the gcode flavor settings.
|
||||
// I don't remember exactly what.
|
||||
afterOnEditingFinishedFunction: manager.updateHasMaterialsMetadata
|
||||
setValueFunction: manager.setMachineExtruderCount
|
||||
|
||||
optionModel: ListModel
|
||||
{
|
||||
id: extruderCountModel
|
||||
Component.onCompleted:
|
||||
{
|
||||
extruderCountModel.clear()
|
||||
for (var i = 1; i <= Cura.MachineManager.activeMachine.maxExtruderCount; i++)
|
||||
{
|
||||
// Use String as value. JavaScript only has Number. PropertyProvider.setPropertyValue()
|
||||
// takes a QVariant as value, and Number gets translated into a float. This will cause problem
|
||||
// for integer settings such as "Number of Extruders".
|
||||
extruderCountModel.append({ text: String(i), value: String(i) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item // Start and End G-code
|
||||
{
|
||||
id: lowerBlock
|
||||
anchors.top: upperBlock.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Cura.GcodeTextArea // "Start G-code"
|
||||
{
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.left: parent.left
|
||||
width: base.columnWidth - UM.Theme.getSize("default_margin").width
|
||||
|
||||
labelText: catalog.i18nc("@title:label", "Start G-code")
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_start_gcode"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
}
|
||||
|
||||
Cura.GcodeTextArea // "End G-code"
|
||||
{
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.right: parent.right
|
||||
width: base.columnWidth - UM.Theme.getSize("default_margin").width
|
||||
|
||||
labelText: catalog.i18nc("@title:label", "End G-code")
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_end_gcode"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,8 +2,6 @@
|
|||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import os.path
|
||||
from UM.Application import Application
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Resources import Resources
|
||||
from cura.Stages.CuraStage import CuraStage
|
||||
|
||||
|
||||
|
|
|
@ -48,20 +48,6 @@ class SliceInfo(QObject, Extension):
|
|||
def _onAppInitialized(self):
|
||||
# DO NOT read any preferences values in the constructor because at the time plugins are created, no version
|
||||
# upgrade has been performed yet because version upgrades are plugins too!
|
||||
if not self._application.getPreferences().getValue("info/asked_send_slice_info"):
|
||||
self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymized usage statistics."),
|
||||
lifetime = 0,
|
||||
dismissable = False,
|
||||
title = catalog.i18nc("@info:title", "Collecting Data"))
|
||||
|
||||
self.send_slice_info_message.addAction("MoreInfo", name = catalog.i18nc("@action:button", "More info"), icon = None,
|
||||
description = catalog.i18nc("@action:tooltip", "See more information on what data Cura sends."), button_style = Message.ActionButtonStyle.LINK)
|
||||
|
||||
self.send_slice_info_message.addAction("Dismiss", name = catalog.i18nc("@action:button", "Allow"), icon = None,
|
||||
description = catalog.i18nc("@action:tooltip", "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."))
|
||||
self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered)
|
||||
self.send_slice_info_message.show()
|
||||
|
||||
if self._more_info_dialog is None:
|
||||
self._more_info_dialog = self._createDialog("MoreInfoWindow.qml")
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ class Toolbox(QObject, Extension):
|
|||
self._request_headers = [] # type: List[Tuple[bytes, bytes]]
|
||||
self._updateRequestHeader()
|
||||
|
||||
|
||||
self._request_urls = {} # type: Dict[str, QUrl]
|
||||
self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated
|
||||
self._old_plugin_ids = set() # type: Set[str]
|
||||
|
|
|
@ -371,7 +371,7 @@ Cura.MachineAction
|
|||
|
||||
Label
|
||||
{
|
||||
text: catalog.i18nc("@alabel", "Enter the IP address or hostname of your printer on the network.")
|
||||
text: catalog.i18nc("@label", "Enter the IP address or hostname of your printer on the network.")
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
renderType: Text.NativeRendering
|
||||
|
|
|
@ -22,7 +22,7 @@ Item
|
|||
width: childrenRect.width
|
||||
height: 18 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
ProgressBar
|
||||
UM.ProgressBar
|
||||
{
|
||||
id: progressBar
|
||||
anchors
|
||||
|
@ -30,22 +30,6 @@ Item
|
|||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
value: printJob ? printJob.progress : 0
|
||||
style: ProgressBarStyle
|
||||
{
|
||||
background: Rectangle
|
||||
{
|
||||
color: UM.Theme.getColor("monitor_progress_bar_empty")
|
||||
implicitHeight: visible ? 12 * screenScaleFactor : 0 // TODO: Theme!
|
||||
implicitWidth: 180 * screenScaleFactor // TODO: Theme!
|
||||
radius: 2 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
progress: Rectangle
|
||||
{
|
||||
id: progressItem;
|
||||
color: printJob && printJob.isActive ? UM.Theme.getColor("monitor_progress_bar_fill") : UM.Theme.getColor("monitor_progress_bar_deactive")
|
||||
radius: 2 * screenScaleFactor // TODO: Theme!
|
||||
}
|
||||
}
|
||||
}
|
||||
Label
|
||||
{
|
||||
|
|
|
@ -18,8 +18,8 @@ from UM.Scene.SceneNode import SceneNode
|
|||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutputDevice import ConnectionType
|
||||
from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
|
||||
|
||||
from .CloudOutputController import CloudOutputController
|
||||
from ..MeshFormatHandler import MeshFormatHandler
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import Union, Dict, Optional, Any
|
||||
|
||||
from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
|
||||
from cura.PrinterOutput.ExtruderOutputModel import ExtruderOutputModel
|
||||
from cura.PrinterOutput.Models.ExtruderConfigurationModel import ExtruderConfigurationModel
|
||||
from cura.PrinterOutput.Models.ExtruderOutputModel import ExtruderOutputModel
|
||||
from .CloudClusterPrinterConfigurationMaterial import CloudClusterPrinterConfigurationMaterial
|
||||
from .BaseCloudModel import BaseCloudModel
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import List, Optional, Union, Dict, Any
|
||||
|
||||
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||
from cura.PrinterOutput.Models.PrinterConfigurationModel import PrinterConfigurationModel
|
||||
from ...UM3PrintJobOutputModel import UM3PrintJobOutputModel
|
||||
from ...ConfigurationChangeModel import ConfigurationChangeModel
|
||||
from ..CloudOutputController import CloudOutputController
|
||||
|
@ -95,9 +95,9 @@ class CloudClusterPrintJobStatus(BaseCloudModel):
|
|||
return model
|
||||
|
||||
## Creates a new configuration model
|
||||
def _createConfigurationModel(self) -> ConfigurationModel:
|
||||
def _createConfigurationModel(self) -> PrinterConfigurationModel:
|
||||
extruders = [extruder.createConfigurationModel() for extruder in self.configuration or ()]
|
||||
configuration = ConfigurationModel()
|
||||
configuration = PrinterConfigurationModel()
|
||||
configuration.setExtruderConfigurations(extruders)
|
||||
return configuration
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ from typing import Optional
|
|||
|
||||
from UM.Logger import Logger
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
|
||||
from cura.PrinterOutput.Models.MaterialOutputModel import MaterialOutputModel
|
||||
from .BaseCloudModel import BaseCloudModel
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from typing import List, Union, Dict, Optional, Any
|
||||
|
||||
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
|
||||
from .CloudClusterBuildPlate import CloudClusterBuildPlate
|
||||
from .CloudClusterPrintCoreConfiguration import CloudClusterPrintCoreConfiguration
|
||||
from .BaseCloudModel import BaseCloudModel
|
||||
|
|
|
@ -19,12 +19,12 @@ from UM.Scene.SceneNode import SceneNode # For typing.
|
|||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||
from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
|
||||
from cura.PrinterOutput.Models.PrinterConfigurationModel import PrinterConfigurationModel
|
||||
from cura.PrinterOutput.Models.ExtruderConfigurationModel import ExtruderConfigurationModel
|
||||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
|
||||
from cura.PrinterOutputDevice import ConnectionType
|
||||
from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.Models.MaterialOutputModel import MaterialOutputModel
|
||||
from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
|
||||
|
||||
from .Cloud.Utils import formatTimeCompleted, formatDateCompleted
|
||||
from .ClusterUM3PrinterOutputController import ClusterUM3PrinterOutputController
|
||||
|
@ -522,7 +522,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
print_job = UM3PrintJobOutputModel(output_controller=ClusterUM3PrinterOutputController(self),
|
||||
key=data["uuid"], name= data["name"])
|
||||
|
||||
configuration = ConfigurationModel()
|
||||
configuration = PrinterConfigurationModel()
|
||||
extruders = [ExtruderConfigurationModel(position = idx) for idx in range(0, self._number_of_extruders)]
|
||||
for index in range(0, self._number_of_extruders):
|
||||
try:
|
||||
|
@ -633,6 +633,11 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
printer.updateKey(data["uuid"])
|
||||
printer.updateType(data["machine_variant"])
|
||||
|
||||
if data["status"] != "unreachable":
|
||||
self._application.getDiscoveredPrintersModel().updateDiscoveredPrinter(data["ip_address"],
|
||||
name = data["friendly_name"],
|
||||
machine_type = data["machine_variant"])
|
||||
|
||||
# Do not store the build plate information that comes from connect if the current printer has not build plate information
|
||||
if "build_plate" in data and machine_definition.getMetaDataEntry("has_variant_buildplates", False):
|
||||
printer.updateBuildplate(data["build_plate"]["type"])
|
||||
|
|
|
@ -5,7 +5,7 @@ from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
|||
|
||||
MYPY = False
|
||||
if MYPY:
|
||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||
from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
|
||||
|
||||
class ClusterUM3PrinterOutputController(PrinterOutputController):
|
||||
def __init__(self, output_device):
|
||||
|
|
|
@ -18,7 +18,7 @@ from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
|||
from .UM3OutputDevicePlugin import UM3OutputDevicePlugin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
@ -41,6 +41,11 @@ class DiscoverUM3Action(MachineAction):
|
|||
# Time to wait after a zero-conf service change before allowing a zeroconf reset
|
||||
self._zero_conf_change_grace_period = 0.25 #type: float
|
||||
|
||||
# Overrides the one in MachineAction.
|
||||
# This requires not attention from the user (any more), so we don't need to show any 'upgrade screens'.
|
||||
def needsUserInteraction(self) -> bool:
|
||||
return False
|
||||
|
||||
@pyqtSlot()
|
||||
def startDiscovery(self):
|
||||
if not self._network_plugin:
|
||||
|
@ -118,49 +123,14 @@ class DiscoverUM3Action(MachineAction):
|
|||
|
||||
if self._network_plugin:
|
||||
# Ensure that the connection states are refreshed.
|
||||
self._network_plugin.reCheckConnections()
|
||||
self._network_plugin.refreshConnections()
|
||||
|
||||
# Associates the currently active machine with the given printer device. The network connection information will be
|
||||
# stored into the metadata of the currently active machine.
|
||||
@pyqtSlot(QObject)
|
||||
def associateActiveMachineWithPrinterDevice(self, printer_device: Optional["PrinterOutputDevice"]) -> None:
|
||||
if not printer_device:
|
||||
return
|
||||
|
||||
Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key)
|
||||
|
||||
global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
|
||||
if not global_container_stack:
|
||||
return
|
||||
|
||||
meta_data = global_container_stack.getMetaData()
|
||||
|
||||
if "um_network_key" in meta_data: # Global stack already had a connection, but it's changed.
|
||||
old_network_key = meta_data["um_network_key"]
|
||||
# Since we might have a bunch of hidden stacks, we also need to change it there.
|
||||
metadata_filter = {"um_network_key": old_network_key}
|
||||
containers = CuraContainerRegistry.getInstance().findContainerStacks(type="machine", **metadata_filter)
|
||||
|
||||
for container in containers:
|
||||
container.setMetaDataEntry("um_network_key", printer_device.key)
|
||||
|
||||
# Delete old authentication data.
|
||||
Logger.log("d", "Removing old authentication id %s for device %s",
|
||||
global_container_stack.getMetaDataEntry("network_authentication_id", None), printer_device.key)
|
||||
|
||||
container.removeMetaDataEntry("network_authentication_id")
|
||||
container.removeMetaDataEntry("network_authentication_key")
|
||||
|
||||
# Ensure that these containers do know that they are configured for network connection
|
||||
container.addConfiguredConnectionType(printer_device.connectionType.value)
|
||||
|
||||
else: # Global stack didn't have a connection yet, configure it.
|
||||
global_container_stack.setMetaDataEntry("um_network_key", printer_device.key)
|
||||
global_container_stack.addConfiguredConnectionType(printer_device.connectionType.value)
|
||||
|
||||
if self._network_plugin:
|
||||
# Ensure that the connection states are refreshed.
|
||||
self._network_plugin.reCheckConnections()
|
||||
self._network_plugin.associateActiveMachineWithPrinterDevice(printer_device)
|
||||
|
||||
@pyqtSlot(result = str)
|
||||
def getStoredKey(self) -> str:
|
||||
|
|
|
@ -2,10 +2,10 @@ from typing import List, Optional
|
|||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
|
||||
from cura.PrinterOutputDevice import ConnectionType
|
||||
from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
|
||||
from cura.PrinterOutput.Models.MaterialOutputModel import MaterialOutputModel
|
||||
from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
|
||||
|
||||
from cura.Settings.ContainerManager import ContainerManager
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
|
|
@ -7,8 +7,8 @@ from UM.Version import Version
|
|||
|
||||
MYPY = False
|
||||
if MYPY:
|
||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
|
||||
from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
|
||||
|
||||
|
||||
class LegacyUM3PrinterOutputController(PrinterOutputController):
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import json
|
||||
import os
|
||||
from queue import Queue
|
||||
from threading import Event, Thread
|
||||
from time import time
|
||||
import os
|
||||
from typing import Optional, TYPE_CHECKING, Dict
|
||||
|
||||
from zeroconf import Zeroconf, ServiceBrowser, ServiceStateChange, ServiceInfo
|
||||
|
||||
from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager
|
||||
from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtGui import QDesktopServices
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutputDevice import ConnectionType
|
||||
from cura.Settings.GlobalStack import GlobalStack # typing
|
||||
from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
from UM.OutputDevice.OutputDeviceManager import ManualDeviceAdditionAttempt
|
||||
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Signal import Signal, signalemitter
|
||||
|
@ -26,17 +28,23 @@ from UM.Version import Version
|
|||
from . import ClusterUM3OutputDevice, LegacyUM3OutputDevice
|
||||
from .Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager
|
||||
|
||||
from typing import Optional
|
||||
if TYPE_CHECKING:
|
||||
from PyQt5.QtNetwork import QNetworkReply
|
||||
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
||||
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
|
||||
|
||||
i18n_catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
## This plugin handles the connection detection & creation of output device objects for the UM3 printer.
|
||||
# Zero-Conf is used to detect printers, which are saved in a dict.
|
||||
# If we discover a printer that has the same key as the active machine instance a connection is made.
|
||||
@signalemitter
|
||||
class UM3OutputDevicePlugin(OutputDevicePlugin):
|
||||
addDeviceSignal = Signal()
|
||||
removeDeviceSignal = Signal()
|
||||
addDeviceSignal = Signal() # Called '...Signal' to avoid confusion with function-names.
|
||||
removeDeviceSignal = Signal() # Ditto ^^^.
|
||||
discoveredDevicesChanged = Signal()
|
||||
cloudFlowIsPossible = Signal()
|
||||
|
||||
|
@ -55,7 +63,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
self.addDeviceSignal.connect(self._onAddDevice)
|
||||
self.removeDeviceSignal.connect(self._onRemoveDevice)
|
||||
|
||||
self._application.globalContainerStackChanged.connect(self.reCheckConnections)
|
||||
self._application.globalContainerStackChanged.connect(self.refreshConnections)
|
||||
|
||||
self._discovered_devices = {}
|
||||
|
||||
|
@ -142,7 +150,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
self.addManualDevice(address)
|
||||
self.resetLastManualDevice()
|
||||
|
||||
def reCheckConnections(self):
|
||||
def refreshConnections(self):
|
||||
active_machine = CuraApplication.getInstance().getGlobalContainerStack()
|
||||
if not active_machine:
|
||||
return
|
||||
|
@ -176,6 +184,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
self.checkCloudFlowIsPossible()
|
||||
else:
|
||||
self.getOutputDeviceManager().removeOutputDevice(key)
|
||||
if key.startswith("manual:"):
|
||||
self.removeManualDeviceSignal.emit(self.getPluginId(), key, self._discovered_devices[key].address)
|
||||
|
||||
def stop(self):
|
||||
if self._zero_conf is not None:
|
||||
|
@ -183,6 +193,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
self._zero_conf.close()
|
||||
self._cloud_output_device_manager.stop()
|
||||
|
||||
def canAddManualDevice(self, address: str = "") -> ManualDeviceAdditionAttempt:
|
||||
# This plugin should always be the fallback option (at least try it):
|
||||
return ManualDeviceAdditionAttempt.POSSIBLE
|
||||
|
||||
def removeManualDevice(self, key, address = None):
|
||||
if key in self._discovered_devices:
|
||||
if not address:
|
||||
|
@ -194,6 +208,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
self._manual_instances.remove(address)
|
||||
self._preferences.setValue("um3networkprinting/manual_instances", ",".join(self._manual_instances))
|
||||
|
||||
self.removeManualDeviceSignal.emit(self.getPluginId(), key, address)
|
||||
|
||||
def addManualDevice(self, address):
|
||||
if address not in self._manual_instances:
|
||||
self._manual_instances.append(address)
|
||||
|
@ -215,6 +231,61 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
|
||||
self._checkManualDevice(address)
|
||||
|
||||
def _createMachineFromDiscoveredPrinter(self, key: str) -> None:
|
||||
discovered_device = self._discovered_devices.get(key)
|
||||
if discovered_device is None:
|
||||
Logger.log("e", "Could not find discovered device with key [%s]", key)
|
||||
return
|
||||
|
||||
group_name = discovered_device.getProperty("name")
|
||||
machine_type_id = discovered_device.getProperty("printer_type")
|
||||
|
||||
Logger.log("i", "Creating machine from network device with key = [%s], group name = [%s], printer type = [%s]",
|
||||
key, group_name, machine_type_id)
|
||||
|
||||
self._application.getMachineManager().addMachine(machine_type_id, group_name)
|
||||
# connect the new machine to that network printer
|
||||
self.associateActiveMachineWithPrinterDevice(discovered_device)
|
||||
# ensure that the connection states are refreshed.
|
||||
self.refreshConnections()
|
||||
|
||||
def associateActiveMachineWithPrinterDevice(self, printer_device: Optional["PrinterOutputDevice"]) -> None:
|
||||
if not printer_device:
|
||||
return
|
||||
|
||||
Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key)
|
||||
|
||||
global_container_stack = CuraApplication.getInstance().getGlobalContainerStack()
|
||||
if not global_container_stack:
|
||||
return
|
||||
|
||||
meta_data = global_container_stack.getMetaData()
|
||||
|
||||
if "um_network_key" in meta_data: # Global stack already had a connection, but it's changed.
|
||||
old_network_key = meta_data["um_network_key"]
|
||||
# Since we might have a bunch of hidden stacks, we also need to change it there.
|
||||
metadata_filter = {"um_network_key": old_network_key}
|
||||
containers = self._application.getContainerRegistry().findContainerStacks(type = "machine", **metadata_filter)
|
||||
|
||||
for container in containers:
|
||||
container.setMetaDataEntry("um_network_key", printer_device.key)
|
||||
|
||||
# Delete old authentication data.
|
||||
Logger.log("d", "Removing old authentication id %s for device %s",
|
||||
global_container_stack.getMetaDataEntry("network_authentication_id", None), printer_device.key)
|
||||
|
||||
container.removeMetaDataEntry("network_authentication_id")
|
||||
container.removeMetaDataEntry("network_authentication_key")
|
||||
|
||||
# Ensure that these containers do know that they are configured for network connection
|
||||
container.addConfiguredConnectionType(printer_device.connectionType.value)
|
||||
|
||||
else: # Global stack didn't have a connection yet, configure it.
|
||||
global_container_stack.setMetaDataEntry("um_network_key", printer_device.key)
|
||||
global_container_stack.addConfiguredConnectionType(printer_device.connectionType.value)
|
||||
|
||||
self.refreshConnections()
|
||||
|
||||
def _checkManualDevice(self, address):
|
||||
# Check if a UM3 family device exists at this address.
|
||||
# If a printer responds, it will replace the preliminary printer created above
|
||||
|
@ -223,21 +294,29 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
name_request = QNetworkRequest(url)
|
||||
self._network_manager.get(name_request)
|
||||
|
||||
def _onNetworkRequestFinished(self, reply):
|
||||
def _onNetworkRequestFinished(self, reply: "QNetworkReply") -> None:
|
||||
reply_url = reply.url().toString()
|
||||
|
||||
if "system" in reply_url:
|
||||
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
|
||||
# Something went wrong with checking the firmware version!
|
||||
return
|
||||
address = reply.url().host()
|
||||
device = None
|
||||
properties = {} # type: Dict[bytes, bytes]
|
||||
|
||||
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
|
||||
# Either:
|
||||
# - Something went wrong with checking the firmware version!
|
||||
# - Something went wrong with checking the amount of printers the cluster has!
|
||||
# - Couldn't find printer at the address when trying to add it manually.
|
||||
if address in self._manual_instances:
|
||||
self.removeManualDeviceSignal.emit(self.getPluginId(), "", address)
|
||||
return
|
||||
|
||||
if "system" in reply_url:
|
||||
try:
|
||||
system_info = json.loads(bytes(reply.readAll()).decode("utf-8"))
|
||||
except:
|
||||
Logger.log("e", "Something went wrong converting the JSON.")
|
||||
return
|
||||
|
||||
address = reply.url().host()
|
||||
has_cluster_capable_firmware = Version(system_info["firmware"]) > self._min_cluster_version
|
||||
instance_name = "manual:%s" % address
|
||||
properties = {
|
||||
|
@ -265,16 +344,12 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
self._network_manager.get(cluster_request)
|
||||
|
||||
elif "printers" in reply_url:
|
||||
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
|
||||
# Something went wrong with checking the amount of printers the cluster has!
|
||||
return
|
||||
# So we confirmed that the device is in fact a cluster printer, and we should now know how big it is.
|
||||
try:
|
||||
cluster_printers_list = json.loads(bytes(reply.readAll()).decode("utf-8"))
|
||||
except:
|
||||
Logger.log("e", "Something went wrong converting the JSON.")
|
||||
return
|
||||
address = reply.url().host()
|
||||
instance_name = "manual:%s" % address
|
||||
if instance_name in self._discovered_devices:
|
||||
device = self._discovered_devices[instance_name]
|
||||
|
@ -285,7 +360,11 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
self._onRemoveDevice(instance_name)
|
||||
self._onAddDevice(instance_name, address, properties)
|
||||
|
||||
def _onRemoveDevice(self, device_id):
|
||||
if device and address in self._manual_instances:
|
||||
self.getOutputDeviceManager().addOutputDevice(device)
|
||||
self.addManualDeviceSignal.emit(self.getPluginId(), device.getId(), address, properties)
|
||||
|
||||
def _onRemoveDevice(self, device_id: str) -> None:
|
||||
device = self._discovered_devices.pop(device_id, None)
|
||||
if device:
|
||||
if device.isConnected():
|
||||
|
@ -295,7 +374,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
except TypeError:
|
||||
# Disconnect already happened.
|
||||
pass
|
||||
|
||||
self._application.getDiscoveredPrintersModel().removeDiscoveredPrinter(device.address)
|
||||
self.discoveredDevicesChanged.emit()
|
||||
|
||||
def _onAddDevice(self, name, address, properties):
|
||||
|
@ -320,7 +399,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
device = ClusterUM3OutputDevice.ClusterUM3OutputDevice(name, address, properties)
|
||||
else:
|
||||
device = LegacyUM3OutputDevice.LegacyUM3OutputDevice(name, address, properties)
|
||||
|
||||
self._application.getDiscoveredPrintersModel().addDiscoveredPrinter(address, device.getId(), name, self._createMachineFromDiscoveredPrinter, properties[b"printer_type"].decode("utf-8"), device)
|
||||
self._discovered_devices[device.getId()] = device
|
||||
self.discoveredDevicesChanged.emit()
|
||||
|
||||
|
@ -412,9 +491,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
Logger.log("d", "Checking if cloud connection is possible...")
|
||||
|
||||
# Pre-Check: Skip if active machine already has been cloud connected or you said don't ask again
|
||||
active_machine = self._application.getMachineManager().activeMachine # type: Optional["GlobalStack"]
|
||||
active_machine = self._application.getMachineManager().activeMachine # type: Optional[GlobalStack]
|
||||
if active_machine:
|
||||
|
||||
# Check 1A: Printer isn't already configured for cloud
|
||||
if ConnectionType.CloudConnection.value in active_machine.configuredConnectionTypes:
|
||||
Logger.log("d", "Active machine was already configured for cloud.")
|
||||
|
@ -486,7 +564,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
return
|
||||
|
||||
def _onDontAskMeAgain(self, checked: bool) -> None:
|
||||
active_machine = self._application.getMachineManager().activeMachine # type: Optional["GlobalStack"]
|
||||
active_machine = self._application.getMachineManager().activeMachine # type: Optional[GlobalStack]
|
||||
if active_machine:
|
||||
active_machine.setMetaDataEntry("do_not_show_cloud_message", checked)
|
||||
if checked:
|
||||
|
|
|
@ -5,7 +5,7 @@ from typing import List
|
|||
|
||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal
|
||||
|
||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||
from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
|
||||
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
||||
from .ConfigurationChangeModel import ConfigurationChangeModel
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ from unittest.mock import patch, MagicMock
|
|||
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from cura.UltimakerCloudAuthentication import CuraCloudAPIRoot
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
|
||||
from ...src.Cloud import CloudApiClient
|
||||
from ...src.Cloud.CloudOutputDevice import CloudOutputDevice
|
||||
from ...src.Cloud.Models.CloudClusterResponse import CloudClusterResponse
|
||||
|
|
|
@ -13,7 +13,7 @@ from time import sleep
|
|||
|
||||
MYPY = False
|
||||
if MYPY:
|
||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
|
||||
|
||||
|
||||
class AvrFirmwareUpdater(FirmwareUpdater):
|
||||
|
|
|
@ -10,9 +10,9 @@ from UM.PluginRegistry import PluginRegistry #To get the g-code output.
|
|||
from UM.Qt.Duration import DurationFormat
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType
|
||||
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
|
||||
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice, ConnectionState, ConnectionType
|
||||
from cura.PrinterOutput.Models.PrinterOutputModel import PrinterOutputModel
|
||||
from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
|
||||
from cura.PrinterOutput.GenericOutputController import GenericOutputController
|
||||
|
||||
from .AutoDetectBaudJob import AutoDetectBaudJob
|
||||
|
|
|
@ -5,15 +5,13 @@ import threading
|
|||
import time
|
||||
import serial.tools.list_ports
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
|
||||
from PyQt5.QtCore import QObject, pyqtSignal
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.Signal import Signal, signalemitter
|
||||
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
from cura.PrinterOutputDevice import ConnectionState
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.PrinterOutputDevice import ConnectionState
|
||||
|
||||
from . import USBPrinterOutputDevice
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
from typing import List
|
||||
|
||||
from cura.MachineAction import MachineAction
|
||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
|
||||
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
|
||||
|
|
|
@ -1,24 +1,27 @@
|
|||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
|
||||
Cura.MachineAction
|
||||
{
|
||||
anchors.fill: parent;
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Item
|
||||
{
|
||||
id: bedLevelMachineAction
|
||||
anchors.fill: parent;
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height * 3
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width * 3 / 4
|
||||
|
||||
Label
|
||||
{
|
||||
|
@ -26,17 +29,21 @@ Cura.MachineAction
|
|||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Build Plate Leveling")
|
||||
wrapMode: Text.WordWrap
|
||||
font.pointSize: 18;
|
||||
font.pointSize: 18
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: pageDescription
|
||||
anchors.top: pageTitle.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height * 3
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "To make sure your prints will come out great, you can now adjust your buildplate. When you click 'Move to Next Position' the nozzle will move to the different positions that can be adjusted.")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: bedlevelingText
|
||||
|
@ -45,37 +52,38 @@ Cura.MachineAction
|
|||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle.")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
id: bedlevelingWrapper
|
||||
anchors.top: bedlevelingText.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height * 3
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: childrenRect.width
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Button
|
||||
Cura.ActionButton
|
||||
{
|
||||
id: startBedLevelingButton
|
||||
text: catalog.i18nc("@action:button","Start Build Plate Leveling")
|
||||
text: catalog.i18nc("@action:button", "Start Build Plate Leveling")
|
||||
onClicked:
|
||||
{
|
||||
startBedLevelingButton.visible = false;
|
||||
bedlevelingButton.visible = true;
|
||||
manager.startBedLeveling();
|
||||
startBedLevelingButton.visible = false
|
||||
bedlevelingButton.visible = true
|
||||
manager.startBedLeveling()
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
Cura.ActionButton
|
||||
{
|
||||
id: bedlevelingButton
|
||||
text: catalog.i18nc("@action:button","Move to Next Position")
|
||||
text: catalog.i18nc("@action:button", "Move to Next Position")
|
||||
visible: false
|
||||
onClicked:
|
||||
{
|
||||
manager.moveToNextLevelPosition();
|
||||
manager.moveToNextLevelPosition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Uranium is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from cura.MachineAction import MachineAction
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtProperty
|
||||
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Application import Application
|
||||
from UM.Util import parseBool
|
||||
|
||||
from cura.MachineAction import MachineAction
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
|
|
|
@ -1,32 +1,24 @@
|
|||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
|
||||
Cura.MachineAction
|
||||
{
|
||||
anchors.fill: parent;
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
anchors.fill: parent
|
||||
|
||||
Item
|
||||
{
|
||||
id: upgradeSelectionMachineAction
|
||||
anchors.fill: parent
|
||||
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Select Printer Upgrades")
|
||||
wrapMode: Text.WordWrap
|
||||
font.pointSize: 18;
|
||||
}
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").width * 5
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width * 4
|
||||
|
||||
Label
|
||||
{
|
||||
|
@ -35,15 +27,19 @@ Cura.MachineAction
|
|||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker 2.");
|
||||
text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker 2.")
|
||||
font: UM.Theme.getFont("medium")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
CheckBox
|
||||
Cura.CheckBox
|
||||
{
|
||||
id: olssonBlockCheckBox
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
|
||||
height: UM.Theme.getSize("setting_control").height
|
||||
|
||||
text: catalog.i18nc("@label", "Olsson Block")
|
||||
checked: manager.hasVariants
|
||||
onClicked: manager.hasVariants = checked
|
||||
|
@ -54,7 +50,5 @@ Cura.MachineAction
|
|||
onHasVariantsChanged: olssonBlockCheckBox.checked = manager.hasVariants
|
||||
}
|
||||
}
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
from cura.MachineAction import MachineAction
|
||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||
from UM.Application import Application
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
## Action to check up if the self-built UMO was done correctly.
|
||||
class UMOCheckupMachineAction(MachineAction):
|
||||
def __init__(self):
|
||||
super().__init__("UMOCheckup", catalog.i18nc("@action", "Checkup"))
|
||||
self._qml_url = "UMOCheckupMachineAction.qml"
|
||||
self._hotend_target_temp = 180
|
||||
self._bed_target_temp = 60
|
||||
self._output_device = None
|
||||
self._bed_test_completed = False
|
||||
self._hotend_test_completed = False
|
||||
|
||||
# Endstop tests
|
||||
self._x_min_endstop_test_completed = False
|
||||
self._y_min_endstop_test_completed = False
|
||||
self._z_min_endstop_test_completed = False
|
||||
|
||||
self._check_started = False
|
||||
|
||||
Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
|
||||
|
||||
onBedTestCompleted = pyqtSignal()
|
||||
onHotendTestCompleted = pyqtSignal()
|
||||
|
||||
onXMinEndstopTestCompleted = pyqtSignal()
|
||||
onYMinEndstopTestCompleted = pyqtSignal()
|
||||
onZMinEndstopTestCompleted = pyqtSignal()
|
||||
|
||||
bedTemperatureChanged = pyqtSignal()
|
||||
hotendTemperatureChanged = pyqtSignal()
|
||||
|
||||
def _onOutputDevicesChanged(self):
|
||||
# Check if this action was started, but no output device was found the first time.
|
||||
# If so, re-try now that an output device has been added/removed.
|
||||
if self._output_device is None and self._check_started:
|
||||
self.startCheck()
|
||||
|
||||
def _getPrinterOutputDevices(self):
|
||||
return [printer_output_device for printer_output_device in
|
||||
Application.getInstance().getOutputDeviceManager().getOutputDevices() if
|
||||
isinstance(printer_output_device, PrinterOutputDevice)]
|
||||
|
||||
def _reset(self):
|
||||
if self._output_device:
|
||||
self._output_device.bedTemperatureChanged.disconnect(self.bedTemperatureChanged)
|
||||
self._output_device.hotendTemperaturesChanged.disconnect(self.hotendTemperatureChanged)
|
||||
self._output_device.bedTemperatureChanged.disconnect(self._onBedTemperatureChanged)
|
||||
self._output_device.hotendTemperaturesChanged.disconnect(self._onHotendTemperatureChanged)
|
||||
self._output_device.endstopStateChanged.disconnect(self._onEndstopStateChanged)
|
||||
try:
|
||||
self._output_device.stopPollEndstop()
|
||||
except AttributeError as e: # Connection is probably not a USB connection. Something went pretty wrong if this happens.
|
||||
Logger.log("e", "An exception occurred while stopping end stop polling: %s" % str(e))
|
||||
|
||||
self._output_device = None
|
||||
|
||||
self._check_started = False
|
||||
self.checkStartedChanged.emit()
|
||||
|
||||
# Ensure everything is reset (and right signals are emitted again)
|
||||
self._bed_test_completed = False
|
||||
self.onBedTestCompleted.emit()
|
||||
self._hotend_test_completed = False
|
||||
self.onHotendTestCompleted.emit()
|
||||
|
||||
self._x_min_endstop_test_completed = False
|
||||
self.onXMinEndstopTestCompleted.emit()
|
||||
self._y_min_endstop_test_completed = False
|
||||
self.onYMinEndstopTestCompleted.emit()
|
||||
self._z_min_endstop_test_completed = False
|
||||
self.onZMinEndstopTestCompleted.emit()
|
||||
|
||||
self.heatedBedChanged.emit()
|
||||
|
||||
@pyqtProperty(bool, notify = onBedTestCompleted)
|
||||
def bedTestCompleted(self):
|
||||
return self._bed_test_completed
|
||||
|
||||
@pyqtProperty(bool, notify = onHotendTestCompleted)
|
||||
def hotendTestCompleted(self):
|
||||
return self._hotend_test_completed
|
||||
|
||||
@pyqtProperty(bool, notify = onXMinEndstopTestCompleted)
|
||||
def xMinEndstopTestCompleted(self):
|
||||
return self._x_min_endstop_test_completed
|
||||
|
||||
@pyqtProperty(bool, notify=onYMinEndstopTestCompleted)
|
||||
def yMinEndstopTestCompleted(self):
|
||||
return self._y_min_endstop_test_completed
|
||||
|
||||
@pyqtProperty(bool, notify=onZMinEndstopTestCompleted)
|
||||
def zMinEndstopTestCompleted(self):
|
||||
return self._z_min_endstop_test_completed
|
||||
|
||||
@pyqtProperty(float, notify = bedTemperatureChanged)
|
||||
def bedTemperature(self):
|
||||
if not self._output_device:
|
||||
return 0
|
||||
return self._output_device.bedTemperature
|
||||
|
||||
@pyqtProperty(float, notify=hotendTemperatureChanged)
|
||||
def hotendTemperature(self):
|
||||
if not self._output_device:
|
||||
return 0
|
||||
return self._output_device.hotendTemperatures[0]
|
||||
|
||||
def _onHotendTemperatureChanged(self):
|
||||
if not self._output_device:
|
||||
return
|
||||
if not self._hotend_test_completed:
|
||||
if self._output_device.hotendTemperatures[0] + 10 > self._hotend_target_temp and self._output_device.hotendTemperatures[0] - 10 < self._hotend_target_temp:
|
||||
self._hotend_test_completed = True
|
||||
self.onHotendTestCompleted.emit()
|
||||
|
||||
def _onBedTemperatureChanged(self):
|
||||
if not self._output_device:
|
||||
return
|
||||
if not self._bed_test_completed:
|
||||
if self._output_device.bedTemperature + 5 > self._bed_target_temp and self._output_device.bedTemperature - 5 < self._bed_target_temp:
|
||||
self._bed_test_completed = True
|
||||
self.onBedTestCompleted.emit()
|
||||
|
||||
def _onEndstopStateChanged(self, switch_type, state):
|
||||
if state:
|
||||
if switch_type == "x_min":
|
||||
self._x_min_endstop_test_completed = True
|
||||
self.onXMinEndstopTestCompleted.emit()
|
||||
elif switch_type == "y_min":
|
||||
self._y_min_endstop_test_completed = True
|
||||
self.onYMinEndstopTestCompleted.emit()
|
||||
elif switch_type == "z_min":
|
||||
self._z_min_endstop_test_completed = True
|
||||
self.onZMinEndstopTestCompleted.emit()
|
||||
|
||||
checkStartedChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty(bool, notify = checkStartedChanged)
|
||||
def checkStarted(self):
|
||||
return self._check_started
|
||||
|
||||
@pyqtSlot()
|
||||
def startCheck(self):
|
||||
self._check_started = True
|
||||
self.checkStartedChanged.emit()
|
||||
output_devices = self._getPrinterOutputDevices()
|
||||
if output_devices:
|
||||
self._output_device = output_devices[0]
|
||||
try:
|
||||
self._output_device.sendCommand("M18") # Turn off all motors so the user can move the axes
|
||||
self._output_device.startPollEndstop()
|
||||
self._output_device.bedTemperatureChanged.connect(self.bedTemperatureChanged)
|
||||
self._output_device.hotendTemperaturesChanged.connect(self.hotendTemperatureChanged)
|
||||
self._output_device.bedTemperatureChanged.connect(self._onBedTemperatureChanged)
|
||||
self._output_device.hotendTemperaturesChanged.connect(self._onHotendTemperatureChanged)
|
||||
self._output_device.endstopStateChanged.connect(self._onEndstopStateChanged)
|
||||
except AttributeError as e: # Connection is probably not a USB connection. Something went pretty wrong if this happens.
|
||||
Logger.log("e", "An exception occurred while starting end stop polling: %s" % str(e))
|
||||
|
||||
@pyqtSlot()
|
||||
def cooldownHotend(self):
|
||||
if self._output_device is not None:
|
||||
self._output_device.setTargetHotendTemperature(0, 0)
|
||||
|
||||
@pyqtSlot()
|
||||
def cooldownBed(self):
|
||||
if self._output_device is not None:
|
||||
self._output_device.setTargetBedTemperature(0)
|
||||
|
||||
@pyqtSlot()
|
||||
def heatupHotend(self):
|
||||
if self._output_device is not None:
|
||||
self._output_device.setTargetHotendTemperature(0, self._hotend_target_temp)
|
||||
|
||||
@pyqtSlot()
|
||||
def heatupBed(self):
|
||||
if self._output_device is not None:
|
||||
self._output_device.setTargetBedTemperature(self._bed_target_temp)
|
||||
|
||||
heatedBedChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty(bool, notify = heatedBedChanged)
|
||||
def hasHeatedBed(self):
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
return global_container_stack.getProperty("machine_heated_bed", "value")
|
|
@ -1,288 +0,0 @@
|
|||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
Cura.MachineAction
|
||||
{
|
||||
anchors.fill: parent;
|
||||
Item
|
||||
{
|
||||
id: checkupMachineAction
|
||||
anchors.fill: parent;
|
||||
property int leftRow: (checkupMachineAction.width * 0.40) | 0
|
||||
property int rightRow: (checkupMachineAction.width * 0.60) | 0
|
||||
property bool heatupHotendStarted: false
|
||||
property bool heatupBedStarted: false
|
||||
property bool printerConnected: Cura.MachineManager.printerConnected
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"}
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Check Printer")
|
||||
wrapMode: Text.WordWrap
|
||||
font.pointSize: 18;
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: pageDescription
|
||||
anchors.top: pageTitle.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional");
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
id: startStopButtons
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: childrenRect.width
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
Button
|
||||
{
|
||||
id: startCheckButton
|
||||
text: catalog.i18nc("@action:button","Start Printer Check");
|
||||
onClicked:
|
||||
{
|
||||
checkupMachineAction.heatupHotendStarted = false;
|
||||
checkupMachineAction.heatupBedStarted = false;
|
||||
manager.startCheck();
|
||||
startCheckButton.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: checkupContent
|
||||
anchors.top: startStopButtons.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
visible: manager.checkStarted
|
||||
width: parent.width
|
||||
height: 250
|
||||
//////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: connectionLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Connection: ")
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: connectionStatus
|
||||
width: checkupMachineAction.rightRow
|
||||
anchors.left: connectionLabel.right
|
||||
anchors.top: parent.top
|
||||
wrapMode: Text.WordWrap
|
||||
text: checkupMachineAction.printerConnected ? catalog.i18nc("@info:status","Connected"): catalog.i18nc("@info:status","Not connected")
|
||||
}
|
||||
//////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: endstopXLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: connectionLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Min endstop X: ")
|
||||
visible: checkupMachineAction.printerConnected
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: endstopXStatus
|
||||
width: checkupMachineAction.rightRow
|
||||
anchors.left: endstopXLabel.right
|
||||
anchors.top: connectionLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: manager.xMinEndstopTestCompleted ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
||||
visible: checkupMachineAction.printerConnected
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: endstopYLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: endstopXLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Min endstop Y: ")
|
||||
visible: checkupMachineAction.printerConnected
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: endstopYStatus
|
||||
width: checkupMachineAction.rightRow
|
||||
anchors.left: endstopYLabel.right
|
||||
anchors.top: endstopXLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: manager.yMinEndstopTestCompleted ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
||||
visible: checkupMachineAction.printerConnected
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: endstopZLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: endstopYLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Min endstop Z: ")
|
||||
visible: checkupMachineAction.printerConnected
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: endstopZStatus
|
||||
width: checkupMachineAction.rightRow
|
||||
anchors.left: endstopZLabel.right
|
||||
anchors.top: endstopYLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: manager.zMinEndstopTestCompleted ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
||||
visible: checkupMachineAction.printerConnected
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: nozzleTempLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
height: nozzleTempButton.height
|
||||
anchors.left: parent.left
|
||||
anchors.top: endstopZLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Nozzle temperature check: ")
|
||||
visible: checkupMachineAction.printerConnected
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: nozzleTempStatus
|
||||
width: (checkupMachineAction.rightRow * 0.4) | 0
|
||||
anchors.top: nozzleTempLabel.top
|
||||
anchors.left: nozzleTempLabel.right
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@info:status","Not checked")
|
||||
visible: checkupMachineAction.printerConnected
|
||||
}
|
||||
Item
|
||||
{
|
||||
id: nozzleTempButton
|
||||
width: (checkupMachineAction.rightRow * 0.3) | 0
|
||||
height: childrenRect.height
|
||||
anchors.top: nozzleTempLabel.top
|
||||
anchors.left: bedTempStatus.right
|
||||
anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width/2)
|
||||
visible: checkupMachineAction.printerConnected
|
||||
Button
|
||||
{
|
||||
text: checkupMachineAction.heatupHotendStarted ? catalog.i18nc("@action:button","Stop Heating") : catalog.i18nc("@action:button","Start Heating")
|
||||
onClicked:
|
||||
{
|
||||
if (checkupMachineAction.heatupHotendStarted)
|
||||
{
|
||||
manager.cooldownHotend()
|
||||
checkupMachineAction.heatupHotendStarted = false
|
||||
} else
|
||||
{
|
||||
manager.heatupHotend()
|
||||
checkupMachineAction.heatupHotendStarted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: nozzleTemp
|
||||
anchors.top: nozzleTempLabel.top
|
||||
anchors.left: nozzleTempButton.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
width: (checkupMachineAction.rightRow * 0.2) | 0
|
||||
wrapMode: Text.WordWrap
|
||||
text: manager.hotendTemperature + "°C"
|
||||
font.bold: true
|
||||
visible: checkupMachineAction.printerConnected
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: bedTempLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
height: bedTempButton.height
|
||||
anchors.left: parent.left
|
||||
anchors.top: nozzleTempLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Build plate temperature check:")
|
||||
visible: checkupMachineAction.printerConnected && manager.hasHeatedBed
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: bedTempStatus
|
||||
width: (checkupMachineAction.rightRow * 0.4) | 0
|
||||
anchors.top: bedTempLabel.top
|
||||
anchors.left: bedTempLabel.right
|
||||
wrapMode: Text.WordWrap
|
||||
text: manager.bedTestCompleted ? catalog.i18nc("@info:status","Not checked"): catalog.i18nc("@info:status","Checked")
|
||||
visible: checkupMachineAction.printerConnected && manager.hasHeatedBed
|
||||
}
|
||||
Item
|
||||
{
|
||||
id: bedTempButton
|
||||
width: (checkupMachineAction.rightRow * 0.3) | 0
|
||||
height: childrenRect.height
|
||||
anchors.top: bedTempLabel.top
|
||||
anchors.left: bedTempStatus.right
|
||||
anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width/2)
|
||||
visible: checkupMachineAction.printerConnected && manager.hasHeatedBed
|
||||
Button
|
||||
{
|
||||
text: checkupMachineAction.heatupBedStarted ?catalog.i18nc("@action:button","Stop Heating") : catalog.i18nc("@action:button","Start Heating")
|
||||
onClicked:
|
||||
{
|
||||
if (checkupMachineAction.heatupBedStarted)
|
||||
{
|
||||
manager.cooldownBed()
|
||||
checkupMachineAction.heatupBedStarted = false
|
||||
} else
|
||||
{
|
||||
manager.heatupBed()
|
||||
checkupMachineAction.heatupBedStarted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: bedTemp
|
||||
width: (checkupMachineAction.rightRow * 0.2) | 0
|
||||
anchors.top: bedTempLabel.top
|
||||
anchors.left: bedTempButton.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
wrapMode: Text.WordWrap
|
||||
text: manager.bedTemperature + "°C"
|
||||
font.bold: true
|
||||
visible: checkupMachineAction.printerConnected && manager.hasHeatedBed
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: resultText
|
||||
visible: false
|
||||
anchors.top: bedTemp.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.left: parent.left
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "Everything is in order! You're done with your CheckUp.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +1,38 @@
|
|||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
|
||||
Cura.MachineAction
|
||||
{
|
||||
anchors.fill: parent;
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
anchors.fill: parent
|
||||
|
||||
Item
|
||||
{
|
||||
id: upgradeSelectionMachineAction
|
||||
anchors.fill: parent
|
||||
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Select Printer Upgrades")
|
||||
wrapMode: Text.WordWrap
|
||||
font.pointSize: 18;
|
||||
}
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").width * 5
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width * 4
|
||||
|
||||
Label
|
||||
{
|
||||
id: pageDescription
|
||||
anchors.top: pageTitle.bottom
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker Original");
|
||||
text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker Original")
|
||||
font: UM.Theme.getFont("medium")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
CheckBox
|
||||
Cura.CheckBox
|
||||
{
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
|
@ -46,7 +41,5 @@ Cura.MachineAction
|
|||
checked: manager.hasHeatedBed
|
||||
onClicked: manager.setHeatedBed(checked)
|
||||
}
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import os
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSlot
|
||||
|
||||
from UM.Extension import Extension
|
||||
from UM.Logger import Logger
|
||||
|
||||
|
||||
class UserAgreement(QObject, Extension):
|
||||
def __init__(self, application):
|
||||
super(UserAgreement, self).__init__()
|
||||
self._application = application
|
||||
self._user_agreement_window = None
|
||||
self._user_agreement_context = None
|
||||
self._application.engineCreatedSignal.connect(self._onEngineCreated)
|
||||
|
||||
self._application.getPreferences().addPreference("general/accepted_user_agreement", False)
|
||||
|
||||
def _onEngineCreated(self):
|
||||
if not self._application.getPreferences().getValue("general/accepted_user_agreement"):
|
||||
self.showUserAgreement()
|
||||
|
||||
def showUserAgreement(self):
|
||||
if not self._user_agreement_window:
|
||||
self.createUserAgreementWindow()
|
||||
|
||||
self._user_agreement_window.show()
|
||||
|
||||
@pyqtSlot(bool)
|
||||
def didAgree(self, user_choice):
|
||||
if user_choice:
|
||||
Logger.log("i", "User agreed to the user agreement")
|
||||
self._application.getPreferences().setValue("general/accepted_user_agreement", True)
|
||||
self._user_agreement_window.hide()
|
||||
else:
|
||||
Logger.log("i", "User did NOT agree to the user agreement")
|
||||
self._application.getPreferences().setValue("general/accepted_user_agreement", False)
|
||||
self._application.quit()
|
||||
self._application.setNeedToShowUserAgreement(False)
|
||||
|
||||
def createUserAgreementWindow(self):
|
||||
path = os.path.join(self._application.getPluginRegistry().getPluginPath(self.getPluginId()), "UserAgreement.qml")
|
||||
self._user_agreement_window = self._application.createQmlComponent(path, {"manager": self})
|
|
@ -1,63 +0,0 @@
|
|||
// Copyright (c) 2017 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.4
|
||||
|
||||
import UM 1.3 as UM
|
||||
|
||||
UM.Dialog
|
||||
{
|
||||
id: baseDialog
|
||||
minimumWidth: Math.round(UM.Theme.getSize("modal_window_minimum").width * 0.75)
|
||||
minimumHeight: Math.round(UM.Theme.getSize("modal_window_minimum").height * 0.5)
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
title: catalog.i18nc("@title:window", "User Agreement")
|
||||
|
||||
TextArea
|
||||
{
|
||||
anchors.top: parent.top
|
||||
width: parent.width
|
||||
anchors.bottom: buttonRow.top
|
||||
text: ' <center><h3>DISCLAIMER BY ULTIMAKER</h3></center>
|
||||
<p>PLEASE READ THIS DISCLAIMER CAREFULLY.</p>
|
||||
<p>EXCEPT WHEN OTHERWISE STATED IN WRITING, ULTIMAKER PROVIDES ANY ULTIMAKER SOFTWARE OR THIRD PARTY SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF ULTIMAKER SOFTWARE IS WITH YOU.</p>
|
||||
<p>UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, IN NO EVENT WILL ULTIMAKER BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE ANY ULTIMAKER SOFTWARE OR THIRD PARTY SOFTWARE.</p>
|
||||
'
|
||||
readOnly: true;
|
||||
textFormat: TextEdit.RichText
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: buttonRow
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width
|
||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura" }
|
||||
|
||||
Button
|
||||
{
|
||||
anchors.right: parent.right
|
||||
text: catalog.i18nc("@action:button", "I understand and agree")
|
||||
onClicked: {
|
||||
baseDialog.accepted()
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
anchors.left: parent.left
|
||||
text: catalog.i18nc("@action:button", "I don't agree")
|
||||
onClicked: {
|
||||
baseDialog.rejected()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: manager.didAgree(true)
|
||||
onRejected: manager.didAgree(false)
|
||||
onClosing: manager.didAgree(false)
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from . import UserAgreement
|
||||
|
||||
def getMetaData():
|
||||
return {}
|
||||
|
||||
def register(app):
|
||||
return {"extension": UserAgreement.UserAgreement(app)}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"name": "UserAgreement",
|
||||
"author": "Ultimaker B.V.",
|
||||
"version": "1.0.1",
|
||||
"description": "Ask the user once if he/she agrees with our license.",
|
||||
"api": "6.0",
|
||||
"i18n-catalog": "cura"
|
||||
}
|
|
@ -3,7 +3,7 @@ from typing import Tuple, List, Set, Dict
|
|||
import io
|
||||
|
||||
from UM.VersionUpgrade import VersionUpgrade
|
||||
from cura.PrinterOutputDevice import ConnectionType
|
||||
from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
|
||||
|
||||
deleted_settings = {"bridge_wall_max_overhang"} # type: Set[str]
|
||||
renamed_configurations = {"connect_group_name": "group_name"} # type: Dict[str, str]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue