Merge pull request #5997 from Ultimaker/CS-134_fix_ordering_and_move_to_top

CS-134: fix ordering and move to top
This commit is contained in:
Ian Paschal 2019-07-10 14:05:36 +02:00 committed by GitHub
commit 5ac167d61a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 113 additions and 167 deletions

View File

@ -97,7 +97,7 @@ Rectangle
horizontalCenter: parent.horizontalCenter horizontalCenter: parent.horizontalCenter
} }
visible: isNetworkConfigured && !isConnected visible: isNetworkConfigured && !isConnected
text: catalog.i18nc("@info", "Please make sure your printer has a connection:\n- Check if the printer is turned on.\n- Check if the printer is connected to the network.") text: catalog.i18nc("@info", "Please make sure your printer has a connection:\n- Check if the printer is turned on.\n- Check if the printer is connected to the network.\n- Check if you are signed in to discover cloud-connected printers.")
font: UM.Theme.getFont("medium") font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("monitor_text_primary") color: UM.Theme.getColor("monitor_text_primary")
wrapMode: Text.WordWrap wrapMode: Text.WordWrap

View File

@ -95,6 +95,22 @@ Item
} }
spacing: 18 * screenScaleFactor // TODO: Theme! spacing: 18 * screenScaleFactor // TODO: Theme!
Label
{
text: catalog.i18nc("@label", "There are no print jobs in the queue. Slice and send a job to add one.")
color: UM.Theme.getColor("monitor_text_primary")
elide: Text.ElideRight
font: UM.Theme.getFont("medium") // 14pt, regular
anchors.verticalCenter: parent.verticalCenter
width: 600 * screenScaleFactor // TODO: Theme! (Should match column size)
// FIXED-LINE-HEIGHT:
height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
visible: printJobList.count === 0
}
Label Label
{ {
text: catalog.i18nc("@label", "Print jobs") text: catalog.i18nc("@label", "Print jobs")
@ -108,6 +124,7 @@ Item
height: 18 * screenScaleFactor // TODO: Theme! height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering renderType: Text.NativeRendering
visible: printJobList.count > 0
} }
Label Label
@ -123,6 +140,7 @@ Item
height: 18 * screenScaleFactor // TODO: Theme! height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering renderType: Text.NativeRendering
visible: printJobList.count > 0
} }
Label Label
@ -138,6 +156,7 @@ Item
height: 18 * screenScaleFactor // TODO: Theme! height: 18 * screenScaleFactor // TODO: Theme!
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering renderType: Text.NativeRendering
visible: printJobList.count > 0
} }
} }
@ -181,88 +200,4 @@ Item
spacing: 6 // TODO: Theme! spacing: 6 // TODO: Theme!
} }
} }
Rectangle
{
anchors
{
horizontalCenter: parent.horizontalCenter
top: printJobQueueHeadings.bottom
topMargin: 12 * screenScaleFactor // TODO: Theme!
}
height: 48 * screenScaleFactor // TODO: Theme!
width: parent.width
color: UM.Theme.getColor("monitor_card_background")
border.color: UM.Theme.getColor("monitor_card_border")
radius: 2 * screenScaleFactor // TODO: Theme!
visible: OutputDevice.printJobs.length == 0
Row
{
anchors
{
left: parent.left
leftMargin: 18 * screenScaleFactor // TODO: Theme!
verticalCenter: parent.verticalCenter
}
spacing: 18 * screenScaleFactor // TODO: Theme!
height: 18 * screenScaleFactor // TODO: Theme!
Label
{
text: i18n.i18nc("@info", "All jobs are printed.")
color: UM.Theme.getColor("monitor_text_primary")
font: UM.Theme.getFont("medium") // 14pt, regular
renderType: Text.NativeRendering
}
Item
{
id: viewPrintHistoryLabel
height: 18 * screenScaleFactor // TODO: Theme!
width: childrenRect.width
visible: !cloudConnection
UM.RecolorImage
{
id: printHistoryIcon
anchors.verticalCenter: parent.verticalCenter
color: UM.Theme.getColor("monitor_text_link")
source: UM.Theme.getIcon("external_link")
width: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!)
height: 16 * screenScaleFactor // TODO: Theme! (Y U NO USE 18 LIKE ALL OTHER ICONS?!)
}
Label
{
id: viewPrintHistoryText
anchors
{
left: printHistoryIcon.right
leftMargin: 6 * screenScaleFactor // TODO: Theme!
verticalCenter: printHistoryIcon.verticalCenter
}
color: UM.Theme.getColor("monitor_text_link")
font: UM.Theme.getFont("medium") // 14pt, regular
linkColor: UM.Theme.getColor("monitor_text_link")
text: catalog.i18nc("@label link to connect manager", "Manage in browser")
renderType: Text.NativeRendering
}
MouseArea
{
anchors.fill: parent
hoverEnabled: true
onClicked: OutputDevice.openPrintJobControlPanel()
onEntered:
{
viewPrintHistoryText.font.underline = true
}
onExited:
{
viewPrintHistoryText.font.underline = false
}
}
}
}
}
} }

View File

@ -35,8 +35,7 @@ from .Models.CloudPrintResponse import CloudPrintResponse
from .Models.CloudPrintJobResponse import CloudPrintJobResponse from .Models.CloudPrintJobResponse import CloudPrintJobResponse
from .Models.CloudClusterPrinterStatus import CloudClusterPrinterStatus from .Models.CloudClusterPrinterStatus import CloudClusterPrinterStatus
from .Models.CloudClusterPrintJobStatus import CloudClusterPrintJobStatus from .Models.CloudClusterPrintJobStatus import CloudClusterPrintJobStatus
from .Utils import findChanges, formatDateCompleted, formatTimeCompleted from .Utils import formatDateCompleted, formatTimeCompleted
I18N_CATALOG = i18nCatalog("cura") I18N_CATALOG = i18nCatalog("cura")
@ -46,7 +45,6 @@ I18N_CATALOG = i18nCatalog("cura")
# As such, those methods have been implemented here. # As such, those methods have been implemented here.
# Note that this device represents a single remote cluster, not a list of multiple clusters. # Note that this device represents a single remote cluster, not a list of multiple clusters.
class CloudOutputDevice(NetworkedPrinterOutputDevice): class CloudOutputDevice(NetworkedPrinterOutputDevice):
# The interval with which the remote clusters are checked # The interval with which the remote clusters are checked
CHECK_CLUSTER_INTERVAL = 10.0 # seconds CHECK_CLUSTER_INTERVAL = 10.0 # seconds
@ -179,7 +177,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
# Show an error message if we're already sending a job. # Show an error message if we're already sending a job.
if self._progress.visible: if self._progress.visible:
message = Message( message = Message(
text = I18N_CATALOG.i18nc("@info:status", "Sending new jobs (temporarily) blocked, still sending the previous print job."), text=I18N_CATALOG.i18nc("@info:status",
"Sending new jobs (temporarily) blocked, still sending the previous print job."),
title=I18N_CATALOG.i18nc("@info:title", "Cloud error"), title=I18N_CATALOG.i18nc("@info:title", "Cloud error"),
lifetime=10 lifetime=10
) )
@ -237,65 +236,74 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
self._updatePrintJobs(status.print_jobs) self._updatePrintJobs(status.print_jobs)
## Updates the local list of printers with the list received from the cloud. ## Updates the local list of printers with the list received from the cloud.
# \param jobs: The printers received from the cloud. # \param remote_printers: The printers received from the cloud.
def _updatePrinters(self, printers: List[CloudClusterPrinterStatus]) -> None: def _updatePrinters(self, remote_printers: List[CloudClusterPrinterStatus]) -> None:
previous = {p.key: p for p in self._printers} # type: Dict[str, PrinterOutputModel]
received = {p.uuid: p for p in printers} # type: Dict[str, CloudClusterPrinterStatus]
removed_printers, added_printers, updated_printers = findChanges(previous, received)
# Keep track of the new printers to show.
# We create a new list instead of changing the existing one to get the correct order.
new_printers = []
# Check which printers need to be created or updated.
for index, printer_data in enumerate(remote_printers):
printer = next(iter(printer for printer in self._printers if printer.key == printer_data.uuid), None)
if not printer:
new_printers.append(printer_data.createOutputModel(CloudOutputController(self)))
else:
printer_data.updateOutputModel(printer)
new_printers.append(printer)
# Check which printers need to be removed (de-referenced).
remote_printers_keys = [printer_data.uuid for printer_data in remote_printers]
removed_printers = [printer for printer in self._printers if printer.key not in remote_printers_keys]
for removed_printer in removed_printers: for removed_printer in removed_printers:
if self._active_printer == removed_printer: if self._active_printer and self._active_printer.key == removed_printer.key:
self.setActivePrinter(None) self.setActivePrinter(None)
self._printers.remove(removed_printer)
for added_printer in added_printers: self._printers = new_printers
self._printers.append(added_printer.createOutputModel(CloudOutputController(self))) if self._printers and not self.activePrinter:
for model, printer in updated_printers:
printer.updateOutputModel(model)
# Always have an active printer
if self._printers and not self._active_printer:
self.setActivePrinter(self._printers[0]) self.setActivePrinter(self._printers[0])
if added_printers or removed_printers:
self.printersChanged.emit() self.printersChanged.emit()
## Updates the local list of print jobs with the list received from the cloud. ## Updates the local list of print jobs with the list received from the cloud.
# \param jobs: The print jobs received from the cloud. # \param remote_jobs: The print jobs received from the cloud.
def _updatePrintJobs(self, jobs: List[CloudClusterPrintJobStatus]) -> None: def _updatePrintJobs(self, remote_jobs: List[CloudClusterPrintJobStatus]) -> None:
received = {j.uuid: j for j in jobs} # type: Dict[str, CloudClusterPrintJobStatus]
previous = {j.key: j for j in self._print_jobs} # type: Dict[str, UM3PrintJobOutputModel]
removed_jobs, added_jobs, updated_jobs = findChanges(previous, received) # Keep track of the new print jobs to show.
# We create a new list instead of changing the existing one to get the correct order.
new_print_jobs = []
# Check which print jobs need to be created or updated.
for index, print_job_data in enumerate(remote_jobs):
print_job = next(
iter(print_job for print_job in self._print_jobs if print_job.key == print_job_data.uuid), None)
if not print_job:
new_print_jobs.append(self._createPrintJobModel(print_job_data))
else:
print_job_data.updateOutputModel(print_job)
if print_job_data.printer_uuid:
self._updateAssignedPrinter(print_job, print_job_data.printer_uuid)
new_print_jobs.append(print_job)
# Check which print job need to be removed (de-referenced).
remote_job_keys = [print_job_data.uuid for print_job_data in remote_jobs]
removed_jobs = [print_job for print_job in self._print_jobs if print_job.key not in remote_job_keys]
for removed_job in removed_jobs: for removed_job in removed_jobs:
if removed_job.assignedPrinter: if removed_job.assignedPrinter:
removed_job.assignedPrinter.updateActivePrintJob(None) removed_job.assignedPrinter.updateActivePrintJob(None)
removed_job.stateChanged.disconnect(self._onPrintJobStateChanged) removed_job.stateChanged.disconnect(self._onPrintJobStateChanged)
self._print_jobs.remove(removed_job)
for added_job in added_jobs: self._print_jobs = new_print_jobs
self._addPrintJob(added_job)
for model, job in updated_jobs:
job.updateOutputModel(model)
if job.printer_uuid:
self._updateAssignedPrinter(model, job.printer_uuid)
# We only have to update when jobs are added or removed
# updated jobs push their changes via their output model
if added_jobs or removed_jobs:
self.printJobsChanged.emit() self.printJobsChanged.emit()
## Registers a new print job received via the cloud API. ## Create a new print job model based on the remote status of the job.
# \param job: The print job received. # \param remote_job: The remote print job data.
def _addPrintJob(self, job: CloudClusterPrintJobStatus) -> None: def _createPrintJobModel(self, remote_job: CloudClusterPrintJobStatus) -> UM3PrintJobOutputModel:
model = job.createOutputModel(CloudOutputController(self)) model = remote_job.createOutputModel(CloudOutputController(self))
model.stateChanged.connect(self._onPrintJobStateChanged) model.stateChanged.connect(self._onPrintJobStateChanged)
if job.printer_uuid: if remote_job.printer_uuid:
self._updateAssignedPrinter(model, job.printer_uuid) self._updateAssignedPrinter(model, remote_job.printer_uuid)
self._print_jobs.append(model) return model
## Handles the event of a change in a print job state ## Handles the event of a change in a print job state
def _onPrintJobStateChanged(self) -> None: def _onPrintJobStateChanged(self) -> None:
@ -306,7 +314,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
self._finished_jobs.add(job.key) self._finished_jobs.add(job.key)
Message( Message(
title=I18N_CATALOG.i18nc("@info:status", "Print finished"), title=I18N_CATALOG.i18nc("@info:status", "Print finished"),
text = (I18N_CATALOG.i18nc("@info:status", "Printer '{printer_name}' has finished printing '{job_name}'.").format( text=(I18N_CATALOG.i18nc("@info:status",
"Printer '{printer_name}' has finished printing '{job_name}'.").format(
printer_name=job.assignedPrinter.name, printer_name=job.assignedPrinter.name,
job_name=job.name job_name=job.name
) if job.assignedPrinter else ) if job.assignedPrinter else
@ -322,7 +331,6 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
Logger.log("w", "Missing printer %s for job %s in %s", model.assignedPrinter, model.key, Logger.log("w", "Missing printer %s for job %s in %s", model.assignedPrinter, model.key,
[p.key for p in self._printers]) [p.key for p in self._printers])
return return
printer.updateActivePrintJob(model) printer.updateActivePrintJob(model)
model.updateAssignedPrinter(printer) model.updateAssignedPrinter(printer)
@ -332,7 +340,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
self._progress.show() self._progress.show()
self._uploaded_print_job = job_response self._uploaded_print_job = job_response
tool_path = cast(bytes, self._tool_path) tool_path = cast(bytes, self._tool_path)
self._api.uploadToolPath(job_response, tool_path, self._onPrintJobUploaded, self._progress.update, self._onUploadError) self._api.uploadToolPath(job_response, tool_path, self._onPrintJobUploaded, self._progress.update,
self._onUploadError)
## Requests the print to be sent to the printer when we finished uploading the mesh. ## Requests the print to be sent to the printer when we finished uploading the mesh.
def _onPrintJobUploaded(self) -> None: def _onPrintJobUploaded(self) -> None:
@ -367,6 +376,8 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
## Whether the printer that this output device represents supports print job actions via the cloud. ## Whether the printer that this output device represents supports print job actions via the cloud.
@pyqtProperty(bool, notify=_clusterPrintersChanged) @pyqtProperty(bool, notify=_clusterPrintersChanged)
def supportsPrintJobActions(self) -> bool: def supportsPrintJobActions(self) -> bool:
if not self._printers:
return False
version_number = self.printers[0].firmwareVersion.split(".") version_number = self.printers[0].firmwareVersion.split(".")
firmware_version = Version([version_number[0], version_number[1], version_number[2]]) firmware_version = Version([version_number[0], version_number[1], version_number[2]])
return firmware_version >= self.PRINT_JOB_ACTIONS_MIN_VERSION return firmware_version >= self.PRINT_JOB_ACTIONS_MIN_VERSION