mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-04-29 23:34:32 +08:00
Add basic support for print job actions via Cloud output device
This commit is contained in:
parent
c65fefce67
commit
eb8d353e11
@ -22,10 +22,6 @@ Item
|
|||||||
// The print job which all other data is derived from
|
// The print job which all other data is derived from
|
||||||
property var printJob: null
|
property var printJob: null
|
||||||
|
|
||||||
// If the printer is a cloud printer or not. Other items base their enabled state off of this boolean. In the future
|
|
||||||
// they might not need to though.
|
|
||||||
property bool cloudConnection: Cura.MachineManager.activeMachineIsUsingCloudConnection
|
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
|
|
||||||
@ -217,7 +213,6 @@ Item
|
|||||||
}
|
}
|
||||||
width: 32 * screenScaleFactor // TODO: Theme!
|
width: 32 * screenScaleFactor // TODO: Theme!
|
||||||
height: 32 * screenScaleFactor // TODO: Theme!
|
height: 32 * screenScaleFactor // TODO: Theme!
|
||||||
enabled: !cloudConnection
|
|
||||||
onClicked: enabled ? contextMenu.switchPopupState() : {}
|
onClicked: enabled ? contextMenu.switchPopupState() : {}
|
||||||
visible:
|
visible:
|
||||||
{
|
{
|
||||||
|
@ -172,7 +172,6 @@ Item
|
|||||||
}
|
}
|
||||||
width: 36 * screenScaleFactor // TODO: Theme!
|
width: 36 * screenScaleFactor // TODO: Theme!
|
||||||
height: 36 * screenScaleFactor // TODO: Theme!
|
height: 36 * screenScaleFactor // TODO: Theme!
|
||||||
enabled: !cloudConnection
|
|
||||||
|
|
||||||
onClicked: enabled ? contextMenu.switchPopupState() : {}
|
onClicked: enabled ? contextMenu.switchPopupState() : {}
|
||||||
visible:
|
visible:
|
||||||
|
@ -73,8 +73,6 @@ Item
|
|||||||
MouseArea
|
MouseArea
|
||||||
{
|
{
|
||||||
anchors.fill: manageQueueLabel
|
anchors.fill: manageQueueLabel
|
||||||
enabled: !cloudConnection
|
|
||||||
hoverEnabled: !cloudConnection
|
|
||||||
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel()
|
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrintJobControlPanel()
|
||||||
onEntered:
|
onEntered:
|
||||||
{
|
{
|
||||||
|
@ -96,6 +96,21 @@ class CloudApiClient:
|
|||||||
reply = self._manager.post(self._createEmptyRequest(url), b"")
|
reply = self._manager.post(self._createEmptyRequest(url), b"")
|
||||||
self._addCallback(reply, on_finished, CloudPrintResponse)
|
self._addCallback(reply, on_finished, CloudPrintResponse)
|
||||||
|
|
||||||
|
## Send a print job action to the cluster for the given print job.
|
||||||
|
# \param cluster_id: The ID of the cluster.
|
||||||
|
# \param cluster_job_id: The ID of the print job within the cluster.
|
||||||
|
# \param action: The name of the action to execute.
|
||||||
|
def doPrintJobAction(self, cluster_id: str, cluster_job_id: str, action: str, data: Dict[str, any] = None) -> None:
|
||||||
|
body = b""
|
||||||
|
if data:
|
||||||
|
try:
|
||||||
|
body = json.dumps({"data": data}).encode()
|
||||||
|
except JSONDecodeError as err:
|
||||||
|
Logger.log("w", "Could not encode body: %s", err)
|
||||||
|
return
|
||||||
|
url = "{}/clusters/{}/print_jobs/{}/action/{}".format(self.CLUSTER_API_ROOT, cluster_id, cluster_job_id, action)
|
||||||
|
self._manager.post(self._createEmptyRequest(url), body)
|
||||||
|
|
||||||
## We override _createEmptyRequest in order to add the user credentials.
|
## We override _createEmptyRequest in order to add the user credentials.
|
||||||
# \param url: The URL to request
|
# \param url: The URL to request
|
||||||
# \param content_type: The type of the body contents.
|
# \param content_type: The type of the body contents.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
|
||||||
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
@ -13,10 +14,13 @@ class CloudOutputController(PrinterOutputController):
|
|||||||
|
|
||||||
# The cloud connection only supports fetching the printer and queue status and adding a job to the queue.
|
# The cloud connection only supports fetching the printer and queue status and adding a job to the queue.
|
||||||
# To let the UI know this we mark all features below as False.
|
# To let the UI know this we mark all features below as False.
|
||||||
self.can_pause = False
|
self.can_pause = True
|
||||||
self.can_abort = False
|
self.can_abort = True
|
||||||
self.can_pre_heat_bed = False
|
self.can_pre_heat_bed = False
|
||||||
self.can_pre_heat_hotends = False
|
self.can_pre_heat_hotends = False
|
||||||
self.can_send_raw_gcode = False
|
self.can_send_raw_gcode = False
|
||||||
self.can_control_manually = False
|
self.can_control_manually = False
|
||||||
self.can_update_firmware = False
|
self.can_update_firmware = False
|
||||||
|
|
||||||
|
def setJobState(self, job: "PrintJobOutputModel", state: str):
|
||||||
|
self._output_device.setJobState(job.key, state)
|
||||||
|
@ -6,6 +6,7 @@ from time import time
|
|||||||
from typing import Dict, List, Optional, Set, cast
|
from typing import Dict, List, Optional, Set, cast
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot
|
||||||
|
from PyQt5.QtGui import QDesktopServices
|
||||||
|
|
||||||
from UM import i18nCatalog
|
from UM import i18nCatalog
|
||||||
from UM.Backend.Backend import BackendState
|
from UM.Backend.Backend import BackendState
|
||||||
@ -399,6 +400,22 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
return [print_job for print_job in self._print_jobs if
|
return [print_job for print_job in self._print_jobs if
|
||||||
print_job.assignedPrinter is not None and print_job.state != "queued"]
|
print_job.assignedPrinter is not None and print_job.state != "queued"]
|
||||||
|
|
||||||
|
def setJobState(self, print_job_uuid: str, state: str) -> None:
|
||||||
|
self._api.doPrintJobAction(self._cluster.cluster_id, print_job_uuid, state)
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def sendJobToTop(self, print_job_uuid: str) -> None:
|
||||||
|
self._api.doPrintJobAction(self._cluster.cluster_id, print_job_uuid, "move",
|
||||||
|
{"list": "queued", "to_position": 0})
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def deleteJobFromQueue(self, print_job_uuid: str) -> None:
|
||||||
|
self._api.doPrintJobAction(self._cluster.cluster_id, print_job_uuid, "remove")
|
||||||
|
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def forceSendJob(self, print_job_uuid: str) -> None:
|
||||||
|
self._api.doPrintJobAction(self._cluster.cluster_id, print_job_uuid, "force")
|
||||||
|
|
||||||
@pyqtSlot(int, result = str)
|
@pyqtSlot(int, result = str)
|
||||||
def formatDuration(self, seconds: int) -> str:
|
def formatDuration(self, seconds: int) -> str:
|
||||||
return Duration(seconds).getDisplayString(DurationFormat.Format.Short)
|
return Duration(seconds).getDisplayString(DurationFormat.Format.Short)
|
||||||
@ -411,6 +428,18 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
def getDateCompleted(self, time_remaining: int) -> str:
|
def getDateCompleted(self, time_remaining: int) -> str:
|
||||||
return formatDateCompleted(time_remaining)
|
return formatDateCompleted(time_remaining)
|
||||||
|
|
||||||
|
@pyqtProperty(bool, notify=printJobsChanged)
|
||||||
|
def receivedPrintJobs(self) -> bool:
|
||||||
|
return bool(self._print_jobs)
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def openPrintJobControlPanel(self) -> None:
|
||||||
|
QDesktopServices.openUrl(QUrl("https://mycloud.ultimaker.com"))
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def openPrinterControlPanel(self) -> None:
|
||||||
|
QDesktopServices.openUrl(QUrl("https://mycloud.ultimaker.com"))
|
||||||
|
|
||||||
## TODO: The following methods are required by the monitor page QML, but are not actually available using cloud.
|
## TODO: The following methods are required by the monitor page QML, but are not actually available using cloud.
|
||||||
# TODO: We fake the methods here to not break the monitor page.
|
# TODO: We fake the methods here to not break the monitor page.
|
||||||
|
|
||||||
@ -422,30 +451,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
def setActiveCameraUrl(self, camera_url: "QUrl") -> None:
|
def setActiveCameraUrl(self, camera_url: "QUrl") -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@pyqtProperty(bool, notify = printJobsChanged)
|
|
||||||
def receivedPrintJobs(self) -> bool:
|
|
||||||
return bool(self._print_jobs)
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def openPrintJobControlPanel(self) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def openPrinterControlPanel(self) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@pyqtSlot(str)
|
|
||||||
def sendJobToTop(self, print_job_uuid: str) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@pyqtSlot(str)
|
|
||||||
def deleteJobFromQueue(self, print_job_uuid: str) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@pyqtSlot(str)
|
|
||||||
def forceSendJob(self, print_job_uuid: str) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@pyqtProperty("QVariantList", notify = _clusterPrintersChanged)
|
@pyqtProperty("QVariantList", notify = _clusterPrintersChanged)
|
||||||
def connectedPrintersTypeCount(self) -> List[Dict[str, str]]:
|
def connectedPrintersTypeCount(self) -> List[Dict[str, str]]:
|
||||||
return []
|
return []
|
||||||
|
BIN
resources/qml/BorderGroup.qmlc.pqgKbT
Normal file
BIN
resources/qml/BorderGroup.qmlc.pqgKbT
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user