diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index de7da13d1c..75b1d67697 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -886,8 +886,9 @@ class CuraApplication(QtApplication): # Initialize camera tool camera_tool = controller.getTool("CameraTool") - camera_tool.setOrigin(Vector(0, 100, 0)) - camera_tool.setZoomRange(0.1, 2000) + if camera_tool: + camera_tool.setOrigin(Vector(0, 100, 0)) + camera_tool.setZoomRange(0.1, 2000) # Initialize camera animations self._camera_animation = CameraAnimation.CameraAnimation() diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py index 20d8fd20ff..c88e103f3a 100644 --- a/cura/Machines/Models/QualitySettingsModel.py +++ b/cura/Machines/Models/QualitySettingsModel.py @@ -100,7 +100,8 @@ class QualitySettingsModel(ListModel): # the settings in that quality_changes_group. if quality_changes_group is not None: container_registry = ContainerRegistry.getInstance() - global_containers = container_registry.findContainers(id = quality_changes_group.metadata_for_global["id"]) + metadata_for_global = quality_changes_group.metadata_for_global + global_containers = container_registry.findContainers(id = metadata_for_global["id"]) global_container = None if len(global_containers) == 0 else global_containers[0] extruders_containers = {pos: container_registry.findContainers(id = quality_changes_group.metadata_per_extruder[pos]["id"]) for pos in quality_changes_group.metadata_per_extruder} extruders_container = {pos: None if not containers else containers[0] for pos, containers in extruders_containers.items()} diff --git a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py index 246c33b0c7..3c80565fa1 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py @@ -20,9 +20,6 @@ class ToolPathUploader: # The HTTP codes that should trigger a retry. RETRY_HTTP_CODES = {500, 502, 503, 504} - # The amount of bytes to send per request - BYTES_PER_REQUEST = 256 * 1024 - def __init__(self, http: HttpRequestManager, print_job: CloudPrintJobResponse, data: bytes, on_finished: Callable[[], Any], on_progress: Callable[[int], Any], on_error: Callable[[], Any] ) -> None: @@ -44,7 +41,6 @@ class ToolPathUploader: self._on_progress = on_progress self._on_error = on_error - self._sent_bytes = 0 self._retries = 0 self._finished = False @@ -54,50 +50,34 @@ class ToolPathUploader: return self._print_job - def _chunkRange(self) -> Tuple[int, int]: - """Determines the bytes that should be uploaded next. - - :return: A tuple with the first and the last byte to upload. - """ - last_byte = min(len(self._data), self._sent_bytes + self.BYTES_PER_REQUEST) - return self._sent_bytes, last_byte - def start(self) -> None: """Starts uploading the mesh.""" if self._finished: # reset state. - self._sent_bytes = 0 self._retries = 0 self._finished = False - self._uploadChunk() + self._upload() def stop(self): """Stops uploading the mesh, marking it as finished.""" - Logger.log("i", "Stopped uploading") - self._finished = True - - def _uploadChunk(self) -> None: - """Uploads a chunk of the mesh to the cloud.""" + Logger.log("i", "Finished uploading") + self._finished = True # Signal to any ongoing retries that we should stop retrying. + self._on_finished() + def _upload(self) -> None: + """ + Uploads the print job to the cloud printer. + """ if self._finished: raise ValueError("The upload is already finished") - first_byte, last_byte = self._chunkRange() - content_range = "bytes {}-{}/{}".format(first_byte, last_byte - 1, len(self._data)) - - headers = { - "Content-Type": cast(str, self._print_job.content_type), - "Content-Range": content_range - } # type: Dict[str, str] - - Logger.log("i", "Uploading %s to %s", content_range, self._print_job.upload_url) - + Logger.log("i", "Uploading print to {upload_url}".format(upload_url = self._print_job.upload_url)) self._http.put( url = cast(str, self._print_job.upload_url), - headers_dict = headers, - data = self._data[first_byte:last_byte], + headers_dict = {"Content-Type": cast(str, self._print_job.content_type)}, + data = self._data, callback = self._finishedCallback, error_callback = self._errorCallback, upload_progress_callback = self._progressCallback @@ -109,10 +89,9 @@ class ToolPathUploader: :param bytes_sent: The amount of bytes sent in the current request. :param bytes_total: The amount of bytes to send in the current request. """ - Logger.log("i", "Progress callback %s / %s", bytes_sent, bytes_total) + Logger.debug("Cloud upload progress %s / %s", bytes_sent, bytes_total) if bytes_total: - total_sent = self._sent_bytes + bytes_sent - self._on_progress(int(total_sent / len(self._data) * 100)) + self._on_progress(int(bytes_sent / len(self._data) * 100)) ## Handles an error uploading. def _errorCallback(self, reply: QNetworkReply, error: QNetworkReply.NetworkError) -> None: @@ -136,7 +115,7 @@ class ToolPathUploader: self._retries += 1 Logger.log("i", "Retrying %s/%s request %s", self._retries, self.MAX_RETRIES, reply.url().toString()) try: - self._uploadChunk() + self._upload() except ValueError: # Asynchronously it could have completed in the meanwhile. pass return @@ -148,16 +127,5 @@ class ToolPathUploader: Logger.log("d", "status_code: %s, Headers: %s, body: %s", status_code, [bytes(header).decode() for header in reply.rawHeaderList()], bytes(reply.readAll()).decode()) - self._chunkUploaded() - def _chunkUploaded(self) -> None: - """Handles a chunk of data being uploaded, starting the next chunk if needed.""" - - # We got a successful response. Let's start the next chunk or report the upload is finished. - first_byte, last_byte = self._chunkRange() - self._sent_bytes += last_byte - first_byte - if self._sent_bytes >= len(self._data): - self.stop() - self._on_finished() - else: - self._uploadChunk() + self.stop() diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml index f0ada92810..9891fc1d69 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationMenu.qml @@ -4,6 +4,7 @@ import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura @@ -37,70 +38,68 @@ Cura.ExpandablePopup headerItem: Item { // Horizontal list that shows the extruders and their materials - ListView + RowLayout { - id: extrudersList - - orientation: ListView.Horizontal anchors.fill: parent - model: extrudersModel - visible: Cura.MachineManager.activeMachine.hasMaterials - - delegate: Item + Repeater { - height: parent.height - width: Math.round(ListView.view.width / extrudersModel.count) - - // Extruder icon. Shows extruder index and has the same color as the active material. - Cura.ExtruderIcon + model: extrudersModel + delegate: Item { - id: extruderIcon - materialColor: model.color - extruderEnabled: model.enabled - height: parent.height - width: height - } + Layout.fillWidth: true + Layout.fillHeight: true - // Label for the brand of the material - Label - { - id: typeAndBrandNameLabel - - text: model.material_brand + " " + model.material - elide: Text.ElideRight - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - renderType: Text.NativeRendering - - anchors + // Extruder icon. Shows extruder index and has the same color as the active material. + Cura.ExtruderIcon { - top: extruderIcon.top - left: extruderIcon.right - leftMargin: UM.Theme.getSize("default_margin").width - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width + id: extruderIcon + materialColor: model.color + extruderEnabled: model.enabled + height: parent.height + width: height } - } - // Label that shows the name of the variant - Label - { - id: variantLabel - visible: Cura.MachineManager.activeMachine.hasVariants - - text: model.variant - elide: Text.ElideRight - font: UM.Theme.getFont("default_bold") - color: UM.Theme.getColor("text") - renderType: Text.NativeRendering - - anchors + // Label for the brand of the material + Label { - left: extruderIcon.right - leftMargin: UM.Theme.getSize("default_margin").width - top: typeAndBrandNameLabel.bottom - right: parent.right - rightMargin: UM.Theme.getSize("default_margin").width + id: typeAndBrandNameLabel + + text: model.material_brand + " " + model.material + elide: Text.ElideRight + font: UM.Theme.getFont("default") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + + anchors + { + top: extruderIcon.top + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } + } + // Label that shows the name of the variant + Label + { + id: variantLabel + + visible: Cura.MachineManager.activeMachine.hasVariants + + text: model.variant + elide: Text.ElideRight + font: UM.Theme.getFont("default_bold") + color: UM.Theme.getColor("text") + renderType: Text.NativeRendering + + anchors + { + left: extruderIcon.right + leftMargin: UM.Theme.getSize("default_margin").width + top: typeAndBrandNameLabel.bottom + right: parent.right + rightMargin: UM.Theme.getSize("default_margin").width + } } } }