mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-05 13:03:59 -06:00
Merge branch 'master' of https://github.com/Ultimaker/Cura
This commit is contained in:
commit
19412c5bda
34 changed files with 1154 additions and 990 deletions
|
@ -6,6 +6,12 @@ include(GNUInstallDirs)
|
|||
|
||||
set(URANIUM_SCRIPTS_DIR "${CMAKE_SOURCE_DIR}/../uranium/scripts" CACHE DIRECTORY "The location of the scripts directory of the Uranium repository")
|
||||
|
||||
# Tests
|
||||
# Note that we use exit 0 here to not mark the build as a failure on test failure
|
||||
add_custom_target(tests)
|
||||
add_custom_command(TARGET tests POST_BUILD COMMAND "PYTHONPATH=${CMAKE_SOURCE_DIR}/../Uranium/:${CMAKE_SOURCE_DIR}" ${PYTHON_EXECUTABLE} -m pytest -r a --junitxml=${CMAKE_BINARY_DIR}/junit.xml ${CMAKE_SOURCE_DIR} || exit 0)
|
||||
|
||||
|
||||
set(CURA_VERSION "master" CACHE STRING "Version name of Cura")
|
||||
set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'")
|
||||
configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY)
|
||||
|
|
|
@ -44,6 +44,7 @@ from . import ZOffsetDecorator
|
|||
from . import CuraSplashScreen
|
||||
from . import MachineManagerModel
|
||||
from . import ContainerSettingsModel
|
||||
from . import MachineActionManager
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS
|
||||
from PyQt5.QtGui import QColor, QIcon
|
||||
|
@ -99,6 +100,8 @@ class CuraApplication(QtApplication):
|
|||
SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True)
|
||||
SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator)
|
||||
|
||||
self._machine_action_manager = MachineActionManager.MachineActionManager()
|
||||
|
||||
super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType)
|
||||
|
||||
self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png")))
|
||||
|
@ -367,6 +370,7 @@ class CuraApplication(QtApplication):
|
|||
qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager",
|
||||
MachineManagerModel.createMachineManagerModel)
|
||||
|
||||
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
|
||||
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
||||
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
||||
self.initializeEngine()
|
||||
|
@ -383,6 +387,12 @@ class CuraApplication(QtApplication):
|
|||
|
||||
self.exec_()
|
||||
|
||||
## Get the machine action manager
|
||||
# We ignore any *args given to this, as we also register the machine manager as qml singleton.
|
||||
# It wants to give this function an engine and script engine, but we don't care about that.
|
||||
def getMachineActionManager(self, *args):
|
||||
return self._machine_action_manager
|
||||
|
||||
## Handle Qt events
|
||||
def event(self, event):
|
||||
if event.type() == QEvent.FileOpen:
|
||||
|
|
78
cura/MachineAction.py
Normal file
78
cura/MachineAction.py
Normal file
|
@ -0,0 +1,78 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal, QUrl
|
||||
from PyQt5.QtQml import QQmlComponent, QQmlContext
|
||||
|
||||
from UM.PluginObject import PluginObject
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
|
||||
from UM.Application import Application
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class MachineAction(QObject, PluginObject):
|
||||
def __init__(self, key, label = ""):
|
||||
super().__init__()
|
||||
self._key = key
|
||||
self._label = label
|
||||
self._qml_url = ""
|
||||
|
||||
self._component = None
|
||||
self._context = None
|
||||
self._view = None
|
||||
self._finished = False
|
||||
|
||||
labelChanged = pyqtSignal()
|
||||
onFinished = pyqtSignal()
|
||||
|
||||
def getKey(self):
|
||||
return self._key
|
||||
|
||||
@pyqtProperty(str, notify = labelChanged)
|
||||
def label(self):
|
||||
return self._label
|
||||
|
||||
def setLabel(self, label):
|
||||
if self._label != label:
|
||||
self._label = label
|
||||
self.labelChanged.emit()
|
||||
|
||||
## Reset the action to it's default state.
|
||||
# This should not be re-implemented by child classes, instead re-implement _reset.
|
||||
# /sa _reset
|
||||
@pyqtSlot()
|
||||
def reset(self):
|
||||
self._finished = False
|
||||
self._reset()
|
||||
|
||||
## Protected implementation of reset.
|
||||
# /sa reset()
|
||||
def _reset(self):
|
||||
pass
|
||||
|
||||
@pyqtSlot()
|
||||
def setFinished(self):
|
||||
self._finished = True
|
||||
self._reset()
|
||||
self.onFinished.emit()
|
||||
|
||||
@pyqtProperty(bool, notify = onFinished)
|
||||
def finished(self):
|
||||
return self._finished
|
||||
|
||||
def _createViewFromQML(self):
|
||||
path = QUrl.fromLocalFile(
|
||||
os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url))
|
||||
self._component = QQmlComponent(Application.getInstance()._engine, path)
|
||||
self._context = QQmlContext(Application.getInstance()._engine.rootContext())
|
||||
self._context.setContextProperty("manager", self)
|
||||
self._view = self._component.create(self._context)
|
||||
|
||||
@pyqtProperty(QObject, constant = True)
|
||||
def displayItem(self):
|
||||
if not self._component:
|
||||
self._createViewFromQML()
|
||||
|
||||
return self._view
|
143
cura/MachineActionManager.py
Normal file
143
cura/MachineActionManager.py
Normal file
|
@ -0,0 +1,143 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
from UM.Logger import Logger
|
||||
from UM.PluginRegistry import PluginRegistry # So MachineAction can be added as plugin type
|
||||
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSlot
|
||||
|
||||
## Raised when trying to add an unknown machine action as a required action
|
||||
class UnknownMachineActionError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
## Raised when trying to add a machine action that does not have an unique key.
|
||||
class NotUniqueMachineActionError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class MachineActionManager(QObject):
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
|
||||
self._machine_actions = {} # Dict of all known machine actions
|
||||
self._required_actions = {} # Dict of all required actions by definition ID
|
||||
self._supported_actions = {} # Dict of all supported actions by definition ID
|
||||
self._first_start_actions = {} # Dict of all actions that need to be done when first added by definition ID
|
||||
|
||||
# Add machine_action as plugin type
|
||||
PluginRegistry.addType("machine_action", self.addMachineAction)
|
||||
|
||||
# Ensure that all containers that were registered before creation of this registry are also handled.
|
||||
# This should not have any effect, but it makes it safer if we ever refactor the order of things.
|
||||
for container in ContainerRegistry.getInstance().findDefinitionContainers():
|
||||
self._onContainerAdded(container)
|
||||
|
||||
ContainerRegistry.getInstance().containerAdded.connect(self._onContainerAdded)
|
||||
|
||||
def _onContainerAdded(self, container):
|
||||
## Ensure that the actions are added to this manager
|
||||
if isinstance(container, DefinitionContainer):
|
||||
supported_actions = container.getMetaDataEntry("supported_actions", [])
|
||||
for action in supported_actions:
|
||||
self.addSupportedAction(container.getId(), action)
|
||||
|
||||
required_actions = container.getMetaDataEntry("required_actions", [])
|
||||
for action in required_actions:
|
||||
self.addRequiredAction(container.getId(), action)
|
||||
|
||||
first_start_actions = container.getMetaDataEntry("first_start_actions", [])
|
||||
for action in first_start_actions:
|
||||
self.addFirstStartAction(container.getId(), action)
|
||||
|
||||
## Add a required action to a machine
|
||||
# Raises an exception when the action is not recognised.
|
||||
def addRequiredAction(self, definition_id, action_key):
|
||||
if action_key in self._machine_actions:
|
||||
if definition_id in self._required_actions:
|
||||
self._required_actions[definition_id] |= {self._machine_actions[action_key]}
|
||||
else:
|
||||
self._required_actions[definition_id] = {self._machine_actions[action_key]}
|
||||
else:
|
||||
raise UnknownMachineActionError("Action %s, which is required for %s is not known." % (action_key, definition_id))
|
||||
|
||||
## Add a supported action to a machine.
|
||||
def addSupportedAction(self, definition_id, action_key):
|
||||
if action_key in self._machine_actions:
|
||||
if definition_id in self._supported_actions:
|
||||
self._supported_actions[definition_id] |= {self._machine_actions[action_key]}
|
||||
else:
|
||||
self._supported_actions[definition_id] = {self._machine_actions[action_key]}
|
||||
else:
|
||||
Logger.log("w", "Unable to add %s to %s, as the action is not recognised", action_key, definition_id)
|
||||
|
||||
## Add an action to the first start list of a machine.
|
||||
def addFirstStartAction(self, definition_id, action_key, index = None):
|
||||
if action_key in self._machine_actions:
|
||||
if definition_id in self._first_start_actions:
|
||||
if index is not None:
|
||||
self._first_start_actions[definition_id].insert(index, self._machine_actions[action_key])
|
||||
else:
|
||||
self._first_start_actions[definition_id].append(self._machine_actions[action_key])
|
||||
else:
|
||||
self._first_start_actions[definition_id] = [self._machine_actions[action_key]]
|
||||
else:
|
||||
Logger.log("w", "Unable to add %s to %s, as the action is not recognised", action_key, definition_id)
|
||||
|
||||
## Add a (unique) MachineAction
|
||||
# if the Key of the action is not unique, an exception is raised.
|
||||
def addMachineAction(self, action):
|
||||
if action.getKey() not in self._machine_actions:
|
||||
self._machine_actions[action.getKey()] = action
|
||||
else:
|
||||
raise NotUniqueMachineActionError("MachineAction with key %s was already added. Actions must have unique keys.", action.getKey())
|
||||
|
||||
## Get all actions supported by given machine
|
||||
# \param definition_id The ID of the definition you want the supported actions of
|
||||
# \returns set of supported actions.
|
||||
@pyqtSlot(str, result = "QVariantList")
|
||||
def getSupportedActions(self, definition_id):
|
||||
if definition_id in self._supported_actions:
|
||||
return list(self._supported_actions[definition_id])
|
||||
else:
|
||||
return set()
|
||||
|
||||
## Get all actions required by given machine
|
||||
# \param definition_id The ID of the definition you want the required actions of
|
||||
# \returns set of required actions.
|
||||
def getRequiredActions(self, definition_id):
|
||||
if definition_id in self._required_actions:
|
||||
return self._required_actions[definition_id]
|
||||
else:
|
||||
return set()
|
||||
|
||||
## Get all actions that need to be performed upon first start of a given machine.
|
||||
# Note that contrary to required / supported actions a list is returned (as it could be required to run the same
|
||||
# action multiple times).
|
||||
# \param definition_id The ID of the definition that you want to get the "on added" actions for.
|
||||
# \returns List of actions.
|
||||
@pyqtSlot(str, result="QVariantList")
|
||||
def getFirstStartActions(self, definition_id):
|
||||
if definition_id in self._first_start_actions:
|
||||
return self._first_start_actions[definition_id]
|
||||
else:
|
||||
return []
|
||||
|
||||
## Remove Machine action from manager
|
||||
# \param action to remove
|
||||
def removeMachineAction(self, action):
|
||||
try:
|
||||
del self._machine_actions[action.getKey()]
|
||||
except KeyError:
|
||||
Logger.log("w", "Trying to remove MachineAction (%s) that was already removed", action.getKey())
|
||||
|
||||
## Get MachineAction by key
|
||||
# \param key String of key to select
|
||||
# \return Machine action if found, None otherwise
|
||||
def getMachineAction(self, key):
|
||||
if key in self._machine_actions:
|
||||
return self._machine_actions[key]
|
||||
else:
|
||||
return None
|
|
@ -3,36 +3,44 @@ from UM.Application import Application
|
|||
from UM.Settings.SettingInstance import SettingInstance
|
||||
from UM.Logger import Logger
|
||||
|
||||
import UM.Settings.Models
|
||||
|
||||
from cura.SettingOverrideDecorator import SettingOverrideDecorator
|
||||
|
||||
## The per object setting visibility handler ensures that only setting defintions that have a matching instance Container
|
||||
# are returned as visible.
|
||||
class PerObjectSettingVisibilityHandler(QObject):
|
||||
class PerObjectSettingVisibilityHandler(UM.Settings.Models.SettingVisibilityHandler):
|
||||
def __init__(self, parent = None, *args, **kwargs):
|
||||
super().__init__(parent = parent, *args, **kwargs)
|
||||
self._selected_object_id = None
|
||||
|
||||
visibilityChanged = pyqtSignal()
|
||||
self._selected_object_id = None
|
||||
self._node = None
|
||||
self._stack = None
|
||||
|
||||
def setSelectedObjectId(self, id):
|
||||
self._selected_object_id = id
|
||||
self.visibilityChanged.emit()
|
||||
if id != self._selected_object_id:
|
||||
self._selected_object_id = id
|
||||
|
||||
self._node = Application.getInstance().getController().getScene().findObject(self._selected_object_id)
|
||||
if self._node:
|
||||
self._stack = self._node.callDecoration("getStack")
|
||||
|
||||
self.visibilityChanged.emit()
|
||||
|
||||
@pyqtProperty("quint64", fset = setSelectedObjectId)
|
||||
def selectedObjectId(self):
|
||||
pass
|
||||
return self._selected_object_id
|
||||
|
||||
def setVisible(self, visible):
|
||||
node = Application.getInstance().getController().getScene().findObject(self._selected_object_id)
|
||||
if not node:
|
||||
if not self._node:
|
||||
return
|
||||
stack = node.callDecoration("getStack")
|
||||
if not stack:
|
||||
node.addDecorator(SettingOverrideDecorator())
|
||||
stack = node.callDecoration("getStack")
|
||||
|
||||
settings = stack.getTop()
|
||||
all_instances = settings.findInstances(**{})
|
||||
if not self._stack:
|
||||
self._node.addDecorator(SettingOverrideDecorator())
|
||||
self._stack = self._node.callDecoration("getStack")
|
||||
|
||||
settings = self._stack.getTop()
|
||||
all_instances = settings.findInstances()
|
||||
visibility_changed = False # Flag to check if at the end the signal needs to be emitted
|
||||
|
||||
# Remove all instances that are not in visibility list
|
||||
|
@ -41,13 +49,12 @@ class PerObjectSettingVisibilityHandler(QObject):
|
|||
settings.removeInstance(instance.definition.key)
|
||||
visibility_changed = True
|
||||
|
||||
# Add all instances that are not added, but are in visiblity list
|
||||
# Add all instances that are not added, but are in visibility list
|
||||
for item in visible:
|
||||
if not settings.getInstance(item):
|
||||
definition_container = Application.getInstance().getGlobalContainerStack().getBottom()
|
||||
definitions = definition_container.findDefinitions(key = item)
|
||||
if definitions:
|
||||
settings.addInstance(SettingInstance(definitions[0], settings))
|
||||
definition = self._stack.getSettingDefinition(item)
|
||||
if definition:
|
||||
settings.addInstance(SettingInstance(definition, settings))
|
||||
visibility_changed = True
|
||||
else:
|
||||
Logger.log("w", "Unable to add instance (%s) to perobject visibility because we couldn't find the matching definition", item)
|
||||
|
@ -57,20 +64,16 @@ class PerObjectSettingVisibilityHandler(QObject):
|
|||
|
||||
def getVisible(self):
|
||||
visible_settings = set()
|
||||
node = Application.getInstance().getController().getScene().findObject(self._selected_object_id)
|
||||
if not node:
|
||||
if not self._node:
|
||||
return visible_settings
|
||||
|
||||
stack = node.callDecoration("getStack")
|
||||
if not stack:
|
||||
if not self._stack:
|
||||
return visible_settings
|
||||
|
||||
settings = stack.getTop()
|
||||
settings = self._stack.getTop()
|
||||
if not settings:
|
||||
return visible_settings
|
||||
|
||||
all_instances = settings.findInstances(**{})
|
||||
for instance in all_instances:
|
||||
visible_settings.add(instance.definition.key)
|
||||
visible_settings = set(map(lambda i: i.definition.key, settings.findInstances()))
|
||||
return visible_settings
|
||||
|
||||
|
|
|
@ -153,6 +153,8 @@ Item {
|
|||
{
|
||||
id: addedSettingsModel;
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
expanded: [ "*" ]
|
||||
|
||||
visibilityHandler: Cura.PerObjectSettingVisibilityHandler
|
||||
{
|
||||
selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId")
|
||||
|
@ -215,9 +217,8 @@ Item {
|
|||
|
||||
style: ButtonStyle
|
||||
{
|
||||
background: Rectangle
|
||||
background: Item
|
||||
{
|
||||
color: control.hovered ? control.parent.style.controlHighlightColor : control.parent.style.controlColor;
|
||||
UM.RecolorImage
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
@ -340,6 +341,8 @@ Item {
|
|||
"settable_per_mesh": true
|
||||
}
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
|
||||
expanded: [ "*" ]
|
||||
exclude: [ "machine_settings" ]
|
||||
}
|
||||
delegate:Loader
|
||||
{
|
||||
|
|
53
plugins/UltimakerMachineActions/BedLevelMachineAction.py
Normal file
53
plugins/UltimakerMachineActions/BedLevelMachineAction.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
from cura.MachineAction import MachineAction
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
|
||||
from UM.Application import Application
|
||||
|
||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||
|
||||
class BedLevelMachineAction(MachineAction):
|
||||
def __init__(self):
|
||||
super().__init__("BedLevel", "Level bed")
|
||||
self._qml_url = "BedLevelMachineAction.qml"
|
||||
self._bed_level_position = 0
|
||||
|
||||
def _execute(self):
|
||||
pass
|
||||
|
||||
def _reset(self):
|
||||
self._bed_level_position = 0
|
||||
printer_output_devices = self._getPrinterOutputDevices()
|
||||
if printer_output_devices:
|
||||
printer_output_devices[0].homeBed()
|
||||
printer_output_devices[0].moveHead(0, 0, 3)
|
||||
printer_output_devices[0].homeHead()
|
||||
|
||||
def _getPrinterOutputDevices(self):
|
||||
return [printer_output_device for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices() if isinstance(printer_output_device, PrinterOutputDevice)]
|
||||
|
||||
@pyqtSlot()
|
||||
def moveToNextLevelPosition(self):
|
||||
output_devices = self._getPrinterOutputDevices()
|
||||
if output_devices: # We found at least one output device
|
||||
output_device = output_devices[0]
|
||||
|
||||
if self._bed_level_position == 0:
|
||||
output_device.moveHead(0, 0, 3)
|
||||
output_device.homeHead()
|
||||
output_device.moveHead(0, 0, 3)
|
||||
output_device.moveHead(Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") - 10, 0, 0)
|
||||
output_device.moveHead(0, 0, -3)
|
||||
self._bed_level_position += 1
|
||||
elif self._bed_level_position == 1:
|
||||
output_device.moveHead(0, 0, 3)
|
||||
output_device.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value" ) / 2, Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") - 10, 0)
|
||||
output_device.moveHead(0, 0, -3)
|
||||
self._bed_level_position += 1
|
||||
elif self._bed_level_position == 2:
|
||||
output_device.moveHead(0, 0, 3)
|
||||
output_device.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") / 2 + 10, -(Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") + 10), 0)
|
||||
output_device.moveHead(0, 0, -3)
|
||||
self._bed_level_position += 1
|
||||
elif self._bed_level_position >= 3:
|
||||
self.setFinished()
|
85
plugins/UltimakerMachineActions/BedLevelMachineAction.qml
Normal file
85
plugins/UltimakerMachineActions/BedLevelMachineAction.qml
Normal file
|
@ -0,0 +1,85 @@
|
|||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
|
||||
Cura.MachineAction
|
||||
{
|
||||
anchors.fill: parent;
|
||||
Item
|
||||
{
|
||||
id: bedLevelMachineAction
|
||||
anchors.fill: parent;
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Bed Leveling")
|
||||
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", "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.")
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: bedlevelingText
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
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 bed height. The print bed height is right when the paper is slightly gripped by the tip of the nozzle.")
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: bedlevelingWrapper
|
||||
anchors.top: bedlevelingText.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: skipBedlevelingButton.height
|
||||
width: bedlevelingButton.width + skipBedlevelingButton.width + UM.Theme.getSize("default_margin").height < bedLevelMachineAction.width ? bedlevelingButton.width + skipBedlevelingButton.width + UM.Theme.getSize("default_margin").height : bedLevelMachineAction.width
|
||||
Button
|
||||
{
|
||||
id: bedlevelingButton
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
text: catalog.i18nc("@action:button","Move to Next Position");
|
||||
onClicked:
|
||||
{
|
||||
manager.moveToNextLevelPosition()
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: skipBedlevelingButton
|
||||
anchors.top: parent.width < bedLevelMachineAction.width ? parent.top : bedlevelingButton.bottom
|
||||
anchors.topMargin: parent.width < bedLevelMachineAction.width ? 0 : UM.Theme.getSize("default_margin").height/2
|
||||
anchors.left: parent.width < bedLevelMachineAction.width ? bedlevelingButton.right : parent.left
|
||||
anchors.leftMargin: parent.width < bedLevelMachineAction.width ? UM.Theme.getSize("default_margin").width : 0
|
||||
text: catalog.i18nc("@action:button","Skip bed leveling");
|
||||
onClicked:
|
||||
{
|
||||
manager.setFinished()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
160
plugins/UltimakerMachineActions/UMOCheckupMachineAction.py
Normal file
160
plugins/UltimakerMachineActions/UMOCheckupMachineAction.py
Normal file
|
@ -0,0 +1,160 @@
|
|||
from cura.MachineAction import MachineAction
|
||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||
from UM.Application import Application
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty
|
||||
|
||||
class UMOCheckupMachineAction(MachineAction):
|
||||
def __init__(self):
|
||||
super().__init__("UMOCheckup", "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: # Connection is probably not a USB connection. Something went pretty wrong if this happens.
|
||||
pass
|
||||
self._output_device = None
|
||||
|
||||
self._check_started = False
|
||||
|
||||
# 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()
|
||||
|
||||
@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()
|
||||
|
||||
@pyqtSlot()
|
||||
def startCheck(self):
|
||||
self._check_started = True
|
||||
output_devices = self._getPrinterOutputDevices()
|
||||
if output_devices:
|
||||
self._output_device = output_devices[0]
|
||||
try:
|
||||
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: # Connection is probably not a USB connection. Something went pretty wrong if this happens.
|
||||
pass
|
||||
|
||||
@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)
|
271
plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml
Normal file
271
plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml
Normal file
|
@ -0,0 +1,271 @@
|
|||
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
|
||||
property int rightRow: checkupMachineAction.width * 0.60
|
||||
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");
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: startStopButtons
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: childrenRect.height
|
||||
width: startCheckButton.width + skipCheckButton.width + UM.Theme.getSize("default_margin").height < checkupMachineAction.width ? startCheckButton.width + skipCheckButton.width + UM.Theme.getSize("default_margin").height : checkupMachineAction.width
|
||||
Button
|
||||
{
|
||||
id: startCheckButton
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
text: catalog.i18nc("@action:button","Start Printer Check");
|
||||
onClicked:
|
||||
{
|
||||
checkupContent.visible = true
|
||||
startCheckButton.enabled = false
|
||||
manager.startCheck()
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: skipCheckButton
|
||||
anchors.top: parent.width < checkupMachineAction.width ? parent.top : startCheckButton.bottom
|
||||
anchors.topMargin: parent.width < checkupMachineAction.width ? 0 : UM.Theme.getSize("default_margin").height/2
|
||||
anchors.left: parent.width < checkupMachineAction.width ? startCheckButton.right : parent.left
|
||||
anchors.leftMargin: parent.width < checkupMachineAction.width ? UM.Theme.getSize("default_margin").width : 0
|
||||
text: catalog.i18nc("@action:button", "Skip Printer Check");
|
||||
onClicked: manager.setFinished()
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: checkupContent
|
||||
anchors.top: startStopButtons.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
visible: false
|
||||
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: Cura.USBPrinterManager.connectedPrinterList.rowCount() > 0 || base.addOriginalProgress.checkUp[0] ? catalog.i18nc("@info:status","Done"):catalog.i18nc("@info:status","Incomplete")
|
||||
}
|
||||
//////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: endstopXLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: connectionLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Min endstop X: ")
|
||||
}
|
||||
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")
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: endstopYLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: endstopXLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Min endstop Y: ")
|
||||
}
|
||||
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")
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: endstopZLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: endstopYLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Min endstop Z: ")
|
||||
}
|
||||
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")
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: nozzleTempLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: endstopZLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Nozzle temperature check: ")
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: nozzleTempStatus
|
||||
width: checkupMachineAction.rightRow * 0.4
|
||||
anchors.top: nozzleTempLabel.top
|
||||
anchors.left: nozzleTempLabel.right
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@info:status","Not checked")
|
||||
}
|
||||
Item
|
||||
{
|
||||
id: nozzleTempButton
|
||||
width: checkupMachineAction.rightRow * 0.3
|
||||
height: nozzleTemp.height
|
||||
anchors.top: nozzleTempLabel.top
|
||||
anchors.left: bedTempStatus.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
|
||||
Button
|
||||
{
|
||||
height: nozzleTemp.height - 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: catalog.i18nc("@action:button","Start Heating")
|
||||
onClicked:
|
||||
{
|
||||
manager.heatupHotend()
|
||||
nozzleTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
||||
}
|
||||
}
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: nozzleTemp
|
||||
anchors.top: nozzleTempLabel.top
|
||||
anchors.left: nozzleTempButton.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
width: checkupMachineAction.rightRow * 0.2
|
||||
wrapMode: Text.WordWrap
|
||||
text: manager.hotendTemperature + "°C"
|
||||
font.bold: true
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: bedTempLabel
|
||||
width: checkupMachineAction.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: nozzleTempLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","bed temperature check:")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: bedTempStatus
|
||||
width: checkupMachineAction.rightRow * 0.4
|
||||
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")
|
||||
}
|
||||
Item
|
||||
{
|
||||
id: bedTempButton
|
||||
width: checkupMachineAction.rightRow * 0.3
|
||||
height: bedTemp.height
|
||||
anchors.top: bedTempLabel.top
|
||||
anchors.left: bedTempStatus.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
|
||||
Button
|
||||
{
|
||||
height: bedTemp.height - 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: catalog.i18nc("@action:button","Start Heating")
|
||||
onClicked:
|
||||
{
|
||||
manager.heatupBed()
|
||||
}
|
||||
}
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: bedTemp
|
||||
width: checkupMachineAction.rightRow * 0.2
|
||||
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
|
||||
}
|
||||
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.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
from cura.MachineAction import MachineAction
|
||||
|
||||
class UpgradeFirmwareMachineAction(MachineAction):
|
||||
def __init__(self):
|
||||
super().__init__("UpgradeFirmware", "Upgrade Firmware")
|
||||
self._qml_url = "UpgradeFirmwareMachineAction.qml"
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
|
||||
Cura.MachineAction
|
||||
{
|
||||
anchors.fill: parent;
|
||||
Item
|
||||
{
|
||||
id: upgradeFirmwareMachineAction
|
||||
anchors.fill: parent;
|
||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Upgrade Firmware")
|
||||
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", "Firmware is the piece of software running directly on your 3D printer. This firmware controls the step motors, regulates the temperature and ultimately makes your printer work.")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: upgradeText1
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "The firmware shipping with new Ultimakers works, but upgrades have been made to make better prints, and make calibration easier.");
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: upgradeText2
|
||||
anchors.top: upgradeText1.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "Cura requires these new features and thus your firmware will most likely need to be upgraded. You can do so now.");
|
||||
}
|
||||
Item
|
||||
{
|
||||
anchors.top: upgradeText2.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: upgradeButton.width + skipUpgradeButton.width + UM.Theme.getSize("default_margin").height < upgradeFirmwareMachineAction.width ? upgradeButton.width + skipUpgradeButton.width + UM.Theme.getSize("default_margin").height : upgradeFirmwareMachineAction.width
|
||||
Button
|
||||
{
|
||||
id: upgradeButton
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
text: catalog.i18nc("@action:button","Upgrade to Marlin Firmware");
|
||||
onClicked: Cura.USBPrinterManager.updateAllFirmware()
|
||||
}
|
||||
Button
|
||||
{
|
||||
id: skipUpgradeButton
|
||||
anchors.top: parent.width < upgradeFirmwareMachineAction.width ? parent.top : upgradeButton.bottom
|
||||
anchors.topMargin: parent.width < upgradeFirmwareMachineAction.width ? 0 : UM.Theme.getSize("default_margin").height / 2
|
||||
anchors.left: parent.width < upgradeFirmwareMachineAction.width ? upgradeButton.right : parent.left
|
||||
anchors.leftMargin: parent.width < upgradeFirmwareMachineAction.width ? UM.Theme.getSize("default_margin").width : 0
|
||||
text: catalog.i18nc("@action:button", "Skip Upgrade");
|
||||
onClicked: manager.setFinished()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
plugins/UltimakerMachineActions/__init__.py
Normal file
23
plugins/UltimakerMachineActions/__init__.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from . import BedLevelMachineAction
|
||||
from . import UpgradeFirmwareMachineAction
|
||||
from . import UMOCheckupMachineAction
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
def getMetaData():
|
||||
return {
|
||||
"plugin": {
|
||||
"name": catalog.i18nc("@label", "Ultimaker machine actions"),
|
||||
"author": "Ultimaker",
|
||||
"version": "1.0",
|
||||
"description": catalog.i18nc("@info:whatsthis", "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc)"),
|
||||
"api": 3
|
||||
}
|
||||
}
|
||||
|
||||
def register(app):
|
||||
return { "machine_action": [BedLevelMachineAction.BedLevelMachineAction(), UpgradeFirmwareMachineAction.UpgradeFirmwareMachineAction(), UMOCheckupMachineAction.UMOCheckupMachineAction()]}
|
4
pytest.ini
Normal file
4
pytest.ini
Normal file
|
@ -0,0 +1,4 @@
|
|||
[pytest]
|
||||
testpaths = tests
|
||||
python_files = Test*.py
|
||||
python_classes = Test
|
|
@ -12,7 +12,8 @@
|
|||
"icon": "icon_ultimaker2.png",
|
||||
"platform": "ultimaker2_platform.obj",
|
||||
"platform_texture": "Ultimaker2backplate.png",
|
||||
"platform_offset": [9, 0, 0]
|
||||
"platform_offset": [9, 0, 0],
|
||||
"supported_actions":["UpgradeFirmware"]
|
||||
},
|
||||
"overrides": {
|
||||
"machine_start_gcode" : {
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2.png",
|
||||
"platform": "ultimaker2_platform.obj",
|
||||
"platform_texture": "Ultimaker2Extendedbackplate.png"
|
||||
"platform_texture": "Ultimaker2Extendedbackplate.png",
|
||||
"supported_actions": ["UpgradeFirmware"]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
"category": "Ultimaker",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform": "ultimaker2_platform.obj",
|
||||
"platform_texture": "Ultimaker2ExtendedPlusbackplate.png"
|
||||
"platform_texture": "Ultimaker2ExtendedPlusbackplate.png",
|
||||
"supported_actions":["UpgradeFirmware"]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
"icon": "icon_ultimaker2.png",
|
||||
"platform": "ultimaker2go_platform.obj",
|
||||
"platform_texture": "Ultimaker2Gobackplate.png",
|
||||
"platform_offset": [0, 0, 0]
|
||||
"platform_offset": [0, 0, 0],
|
||||
"supported_actions":["UpgradeFirmware"]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
"has_variants": true,
|
||||
"has_materials": true,
|
||||
"has_machine_materials": true,
|
||||
"has_machine_quality": true
|
||||
"has_machine_quality": true,
|
||||
"supported_actions":["UpgradeFirmware"]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
|
|
|
@ -14,12 +14,7 @@
|
|||
"has_materials": true,
|
||||
"preferred_material": "*pla*",
|
||||
"preferred_quality": "*normal*",
|
||||
"pages": [
|
||||
"SelectUpgradedParts",
|
||||
"UpgradeFirmware",
|
||||
"UltimakerCheckup",
|
||||
"BedLeveling"
|
||||
]
|
||||
"supported_actions":["UMOCheckup", "UpgradeFirmware", "BedLevel"]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
|
|
|
@ -11,11 +11,7 @@
|
|||
"icon": "icon_ultimaker.png",
|
||||
"platform": "ultimaker2_platform.obj",
|
||||
"platform_texture": "UltimakerPlusbackplate.png",
|
||||
"pages": [
|
||||
"UpgradeFirmware",
|
||||
"UltimakerCheckup",
|
||||
"BedLeveling"
|
||||
]
|
||||
"supported_actions":["UMOCheckup", "UpgradeFirmware", "BedLevel"]
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
|
|
|
@ -18,6 +18,7 @@ UM.Dialog
|
|||
title: catalog.i18nc("@title:window", "Add Printer")
|
||||
property string activeManufacturer: "Ultimaker";
|
||||
|
||||
signal machineAdded(string id)
|
||||
function getMachineName()
|
||||
{
|
||||
var name = machineList.model.getItem(machineList.currentIndex).name
|
||||
|
@ -162,6 +163,7 @@ UM.Dialog
|
|||
base.visible = false
|
||||
var item = machineList.model.getItem(machineList.currentIndex);
|
||||
Cura.MachineManager.addMachine(machineName.text, item.id)
|
||||
base.machineAdded(item.id) // Emit signal that the user added a machine.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -771,6 +771,38 @@ UM.MainWindow
|
|||
AddMachineDialog
|
||||
{
|
||||
id: addMachineDialog
|
||||
onMachineAdded:
|
||||
{
|
||||
machineActionsWizard.start(id)
|
||||
}
|
||||
}
|
||||
|
||||
// Dialog to handle first run machine actions
|
||||
UM.Wizard
|
||||
{
|
||||
id: machineActionsWizard;
|
||||
|
||||
title: catalog.i18nc("@title:window", "Add Printer")
|
||||
property var machine;
|
||||
|
||||
function start(id)
|
||||
{
|
||||
var actions = Cura.MachineActionManager.getFirstStartActions(id)
|
||||
resetPages() // Remove previous pages
|
||||
|
||||
for (var i = 0; i < actions.length; i++)
|
||||
{
|
||||
actions[i].displayItem.reset()
|
||||
machineActionsWizard.appendPage(actions[i].displayItem, catalog.i18nc("@title", actions[i].label));
|
||||
}
|
||||
|
||||
//Only start if there are actions to perform.
|
||||
if (actions.length > 0)
|
||||
{
|
||||
machineActionsWizard.currentPage = 0;
|
||||
show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections
|
||||
|
|
15
resources/qml/MachineAction.qml
Normal file
15
resources/qml/MachineAction.qml
Normal file
|
@ -0,0 +1,15 @@
|
|||
import QtQuick 2.2
|
||||
|
||||
Item
|
||||
{
|
||||
id: contentItem
|
||||
// Connect the finished property change to completed signal.
|
||||
property var finished: manager.finished
|
||||
onFinishedChanged: if(manager.finished) {completed()}
|
||||
signal completed()
|
||||
|
||||
function reset()
|
||||
{
|
||||
manager.reset()
|
||||
}
|
||||
}
|
|
@ -41,6 +41,37 @@ UM.ManagementPage
|
|||
anchors.fill: parent;
|
||||
spacing: UM.Theme.getSize("default_margin").height;
|
||||
|
||||
Row
|
||||
{
|
||||
Repeater
|
||||
{
|
||||
id: machineActionRepeater
|
||||
model: Cura.MachineActionManager.getSupportedActions(Cura.MachineManager.activeDefinitionId)
|
||||
|
||||
Button
|
||||
{
|
||||
text: machineActionRepeater.model[index].label;
|
||||
onClicked:
|
||||
{
|
||||
actionDialog.content = machineActionRepeater.model[index].displayItem
|
||||
machineActionRepeater.model[index].displayItem.reset()
|
||||
actionDialog.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.Dialog
|
||||
{
|
||||
id: actionDialog
|
||||
property var content
|
||||
onContentChanged:
|
||||
{
|
||||
contents = content;
|
||||
content.onCompleted.connect(hide)
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
text: base.currentItem && base.currentItem.name ? base.currentItem.name : ""
|
||||
|
|
|
@ -34,34 +34,34 @@ Item {
|
|||
|
||||
property string tooltipText:
|
||||
{
|
||||
var affects = settingDefinitionsModel.getRequiredBy(definition.key, "value")
|
||||
var affected_by = settingDefinitionsModel.getRequires(definition.key, "value")
|
||||
var affects = settingDefinitionsModel.getRequiredBy(definition.key, "value")
|
||||
var affected_by = settingDefinitionsModel.getRequires(definition.key, "value")
|
||||
|
||||
var affected_by_list = ""
|
||||
for(var i in affected_by)
|
||||
{
|
||||
affected_by_list += "<li>%1</li>\n".arg(affected_by[i].label)
|
||||
}
|
||||
var affected_by_list = ""
|
||||
for(var i in affected_by)
|
||||
{
|
||||
affected_by_list += "<li>%1</li>\n".arg(affected_by[i].label)
|
||||
}
|
||||
|
||||
var affects_list = ""
|
||||
for(var i in affects)
|
||||
{
|
||||
affects_list += "<li>%1</li>\n".arg(affects[i].label)
|
||||
}
|
||||
var affects_list = ""
|
||||
for(var i in affects)
|
||||
{
|
||||
affects_list += "<li>%1</li>\n".arg(affects[i].label)
|
||||
}
|
||||
|
||||
var tooltip = "<b>%1</b>\n<p>%2</p>".arg(definition.label).arg(definition.description)
|
||||
var tooltip = "<b>%1</b>\n<p>%2</p>".arg(definition.label).arg(definition.description)
|
||||
|
||||
if(affects_list != "")
|
||||
{
|
||||
tooltip += "<br/><b>%1</b>\n<ul>\n%2</ul>".arg(catalog.i18nc("@label", "Affects")).arg(affects_list)
|
||||
}
|
||||
if(affects_list != "")
|
||||
{
|
||||
tooltip += "<br/><b>%1</b>\n<ul>\n%2</ul>".arg(catalog.i18nc("@label", "Affects")).arg(affects_list)
|
||||
}
|
||||
|
||||
if(affected_by_list != "")
|
||||
{
|
||||
tooltip += "<br/><b>%1</b>\n<ul>\n%2</ul>".arg(catalog.i18nc("@label", "Affected By")).arg(affected_by_list)
|
||||
}
|
||||
if(affected_by_list != "")
|
||||
{
|
||||
tooltip += "<br/><b>%1</b>\n<ul>\n%2</ul>".arg(catalog.i18nc("@label", "Affected By")).arg(affected_by_list)
|
||||
}
|
||||
|
||||
return tooltip
|
||||
return tooltip
|
||||
}
|
||||
|
||||
MouseArea
|
||||
|
@ -236,7 +236,7 @@ Item {
|
|||
{
|
||||
id: controlContainer;
|
||||
|
||||
enabled: provider.isValueUsed
|
||||
enabled: propertyProvider.isValueUsed
|
||||
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
|
|
|
@ -19,11 +19,6 @@ SettingItem
|
|||
border.width: UM.Theme.getSize("default_lining").width
|
||||
border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border")
|
||||
|
||||
property variant parentValue: value //From parent loader
|
||||
function notifyReset() {
|
||||
input.text = format(parentValue)
|
||||
}
|
||||
|
||||
color: {
|
||||
if (!enabled)
|
||||
{
|
||||
|
|
|
@ -29,8 +29,10 @@ ScrollView
|
|||
model: UM.SettingDefinitionsModel {
|
||||
id: definitionsModel;
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
exclude: ["machine_settings"]
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
|
||||
exclude: ["machine_settings"]
|
||||
expanded: Printer.expandedCategories
|
||||
onExpandedChanged: Printer.setExpandedCategories(expanded)
|
||||
|
||||
filter:
|
||||
{
|
||||
|
|
|
@ -1,243 +0,0 @@
|
|||
// Copyright (c) 2015 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
|
||||
import UM 1.1 as UM
|
||||
|
||||
Item
|
||||
{
|
||||
id: base
|
||||
|
||||
property string activeManufacturer: "Ultimaker";
|
||||
|
||||
property variant wizard: null;
|
||||
|
||||
property bool visibility: base.wizard.visible
|
||||
onVisibilityChanged:
|
||||
{
|
||||
machineName.text = getMachineName()
|
||||
}
|
||||
|
||||
function getMachineName()
|
||||
{
|
||||
var name = machineList.model.getItem(machineList.currentIndex).name
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: base.wizard
|
||||
onNextClicked: //You can add functions here that get triggered when the final button is clicked in the wizard-element
|
||||
{
|
||||
base.wizard.resetPages()
|
||||
saveMachine()
|
||||
}
|
||||
onBackClicked: base.wizard.resetPages()
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: title
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
text: catalog.i18nc("@title", "Add Printer")
|
||||
font.pointSize: 18;
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: subTitle
|
||||
anchors.left: parent.left
|
||||
anchors.top: title.bottom
|
||||
text: catalog.i18nc("@label", "Please select the type of printer:");
|
||||
}
|
||||
|
||||
ScrollView
|
||||
{
|
||||
id: machinesHolder
|
||||
|
||||
anchors
|
||||
{
|
||||
left: parent.left;
|
||||
top: subTitle.bottom;
|
||||
right: parent.right;
|
||||
bottom: machineNameHolder.top;
|
||||
}
|
||||
|
||||
ListView
|
||||
{
|
||||
id: machineList
|
||||
|
||||
model: UM.MachineDefinitionsModel { id: machineDefinitionsModel; showVariants: false; }
|
||||
focus: true
|
||||
|
||||
section.property: "manufacturer"
|
||||
section.delegate: Button {
|
||||
text: section
|
||||
style: ButtonStyle {
|
||||
background: Rectangle {
|
||||
border.width: 0
|
||||
color: "transparent";
|
||||
height: UM.Theme.getSize("standard_list_lineheight").height
|
||||
width: machineList.width
|
||||
}
|
||||
label: Label {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("standard_arrow").width + UM.Theme.getSize("default_margin").width
|
||||
text: control.text
|
||||
color: palette.windowText
|
||||
font.bold: true
|
||||
UM.RecolorImage {
|
||||
id: downArrow
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.left
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
width: UM.Theme.getSize("standard_arrow").width
|
||||
height: UM.Theme.getSize("standard_arrow").height
|
||||
sourceSize.width: width
|
||||
sourceSize.height: width
|
||||
color: palette.windowText
|
||||
source: base.activeManufacturer == section ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
base.activeManufacturer = section;
|
||||
machineList.currentIndex = machineList.model.find("manufacturer", section)
|
||||
machineName.text = getMachineName()
|
||||
}
|
||||
}
|
||||
|
||||
delegate: RadioButton {
|
||||
id: machineButton
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("standard_list_lineheight").width
|
||||
|
||||
opacity: 1;
|
||||
height: UM.Theme.getSize("standard_list_lineheight").height;
|
||||
|
||||
checked: ListView.isCurrentItem;
|
||||
|
||||
exclusiveGroup: printerGroup;
|
||||
|
||||
text: model.name
|
||||
|
||||
onClicked: {
|
||||
ListView.view.currentIndex = index;
|
||||
machineName.text = getMachineName()
|
||||
}
|
||||
|
||||
states: State {
|
||||
name: "collapsed";
|
||||
when: base.activeManufacturer != model.manufacturer;
|
||||
|
||||
PropertyChanges { target: machineButton; opacity: 0; height: 0; }
|
||||
}
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
to: "collapsed";
|
||||
SequentialAnimation {
|
||||
NumberAnimation { property: "opacity"; duration: 75; }
|
||||
NumberAnimation { property: "height"; duration: 75; }
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "collapsed";
|
||||
SequentialAnimation {
|
||||
NumberAnimation { property: "height"; duration: 75; }
|
||||
NumberAnimation { property: "opacity"; duration: 75; }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Column
|
||||
{
|
||||
id: machineNameHolder
|
||||
anchors.bottom: parent.bottom;
|
||||
|
||||
Item
|
||||
{
|
||||
height: errorMessage.lineHeight
|
||||
anchors.bottom: insertNameLabel.top
|
||||
anchors.bottomMargin: insertNameLabel.height * errorMessage.lineCount
|
||||
Label
|
||||
{
|
||||
id: errorMessage
|
||||
property bool show: false
|
||||
width: base.width
|
||||
height: errorMessage.show ? errorMessage.lineHeight : 0
|
||||
visible: errorMessage.show
|
||||
text: catalog.i18nc("@label", "This printer name has already been used. Please choose a different printer name.");
|
||||
wrapMode: Text.WordWrap
|
||||
Behavior on height {NumberAnimation {duration: 75; }}
|
||||
color: UM.Theme.getColor("error")
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: insertNameLabel
|
||||
text: catalog.i18nc("@label:textbox", "Printer Name:");
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: machineName;
|
||||
text: getMachineName()
|
||||
implicitWidth: UM.Theme.getSize("standard_list_input").width
|
||||
maximumLength: 40
|
||||
}
|
||||
}
|
||||
|
||||
function saveMachine()
|
||||
{
|
||||
if(machineList.currentIndex != -1)
|
||||
{
|
||||
var item = machineList.model.getItem(machineList.currentIndex);
|
||||
machineList.model.createInstance(machineName.text, item.id)
|
||||
|
||||
var pages = machineList.model.getItem(machineList.currentIndex).pages
|
||||
|
||||
// Insert new pages (if any)
|
||||
for(var i = 0; i < pages.length; i++)
|
||||
{
|
||||
switch(pages[i]) {
|
||||
case "SelectUpgradedParts":
|
||||
base.wizard.appendPage(Qt.resolvedUrl("SelectUpgradedParts.qml"), catalog.i18nc("@title", "Select Upgraded Parts"));
|
||||
break;
|
||||
case "SelectUpgradedPartsUM2":
|
||||
base.wizard.appendPage(Qt.resolvedUrl("SelectUpgradedPartsUM2.qml"), catalog.i18nc("@title", "Select Upgraded Parts"));
|
||||
break;
|
||||
case "UpgradeFirmware":
|
||||
base.wizard.appendPage(Qt.resolvedUrl("UpgradeFirmware.qml"), catalog.i18nc("@title", "Upgrade Firmware"));
|
||||
break;
|
||||
case "UltimakerCheckup":
|
||||
base.wizard.appendPage(Qt.resolvedUrl("UltimakerCheckup.qml"), catalog.i18nc("@title", "Check Printer"));
|
||||
break;
|
||||
case "BedLeveling":
|
||||
base.wizard.appendPage(Qt.resolvedUrl("Bedleveling.qml"), catalog.i18nc("@title", "Bed Levelling"));
|
||||
break;
|
||||
default:
|
||||
base.wizard.appendPage(Qt.resolvedUrl("%1.qml".arg(pages[i])), pages[i])
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExclusiveGroup { id: printerGroup; }
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
SystemPalette { id: palette }
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
// Copyright (c) 2015 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.1 as UM
|
||||
import Cura 1.0 as Cura
|
||||
import ".."
|
||||
|
||||
Item
|
||||
{
|
||||
id: wizardPage
|
||||
property int leveling_state: 0
|
||||
property bool three_point_leveling: true
|
||||
property int platform_width: UM.MachineManager.getSettingValue("machine_width")
|
||||
property int platform_height: UM.MachineManager.getSettingValue("machine_depth")
|
||||
anchors.fill: parent;
|
||||
property variant printer_connection: Cura.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
||||
Component.onCompleted:
|
||||
{
|
||||
printer_connection.homeBed()
|
||||
printer_connection.moveHead(0, 0, 3)
|
||||
printer_connection.homeHead()
|
||||
}
|
||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||
property variant wizard: null;
|
||||
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Bed Leveling")
|
||||
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","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.")
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: bedlevelingText
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "For every postition; insert a piece of paper under the nozzle and adjust the print bed height. The print bed height is right when the paper is slightly gripped by the tip of the nozzle.")
|
||||
}
|
||||
|
||||
Item{
|
||||
id: bedlevelingWrapper
|
||||
anchors.top: bedlevelingText.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: skipBedlevelingButton.height
|
||||
width: bedlevelingButton.width + skipBedlevelingButton.width + UM.Theme.getSize("default_margin").height < wizardPage.width ? bedlevelingButton.width + skipBedlevelingButton.width + UM.Theme.getSize("default_margin").height : wizardPage.width
|
||||
Button
|
||||
{
|
||||
id: bedlevelingButton
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
text: catalog.i18nc("@action:button","Move to Next Position");
|
||||
onClicked:
|
||||
{
|
||||
if(wizardPage.leveling_state == 0)
|
||||
{
|
||||
printer_connection.moveHead(0, 0, 3)
|
||||
printer_connection.homeHead()
|
||||
printer_connection.moveHead(0, 0, 3)
|
||||
printer_connection.moveHead(platform_width - 10, 0, 0)
|
||||
printer_connection.moveHead(0, 0, -3)
|
||||
}
|
||||
if(wizardPage.leveling_state == 1)
|
||||
{
|
||||
printer_connection.moveHead(0, 0, 3)
|
||||
printer_connection.moveHead(-platform_width/2, platform_height - 10, 0)
|
||||
printer_connection.moveHead(0, 0, -3)
|
||||
}
|
||||
if(wizardPage.leveling_state == 2)
|
||||
{
|
||||
printer_connection.moveHead(0, 0, 3)
|
||||
printer_connection.moveHead(-platform_width/2 + 10, -(platform_height + 10), 0)
|
||||
printer_connection.moveHead(0, 0, -3)
|
||||
}
|
||||
wizardPage.leveling_state++
|
||||
if (wizardPage.leveling_state >= 3){
|
||||
resultText.visible = true
|
||||
skipBedlevelingButton.enabled = false
|
||||
bedlevelingButton.enabled = false
|
||||
wizardPage.leveling_state = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: skipBedlevelingButton
|
||||
anchors.top: parent.width < wizardPage.width ? parent.top : bedlevelingButton.bottom
|
||||
anchors.topMargin: parent.width < wizardPage.width ? 0 : UM.Theme.getSize("default_margin").height/2
|
||||
anchors.left: parent.width < wizardPage.width ? bedlevelingButton.right : parent.left
|
||||
anchors.leftMargin: parent.width < wizardPage.width ? UM.Theme.getSize("default_margin").width : 0
|
||||
text: catalog.i18nc("@action:button","Skip Bedleveling");
|
||||
onClicked: base.nextPage()
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: resultText
|
||||
visible: false
|
||||
anchors.top: bedlevelingWrapper.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 bedleveling.")
|
||||
}
|
||||
|
||||
function threePointLeveling(width, height)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
// Copyright (c) 2015 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.1 as UM
|
||||
|
||||
Item
|
||||
{
|
||||
id: wizardPage
|
||||
property string title
|
||||
|
||||
SystemPalette{id: palette}
|
||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||
|
||||
Component.onDestruction:
|
||||
{
|
||||
if (heatedBedCheckBox1.checked == true || heatedBedCheckBox2.checked == true){
|
||||
UM.MachineManager.setMachineSettingValue("machine_heated_bed", true)
|
||||
}
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Select Upgraded Parts")
|
||||
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","To assist you in having better default settings for your Ultimaker. Cura would like to know which upgrades you have in your machine:")
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
id: pageCheckboxes
|
||||
height: childrenRect.height
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width - UM.Theme.getSize("default_margin").width
|
||||
CheckBox
|
||||
{
|
||||
id: heatedBedCheckBox1
|
||||
text: catalog.i18nc("@option:check","Heated printer bed")
|
||||
y: extruderCheckBox.height * 1
|
||||
checked: false
|
||||
onClicked: {
|
||||
if (heatedBedCheckBox2.checked == true)
|
||||
heatedBedCheckBox2.checked = false
|
||||
}
|
||||
}
|
||||
CheckBox
|
||||
{
|
||||
id: heatedBedCheckBox2
|
||||
text: catalog.i18nc("@option:check","Heated printer bed (self built)")
|
||||
y: extruderCheckBox.height * 2
|
||||
checked: false
|
||||
onClicked: {
|
||||
if (heatedBedCheckBox1.checked == true)
|
||||
heatedBedCheckBox1.checked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
width: parent.width
|
||||
anchors.top: pageCheckboxes.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","If you bought your Ultimaker after october 2012 you will have the Extruder drive upgrade. If you do not have this upgrade, it is highly recommended to improve reliability. This upgrade can be bought from the Ultimaker webshop or found on thingiverse as thing:26094");
|
||||
}
|
||||
|
||||
ExclusiveGroup { id: printerGroup; }
|
||||
}
|
|
@ -1,378 +0,0 @@
|
|||
// Copyright (c) 2015 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.1 as UM
|
||||
|
||||
Item
|
||||
{
|
||||
id: wizardPage
|
||||
property string title
|
||||
property int leftRow: wizardPage.width*0.40
|
||||
property int rightRow: wizardPage.width*0.60
|
||||
anchors.fill: parent;
|
||||
property bool x_min_pressed: false
|
||||
property bool y_min_pressed: false
|
||||
property bool z_min_pressed: false
|
||||
property bool heater_works: false
|
||||
property int extruder_target_temp: 0
|
||||
property int bed_target_temp: 0
|
||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||
property var checkupProgress: {
|
||||
"connection": false,
|
||||
"endstopX": wizardPage.x_min_pressed,
|
||||
"endstopY": wizardPage.y_min_pressed,
|
||||
"endstopZ": wizardPage.z_min_pressed,
|
||||
"nozzleTemp": false,
|
||||
"bedTemp": false
|
||||
}
|
||||
|
||||
property variant printer_connection: {
|
||||
if (Cura.USBPrinterManager.connectedPrinterList.rowCount() != 0){
|
||||
wizardPage.checkupProgress.connection = true
|
||||
return Cura.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function checkTotalCheckUp(){
|
||||
var allDone = true
|
||||
for(var property in checkupProgress){
|
||||
if (checkupProgress[property] == false){
|
||||
allDone = false
|
||||
}
|
||||
}
|
||||
if (allDone == true){
|
||||
skipCheckButton.enabled = false
|
||||
resultText.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted:
|
||||
{
|
||||
if (printer_connection != null){
|
||||
printer_connection.startPollEndstop()
|
||||
}
|
||||
}
|
||||
Component.onDestruction:
|
||||
{
|
||||
if (printer_connection != null){
|
||||
printer_connection.stopPollEndstop()
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
Item{
|
||||
id: startStopButtons
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: childrenRect.height
|
||||
width: startCheckButton.width + skipCheckButton.width + UM.Theme.getSize("default_margin").height < wizardPage.width ? startCheckButton.width + skipCheckButton.width + UM.Theme.getSize("default_margin").height : wizardPage.width
|
||||
Button
|
||||
{
|
||||
id: startCheckButton
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
//enabled: !alreadyTested
|
||||
text: catalog.i18nc("@action:button","Start Printer Check");
|
||||
onClicked: {
|
||||
checkupContent.visible = true
|
||||
startCheckButton.enabled = false
|
||||
printer_connection.homeHead()
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: skipCheckButton
|
||||
anchors.top: parent.width < wizardPage.width ? parent.top : startCheckButton.bottom
|
||||
anchors.topMargin: parent.width < wizardPage.width ? 0 : UM.Theme.getSize("default_margin").height/2
|
||||
anchors.left: parent.width < wizardPage.width ? startCheckButton.right : parent.left
|
||||
anchors.leftMargin: parent.width < wizardPage.width ? UM.Theme.getSize("default_margin").width : 0
|
||||
//enabled: !alreadyTested
|
||||
text: catalog.i18nc("@action:button","Skip Printer Check");
|
||||
onClicked: base.nextPage()
|
||||
}
|
||||
}
|
||||
|
||||
Item{
|
||||
id: checkupContent
|
||||
anchors.top: startStopButtons.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
visible: false
|
||||
//////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: connectionLabel
|
||||
width: wizardPage.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Connection: ")
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: connectionStatus
|
||||
width: wizardPage.rightRow
|
||||
anchors.left: connectionLabel.right
|
||||
anchors.top: parent.top
|
||||
wrapMode: Text.WordWrap
|
||||
text: Cura.USBPrinterManager.connectedPrinterList.rowCount() > 0 || base.addOriginalProgress.checkUp[0] ? catalog.i18nc("@info:status","Done"):catalog.i18nc("@info:status","Incomplete")
|
||||
}
|
||||
//////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: endstopXLabel
|
||||
width: wizardPage.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: connectionLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Min endstop X: ")
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: endstopXStatus
|
||||
width: wizardPage.rightRow
|
||||
anchors.left: endstopXLabel.right
|
||||
anchors.top: connectionLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: x_min_pressed ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: endstopYLabel
|
||||
width: wizardPage.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: endstopXLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Min endstop Y: ")
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: endstopYStatus
|
||||
width: wizardPage.rightRow
|
||||
anchors.left: endstopYLabel.right
|
||||
anchors.top: endstopXLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: y_min_pressed ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: endstopZLabel
|
||||
width: wizardPage.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: endstopYLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Min endstop Z: ")
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: endstopZStatus
|
||||
width: wizardPage.rightRow
|
||||
anchors.left: endstopZLabel.right
|
||||
anchors.top: endstopYLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: z_min_pressed ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: nozzleTempLabel
|
||||
width: wizardPage.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: endstopZLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Nozzle temperature check: ")
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: nozzleTempStatus
|
||||
width: wizardPage.rightRow * 0.4
|
||||
anchors.top: nozzleTempLabel.top
|
||||
anchors.left: nozzleTempLabel.right
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@info:status","Not checked")
|
||||
}
|
||||
Item
|
||||
{
|
||||
id: nozzleTempButton
|
||||
width: wizardPage.rightRow * 0.3
|
||||
height: nozzleTemp.height
|
||||
anchors.top: nozzleTempLabel.top
|
||||
anchors.left: bedTempStatus.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
|
||||
Button
|
||||
{
|
||||
height: nozzleTemp.height - 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: catalog.i18nc("@action:button","Start Heating")
|
||||
onClicked:
|
||||
{
|
||||
if(printer_connection != null)
|
||||
{
|
||||
nozzleTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
||||
printer_connection.setTargetHotendTemperature(0, 190)
|
||||
wizardPage.extruder_target_temp = 190
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: nozzleTemp
|
||||
anchors.top: nozzleTempLabel.top
|
||||
anchors.left: nozzleTempButton.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
width: wizardPage.rightRow * 0.2
|
||||
wrapMode: Text.WordWrap
|
||||
text: printer_connection != null ? printer_connection.hotendTemperatures[0] + "°C" : "0°C"
|
||||
font.bold: true
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Label
|
||||
{
|
||||
id: bedTempLabel
|
||||
width: wizardPage.leftRow
|
||||
anchors.left: parent.left
|
||||
anchors.top: nozzleTempLabel.bottom
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","bed temperature check:")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: bedTempStatus
|
||||
width: wizardPage.rightRow * 0.4
|
||||
anchors.top: bedTempLabel.top
|
||||
anchors.left: bedTempLabel.right
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@info:status","Not checked")
|
||||
}
|
||||
Item
|
||||
{
|
||||
id: bedTempButton
|
||||
width: wizardPage.rightRow * 0.3
|
||||
height: bedTemp.height
|
||||
anchors.top: bedTempLabel.top
|
||||
anchors.left: bedTempStatus.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
|
||||
Button
|
||||
{
|
||||
height: bedTemp.height - 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: catalog.i18nc("@action:button","Start Heating")
|
||||
onClicked:
|
||||
{
|
||||
if(printer_connection != null)
|
||||
{
|
||||
bedTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
||||
printer_connection.setTargetBedTemperature(60)
|
||||
wizardPage.bed_target_temp = 60
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Label
|
||||
{
|
||||
id: bedTemp
|
||||
width: wizardPage.rightRow * 0.2
|
||||
anchors.top: bedTempLabel.top
|
||||
anchors.left: bedTempButton.right
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
wrapMode: Text.WordWrap
|
||||
text: printer_connection != null ? printer_connection.bedTemperature + "°C": "0°C"
|
||||
font.bold: true
|
||||
}
|
||||
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.")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Connections
|
||||
{
|
||||
target: printer_connection
|
||||
onEndstopStateChanged:
|
||||
{
|
||||
if(key == "x_min")
|
||||
{
|
||||
x_min_pressed = true
|
||||
checkTotalCheckUp()
|
||||
}
|
||||
if(key == "y_min")
|
||||
{
|
||||
y_min_pressed = true
|
||||
checkTotalCheckUp()
|
||||
}
|
||||
if(key == "z_min")
|
||||
{
|
||||
z_min_pressed = true
|
||||
checkTotalCheckUp()
|
||||
}
|
||||
}
|
||||
|
||||
onHotendTemperaturesChanged:
|
||||
{
|
||||
if(printer_connection.hotendTemperatures[0] > wizardPage.extruder_target_temp - 10 && printer_connection.hotendTemperatures[0] < wizardPage.extruder_target_temp + 10)
|
||||
{
|
||||
if(printer_connection != null)
|
||||
{
|
||||
nozzleTempStatus.text = catalog.i18nc("@info:status","Works")
|
||||
wizardPage.checkupProgress.nozzleTemp = true
|
||||
checkTotalCheckUp()
|
||||
printer_connection.setTargetHotendTemperature(0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
onBedTemperatureChanged:
|
||||
{
|
||||
if(printer_connection.bedTemperature > wizardPage.bed_target_temp - 5 && printer_connection.bedTemperature < wizardPage.bed_target_temp + 5)
|
||||
{
|
||||
bedTempStatus.text = catalog.i18nc("@info:status","Works")
|
||||
wizardPage.checkupProgress.bedTemp = true
|
||||
checkTotalCheckUp()
|
||||
printer_connection.setTargetBedTemperature(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExclusiveGroup
|
||||
{
|
||||
id: printerGroup;
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
// Copyright (c) 2015 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.1 as UM
|
||||
|
||||
Item
|
||||
{
|
||||
id: wizardPage
|
||||
property string title
|
||||
|
||||
SystemPalette{id: palette}
|
||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||
property variant printer_connection: Cura.USBPrinterManager.connectedPrinterList.rowCount() != 0 ? Cura.USBPrinterManager.connectedPrinterList.getItem(0).printer : null
|
||||
Label
|
||||
{
|
||||
id: pageTitle
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@title", "Upgrade Firmware")
|
||||
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","Firmware is the piece of software running directly on your 3D printer. This firmware controls the step motors, regulates the temperature and ultimately makes your printer work.")
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: upgradeText1
|
||||
anchors.top: pageDescription.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","The firmware shipping with new Ultimakers works, but upgrades have been made to make better prints, and make calibration easier.");
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: upgradeText2
|
||||
anchors.top: upgradeText1.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label","Cura requires these new features and thus your firmware will most likely need to be upgraded. You can do so now.");
|
||||
}
|
||||
Item{
|
||||
anchors.top: upgradeText2.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: upgradeButton.width + skipUpgradeButton.width + UM.Theme.getSize("default_margin").height < wizardPage.width ? upgradeButton.width + skipUpgradeButton.width + UM.Theme.getSize("default_margin").height : wizardPage.width
|
||||
Button {
|
||||
id: upgradeButton
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
text: catalog.i18nc("@action:button","Upgrade to Marlin Firmware");
|
||||
onClicked: Cura.USBPrinterManager.updateAllFirmware()
|
||||
}
|
||||
Button {
|
||||
id: skipUpgradeButton
|
||||
anchors.top: parent.width < wizardPage.width ? parent.top : upgradeButton.bottom
|
||||
anchors.topMargin: parent.width < wizardPage.width ? 0 : UM.Theme.getSize("default_margin").height/2
|
||||
anchors.left: parent.width < wizardPage.width ? upgradeButton.right : parent.left
|
||||
anchors.leftMargin: parent.width < wizardPage.width ? UM.Theme.getSize("default_margin").width : 0
|
||||
text: catalog.i18nc("@action:button","Skip Upgrade");
|
||||
onClicked: base.nextPage()
|
||||
}
|
||||
}
|
||||
ExclusiveGroup { id: printerGroup; }
|
||||
}
|
77
tests/TestMachineAction.py
Normal file
77
tests/TestMachineAction.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
#Todo: Write tests
|
||||
|
||||
import pytest
|
||||
|
||||
from cura.MachineAction import MachineAction
|
||||
from cura.MachineActionManager import MachineActionManager, NotUniqueMachineActionError, UnknownMachineActionError
|
||||
|
||||
class Machine:
|
||||
def __init__(self, key = ""):
|
||||
self._key = key
|
||||
|
||||
def getKey(self):
|
||||
return self._key
|
||||
|
||||
def test_addMachineAction():
|
||||
|
||||
machine_manager = MachineActionManager()
|
||||
|
||||
test_action = MachineAction(key = "test_action")
|
||||
test_action_2 = MachineAction(key = "test_action_2")
|
||||
test_machine = Machine("test_machine")
|
||||
machine_manager.addMachineAction(test_action)
|
||||
machine_manager.addMachineAction(test_action_2)
|
||||
|
||||
assert machine_manager.getMachineAction("test_action") == test_action
|
||||
assert machine_manager.getMachineAction("key_that_doesnt_exist") is None
|
||||
|
||||
# Adding the same machine action is not allowed.
|
||||
with pytest.raises(NotUniqueMachineActionError):
|
||||
machine_manager.addMachineAction(test_action)
|
||||
|
||||
# Check that the machine has no supported actions yet.
|
||||
assert machine_manager.getSupportedActions(test_machine) == set()
|
||||
|
||||
# Check if adding a supported action works.
|
||||
machine_manager.addSupportedAction(test_machine, "test_action")
|
||||
assert machine_manager.getSupportedActions(test_machine) == {test_action}
|
||||
|
||||
# Check that adding a unknown action doesn't change anything.
|
||||
machine_manager.addSupportedAction(test_machine, "key_that_doesnt_exist")
|
||||
assert machine_manager.getSupportedActions(test_machine) == {test_action}
|
||||
|
||||
# Check if adding multiple supported actions works.
|
||||
machine_manager.addSupportedAction(test_machine, "test_action_2")
|
||||
assert machine_manager.getSupportedActions(test_machine) == {test_action, test_action_2}
|
||||
|
||||
# Check that the machine has no required actions yet.
|
||||
assert machine_manager.getRequiredActions(test_machine) == set()
|
||||
|
||||
## Ensure that only known actions can be added.
|
||||
with pytest.raises(UnknownMachineActionError):
|
||||
machine_manager.addRequiredAction(test_machine, "key_that_doesnt_exist")
|
||||
|
||||
## Check if adding single required action works
|
||||
machine_manager.addRequiredAction(test_machine, "test_action")
|
||||
assert machine_manager.getRequiredActions(test_machine) == {test_action}
|
||||
|
||||
# Check if adding multiple required actions works.
|
||||
machine_manager.addRequiredAction(test_machine, "test_action_2")
|
||||
assert machine_manager.getRequiredActions(test_machine) == {test_action, test_action_2}
|
||||
|
||||
# Ensure that firstStart actions are empty by default.
|
||||
assert machine_manager.getFirstStartActions(test_machine) == []
|
||||
|
||||
# Check if adding multiple (the same) actions to first start actions work.
|
||||
machine_manager.addFirstStartAction(test_machine, "test_action")
|
||||
machine_manager.addFirstStartAction(test_machine, "test_action")
|
||||
assert machine_manager.getFirstStartActions(test_machine) == [test_action, test_action]
|
||||
|
||||
# Check if inserting an action works
|
||||
machine_manager.addFirstStartAction(test_machine, "test_action_2", index = 1)
|
||||
assert machine_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action]
|
||||
|
||||
# Check that adding a unknown action doesn't change anything.
|
||||
machine_manager.addFirstStartAction(test_machine, "key_that_doesnt_exist", index = 1)
|
||||
assert machine_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action]
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue