mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-06 22:47:29 -06:00
Merge pull request #20680 from Ultimaker/CURA-12557_handle-deactivated-things
CURA-12557 handle deactivated things
This commit is contained in:
commit
4e04d06db0
16 changed files with 207 additions and 48 deletions
|
@ -33,8 +33,8 @@ class AuthState(IntEnum):
|
|||
class NetworkedPrinterOutputDevice(PrinterOutputDevice):
|
||||
authenticationStateChanged = pyqtSignal()
|
||||
|
||||
def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], connection_type: ConnectionType = ConnectionType.NetworkConnection, parent: QObject = None) -> None:
|
||||
super().__init__(device_id = device_id, connection_type = connection_type, parent = parent)
|
||||
def __init__(self, device_id, address: str, properties: Dict[bytes, bytes], connection_type: ConnectionType = ConnectionType.NetworkConnection, parent: QObject = None, active: bool = True) -> None:
|
||||
super().__init__(device_id = device_id, connection_type = connection_type, parent = parent, active = active)
|
||||
self._manager = None # type: Optional[QNetworkAccessManager]
|
||||
self._timeout_time = 10 # After how many seconds of no response should a timeout occur?
|
||||
|
||||
|
|
|
@ -72,7 +72,10 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
# Signal to indicate that the configuration of one of the printers has changed.
|
||||
uniqueConfigurationsChanged = pyqtSignal()
|
||||
|
||||
def __init__(self, device_id: str, connection_type: "ConnectionType" = ConnectionType.NotConnected, parent: QObject = None) -> None:
|
||||
# Signal to indicate that the printer has become active or inactive
|
||||
activeChanged = pyqtSignal()
|
||||
|
||||
def __init__(self, device_id: str, connection_type: "ConnectionType" = ConnectionType.NotConnected, parent: QObject = None, active: bool = True) -> None:
|
||||
super().__init__(device_id = device_id, parent = parent) # type: ignore # MyPy complains with the multiple inheritance
|
||||
|
||||
self._printers = [] # type: List[PrinterOutputModel]
|
||||
|
@ -88,6 +91,8 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
|
||||
self._accepts_commands = False # type: bool
|
||||
|
||||
self._active: bool = active
|
||||
|
||||
self._update_timer = QTimer() # type: QTimer
|
||||
self._update_timer.setInterval(2000) # TODO; Add preference for update interval
|
||||
self._update_timer.setSingleShot(False)
|
||||
|
@ -295,3 +300,17 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
|||
return
|
||||
|
||||
self._firmware_updater.updateFirmware(firmware_file)
|
||||
|
||||
@pyqtProperty(bool, notify = activeChanged)
|
||||
def active(self) -> bool:
|
||||
"""
|
||||
Indicates whether the printer is active, which is not the same as "being the active printer". In this case,
|
||||
active means that the printer can be used. An example of an inactive printer is one that cannot be used because
|
||||
the user doesn't have enough seats on Digital Factory.
|
||||
"""
|
||||
return self._active
|
||||
|
||||
def _setActive(self, active: bool) -> None:
|
||||
if active != self._active:
|
||||
self._active = active
|
||||
self.activeChanged.emit()
|
||||
|
|
|
@ -183,10 +183,14 @@ class MachineManager(QObject):
|
|||
self.setActiveMachine(active_machine_id)
|
||||
|
||||
def _onOutputDevicesChanged(self) -> None:
|
||||
for printer_output_device in self._printer_output_devices:
|
||||
printer_output_device.activeChanged.disconnect(self.printerConnectedStatusChanged)
|
||||
|
||||
self._printer_output_devices = []
|
||||
for printer_output_device in self._application.getOutputDeviceManager().getOutputDevices():
|
||||
if isinstance(printer_output_device, PrinterOutputDevice):
|
||||
self._printer_output_devices.append(printer_output_device)
|
||||
printer_output_device.activeChanged.connect(self.printerConnectedStatusChanged)
|
||||
|
||||
self.outputDevicesChanged.emit()
|
||||
|
||||
|
@ -569,6 +573,13 @@ class MachineManager(QObject):
|
|||
def activeMachineIsUsingCloudConnection(self) -> bool:
|
||||
return self.activeMachineHasCloudConnection and not self.activeMachineHasNetworkConnection
|
||||
|
||||
@pyqtProperty(bool, notify = printerConnectedStatusChanged)
|
||||
def activeMachineIsActive(self) -> bool:
|
||||
if not self._printer_output_devices:
|
||||
return True
|
||||
|
||||
return self._printer_output_devices[0].active
|
||||
|
||||
def activeMachineNetworkKey(self) -> str:
|
||||
if self._global_container_stack:
|
||||
return self._global_container_stack.getMetaDataEntry("um_network_key", "")
|
||||
|
|
|
@ -11,10 +11,10 @@ Cura.RoundedRectangle
|
|||
width: parent.width
|
||||
height: projectImage.height + 2 * UM.Theme.getSize("default_margin").width
|
||||
cornerSide: Cura.RoundedRectangle.Direction.All
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
border.color: enabled ? UM.Theme.getColor("lining") : UM.Theme.getColor("action_button_disabled_border")
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
radius: UM.Theme.getSize("default_radius").width
|
||||
color: UM.Theme.getColor("main_background")
|
||||
color: getBackgroundColor()
|
||||
signal clicked()
|
||||
property alias imageSource: projectImage.source
|
||||
property alias projectNameText: displayNameLabel.text
|
||||
|
@ -22,17 +22,18 @@ Cura.RoundedRectangle
|
|||
property alias projectLastUpdatedText: lastUpdatedLabel.text
|
||||
property alias cardMouseAreaEnabled: cardMouseArea.enabled
|
||||
|
||||
onVisibleChanged: color = UM.Theme.getColor("main_background")
|
||||
onVisibleChanged: color = getBackgroundColor()
|
||||
|
||||
MouseArea
|
||||
{
|
||||
id: cardMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: base.color = UM.Theme.getColor("action_button_hovered")
|
||||
onExited: base.color = UM.Theme.getColor("main_background")
|
||||
hoverEnabled: base.enabled
|
||||
onEntered: color = getBackgroundColor()
|
||||
onExited: color = getBackgroundColor()
|
||||
onClicked: base.clicked()
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
id: projectInformationRow
|
||||
|
@ -73,7 +74,7 @@ Cura.RoundedRectangle
|
|||
width: parent.width
|
||||
height: Math.round(parent.height / 3)
|
||||
elide: Text.ElideRight
|
||||
color: UM.Theme.getColor("small_button_text")
|
||||
color: base.enabled ? UM.Theme.getColor("small_button_text") : UM.Theme.getColor("text_disabled")
|
||||
}
|
||||
|
||||
UM.Label
|
||||
|
@ -82,8 +83,27 @@ Cura.RoundedRectangle
|
|||
width: parent.width
|
||||
height: Math.round(parent.height / 3)
|
||||
elide: Text.ElideRight
|
||||
color: UM.Theme.getColor("small_button_text")
|
||||
color: base.enabled ? UM.Theme.getColor("small_button_text") : UM.Theme.getColor("text_disabled")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getBackgroundColor()
|
||||
{
|
||||
if(enabled)
|
||||
{
|
||||
if(cardMouseArea.containsMouse)
|
||||
{
|
||||
return UM.Theme.getColor("action_button_hovered")
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getColor("main_background")
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getColor("action_button_disabled")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -159,20 +159,33 @@ Item
|
|||
Repeater
|
||||
{
|
||||
model: manager.digitalFactoryProjectModel
|
||||
delegate: ProjectSummaryCard
|
||||
delegate: Item
|
||||
{
|
||||
width: parent.width
|
||||
height: projectSummaryCard.height
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
text: "This project is inactive and cannot be used."
|
||||
enabled: !model.active
|
||||
}
|
||||
|
||||
ProjectSummaryCard
|
||||
{
|
||||
id: projectSummaryCard
|
||||
imageSource: model.thumbnailUrl || "../images/placeholder.svg"
|
||||
projectNameText: model.displayName
|
||||
projectUsernameText: model.username
|
||||
projectLastUpdatedText: "Last updated: " + model.lastUpdated
|
||||
enabled: model.active
|
||||
|
||||
onClicked:
|
||||
{
|
||||
onClicked: {
|
||||
manager.selectedProjectIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoadMoreProjectsCard
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@ class DigitalFactoryProjectModel(ListModel):
|
|||
ThumbnailUrlRole = Qt.ItemDataRole.UserRole + 5
|
||||
UsernameRole = Qt.ItemDataRole.UserRole + 6
|
||||
LastUpdatedRole = Qt.ItemDataRole.UserRole + 7
|
||||
ActiveRole = Qt.ItemDataRole.UserRole + 8
|
||||
|
||||
dfProjectModelChanged = pyqtSignal()
|
||||
|
||||
|
@ -28,6 +29,7 @@ class DigitalFactoryProjectModel(ListModel):
|
|||
self.addRoleName(self.ThumbnailUrlRole, "thumbnailUrl")
|
||||
self.addRoleName(self.UsernameRole, "username")
|
||||
self.addRoleName(self.LastUpdatedRole, "lastUpdated")
|
||||
self.addRoleName(self.ActiveRole, "active")
|
||||
self._projects = [] # type: List[DigitalFactoryProjectResponse]
|
||||
|
||||
def setProjects(self, df_projects: List[DigitalFactoryProjectResponse]) -> None:
|
||||
|
@ -59,5 +61,6 @@ class DigitalFactoryProjectModel(ListModel):
|
|||
"thumbnailUrl": project.thumbnail_url,
|
||||
"username": project.username,
|
||||
"lastUpdated": project.last_updated.strftime(PROJECT_UPDATED_AT_DATETIME_FORMAT) if project.last_updated else "",
|
||||
"active": project.active,
|
||||
})
|
||||
self.dfProjectModelChanged.emit()
|
||||
|
|
|
@ -28,6 +28,7 @@ class DigitalFactoryProjectResponse(BaseModel):
|
|||
team_ids: Optional[List[str]] = None,
|
||||
status: Optional[str] = None,
|
||||
technical_requirements: Optional[Dict[str, Any]] = None,
|
||||
is_inactive: bool = False,
|
||||
**kwargs) -> None:
|
||||
"""
|
||||
Creates a new digital factory project response object
|
||||
|
@ -56,6 +57,7 @@ class DigitalFactoryProjectResponse(BaseModel):
|
|||
self.last_updated = datetime.strptime(last_updated, DIGITAL_FACTORY_RESPONSE_DATETIME_FORMAT) if last_updated else None
|
||||
self.status = status
|
||||
self.technical_requirements = technical_requirements
|
||||
self.active = not is_inactive
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def __str__(self) -> str:
|
||||
|
|
|
@ -163,7 +163,7 @@ class CloudApiClient:
|
|||
scope=self._scope,
|
||||
data=b"",
|
||||
callback=self._parseCallback(on_finished, CloudPrintResponse),
|
||||
error_callback=on_error,
|
||||
error_callback=self._parseError(on_error),
|
||||
timeout=self.DEFAULT_REQUEST_TIMEOUT)
|
||||
|
||||
def doPrintJobAction(self, cluster_id: str, cluster_job_id: str, action: str,
|
||||
|
@ -256,7 +256,6 @@ class CloudApiClient:
|
|||
"""Creates a callback function so that it includes the parsing of the response into the correct model.
|
||||
|
||||
The callback is added to the 'finished' signal of the reply.
|
||||
:param reply: The reply that should be listened to.
|
||||
:param on_finished: The callback in case the response is successful. Depending on the endpoint it will be either
|
||||
a list or a single item.
|
||||
:param model: The type of the model to convert the response to.
|
||||
|
@ -281,6 +280,25 @@ class CloudApiClient:
|
|||
self._anti_gc_callbacks.append(parse)
|
||||
return parse
|
||||
|
||||
def _parseError(self,
|
||||
on_error: Callable[[CloudError, "QNetworkReply.NetworkError", int], None]) -> Callable[[QNetworkReply, "QNetworkReply.NetworkError"], None]:
|
||||
|
||||
"""Creates a callback function so that it includes the parsing of an explicit error response into the correct model.
|
||||
|
||||
:param on_error: The callback in case the response gives an explicit error
|
||||
"""
|
||||
|
||||
def parse(reply: QNetworkReply, error: "QNetworkReply.NetworkError") -> None:
|
||||
|
||||
self._anti_gc_callbacks.remove(parse)
|
||||
|
||||
http_code, response = self._parseReply(reply)
|
||||
result = CloudError(**response["errors"][0])
|
||||
on_error(result, error, http_code)
|
||||
|
||||
self._anti_gc_callbacks.append(parse)
|
||||
return parse
|
||||
|
||||
@classmethod
|
||||
def getMachineIDMap(cls) -> Dict[str, str]:
|
||||
if cls._machine_id_to_name is None:
|
||||
|
|
|
@ -27,9 +27,11 @@ from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOut
|
|||
from ..Messages.PrintJobUploadBlockedMessage import PrintJobUploadBlockedMessage
|
||||
from ..Messages.PrintJobUploadErrorMessage import PrintJobUploadErrorMessage
|
||||
from ..Messages.PrintJobUploadQueueFullMessage import PrintJobUploadQueueFullMessage
|
||||
from ..Messages.PrintJobUploadPrinterInactiveMessage import PrintJobUploadPrinterInactiveMessage
|
||||
from ..Messages.PrintJobUploadSuccessMessage import PrintJobUploadSuccessMessage
|
||||
from ..Models.Http.CloudClusterResponse import CloudClusterResponse
|
||||
from ..Models.Http.CloudClusterStatus import CloudClusterStatus
|
||||
from ..Models.Http.CloudError import CloudError
|
||||
from ..Models.Http.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
|
||||
from ..Models.Http.CloudPrintResponse import CloudPrintResponse
|
||||
from ..Models.Http.CloudPrintJobResponse import CloudPrintJobResponse
|
||||
|
@ -87,7 +89,8 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
|
|||
address="",
|
||||
connection_type=ConnectionType.CloudConnection,
|
||||
properties=properties,
|
||||
parent=parent
|
||||
parent=parent,
|
||||
active=cluster.display_status != "inactive"
|
||||
)
|
||||
|
||||
self._api = api_client
|
||||
|
@ -190,6 +193,8 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
|
|||
self._received_print_jobs = status.print_jobs
|
||||
self._updatePrintJobs(status.print_jobs)
|
||||
|
||||
self._setActive(status.active)
|
||||
|
||||
def requestWrite(self, nodes: List[SceneNode], file_name: Optional[str] = None, limit_mimetypes: bool = False,
|
||||
file_handler: Optional[FileHandler] = None, filter_by_machine: bool = False, **kwargs) -> None:
|
||||
|
||||
|
@ -291,19 +296,21 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
|
|||
|
||||
self.writeFinished.emit()
|
||||
|
||||
def _onPrintUploadSpecificError(self, reply: "QNetworkReply", _: "QNetworkReply.NetworkError"):
|
||||
def _onPrintUploadSpecificError(self, error: CloudError, _: "QNetworkReply.NetworkError", http_error: int):
|
||||
"""
|
||||
Displays a message when an error occurs specific to uploading print job (i.e. queue is full).
|
||||
"""
|
||||
error_code = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute)
|
||||
if error_code == 409:
|
||||
if http_error == 409:
|
||||
if error.code == "printerInactive":
|
||||
PrintJobUploadPrinterInactiveMessage().show()
|
||||
else:
|
||||
PrintJobUploadQueueFullMessage().show()
|
||||
else:
|
||||
PrintJobUploadErrorMessage(I18N_CATALOG.i18nc("@error:send",
|
||||
"Unknown error code when uploading print job: {0}",
|
||||
error_code)).show()
|
||||
http_error)).show()
|
||||
|
||||
Logger.log("w", "Upload of print job failed specifically with error code {}".format(error_code))
|
||||
Logger.log("w", "Upload of print job failed specifically with error code {}".format(http_error))
|
||||
|
||||
self._progress.hide()
|
||||
self._pre_upload_print_job = None
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# Copyright (c) 2020 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from UM import i18nCatalog
|
||||
from UM.Message import Message
|
||||
|
||||
|
||||
I18N_CATALOG = i18nCatalog("cura")
|
||||
|
||||
|
||||
class PrintJobUploadPrinterInactiveMessage(Message):
|
||||
"""Message shown when uploading a print job to a cluster and the printer is inactive."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
text = I18N_CATALOG.i18nc("@info:status", "The printer is inactive and cannot accept a new print job."),
|
||||
title = I18N_CATALOG.i18nc("@info:title", "Printer inactive"),
|
||||
lifetime = 10,
|
||||
message_type=Message.MessageType.ERROR
|
||||
)
|
|
@ -10,7 +10,7 @@ class CloudClusterResponse(BaseModel):
|
|||
"""Class representing a cloud connected cluster."""
|
||||
|
||||
def __init__(self, cluster_id: str, host_guid: str, host_name: str, is_online: bool, status: str,
|
||||
host_internal_ip: Optional[str] = None, host_version: Optional[str] = None,
|
||||
display_status: str, host_internal_ip: Optional[str] = None, host_version: Optional[str] = None,
|
||||
friendly_name: Optional[str] = None, printer_type: str = "ultimaker3", printer_count: int = 1,
|
||||
capabilities: Optional[List[str]] = None, **kwargs) -> None:
|
||||
"""Creates a new cluster response object.
|
||||
|
@ -20,6 +20,7 @@ class CloudClusterResponse(BaseModel):
|
|||
:param host_name: The name of the printer as configured during the Wi-Fi setup. Used as identifier for end users.
|
||||
:param is_online: Whether this cluster is currently connected to the cloud.
|
||||
:param status: The status of the cluster authentication (active or inactive).
|
||||
:param display_status: The display status of the cluster.
|
||||
:param host_version: The firmware version of the cluster host. This is where the Stardust client is running on.
|
||||
:param host_internal_ip: The internal IP address of the host printer.
|
||||
:param friendly_name: The human readable name of the host printer.
|
||||
|
@ -31,6 +32,7 @@ class CloudClusterResponse(BaseModel):
|
|||
self.host_guid = host_guid
|
||||
self.host_name = host_name
|
||||
self.status = status
|
||||
self.display_status = display_status
|
||||
self.is_online = is_online
|
||||
self.host_version = host_version
|
||||
self.host_internal_ip = host_internal_ip
|
||||
|
@ -51,5 +53,5 @@ class CloudClusterResponse(BaseModel):
|
|||
Convenience function for printing when debugging.
|
||||
:return: A human-readable representation of the data in this object.
|
||||
"""
|
||||
return str({k: v for k, v in self.__dict__.items() if k in {"cluster_id", "host_guid", "host_name", "status", "is_online", "host_version", "host_internal_ip", "friendly_name", "printer_type", "printer_count", "capabilities"}})
|
||||
return str({k: v for k, v in self.__dict__.items() if k in {"cluster_id", "host_guid", "host_name", "status", "display_status", "is_online", "host_version", "host_internal_ip", "friendly_name", "printer_type", "printer_count", "capabilities"}})
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ class CloudClusterStatus(BaseModel):
|
|||
def __init__(self, printers: List[Union[ClusterPrinterStatus, Dict[str, Any]]],
|
||||
print_jobs: List[Union[ClusterPrintJobStatus, Dict[str, Any]]],
|
||||
generated_time: Union[str, datetime],
|
||||
unavailable: bool = False,
|
||||
**kwargs) -> None:
|
||||
"""Creates a new cluster status model object.
|
||||
|
||||
|
@ -23,6 +24,7 @@ class CloudClusterStatus(BaseModel):
|
|||
"""
|
||||
|
||||
self.generated_time = self.parseDate(generated_time)
|
||||
self.active = not unavailable
|
||||
self.printers = self.parseModels(ClusterPrinterStatus, printers)
|
||||
self.print_jobs = self.parseModels(ClusterPrintJobStatus, print_jobs)
|
||||
super().__init__(**kwargs)
|
||||
|
|
|
@ -20,13 +20,23 @@ from ..BaseModel import BaseModel
|
|||
class ClusterPrinterStatus(BaseModel):
|
||||
"""Class representing a cluster printer"""
|
||||
|
||||
def __init__(self, enabled: bool, firmware_version: str, friendly_name: str, ip_address: str, machine_variant: str,
|
||||
status: str, unique_name: str, uuid: str,
|
||||
configuration: List[Union[Dict[str, Any], ClusterPrintCoreConfiguration]],
|
||||
reserved_by: Optional[str] = None, maintenance_required: Optional[bool] = None,
|
||||
firmware_update_status: Optional[str] = None, latest_available_firmware: Optional[str] = None,
|
||||
build_plate: Union[Dict[str, Any], ClusterBuildPlate] = None,
|
||||
material_station: Union[Dict[str, Any], ClusterPrinterMaterialStation] = None, **kwargs) -> None:
|
||||
def __init__(self,
|
||||
enabled: Optional[bool] = True,
|
||||
friendly_name: Optional[str] = "",
|
||||
machine_variant: Optional[str] = "",
|
||||
status: Optional[str] = "unknown",
|
||||
unique_name: Optional[str] = "",
|
||||
uuid: Optional[str] = "",
|
||||
configuration: Optional[List[Union[Dict[str, Any], ClusterPrintCoreConfiguration]]] = None,
|
||||
firmware_version: Optional[str] = None,
|
||||
ip_address: Optional[str] = None,
|
||||
reserved_by: Optional[str] = "",
|
||||
maintenance_required: Optional[bool] = False,
|
||||
firmware_update_status: Optional[str] = "",
|
||||
latest_available_firmware: Optional[str] = "",
|
||||
build_plate: Optional[Union[Dict[str, Any], ClusterBuildPlate]] = None,
|
||||
material_station: Optional[Union[Dict[str, Any], ClusterPrinterMaterialStation]] = None,
|
||||
**kwargs) -> None:
|
||||
"""
|
||||
Creates a new cluster printer status
|
||||
:param enabled: A printer can be disabled if it should not receive new jobs. By default, every printer is enabled.
|
||||
|
@ -47,7 +57,7 @@ class ClusterPrinterStatus(BaseModel):
|
|||
:param material_station: The material station that is on the printer.
|
||||
"""
|
||||
|
||||
self.configuration = self.parseModels(ClusterPrintCoreConfiguration, configuration)
|
||||
self.configuration = self.parseModels(ClusterPrintCoreConfiguration, configuration) if configuration else []
|
||||
self.enabled = enabled
|
||||
self.firmware_version = firmware_version
|
||||
self.friendly_name = friendly_name
|
||||
|
@ -70,7 +80,7 @@ class ClusterPrinterStatus(BaseModel):
|
|||
|
||||
:param controller: - The controller of the model.
|
||||
"""
|
||||
model = PrinterOutputModel(controller, len(self.configuration), firmware_version = self.firmware_version)
|
||||
model = PrinterOutputModel(controller, len(self.configuration), firmware_version = self.firmware_version or "")
|
||||
self.updateOutputModel(model)
|
||||
return model
|
||||
|
||||
|
@ -86,6 +96,7 @@ class ClusterPrinterStatus(BaseModel):
|
|||
model.updateType(self.machine_variant)
|
||||
model.updateState(self.status if self.enabled else "disabled")
|
||||
model.updateBuildplate(self.build_plate.type if self.build_plate else "glass")
|
||||
if self.ip_address:
|
||||
model.setCameraUrl(QUrl("http://{}:8080/?action=stream".format(self.ip_address)))
|
||||
|
||||
if not model.printerConfiguration:
|
||||
|
|
|
@ -46,10 +46,10 @@ class UltimakerNetworkedPrinterOutputDevice(NetworkedPrinterOutputDevice):
|
|||
QUEUED_PRINT_JOBS_STATES = {"queued", "error"}
|
||||
|
||||
def __init__(self, device_id: str, address: str, properties: Dict[bytes, bytes], connection_type: ConnectionType,
|
||||
parent=None) -> None:
|
||||
parent=None, active: bool = True) -> None:
|
||||
|
||||
super().__init__(device_id=device_id, address=address, properties=properties, connection_type=connection_type,
|
||||
parent=parent)
|
||||
parent=parent, active=active)
|
||||
# Trigger the printersChanged signal when the private signal is triggered.
|
||||
self.printersChanged.connect(self._clusterPrintersChanged)
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ Cura.ExpandablePopup
|
|||
property bool isConnectedCloudPrinter: machineManager.activeMachineHasCloudConnection
|
||||
property bool isCloudRegistered: machineManager.activeMachineHasCloudRegistration
|
||||
property bool isGroup: machineManager.activeMachineIsGroup
|
||||
property bool isActive: machineManager.activeMachineIsActive
|
||||
property string machineName: {
|
||||
if (isNetworkPrinter && machineManager.activeMachineNetworkGroupName != "")
|
||||
{
|
||||
|
@ -39,9 +40,16 @@ Cura.ExpandablePopup
|
|||
return "printer_connected"
|
||||
}
|
||||
else if (isConnectedCloudPrinter && Cura.API.connectionStatus.isInternetReachable)
|
||||
{
|
||||
if (isActive)
|
||||
{
|
||||
return "printer_cloud_connected"
|
||||
}
|
||||
else
|
||||
{
|
||||
return "printer_cloud_inactive"
|
||||
}
|
||||
}
|
||||
else if (isCloudRegistered)
|
||||
{
|
||||
return "printer_cloud_not_available"
|
||||
|
@ -53,7 +61,7 @@ Cura.ExpandablePopup
|
|||
}
|
||||
|
||||
function getConnectionStatusMessage() {
|
||||
if (connectionStatus == "printer_cloud_not_available")
|
||||
if (connectionStatus === "printer_cloud_not_available")
|
||||
{
|
||||
if(Cura.API.connectionStatus.isInternetReachable)
|
||||
{
|
||||
|
@ -78,6 +86,10 @@ Cura.ExpandablePopup
|
|||
return catalog.i18nc("@status", "The cloud connection is currently unavailable. Please check your internet connection.")
|
||||
}
|
||||
}
|
||||
else if(connectionStatus === "printer_cloud_inactive")
|
||||
{
|
||||
return catalog.i18nc("@status", "This printer is deactivated and can not accept commands or jobs.")
|
||||
}
|
||||
else
|
||||
{
|
||||
return ""
|
||||
|
@ -130,14 +142,18 @@ Cura.ExpandablePopup
|
|||
|
||||
source:
|
||||
{
|
||||
if (connectionStatus == "printer_connected")
|
||||
if (connectionStatus === "printer_connected")
|
||||
{
|
||||
return UM.Theme.getIcon("CheckBlueBG", "low")
|
||||
}
|
||||
else if (connectionStatus == "printer_cloud_connected" || connectionStatus == "printer_cloud_not_available")
|
||||
else if (connectionStatus === "printer_cloud_connected" || connectionStatus === "printer_cloud_not_available")
|
||||
{
|
||||
return UM.Theme.getIcon("CloudBadge", "low")
|
||||
}
|
||||
else if (connectionStatus === "printer_cloud_inactive")
|
||||
{
|
||||
return UM.Theme.getIcon("WarningBadge", "low")
|
||||
}
|
||||
else
|
||||
{
|
||||
return ""
|
||||
|
@ -147,7 +163,21 @@ Cura.ExpandablePopup
|
|||
width: UM.Theme.getSize("printer_status_icon").width
|
||||
height: UM.Theme.getSize("printer_status_icon").height
|
||||
|
||||
color: connectionStatus == "printer_cloud_not_available" ? UM.Theme.getColor("cloud_unavailable") : UM.Theme.getColor("primary")
|
||||
color:
|
||||
{
|
||||
if (connectionStatus === "printer_cloud_not_available")
|
||||
{
|
||||
return UM.Theme.getColor("cloud_unavailable")
|
||||
}
|
||||
else if(connectionStatus === "printer_cloud_inactive")
|
||||
{
|
||||
return UM.Theme.getColor("cloud_inactive")
|
||||
}
|
||||
else
|
||||
{
|
||||
return UM.Theme.getColor("primary")
|
||||
}
|
||||
}
|
||||
|
||||
visible: (isNetworkPrinter || isCloudRegistered) && source != ""
|
||||
|
||||
|
|
|
@ -498,6 +498,7 @@
|
|||
"monitor_carousel_dot_current": [119, 119, 119, 255],
|
||||
|
||||
"cloud_unavailable": [153, 153, 153, 255],
|
||||
"cloud_inactive": [253, 209, 58, 255],
|
||||
"connection_badge_background": [255, 255, 255, 255],
|
||||
"warning_badge_background": [0, 0, 0, 255],
|
||||
"error_badge_background": [255, 255, 255, 255],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue