Create firmware update progress window from QML

This commit is contained in:
fieldOfView 2018-10-03 09:17:51 +02:00
parent b4e186ce78
commit 718ac0a307
5 changed files with 151 additions and 122 deletions

View file

@ -3,26 +3,25 @@
from PyQt5.QtCore import QObject, QUrl, pyqtSignal, pyqtProperty
from UM.Resources import Resources
from cura.PrinterOutputDevice import PrinterOutputDevice
from cura.CuraApplication import CuraApplication
from enum import IntEnum
from threading import Thread
from typing import Union
MYPY = False
if MYPY:
from cura.PrinterOutputDevice import PrinterOutputDevice
class FirmwareUpdater(QObject):
firmwareProgressChanged = pyqtSignal()
firmwareUpdateStateChanged = pyqtSignal()
def __init__(self, output_device: PrinterOutputDevice) -> None:
def __init__(self, output_device: "PrinterOutputDevice") -> None:
super().__init__()
self._output_device = output_device
self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True)
self._firmware_view = None
self._firmware_location = ""
self._firmware_progress = 0
self._firmware_update_state = FirmwareUpdateState.idle
@ -33,7 +32,7 @@ class FirmwareUpdater(QObject):
self._firmware_location = QUrl(file).toLocalFile()
else:
self._firmware_location = file
self._showFirmwareInterface()
self._setFirmwareUpdateState(FirmwareUpdateState.updating)
self._update_firmware_thread.start()
@ -41,20 +40,6 @@ class FirmwareUpdater(QObject):
def _updateFirmware(self) -> None:
raise NotImplementedError("_updateFirmware needs to be implemented")
## Show firmware interface.
# This will create the view if its not already created.
def _showFirmwareInterface(self) -> None:
if self._firmware_view is None:
path = Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "FirmwareUpdateWindow.qml")
self._firmware_view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
if not self._firmware_view:
return
self._onFirmwareProgress(0)
self._setFirmwareUpdateState(FirmwareUpdateState.idle)
self._firmware_view.show()
## Cleanup after a succesful update
def _cleanupAfterUpdate(self) -> None:
# Clean up for next attempt.

View file

@ -20,6 +20,7 @@ MYPY = False
if MYPY:
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
from cura.PrinterOutput.FirmwareUpdater import FirmwareUpdater
i18n_catalog = i18nCatalog("cura")
@ -83,6 +84,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
self._connection_state = ConnectionState.closed #type: ConnectionState
self._firmware_updater = None #type: Optional[FirmwareUpdater]
self._firmware_name = None #type: Optional[str]
self._address = "" #type: str
self._connection_text = "" #type: str
@ -225,4 +227,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
#
# This name can be used to define device type
def getFirmwareName(self) -> Optional[str]:
return self._firmware_name
return self._firmware_name
def getFirmwareUpdater(self) -> Optional["FirmwareUpdater"]:
return self._firmware_updater

View file

@ -1,19 +1,58 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from UM.Application import Application
from UM.Settings.DefinitionContainer import DefinitionContainer
from cura.MachineAction import MachineAction
from UM.i18n import i18nCatalog
from UM.Settings.ContainerRegistry import ContainerRegistry
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject
from typing import Optional
MYPY = False
if MYPY:
from cura.PrinterOutput.FirmwareUpdater import FirmwareUpdater
catalog = i18nCatalog("cura")
## Upgrade the firmware of a machine by USB with this action.
class UpgradeFirmwareMachineAction(MachineAction):
def __init__(self):
def __init__(self) -> None:
super().__init__("UpgradeFirmware", catalog.i18nc("@action", "Upgrade Firmware"))
self._qml_url = "UpgradeFirmwareMachineAction.qml"
ContainerRegistry.getInstance().containerAdded.connect(self._onContainerAdded)
def _onContainerAdded(self, container):
self._active_output_device = None
Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
def _onEngineCreated(self) -> None:
Application.getInstance().getMachineManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
def _onContainerAdded(self, container) -> None:
# Add this action as a supported action to all machine definitions if they support USB connection
if isinstance(container, DefinitionContainer) and container.getMetaDataEntry("type") == "machine" and container.getMetaDataEntry("supports_usb_connection"):
Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey())
def _onOutputDevicesChanged(self) -> None:
if self._active_output_device:
self._active_output_device.activePrinter.getController().canUpdateFirmwareChanged.disconnect(self._onControllerCanUpdateFirmwareChanged)
output_devices = Application.getInstance().getMachineManager().printerOutputDevices
print(output_devices)
self._active_output_device = output_devices[0] if output_devices else None
if self._active_output_device:
self._active_output_device.activePrinter.getController().canUpdateFirmwareChanged.connect(self._onControllerCanUpdateFirmwareChanged)
self.outputDeviceCanUpdateFirmwareChanged.emit()
def _onControllerCanUpdateFirmwareChanged(self) -> None:
self.outputDeviceCanUpdateFirmwareChanged.emit()
outputDeviceCanUpdateFirmwareChanged = pyqtSignal()
@pyqtProperty(QObject, notify = outputDeviceCanUpdateFirmwareChanged)
def firmwareUpdater(self) -> Optional["firmwareUpdater"]:
if self._active_output_device and self._active_output_device.activePrinter.getController().can_update_firmware:
return self._active_output_device.getFirmwareUpdater()
return None

View file

@ -1,4 +1,4 @@
// Copyright (c) 2016 Ultimaker B.V.
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
@ -59,7 +59,8 @@ Cura.MachineAction
enabled: parent.firmwareName != "" && canUpdateFirmware
onClicked:
{
activeOutputDevice.updateFirmware(parent.firmwareName)
firmwareUpdateWindow.visible = true;
activeOutputDevice.updateFirmware(parent.firmwareName);
}
}
Button
@ -78,7 +79,7 @@ Cura.MachineAction
{
width: parent.width
wrapMode: Text.WordWrap
visible: !printerConnected
visible: !printerConnected && !firmwareUpdateWindow.visible
text: catalog.i18nc("@label", "Firmware can not be upgraded because there is no connection with the printer.");
}
@ -89,14 +90,102 @@ Cura.MachineAction
visible: printerConnected && !canUpdateFirmware
text: catalog.i18nc("@label", "Firmware can not be upgraded because the connection with the printer does not support upgrading firmware.");
}
}
FileDialog
FileDialog
{
id: customFirmwareDialog
title: catalog.i18nc("@title:window", "Select custom firmware")
nameFilters: "Firmware image files (*.hex)"
selectExisting: true
onAccepted:
{
id: customFirmwareDialog
title: catalog.i18nc("@title:window", "Select custom firmware")
nameFilters: "Firmware image files (*.hex)"
selectExisting: true
onAccepted: activeOutputDevice.updateFirmware(fileUrl)
firmwareUpdateWindow.visible = true;
activeOutputDevice.updateFirmware(fileUrl);
}
}
UM.Dialog
{
id: firmwareUpdateWindow
width: minimumWidth
minimumWidth: 500 * screenScaleFactor
height: minimumHeight
minimumHeight: 100 * screenScaleFactor
modality: Qt.ApplicationModal
title: catalog.i18nc("@title:window","Firmware Update")
Column
{
anchors.fill: parent
Label
{
anchors
{
left: parent.left
right: parent.right
}
text: {
if(manager.firmwareUpdater == null)
{
return "";
}
switch (manager.firmwareUpdater.firmwareUpdateState)
{
case 0:
return ""; //Not doing anything (eg; idling)
case 1:
return catalog.i18nc("@label","Updating firmware.");
case 2:
return catalog.i18nc("@label","Firmware update completed.");
case 3:
return catalog.i18nc("@label","Firmware update failed due to an unknown error.");
case 4:
return catalog.i18nc("@label","Firmware update failed due to an communication error.");
case 5:
return catalog.i18nc("@label","Firmware update failed due to an input/output error.");
case 6:
return catalog.i18nc("@label","Firmware update failed due to missing firmware.");
}
}
wrapMode: Text.Wrap
}
ProgressBar
{
id: prog
value: (manager.firmwareUpdater != null) ? manager.firmwareUpdater.firmwareProgress : 0
minimumValue: 0
maximumValue: 100
indeterminate:
{
if(manager.firmwareUpdater == null)
{
return false;
}
return manager.firmwareUpdater.firmwareProgress < 1 && manager.firmwareUpdater.firmwareProgress > 0;
}
anchors
{
left: parent.left;
right: parent.right;
}
}
}
rightButtons: [
Button
{
text: catalog.i18nc("@action:button","Close");
enabled: (manager.firmwareUpdater != null) ? manager.firmwareUpdater.firmwareUpdateState != 1 : true;
onClicked: firmwareUpdateWindow.visible = false;
}
]
}
}

View file

@ -1,89 +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.Window 2.2
import QtQuick.Controls 1.2
import UM 1.1 as UM
UM.Dialog
{
id: base;
width: minimumWidth;
minimumWidth: 500 * screenScaleFactor;
height: minimumHeight;
minimumHeight: 100 * screenScaleFactor;
visible: true;
modality: Qt.ApplicationModal;
title: catalog.i18nc("@title:window","Firmware Update");
Column
{
anchors.fill: parent;
Label
{
anchors
{
left: parent.left;
right: parent.right;
}
text: {
switch (manager.firmwareUpdateState)
{
case 0:
return "" //Not doing anything (eg; idling)
case 1:
return catalog.i18nc("@label","Updating firmware.")
case 2:
return catalog.i18nc("@label","Firmware update completed.")
case 3:
return catalog.i18nc("@label","Firmware update failed due to an unknown error.")
case 4:
return catalog.i18nc("@label","Firmware update failed due to an communication error.")
case 5:
return catalog.i18nc("@label","Firmware update failed due to an input/output error.")
case 6:
return catalog.i18nc("@label","Firmware update failed due to missing firmware.")
}
}
wrapMode: Text.Wrap;
}
ProgressBar
{
id: prog
value: manager.firmwareProgress
minimumValue: 0
maximumValue: 100
indeterminate: manager.firmwareProgress < 1 && manager.firmwareProgress > 0
anchors
{
left: parent.left;
right: parent.right;
}
}
SystemPalette
{
id: palette;
}
UM.I18nCatalog { id: catalog; name: "cura"; }
}
rightButtons: [
Button
{
text: catalog.i18nc("@action:button","Close");
enabled: manager.firmwareUpdateState != 1;
onClicked: base.visible = false;
}
]
}