Merge pull request #1 from Ultimaker/master

Resync with ultimaker
This commit is contained in:
Cataldo URSO 2020-04-24 00:03:57 +02:00 committed by GitHub
commit e0d95c1255
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 1575 additions and 795 deletions

View file

@ -29,10 +29,12 @@ class Account(QObject):
# Signal emitted when user logged in or out. # Signal emitted when user logged in or out.
loginStateChanged = pyqtSignal(bool) loginStateChanged = pyqtSignal(bool)
accessTokenChanged = pyqtSignal() accessTokenChanged = pyqtSignal()
cloudPrintersDetectedChanged = pyqtSignal(bool)
def __init__(self, application: "CuraApplication", parent = None) -> None: def __init__(self, application: "CuraApplication", parent = None) -> None:
super().__init__(parent) super().__init__(parent)
self._application = application self._application = application
self._new_cloud_printers_detected = False
self._error_message = None # type: Optional[Message] self._error_message = None # type: Optional[Message]
self._logged_in = False self._logged_in = False
@ -74,6 +76,10 @@ class Account(QObject):
def isLoggedIn(self) -> bool: def isLoggedIn(self) -> bool:
return self._logged_in return self._logged_in
@pyqtProperty(bool, notify=cloudPrintersDetectedChanged)
def newCloudPrintersDetected(self) -> bool:
return self._new_cloud_printers_detected
def _onLoginStateChanged(self, logged_in: bool = False, error_message: Optional[str] = None) -> None: def _onLoginStateChanged(self, logged_in: bool = False, error_message: Optional[str] = None) -> None:
if error_message: if error_message:
if self._error_message: if self._error_message:

View file

@ -196,6 +196,7 @@ class Arrange:
start_idx = 0 start_idx = 0
else: else:
start_idx = 0 start_idx = 0
priority = 0
for priority in self._priority_unique_values[start_idx::step]: for priority in self._priority_unique_values[start_idx::step]:
tryout_idx = numpy.where(self._priority == priority) tryout_idx = numpy.where(self._priority == priority)
for idx in range(len(tryout_idx[0])): for idx in range(len(tryout_idx[0])):

View file

@ -1,4 +1,4 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2020 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.
import os import os
@ -206,8 +206,11 @@ class ContainerManager(QObject):
if contents is None: if contents is None:
return {"status": "error", "message": "Serialization returned None. Unable to write to file"} return {"status": "error", "message": "Serialization returned None. Unable to write to file"}
with SaveFile(file_url, "w") as f: try:
f.write(contents) with SaveFile(file_url, "w") as f:
f.write(contents)
except OSError:
return {"status": "error", "message": "Unable to write to this location.", "path": file_url}
return {"status": "success", "message": "Successfully exported container", "path": file_url} return {"status": "success", "message": "Successfully exported container", "path": file_url}

View file

@ -243,6 +243,10 @@ class WelcomePagesModel(ListModel):
{"id": "data_collections", {"id": "data_collections",
"page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"), "page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"),
}, },
{"id": "cloud",
"page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
"should_show_function": self.shouldShowCloudPage,
},
{"id": "add_network_or_local_printer", {"id": "add_network_or_local_printer",
"page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"), "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
"next_page_id": "machine_actions", "next_page_id": "machine_actions",
@ -253,12 +257,8 @@ class WelcomePagesModel(ListModel):
}, },
{"id": "machine_actions", {"id": "machine_actions",
"page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"), "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
"next_page_id": "cloud",
"should_show_function": self.shouldShowMachineActions, "should_show_function": self.shouldShowMachineActions,
}, },
{"id": "cloud",
"page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
},
] ]
pages_to_show = all_pages_list pages_to_show = all_pages_list
@ -287,6 +287,17 @@ class WelcomePagesModel(ListModel):
first_start_actions = self._application.getMachineActionManager().getFirstStartActions(definition_id) first_start_actions = self._application.getMachineActionManager().getFirstStartActions(definition_id)
return len([action for action in first_start_actions if action.needsUserInteraction()]) > 0 return len([action for action in first_start_actions if action.needsUserInteraction()]) > 0
def shouldShowCloudPage(self) -> bool:
"""
The cloud page should be shown only if the user is not logged in
:return: True if the user is not logged in, False if he/she is
"""
# Import CuraApplication locally or else it fails
from cura.CuraApplication import CuraApplication
api = CuraApplication.getInstance().getCuraAPI()
return not api.account.isLoggedIn
def addPage(self) -> None: def addPage(self) -> None:
pass pass

View file

@ -720,9 +720,12 @@ class CuraEngineBackend(QObject, Backend):
## Creates a new socket connection. ## Creates a new socket connection.
def _createSocket(self, protocol_file: str = None) -> None: def _createSocket(self, protocol_file: str = None) -> None:
if not protocol_file: if not protocol_file:
if not self.getPluginId():
Logger.error("Can't create socket before CuraEngineBackend plug-in is registered.")
return
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId()) plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
if not plugin_path: if not plugin_path:
Logger.log("e", "Could not get plugin path!", self.getPluginId()) Logger.error("Could not get plugin path!", self.getPluginId())
return return
protocol_file = os.path.abspath(os.path.join(plugin_path, "Cura.proto")) protocol_file = os.path.abspath(os.path.join(plugin_path, "Cura.proto"))
super()._createSocket(protocol_file) super()._createSocket(protocol_file)

File diff suppressed because it is too large Load diff

View file

@ -267,13 +267,23 @@ class SolidView(View):
Class that ducktypes to be a Numpy ndarray. Class that ducktypes to be a Numpy ndarray.
""" """
def __init__(self, qimage): def __init__(self, qimage):
self.__array_interface__ = { bits_pointer = qimage.bits()
"shape": (qimage.height(), qimage.width()), if bits_pointer is None: # If this happens before there is a window.
"typestr": "|u4", # Use 4 bytes per pixel rather than 3, since Numpy doesn't support 3. self.__array_interface__ = {
"data": (int(qimage.bits()), False), "shape": (0, 0),
"strides": (qimage.bytesPerLine(), 3), # This does the magic: For each line, skip the correct number of bytes. Bytes per pixel is always 3 due to QImage.Format.Format_RGB888. "typestr": "|u4",
"version": 3 "data": (0, False),
} "strides": (1, 3),
"version": 3
}
else:
self.__array_interface__ = {
"shape": (qimage.height(), qimage.width()),
"typestr": "|u4", # Use 4 bytes per pixel rather than 3, since Numpy doesn't support 3.
"data": (int(bits_pointer), False),
"strides": (qimage.bytesPerLine(), 3), # This does the magic: For each line, skip the correct number of bytes. Bytes per pixel is always 3 due to QImage.Format.Format_RGB888.
"version": 3
}
array = np.asarray(QImageArrayView(xray_img)).view(np.dtype({ array = np.asarray(QImageArrayView(xray_img)).view(np.dtype({
"r": (np.uint8, 0, "red"), "r": (np.uint8, 0, "red"),
"g": (np.uint8, 1, "green"), "g": (np.uint8, 1, "green"),

View file

@ -1,161 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-122.4 196.9 50.3 74.1"
enable-background="new -122.4 196.9 50.3 74.1" xml:space="preserve">
<title>logo</title>
<desc>Created with Sketch.</desc>
<g id="homepage" sketch:type="MSPage">
<g id="Home-menu" transform="translate(-35.000000, -37.000000)" sketch:type="MSArtboardGroup">
<g id="hero-3" transform="translate(-792.000000, -68.000000)" sketch:type="MSLayerGroup">
<g id="Group-2">
</g>
</g>
<g id="Menu" sketch:type="MSLayerGroup">
<g id="logo" transform="translate(35.000000, 37.845203)" sketch:type="MSShapeGroup">
<g id="Robot" transform="translate(51.265823, 0.000000)">
<path id="Fill-23" fill="#000000" d="M-139.9,203.6c-0.3,0-0.6,0-0.9,0.1c-0.3,0.1-0.5,0.2-0.7,0.4c0,0,0,0,0,0c0,0,0,0,0,0
c-0.1,0.1-0.2,0.2-0.3,0.3c0,0,0,0,0,0c-0.1,0.1-0.1,0.2-0.2,0.3c0,0,0,0,0,0c0,0,0,0,0,0c-0.1,0.1-0.1,0.2-0.1,0.4
c0,0,0,0,0,0c0,0.1,0,0.3,0,0.4c0,0.3,0.1,0.6,0.2,0.9c0.1,0.3,0.3,0.5,0.5,0.7c0.2,0.2,0.5,0.4,0.7,0.5
c0.3,0.1,0.6,0.2,0.9,0.2c0.1,0,0.2,0,0.3,0c0,0,0.1,0,0.1,0c0.1,0,0.1,0,0.2,0c0,0,0.1,0,0.1,0c0.1,0,0.1,0,0.2-0.1
c0,0,0,0,0.1,0c0,0,0,0,0,0c0,0,0,0,0,0c0.3-0.1,0.5-0.2,0.7-0.4c0.1-0.1,0.2-0.2,0.3-0.3c0.1-0.1,0.2-0.3,0.2-0.4
c0.1-0.3,0.2-0.5,0.2-0.8s-0.1-0.6-0.2-0.9c-0.1-0.2-0.2-0.3-0.3-0.5c0,0,0,0,0,0c-0.1-0.1-0.1-0.1-0.2-0.2
c-0.1-0.1-0.2-0.2-0.3-0.3c-0.1-0.1-0.3-0.2-0.4-0.2C-139.3,203.7-139.6,203.6-139.9,203.6"/>
<path id="Fill-24" fill="#000000" d="M-138.4,211.3c-0.1-0.1-0.1-0.1-0.2-0.1c-0.1,0-0.2-0.1-0.3-0.1l-11.4-0.3
c-0.1,0-0.2,0-0.3,0c-0.1,0-0.1,0.1-0.2,0.1c0,0,0,0,0,0c0,0,0,0,0,0c-0.1,0.1-0.1,0.1-0.1,0.2c0,0,0,0,0,0c0,0,0,0,0,0
c0,0.1-0.1,0.1-0.1,0.2v0.7c0,0.1,0,0.2,0.1,0.3c0,0.1,0.1,0.1,0.2,0.2c0.1,0.1,0.1,0.1,0.2,0.1c0.1,0,0.2,0.1,0.3,0.1
l11.4,0.2c0.1,0,0.2,0,0.3,0c0.1,0,0.1-0.1,0.2-0.1c0.1-0.1,0.1-0.1,0.1-0.2c0-0.1,0.1-0.2,0.1-0.2v-0.6c0-0.1,0-0.2-0.1-0.2
C-138.3,211.5-138.4,211.4-138.4,211.3"/>
<path id="Fill-25" fill="#000000" d="M-151,207.2c0.2,0.2,0.5,0.4,0.9,0.6c0.3,0.1,0.7,0.2,1,0.2c0.1,0,0.2,0,0.4,0
c0,0,0.1,0,0.1,0c0.1,0,0.2,0,0.3-0.1c0,0,0,0,0,0c0.1,0,0.2,0,0.2-0.1c0,0,0,0,0,0c0.1,0,0.3-0.1,0.4-0.2c0,0,0,0,0,0
c0.1-0.1,0.3-0.2,0.4-0.3c0.2-0.2,0.4-0.5,0.6-0.8c0.1-0.3,0.2-0.6,0.2-0.9c0-0.3-0.1-0.7-0.2-1c-0.1-0.3-0.3-0.6-0.6-0.8
c-0.2-0.2-0.5-0.4-0.8-0.6c-0.3-0.1-0.7-0.2-1-0.2c-0.4,0-0.7,0-1,0.1c-0.3,0.1-0.6,0.3-0.8,0.4c0,0-0.1,0-0.1,0.1
c0,0-0.1,0.1-0.1,0.1c-0.1,0.1-0.1,0.1-0.2,0.2c-0.1,0.1-0.1,0.2-0.2,0.2c0,0.1-0.1,0.1-0.1,0.2c0,0,0,0,0,0c0,0,0,0,0,0
c-0.1,0.1-0.1,0.3-0.1,0.4c0,0,0,0,0,0c0,0.1-0.1,0.3-0.1,0.5c0,0.3,0.1,0.7,0.2,1C-151.4,206.7-151.3,207-151,207.2"/>
<path id="Fill-26" fill="#000000" d="M-139.8,235.5h0.9c0.6,0,2.1,0.3,2.1,0.3s-1.5,0.3-2.1,0.3h-0.9c0,0-0.1,0-0.1,0l-0.1,0.8
l-0.1-0.8c-0.7-0.1-1.7-0.2-1.7-0.2s1-0.2,1.7-0.2l-0.3-1.6l-3.2-0.1l-0.2,1.9l1.9,0.1l-1.9,0.1l-0.2,1.8h0.4
c0.9,0,3.1,0.3,3.1,0.3s-2.2,0.3-3.1,0.3h-0.4l-0.1,0.7l-0.1-0.7h-0.7c-0.9,0-3.1-0.3-3.1-0.3s2.2-0.3,3.1-0.3h0.7l-0.2-1.8
l-4.6,0.3l-0.4,1.9l-0.4-1.9l-3.6-0.4l3.6-0.4l0.4-1.8l-5.1-0.2l9.8-0.4l-0.1-1.6l-3-0.2l-0.3,1.6l-0.3-1.6l-5.9-0.4l5.9-0.4
l0.4-1.7l0.3,1.6l3-0.2l0.2-2.1c-0.9-0.1-1.6-0.2-1.6-0.2s0.8-0.1,1.7-0.2l0.2-1.6h-0.6c-1.1,0-3.7-0.4-3.7-0.4
s2.6-0.4,3.7-0.4h0.7l0.1-1.2l0.1,1.2h0.6c1.1,0,3.8,0.4,3.8,0.4s-2.7,0.4-3.8,0.4h-0.5l0.2,1.5c0.4,0,0.8-0.1,1.1-0.1h1.5
c1,0,3.7,0.4,3.7,0.4c0,0-2.6,0.4-3.7,0.4h-1.5c-0.3,0-0.7,0-1.1-0.1l0.2,2l2.5,0.7l-2.5,0.7l-0.1,1.5l3.1-0.1l0.5-3.4l0.5,3.4
l4.2,0.5l-4.2,0.5L-139.8,235.5L-139.8,235.5L-139.8,235.5z M-150.9,227.5h1c0.7,0,2.4,0.3,2.4,0.3s-1.7,0.3-2.4,0.3h-1
c-0.7,0-2.3-0.3-2.3-0.3S-151.6,227.5-150.9,227.5L-150.9,227.5z M-137.4,230.5h0.1c0.4,0,1.3,0.3,1.3,0.3s-0.9,0.3-1.3,0.3
h-0.6c-0.4,0-1.3-0.3-1.3-0.3s0.9-0.3,1.3-0.3H-137.4L-137.4,230.5z M-131.8,221.6c0-0.1,0-0.1-0.1-0.2c0-0.1-0.1-0.1-0.1-0.2
c-0.1,0-0.1-0.1-0.2-0.1c-0.1,0-0.2,0-0.3,0l-25,0.1c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0.1-0.2,0.1c-0.1,0.1-0.1,0.1-0.2,0.2
c0,0.1-0.1,0.2-0.1,0.2c-0.2,1.8-0.3,3.6-0.3,5.4c-0.1,1.8-0.1,3.6-0.1,5.4c0,1.8,0,3.6,0.1,5.4c0.1,1.8,0.2,3.6,0.3,5.4
c0,0.1,0,0.2,0.1,0.2c0,0.1,0.1,0.1,0.2,0.2c0.1,0.1,0.2,0.1,0.2,0.1c0.2,0.1,6.9,0.4,6.9,0.4c0.5-0.3,1-0.6,1.5-0.8
c0.5-0.2,1-0.4,1.6-0.6c0.3-0.1,0.5-0.2,0.8-0.2c0,0,0,0,0,0c0.2,0,0.3-0.1,0.5-0.1c0.1,0,0.2-0.1,0.3-0.1c0,0,0,0,0,0h0
c0,0,0,0,0.1,0c0.1,0,0.1,0,0.2,0c0,0,0,0,0,0c0,0,0,0,0.1,0c0.1,0,0.2,0,0.3,0c0.1,0,0.1,0,0.2,0c0.3,0,0.6-0.1,0.8-0.1
c0.3,0,0.5,0,0.8,0c0.1,0,0.1,0,0.2,0c0.2,0,0.4,0,0.6,0h0c0,0,0.1,0,0.1,0c0,0,0,0,0.1,0h0c0.1,0,0.3,0,0.4,0
c0.1,0,0.2,0,0.3,0c2,0.2,3.8,1.1,3.8,1.1c0.5-0.1,6-1.3,6.1-1.3c0.1,0,0.2-0.1,0.2-0.1c0.1-0.1,0.1-0.1,0.2-0.2
c0-0.1,0.1-0.1,0.1-0.2c0.1-1.7,0.2-3.3,0.3-5c0.1-1.7,0.1-3.3,0.1-5c0-1.7,0-3.3-0.1-5C-131.6,224.9-131.7,223.2-131.8,221.6
L-131.8,221.6z"/>
<path id="Fill-27" fill="#000000" d="M-149.4,233.6l0.4,1.8l4.5,0.3l-0.2-1.9L-149.4,233.6"/>
<path id="Fill-28" fill="#000000" d="M-142.3,260.2c-0.2,0.3-0.2,2.2-0.1,2.6c0.1,0.5,2.1,0.1,2.1,0.1s-1.1-2.1,0.7-2.7
c0.4-0.1,1.6-0.4,2.9-0.6c1.9-0.4,4.1-0.7,4.1-0.7s-1.1-0.3-2.7-0.1l-0.3,0l-0.3,0h0l-3.7,0.5
C-141.4,259.6-142,259.8-142.3,260.2"/>
<path id="Fill-29" fill="#000000" d="M-128.1,243.8v-1.5c0,0,0,0,0,0c0.1-0.1,0.1-0.1,0.2-0.2c0.1-0.1,0.3-0.2,0.4-0.3
c0.1-0.1,0.1-0.2,0.1-0.3c0-0.1,0-0.2-0.1-0.4c0-0.1-0.1-0.3-0.2-0.4c-0.1-0.1-0.2-0.3-0.3-0.3c0,0-0.1-0.1-0.1-0.1v-3.2
c0,0,0.1,0,0.1,0c0.3-0.1,0.6-0.2,0.8-0.4c0,0.1,0.1,0.1,0.1,0.2c0.2,0.3,0.5,0.6,0.7,1.1c0.2,0.4,0.4,0.9,0.5,1.5
C-125.8,239.5-125.2,243-128.1,243.8L-128.1,243.8z M-128.1,234.4c0.3-0.1,0.8-0.2,1.1-0.3c0.1,0,0.2-0.1,0.3-0.1v0.3
c-0.1,0-0.2,0.1-0.2,0.1c-0.4,0.2-0.9,0.4-1.2,0.5V234.4L-128.1,234.4z M-128.1,232.8c0.3,0,0.7-0.1,1.1-0.1
c0.1,0,0.3,0,0.4-0.1v0.3c-0.1,0-0.2,0.1-0.4,0.1c-0.4,0.1-0.8,0.2-1.1,0.3V232.8L-128.1,232.8z M-128.1,231.1
c0.4,0,1,0,1.5,0.1v0.2c-0.5,0.1-1,0.2-1.5,0.3V231.1L-128.1,231.1z M-128.1,229.4c0.3,0.1,0.7,0.1,1.1,0.2
c0.1,0,0.3,0.1,0.4,0.1v0.3c-0.1,0-0.3,0-0.4,0c-0.4,0-0.7,0-1,0V229.4L-128.1,229.4z M-128.1,227.6c0.4,0.1,0.8,0.2,1.2,0.4
c0.1,0,0.2,0.1,0.3,0.1v0.3c-0.1,0-0.2-0.1-0.4-0.1c-0.4-0.1-0.8-0.1-1.1-0.2V227.6L-128.1,227.6z M-128.1,221.4
C-128.1,221.4-128,221.4-128.1,221.4c0.5,0.3,1,1.6,1.3,2.2c0.3,0.6,0.4,1.3,0.4,2.1c0,0.1,0,0.1,0,0.2c0,0.1-0.1,0.1-0.1,0.1
c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0-0.2,0c0,0-0.1,0-0.2,0s-0.1,0-0.2,0c0,0-0.1,0-0.1,0c-0.3,0-0.6,0-0.9,0L-128.1,221.4
L-128.1,221.4z M-129.9,221.4v22.7c0,0.3-0.1,0.6-0.2,0.9c-0.1,0.3-0.3,0.5-0.5,0.7c-0.2,0.2-0.5,0.4-0.7,0.5
c-0.3,0.1-0.6,0.2-0.9,0.2l-1.5,0.1c0,0,0,0,0,0l-0.1-0.3c-0.1-0.4-0.5-0.7-0.8-0.7l-1.6,0.1l-19,1.2c-0.4,0-0.8,0.3-0.9,0.7
l-0.4,0.9c0,0,0,0,0,0l-1.3,0.1c-0.4,0-0.7,0-1-0.1c-0.3-0.1-0.6-0.2-0.9-0.4c-0.2-0.2-0.4-0.4-0.6-0.7
c-0.1-0.3-0.2-0.6-0.2-0.9v-25c0-0.3,0.1-0.7,0.2-0.9c0.1-0.3,0.3-0.6,0.6-0.8c0.2-0.2,0.5-0.4,0.9-0.5
c0.3-0.1,0.6-0.2,0.9-0.2c0,0,0.1,0,0.1,0l1.2,0c0-0.1,0-0.1,0-0.2l0-0.4c0-0.4,0.3-0.7,0.7-0.7l11.4,0.2l1.1,0l2.7,0l1.7,0
l5.2,0.1c0.3,0,0.6,0.2,0.7,0.6c0,0.1,0,0.1,0,0.2l0,0.2c0,0,0,0.1,0,0.1l0.8,0c0.3,0,0.6,0.1,0.9,0.2c0.3,0.1,0.5,0.3,0.7,0.5
c0.2,0.2,0.4,0.4,0.5,0.7C-130,220.7-129.9,221-129.9,221.4L-129.9,221.4L-129.9,221.4z M-137.6,255.8v-6.4c0,0,0-0.1,0-0.1
s0,0,0-0.1c0.1,0,0.3,0,0.4,0l0,2.1c0.7-0.6,1.4-1.2,2.3-0.9c0.4,0.1,0.7,0.3,1,0.4v4.6L-137.6,255.8L-137.6,255.8z
M-141.1,258.1l5.5-0.6l1.7-0.2c0.3,0,0.5,0,0.7,0.1c0.2,0.1,0.4,0.2,0.6,0.4c0.2,0.2,0.3,0.4,0.4,0.7c0,0,0,0.1,0,0.1
c0.1,0.2,0.1,0.5,0.1,0.8v3c-0.4,0.1-1.1,0.1-1.8,0.3c-2.4,0.3-6.1,0.8-7.4,1c-2,0.3-1.9-0.5-1.9-0.5v-2.4c0-0.3,0-0.5,0.1-0.8
c0-0.1,0-0.1,0.1-0.2c0.1-0.3,0.2-0.6,0.4-0.8c0.2-0.2,0.4-0.4,0.6-0.6C-141.6,258.2-141.4,258.1-141.1,258.1L-141.1,258.1z
M-140.6,251.9c0.6,0.4,1.4,0.8,2.2,0.4l0.2-0.1l-0.4,3.7l-3.2,0.3v-6.4c0,0,0-0.1,0-0.2c0.1,0,0.2,0,0.4,0l0,3
C-141.2,252.2-140.8,251.7-140.6,251.9L-140.6,251.9z M-131.6,262.9c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0.1c0,0,0.1,0.1,0.1,0.1
c0,0.1,0,0.1,0,0.2v0.4c0,0.1,0,0.1,0,0.2c0,0.1,0,0.1-0.1,0.2c0,0-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0.1l-11.8,1.6
c-0.1,0-0.1,0-0.2,0c0,0-0.1,0-0.1-0.1c0,0-0.1-0.1-0.1-0.1c0-0.1,0-0.1,0-0.2v-0.5c0-0.1,0-0.1,0-0.2c0-0.1,0-0.1,0.1-0.2
c0,0,0.1-0.1,0.1-0.1c0,0,0.1-0.1,0.2-0.1l9.4-1.3l0.1,0l0.2,0l0.8-0.1l0.8-0.1L-131.6,262.9L-131.6,262.9z M-145.2,265.7
c0,0.1,0,0.1,0,0.2c0,0.1-0.1,0.1-0.1,0.2c0,0.1-0.1,0.1-0.1,0.1c0,0-0.1,0.1-0.2,0.1l-12.6,1.7c-0.4,0-0.5-0.5-0.3-1l-7.5-6.2
l8.2,5.7c0,0,0.1,0,0.3,0l11.9-1.6c0.1,0,0.1,0,0.2,0c0,0,0.1,0,0.1,0.1c0,0,0.1,0.1,0.1,0.1c0,0.1,0,0.1,0,0.2V265.7
L-145.2,265.7z M-165.1,245.8c-0.1,0-0.2,0-0.2,0.1c-0.1,0-0.2,0-0.3,0.1c-0.1,0-0.1,0-0.2,0c-0.1,0-0.1,0-0.2,0c0,0,0,0,0,0
c0,0,0,0,0,0c0,0,0,0,0,0c-0.1,0-0.2,0-0.3,0c-0.1,0-0.1,0-0.2,0h0c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0-0.3,0c0,0,0,0,0,0
c0,0,0,0,0,0c-0.2,0-0.4-0.1-0.6-0.1c0,0-0.1,0-0.1,0c0,0,0,0,0,0c0,0-0.1,0-0.2,0c0,0-0.1,0-0.1-0.1c0,0-0.1,0-0.1,0
c0,0,0,0,0,0c-0.1,0-0.1,0-0.2-0.1c0,0,0,0,0,0c0,0,0,0,0,0c0,0-0.1,0-0.1,0c0,0,0,0,0,0h0c-0.1,0-0.1-0.1-0.2-0.1c0,0,0,0,0,0
c0,0-0.1-0.1-0.1-0.1c0,0,0,0,0,0l0,0c0,0-0.1,0-0.1-0.1c0,0,0,0-0.1,0c0,0,3.1-0.1,3.1-0.1s-1.3-0.8-1.6-1.1
c-0.5-0.5,0.7-2.9,0.8-3.2l-2.4-1.1l-0.5-0.2l0.6,0.1l2.7,0.3c-0.2-0.3-1.6-0.6-2.3-0.9c-0.3-0.1-0.4-0.2-0.3-0.3c0,0,0,0,0,0
c0.1,0,0.3,0,0.5,0.1c0.4,0,0.9,0,1.6,0c1.4,0,2.3-0.1,2.9-0.2c0,0,0,0.1,0.1,0.1c0.2,0.4,0.4,1,0.6,1.6
c0.2,0.6,0.4,1.2,0.4,1.8c0.1,0.6,0.1,1.2-0.1,1.7h0c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2-0.1-0.4-0.1c-0.1,0-0.2-0.1-0.3-0.1
c0,0,0,0,0,0c0,0,0,0,0,0c-0.1,0-0.2-0.1-0.3-0.1c0,0,0-0.1,0-0.2c0-0.1,0-0.2-0.1-0.2c0-0.1,0-0.2-0.1-0.3
c0-0.1-0.1-0.2-0.1-0.2c0-0.1-0.1-0.2-0.1-0.3c-0.1-0.1-0.1-0.1-0.2-0.2c-0.1-0.1-0.1-0.1-0.2-0.1c-0.1,0-0.1,0-0.2,0
c-0.2,0-0.3,0.1-0.4,0.2c-0.1,0.1-0.3,0.3-0.4,0.4c-0.1,0.2-0.2,0.3-0.2,0.5c-0.1,0.2-0.1,0.3-0.1,0.4c0,0.1,0.1,0.2,0.2,0.3
c0.1,0.1,0.3,0.2,0.4,0.3c0.1,0.1,0.2,0.1,0.3,0.2c0.1,0,0.1,0.1,0.2,0.1c0.2,0.1,0.4,0.2,0.5,0.2c0,0.1,0,0.2,0,0.3
c0,0.1,0,0.2,0,0.4c0,0.1,0,0.2-0.1,0.3c0,0.1-0.1,0.2-0.2,0.2C-165,245.7-165.1,245.8-165.1,245.8L-165.1,245.8z
M-163.9,235.5l0,0.3c-0.1,0-0.1,0.1-0.2,0.1c-0.7,0.4-1.5,0.6-1.6,0.6c-0.1,0-0.7,0.1-1.2,0.1c-0.3,0-0.5,0-0.7,0
c-0.3,0-0.4,0-0.5,0c-0.1,0-0.8-0.1-1.4-0.3l0-0.4c0.6,0,1.3,0,1.4,0c0,0,0.2,0,0.5,0c0.2,0,0.4,0,0.7,0c0.6,0,1.1-0.1,1.2-0.1
c0.2,0,0.9-0.1,1.6-0.3C-164.1,235.5-164,235.5-163.9,235.5L-163.9,235.5z M-164.2,234.4c-0.7,0.2-1.4,0.4-1.5,0.4
c-0.1,0-0.6,0.1-1.1,0.1c-0.3,0-0.6,0-0.8,0c-0.2,0-0.3,0-0.3,0c-0.1,0-0.8-0.1-1.5-0.3c0,0-0.1,0-0.1,0l0-0.3c0,0,0.1,0,0.1,0
c0.7,0,1.4-0.1,1.5-0.1c0,0,0.2,0,0.3,0c0.2,0,0.5,0,0.8,0c0.5,0,1-0.1,1.1-0.1c0.1,0,0.8,0,1.5,0c0.1,0,0.2,0,0.3,0l0,0.3
C-164,234.3-164.1,234.4-164.2,234.4L-164.2,234.4z M-169.7,232.6c0.7-0.1,1.7-0.3,1.9-0.3l0.1,0l2,0c0.2,0,1.2,0.1,1.9,0.2
v0.2c-0.7,0.1-1.7,0.3-1.9,0.3l-2,0l-0.1,0c-0.2,0-1.2-0.1-1.9-0.2V232.6L-169.7,232.6z M-163.8,231v0.3c-0.1,0-0.2,0-0.4,0
c-0.7,0-1.5,0-1.6,0c-0.1,0-0.6,0-1.2,0c-0.3,0-0.5,0-0.7,0c-0.2,0-0.4,0-0.5,0c-0.2,0-0.9-0.1-1.6,0v-0.4
c0.7-0.2,1.4-0.3,1.6-0.4c0,0,0.2,0,0.5,0c0.2,0,0.5,0,0.7,0c0.6,0,1.1,0,1.2,0c0.2,0,0.9,0.1,1.6,0.4
C-164,230.9-163.9,230.9-163.8,231L-163.8,231z M-164.1,229.6c-0.7-0.2-1.6-0.2-1.7-0.2c-0.1,0-0.7-0.1-1.3-0.1
c-0.2,0-0.4,0-0.6,0c-0.4,0-0.6,0-0.7,0l-0.6,0c-0.2,0-0.5,0-0.7,0.1V229c0.2-0.1,0.5-0.1,0.7-0.2c0.3-0.1,0.6-0.1,0.7-0.1
c0.1,0,0.3,0,0.7,0c0.2,0,0.4,0,0.6,0c0.6,0,1.2,0.1,1.3,0.1c0.2,0,1,0.2,1.7,0.5c0.1,0,0.2,0.1,0.3,0.1v0.2
C-163.9,229.6-164,229.6-164.1,229.6L-164.1,229.6z M-170.2,226.5c0-0.1,0-0.4,0-0.4c0.2-1.6,4.1-6,4.1-6s1.7-0.5,2.4-0.5
c0.5,0,1,0.4,0.9,1.6c0,0.2-0.4,5-0.4,5c0,0,0,0.1-0.1,0.1c0,0-0.1,0.1-0.1,0.1c-0.7,0.6-5.9,0.6-6.4,0.5
C-170.1,226.9-170.2,226.7-170.2,226.5L-170.2,226.5z M-151.5,257.2l0-6.5c0,0,0.1,0,0.4,0l0,2.2c0.7-0.6,1.5-1.2,2.4-1
c0.5,0.1,0.9,0.3,1.3,0.6v4.4L-151.5,257.2L-151.5,257.2z M-154.7,253.4c0.6,0.5,1.4,0.9,2.3,0.4l0.4-0.2l-0.4,3.7l-3.5,0.4
v-5.6l0-1c0,0,0.2,0,0.5,0l0,3.1C-155.4,253.6-155,253.2-154.7,253.4L-154.7,253.4z M-158.1,262.2c0,0,0-0.3,0.1-0.4
c0-0.1,0-0.2,0.1-0.3c0.1-0.3,0.3-0.6,0.5-0.8c0.2-0.2,0.4-0.5,0.7-0.6c0.3-0.2,0.5-0.3,0.8-0.3l7.9-0.9c0.3,0,0.6,0,0.8,0.1
c0.2,0.1,0.5,0.2,0.7,0.4c0.2,0.2,0.3,0.4,0.4,0.7c0,0.1,0,0.1,0.1,0.2c0.1,0.2,0.1,0.5,0.1,0.7v3.2l-0.4,0l-10.1,1.3l-0.5,0.1
c0,0-1,0.1-1.2-0.6v-1.7c-0.4-0.3-6.4-5.2-6.4-5.2L-158.1,262.2L-158.1,262.2z M-158.8,206.5l1.2-0.1l0.5,0c0,0,0,0,0.1,0
c0,0,0,0,0.1,0c0.1,0,0.2,0,0.3,0.1c0.6,0.4,1,1.7,1,3.4c0,2-0.6,3.6-1.3,3.6v0h0c0,0,0,0,0,0h0c0,0,0,0,0,0h0l-1.3,0l-1.6,0.1
l-0.3,0c0,0,0,0,0.1,0c0.4-0.1,0.7-0.8,0.9-1.8c0.1-0.5,0.1-1.1,0.1-1.7c0-0.7-0.1-1.3-0.2-1.8c-0.2-1-0.6-1.6-0.9-1.6
L-158.8,206.5L-158.8,206.5z M-153.3,196.9c0.4-0.1,0.9-0.1,0.9,0.3c0,0.4,0,1.3,0,1.8h0c-0.3,0.1-0.6,0.3-0.9,0.4V196.9
L-153.3,196.9z M-151.5,200.9c0.3-0.1,0.7-0.2,1-0.1l8.4,0.5l2.8,0.2l0.6,0c0.3,0,0.7,0.1,1,0.2c0.3,0.1,0.6,0.3,0.8,0.5
c0.2,0.2,0.4,0.5,0.5,0.8c0.1,0.3,0.2,0.6,0.2,0.9v10.7c0,0.3-0.1,0.6-0.2,0.9c-0.1,0.3-0.3,0.5-0.5,0.7l-3.9-0.1l-11.7-0.2
c-0.2-0.2-0.3-0.4-0.4-0.6c-0.1-0.3-0.2-0.6-0.2-1v-11.2c0-0.3,0.1-0.7,0.2-0.9c0.1-0.3,0.3-0.5,0.6-0.7
C-152.2,201.2-151.9,201-151.5,200.9L-151.5,200.9z M-139.3,197c0.4-0.1,0.8-0.1,0.8,0.3c0,0.5,0,1.6,0,2.1c0,0,0,0,0,0l-0.8,0
V197L-139.3,197z M-172.7,226.4c-0.2,1.8,0.9,2.2,0.9,2.2v5.8c0,0.1,0,0.1,0,0.2l0,1.2c0,0,0,0.1,0,0.1v0.7
c0,0-0.1,0.1-0.1,0.1c-0.4,0.4-0.7,0.9-1,1.4c-0.4,0.7-0.6,1.3-0.7,2c-0.1,0.9-0.1,1.7,0.2,2.5c0.1,0.3,0.3,0.7,0.5,1
c0.9,1.5,2,2.5,3,3.2c1.8,1.3,5,1,5,1v6.7c-0.1,0.1-0.1,0.1-0.2,0.2c0,0-0.1,0.1-0.1,0.1c-0.2,0.2-0.3,0.3-0.5,0.5
c0,0-0.1,0.1-0.1,0.1c-0.2,0.2-0.3,0.5-0.4,0.7c0,0.1-0.1,0.1-0.1,0.2c-0.1,0.2-0.2,0.4-0.2,0.6c0,0.1,0,0.2-0.1,0.3
c0,0.1,0,0.1,0,0.2c0,0.2,0,0.4,0,0.6v2.1c0,0,0,0,0,0c0,0-0.1,0.1-0.1,0.1c-0.2,0.2-0.3,0.4-0.4,0.7c0,0,0,0.1,0,0.1
c-0.1,0.3-0.1,0.5-0.1,0.8v0.4c0,0.1,0,0.3,0,0.4c0,0.1,0.1,0.3,0.1,0.4c0.1,0.1,0.1,0.3,0.2,0.4c0.1,0.1,0.2,0.3,0.3,0.4
l6.1,5.5c0,0,0,0,0.1,0.1c0.3,0.2,0.6,0.4,0.9,0.5c0.3,0.1,0.7,0.1,1,0.1c0.1,0,0.2,0,0.3,0l12.9-1.8c0.4,0,0.7-0.2,1-0.3
c0.4,0.1,0.7,0.1,1.1,0l11.8-1.6c0.4-0.1,0.8-0.2,1.2-0.4c0.3-0.2,0.5-0.4,0.7-0.7c0.2-0.2,0.3-0.5,0.4-0.8
c0.1-0.3,0.1-0.5,0.1-0.8v-0.4c0-0.3-0.1-0.6-0.2-0.8c-0.1-0.3-0.3-0.5-0.5-0.8c0,0,0,0-0.1-0.1v-2.4c0-1.4-0.4-3.3-2.2-3.8
v-6.8c0.6-0.1,3.7-0.4,3.7-2.7c0.9-0.1,3.4-0.6,4.4-4.2c0.2-0.8,0.3-1.7,0.2-2.6c-0.1-0.7-0.3-1.4-0.6-2
c-0.2-0.5-0.5-1-0.9-1.4c-0.1-0.1-0.1-0.1-0.2-0.2v-8.3c0.2-0.1,0.8-0.4,0.8-1.7c0-0.8-1.9-5.4-2.5-6.1c-0.7-0.8-2-1.8-2.8-2.1
c-0.2-0.1-0.4-0.2-0.5-0.2c-0.6-0.2-1.2-0.3-1.8-0.3c-0.1-0.3-0.4-0.5-0.7-0.5l-1.1,0v-2.6c1.2-0.5,1.9-1.7,1.9-3.3
c0-0.7-0.1-2.5-1.2-3.4c-0.2-0.2-0.4-0.3-0.6-0.4v-2.5l0-0.2c0-0.6-0.1-1.1-0.3-1.6c-0.2-0.5-0.5-1-0.9-1.4
c-0.4-0.4-0.9-0.8-1.4-1c-0.3-0.2-0.7-0.3-1-0.3V197c0-0.5-0.9-1.3-3.8-0.3c0,0,0,0,0,0c-0.4,0.1-0.6,0.5-0.6,0.8v1.7l-8.2-0.5
c-0.4,0-0.8,0-1.2,0.1v-1.9c0-0.5-0.9-1.3-3.8-0.3c-0.4,0.1-0.7,0.5-0.7,0.8v3.9c0,0.1,0,0.3,0,0.3l-3.8,3.1
c-0.4,0-0.9,0.1-1.5,0.2c-1.9,0.4-2.6,3.1-2.6,5.3c0,2,0.5,3.5,1.3,4.4v2.3l-3.8,1.1C-167.3,218.3-172.5,224.6-172.7,226.4
L-172.7,226.4z"/>
<path id="Fill-30" fill="#000000" d="M-157,265.1c0.5,0,4.2-0.5,4.2-0.5s-0.8-0.2-0.5-1.6c0.2-1,2.1-1.4,3.4-1.7
c1.3-0.3,3.1-0.5,3.1-0.5s-1.1-0.3-2.7-0.1l-0.3,0l-0.3,0h0c0,0-5.7,0.7-7.1,1.3c-0.4,0.2-0.4,1.9-0.4,2.7
C-157.6,265.1-157.3,265.1-157,265.1"/>
<path id="Fill-31" fill="#000000" d="M-156,260.4c-0.6,0.1-1,0.9-1,0.9l5-0.7C-152.1,260.5-153.5,260.1-156,260.4"/>
<path id="Fill-32" fill="#000000" d="M-138.6,258.8c0,0-1.4-0.4-2.4-0.3c-0.9,0.1-1.2,1-1.2,1
C-141.7,259-138.7,258.8-138.6,258.8"/>
<path id="Fill-33" fill="#000000" d="M-165.5,226.1c0,0-1.8-1-1.5-1.6c0.5-0.9,1.9-0.6,2.4-1.2c0.8-1,0.6-2.5,0.6-2.5
s-1.7-0.3-2.2,0.3c-0.8,1-3,4.2-3.2,4.6C-170.2,226.7-165.5,226.1-165.5,226.1"/>
<path id="Fill-34" fill="#000000" d="M-157,212.9c0.2,0,0.5-0.6,0.7-1.7c0,0-0.1,0-0.1,0c-0.1-0.1-0.3-0.1-0.4-0.2
c-0.1,0-0.1-0.1-0.2-0.1c-0.2-0.2-0.2-0.4-0.4-0.6c-0.3-0.2-0.6-0.2-0.9-0.1c0,0-0.3,0.1-0.4-0.2c0,0.2,0,0.3,0,0.5
c0,0.5-0.1,1.1-0.2,1.4c-0.1,0.3-0.1,0.6-0.2,0.8c0,0.1-0.1,0.2-0.1,0.3L-157,212.9C-157.1,212.9-157.1,212.9-157,212.9"/>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 17 KiB

View file

@ -16,19 +16,10 @@ Column
height: childrenRect.height height: childrenRect.height
anchors.centerIn: parent anchors.centerIn: parent
Image
{
id: profileImage
fillMode: Image.PreserveAspectFit
source: "../../images/logobot.svg"
anchors.horizontalCenter: parent.horizontalCenter
width: Math.round(parent.width / 4)
}
Label Label
{ {
id: welcomeTextLabel id: welcomeTextLabel
text: catalog.i18nc("@description", "Get plugins and materials verified by Ultimaker") text: catalog.i18nc("@description", "Please sign in to get verified plugins and materials for Ultimaker Cura Enterprise")
width: Math.round(parent.width / 2) width: Math.round(parent.width / 2)
font: UM.Theme.getFont("default") font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")

View file

@ -1,26 +1,29 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 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.
import os
from typing import Dict, List, Optional from typing import Dict, List, Optional
from PyQt5.QtCore import QTimer from PyQt5.QtCore import QTimer
from UM import i18nCatalog from UM import i18nCatalog
from UM.Logger import Logger # To log errors talking to the API. from UM.Logger import Logger # To log errors talking to the API.
from UM.Message import Message
from UM.Signal import Signal from UM.Signal import Signal
from cura.API import Account from cura.API import Account
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
from cura.Settings.CuraStackBuilder import CuraStackBuilder from cura.Settings.CuraStackBuilder import CuraStackBuilder
from cura.Settings.GlobalStack import GlobalStack from cura.Settings.GlobalStack import GlobalStack
from .CloudApiClient import CloudApiClient from .CloudApiClient import CloudApiClient
from .CloudOutputDevice import CloudOutputDevice from .CloudOutputDevice import CloudOutputDevice
from ..Models.Http.CloudClusterResponse import CloudClusterResponse from ..Models.Http.CloudClusterResponse import CloudClusterResponse
## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters.
# Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code.
# API spec is available on https://api.ultimaker.com/docs/connect/spec/.
class CloudOutputDeviceManager: class CloudOutputDeviceManager:
"""The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters.
Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code.
API spec is available on https://api.ultimaker.com/docs/connect/spec/.
"""
META_CLUSTER_ID = "um_cloud_cluster_id" META_CLUSTER_ID = "um_cloud_cluster_id"
META_NETWORK_KEY = "um_network_key" META_NETWORK_KEY = "um_network_key"
@ -44,14 +47,16 @@ class CloudOutputDeviceManager:
# Create a timer to update the remote cluster list # Create a timer to update the remote cluster list
self._update_timer = QTimer() self._update_timer = QTimer()
self._update_timer.setInterval(int(self.CHECK_CLUSTER_INTERVAL * 1000)) self._update_timer.setInterval(int(self.CHECK_CLUSTER_INTERVAL * 1000))
self._update_timer.setSingleShot(False) # The timer is restarted explicitly after an update was processed. This prevents 2 concurrent updates
self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._getRemoteClusters) self._update_timer.timeout.connect(self._getRemoteClusters)
# Ensure we don't start twice. # Ensure we don't start twice.
self._running = False self._running = False
## Starts running the cloud output device manager, thus periodically requesting cloud data.
def start(self): def start(self):
"""Starts running the cloud output device manager, thus periodically requesting cloud data."""
if self._running: if self._running:
return return
if not self._account.isLoggedIn: if not self._account.isLoggedIn:
@ -61,8 +66,9 @@ class CloudOutputDeviceManager:
self._update_timer.start() self._update_timer.start()
self._getRemoteClusters() self._getRemoteClusters()
## Stops running the cloud output device manager.
def stop(self): def stop(self):
"""Stops running the cloud output device manager."""
if not self._running: if not self._running:
return return
self._running = False self._running = False
@ -70,87 +76,164 @@ class CloudOutputDeviceManager:
self._update_timer.stop() self._update_timer.stop()
self._onGetRemoteClustersFinished([]) # Make sure we remove all cloud output devices. self._onGetRemoteClustersFinished([]) # Make sure we remove all cloud output devices.
## Force refreshing connections.
def refreshConnections(self) -> None: def refreshConnections(self) -> None:
"""Force refreshing connections."""
self._connectToActiveMachine() self._connectToActiveMachine()
## Called when the uses logs in or out
def _onLoginStateChanged(self, is_logged_in: bool) -> None: def _onLoginStateChanged(self, is_logged_in: bool) -> None:
"""Called when the uses logs in or out"""
if is_logged_in: if is_logged_in:
self.start() self.start()
else: else:
self.stop() self.stop()
## Gets all remote clusters from the API.
def _getRemoteClusters(self) -> None: def _getRemoteClusters(self) -> None:
"""Gets all remote clusters from the API."""
self._api.getClusters(self._onGetRemoteClustersFinished) self._api.getClusters(self._onGetRemoteClustersFinished)
## Callback for when the request for getting the clusters is finished.
def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None: def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None:
"""Callback for when the request for getting the clusters is finished."""
new_clusters = []
online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse] online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse]
for device_id, cluster_data in online_clusters.items(): for device_id, cluster_data in online_clusters.items():
if device_id not in self._remote_clusters: if device_id not in self._remote_clusters:
self._onDeviceDiscovered(cluster_data) new_clusters.append(cluster_data)
else:
self._onDiscoveredDeviceUpdated(cluster_data) self._onDevicesDiscovered(new_clusters)
# Inform whether new cloud printers have been detected. If they have, the welcome wizard can close.
self._account._new_cloud_printers_detected = len(new_clusters) > 0
self._account.cloudPrintersDetectedChanged.emit(len(new_clusters) > 0)
removed_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys()) removed_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys())
for device_id in removed_device_keys: for device_id in removed_device_keys:
self._onDiscoveredDeviceRemoved(device_id) self._onDiscoveredDeviceRemoved(device_id)
def _onDeviceDiscovered(self, cluster_data: CloudClusterResponse) -> None: if new_clusters or removed_device_keys:
device = CloudOutputDevice(self._api, cluster_data) self.discoveredDevicesChanged.emit()
CuraApplication.getInstance().getDiscoveredPrintersModel().addDiscoveredPrinter( if removed_device_keys:
ip_address=device.key, # If the removed device was active we should connect to the new active device
key=device.getId(), self._connectToActiveMachine()
name=device.getName(), # Schedule a new update
create_callback=self._createMachineFromDiscoveredDevice, self._update_timer.start()
machine_type=device.printerType,
device=device
)
self._remote_clusters[device.getId()] = device
self.discoveredDevicesChanged.emit()
self._connectToActiveMachine()
def _onDiscoveredDeviceUpdated(self, cluster_data: CloudClusterResponse) -> None: def _onDevicesDiscovered(self, clusters: List[CloudClusterResponse]) -> None:
device = self._remote_clusters.get(cluster_data.cluster_id) """**Synchronously** create machines for discovered devices
if not device:
Any new machines are made available to the user.
May take a long time to complete. As this code needs access to the Application
and blocks the GIL, creating a Job for this would not make sense.
Shows a Message informing the user of progress.
"""
new_devices = []
remote_clusters_added = False
for cluster_data in clusters:
device = CloudOutputDevice(self._api, cluster_data)
# Create a machine if we don't already have it. Do not make it the active machine.
machine_manager = CuraApplication.getInstance().getMachineManager()
# We only need to add it if it wasn't already added by "local" network or by cloud.
if machine_manager.getMachine(device.printerType, {self.META_CLUSTER_ID: device.key}) is None \
and machine_manager.getMachine(device.printerType, {self.META_NETWORK_KEY: cluster_data.host_name + "*"}) is None: # The host name is part of the network key.
new_devices.append(device)
elif device.getId() not in self._remote_clusters:
self._remote_clusters[device.getId()] = device
remote_clusters_added = True
if not new_devices:
if remote_clusters_added:
self._connectToActiveMachine()
return return
CuraApplication.getInstance().getDiscoveredPrintersModel().updateDiscoveredPrinter(
ip_address=device.key, new_devices.sort(key = lambda x: x.name.lower())
name=cluster_data.friendly_name,
machine_type=device.printerType image_path = os.path.join(
CuraApplication.getInstance().getPluginRegistry().getPluginPath("UM3NetworkPrinting") or "",
"resources", "svg", "cloud-flow-completed.svg"
) )
self.discoveredDevicesChanged.emit()
message = Message(
title = self.I18N_CATALOG.i18ncp(
"info:status",
"New printer detected from your Ultimaker account",
"New printers detected from your Ultimaker account",
len(new_devices)
),
progress = 0,
lifetime = 0,
image_source = image_path
)
message.show()
for idx, device in enumerate(new_devices):
message_text = self.I18N_CATALOG.i18nc(
"info:status", "Adding printer {} ({}) from your account",
device.name,
device.printerTypeName
)
message.setText(message_text)
if len(new_devices) > 1:
message.setProgress((idx / len(new_devices)) * 100)
CuraApplication.getInstance().processEvents()
self._remote_clusters[device.getId()] = device
# If there is no active machine, activate the first available cloud printer
activate = not CuraApplication.getInstance().getMachineManager().activeMachine
self._createMachineFromDiscoveredDevice(device.getId(), activate = activate)
message.setProgress(None)
max_disp_devices = 3
if len(new_devices) > max_disp_devices:
num_hidden = len(new_devices) - max_disp_devices + 1
device_name_list = ["- {} ({})".format(device.name, device.printerTypeName) for device in new_devices[0:num_hidden]]
device_name_list.append(self.I18N_CATALOG.i18nc("info:hidden list items", "- and {} others", num_hidden))
device_names = "\n".join(device_name_list)
else:
device_names = "\n".join(["- {} ({})".format(device.name, device.printerTypeName) for device in new_devices])
message_text = self.I18N_CATALOG.i18nc(
"info:status",
"Cloud printers added from your account:\n{}",
device_names
)
message.setText(message_text)
def _onDiscoveredDeviceRemoved(self, device_id: str) -> None: def _onDiscoveredDeviceRemoved(self, device_id: str) -> None:
device = self._remote_clusters.pop(device_id, None) # type: Optional[CloudOutputDevice] device = self._remote_clusters.pop(device_id, None) # type: Optional[CloudOutputDevice]
if not device: if not device:
return return
device.close() device.close()
CuraApplication.getInstance().getDiscoveredPrintersModel().removeDiscoveredPrinter(device.key)
output_device_manager = CuraApplication.getInstance().getOutputDeviceManager() output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
if device.key in output_device_manager.getOutputDeviceIds(): if device.key in output_device_manager.getOutputDeviceIds():
output_device_manager.removeOutputDevice(device.key) output_device_manager.removeOutputDevice(device.key)
self.discoveredDevicesChanged.emit()
def _createMachineFromDiscoveredDevice(self, key: str) -> None: def _createMachineFromDiscoveredDevice(self, key: str, activate: bool = True) -> None:
device = self._remote_clusters[key] device = self._remote_clusters[key]
if not device: if not device:
return return
# Create a new machine and activate it. # Create a new machine.
# We do not use use MachineManager.addMachine here because we need to set the cluster ID before activating it. # We do not use use MachineManager.addMachine here because we need to set the cluster ID before activating it.
new_machine = CuraStackBuilder.createMachine(device.name, device.printerType) new_machine = CuraStackBuilder.createMachine(device.name, device.printerType)
if not new_machine: if not new_machine:
Logger.log("e", "Failed creating a new machine") Logger.log("e", "Failed creating a new machine")
return return
new_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) new_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key)
CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId())
if activate:
CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId())
self._connectToOutputDevice(device, new_machine) self._connectToOutputDevice(device, new_machine)
## Callback for when the active machine was changed by the user or a new remote cluster was found.
def _connectToActiveMachine(self) -> None: def _connectToActiveMachine(self) -> None:
"""Callback for when the active machine was changed by the user"""
active_machine = CuraApplication.getInstance().getGlobalContainerStack() active_machine = CuraApplication.getInstance().getGlobalContainerStack()
if not active_machine: if not active_machine:
return return
@ -169,8 +252,9 @@ class CloudOutputDeviceManager:
# Remove device if it is not meant for the active machine. # Remove device if it is not meant for the active machine.
output_device_manager.removeOutputDevice(device.key) output_device_manager.removeOutputDevice(device.key)
## Connects to an output device and makes sure it is registered in the output device manager.
def _connectToOutputDevice(self, device: CloudOutputDevice, machine: GlobalStack) -> None: def _connectToOutputDevice(self, device: CloudOutputDevice, machine: GlobalStack) -> None:
"""Connects to an output device and makes sure it is registered in the output device manager."""
machine.setName(device.name) machine.setName(device.name)
machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key) machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key)
machine.setMetaDataEntry("group_name", device.name) machine.setMetaDataEntry("group_name", device.name)

View file

@ -92,9 +92,13 @@ class SendMaterialJob(Job):
parts = [] parts = []
# Add the material file. # Add the material file.
with open(file_path, "rb") as f: try:
parts.append(self.device.createFormPart("name=\"file\"; filename=\"{file_name}\"" with open(file_path, "rb") as f:
.format(file_name = file_name), f.read())) parts.append(self.device.createFormPart("name=\"file\"; filename=\"{file_name}\""
.format(file_name = file_name), f.read()))
except FileNotFoundError:
Logger.error("Unable to send material {material_id}, since it has been deleted in the meanwhile.".format(material_id = material_id))
return
# Add the material signature file if needed. # Add the material signature file if needed.
signature_file_path = "{}.sig".format(file_path) signature_file_path = "{}.sig".format(file_path)

View file

@ -52,7 +52,6 @@ class UltimakerNetworkedPrinterOutputDevice(NetworkedPrinterOutputDevice):
super().__init__(device_id=device_id, address=address, properties=properties, connection_type=connection_type, super().__init__(device_id=device_id, address=address, properties=properties, connection_type=connection_type,
parent=parent) parent=parent)
# Trigger the printersChanged signal when the private signal is triggered. # Trigger the printersChanged signal when the private signal is triggered.
self.printersChanged.connect(self._clusterPrintersChanged) self.printersChanged.connect(self._clusterPrintersChanged)

View file

@ -191,7 +191,10 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
try: try:
self._serial = Serial(str(self._serial_port), self._baud_rate, timeout=self._timeout, writeTimeout=self._timeout) self._serial = Serial(str(self._serial_port), self._baud_rate, timeout=self._timeout, writeTimeout=self._timeout)
except SerialException: except SerialException:
Logger.log("w", "An exception occurred while trying to create serial connection") Logger.warning("An exception occurred while trying to create serial connection.")
return
except OSError as e:
Logger.warning("The serial device is suddenly unavailable while trying to create a serial connection: {err}".format(err = str(e)))
return return
CuraApplication.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) CuraApplication.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged)
self._onGlobalContainerStackChanged() self._onGlobalContainerStackChanged()

View file

@ -236,23 +236,11 @@ _variant_translations_materials = {
} }
} # type: Dict[str, Dict[str, str]] } # type: Dict[str, Dict[str, str]]
## Converts configuration from Cura 2.1's file formats to Cura 2.2's. ## Converts configuration from Cura 2.1's file formats to Cura 2.2's.
# #
# It converts the machine instances and profiles. # It converts the machine instances and profiles.
class VersionUpgrade21to22(VersionUpgrade): class VersionUpgrade21to22(VersionUpgrade):
## Gets the version number from a config file.
#
# In all config files that concern this version upgrade, the version
# number is stored in general/version, so get the data from that key.
#
# \param serialised The contents of a config file.
# \return The version number of that config file.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Gets the fallback quality to use for a specific machine-variant-material ## Gets the fallback quality to use for a specific machine-variant-material
# combination. # combination.

View file

@ -19,6 +19,7 @@ _split_settings = { #These settings should be copied to all settings it was spli
"support_interface_line_distance": {"support_roof_line_distance", "support_bottom_line_distance"} "support_interface_line_distance": {"support_roof_line_distance", "support_bottom_line_distance"}
} # type: Dict[str, Set[str]] } # type: Dict[str, Set[str]]
## A collection of functions that convert the configuration of the user in Cura ## A collection of functions that convert the configuration of the user in Cura
# 2.5 to a configuration for Cura 2.6. # 2.5 to a configuration for Cura 2.6.
# #
@ -28,24 +29,6 @@ class VersionUpgrade25to26(VersionUpgrade):
super().__init__() super().__init__()
self._current_fdm_printer_count = 2 self._current_fdm_printer_count = 2
## Gets the version number from a CFG file in Uranium's 2.5 format.
#
# Since the format may change, this is implemented for the 2.5 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades the preferences file from version 2.5 to 2.6. ## Upgrades the preferences file from version 2.5 to 2.6.
# #
# \param serialised The serialised form of a preferences file. # \param serialised The serialised form of a preferences file.

View file

@ -64,29 +64,12 @@ _renamed_quality_profiles = {
"um3_bb0.8_TPU_Not_Supported_Superdraft_Quality": "um3_bb0.8_TPU_Superdraft_Print", "um3_bb0.8_TPU_Not_Supported_Superdraft_Quality": "um3_bb0.8_TPU_Superdraft_Print",
} # type: Dict[str, str] } # type: Dict[str, str]
## A collection of functions that convert the configuration of the user in Cura ## A collection of functions that convert the configuration of the user in Cura
# 2.6 to a configuration for Cura 2.7. # 2.6 to a configuration for Cura 2.7.
# #
# All of these methods are essentially stateless. # All of these methods are essentially stateless.
class VersionUpgrade26to27(VersionUpgrade): class VersionUpgrade26to27(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 2.6 format.
#
# Since the format may change, this is implemented for the 2.6 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades a preferences file from version 2.6 to 2.7. ## Upgrades a preferences file from version 2.6 to 2.7.
# #
# \param serialised The serialised form of a preferences file. # \param serialised The serialised form of a preferences file.

View file

@ -62,24 +62,6 @@ _RENAMED_DEFINITION_DICT = {
class VersionUpgrade30to31(VersionUpgrade): class VersionUpgrade30to31(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 3.0 format.
#
# Since the format may change, this is implemented for the 3.0 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades a preferences file from version 3.0 to 3.1. ## Upgrades a preferences file from version 3.0 to 3.1.
# #
# \param serialised The serialised form of a preferences file. # \param serialised The serialised form of a preferences file.

View file

@ -68,24 +68,6 @@ _RENAMED_QUALITY_TYPES = {
class VersionUpgrade32to33(VersionUpgrade): class VersionUpgrade32to33(VersionUpgrade):
temporary_group_name_counter = 1 temporary_group_name_counter = 1
## Gets the version number from a CFG file in Uranium's 3.2 format.
#
# Since the format may change, this is implemented for the 3.2 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades a preferences file from version 3.2 to 3.3. ## Upgrades a preferences file from version 3.2 to 3.3.
# #
# \param serialised The serialised form of a preferences file. # \param serialised The serialised form of a preferences file.

View file

@ -14,24 +14,6 @@ _renamed_settings = {
## Upgrades configurations from the state they were in at version 3.3 to the ## Upgrades configurations from the state they were in at version 3.3 to the
# state they should be in at version 3.4. # state they should be in at version 3.4.
class VersionUpgrade33to34(VersionUpgrade): class VersionUpgrade33to34(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 3.3 format.
#
# Since the format may change, this is implemented for the 3.3 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades instance containers to have the new version ## Upgrades instance containers to have the new version
# number. # number.
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:

View file

@ -63,24 +63,6 @@ _RENAMED_MATERIAL_PROFILES = {
## Upgrades configurations from the state they were in at version 3.4 to the ## Upgrades configurations from the state they were in at version 3.4 to the
# state they should be in at version 3.5. # state they should be in at version 3.5.
class VersionUpgrade34to35(VersionUpgrade): class VersionUpgrade34to35(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 3.4 format.
#
# Since the format may change, this is implemented for the 3.4 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades Preferences to have the new version number. ## Upgrades Preferences to have the new version number.
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
parser = configparser.ConfigParser(interpolation = None) parser = configparser.ConfigParser(interpolation = None)

View file

@ -34,13 +34,6 @@ class VersionUpgrade35to40(VersionUpgrade):
parser.write(result) parser.write(result)
return [filename], [result.getvalue()] return [filename], [result.getvalue()]
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades Preferences to have the new version number. ## Upgrades Preferences to have the new version number.
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
parser = configparser.ConfigParser(interpolation=None) parser = configparser.ConfigParser(interpolation=None)

View file

@ -23,24 +23,6 @@ _renamed_quality_profiles = {
## Upgrades configurations from the state they were in at version 4.0 to the ## Upgrades configurations from the state they were in at version 4.0 to the
# state they should be in at version 4.1. # state they should be in at version 4.1.
class VersionUpgrade40to41(VersionUpgrade): class VersionUpgrade40to41(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 4.0 format.
#
# Since the format may change, this is implemented for the 4.0 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades instance containers to have the new version ## Upgrades instance containers to have the new version
# number. # number.
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:

View file

@ -213,27 +213,10 @@ _creality_limited_quality_type = {
"extra_coarse": "draft" "extra_coarse": "draft"
} }
## Upgrades configurations from the state they were in at version 4.1 to the ## Upgrades configurations from the state they were in at version 4.1 to the
# state they should be in at version 4.2. # state they should be in at version 4.2.
class VersionUpgrade41to42(VersionUpgrade): class VersionUpgrade41to42(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 4.1 format.
#
# Since the format may change, this is implemented for the 4.1 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades instance containers to have the new version ## Upgrades instance containers to have the new version
# number. # number.
# #

View file

@ -56,27 +56,10 @@ _renamed_settings = {
"support_infill_angle": "support_infill_angles" "support_infill_angle": "support_infill_angles"
} # type: Dict[str, str] } # type: Dict[str, str]
## Upgrades configurations from the state they were in at version 4.2 to the ## Upgrades configurations from the state they were in at version 4.2 to the
# state they should be in at version 4.3. # state they should be in at version 4.3.
class VersionUpgrade42to43(VersionUpgrade): class VersionUpgrade42to43(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 4.2 format.
#
# Since the format may change, this is implemented for the 4.2 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
def upgradePreferences(self, serialized: str, filename: str): def upgradePreferences(self, serialized: str, filename: str):
parser = configparser.ConfigParser(interpolation = None) parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized) parser.read_string(serialized)

View file

@ -26,12 +26,6 @@ _renamed_container_id_map = {
class VersionUpgrade43to44(VersionUpgrade): class VersionUpgrade43to44(VersionUpgrade):
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades Preferences to have the new version number. ## Upgrades Preferences to have the new version number.
# #

View file

@ -122,13 +122,6 @@ class VersionUpgrade44to45(VersionUpgrade):
except OSError: # Is a directory, file not found, or insufficient rights. except OSError: # Is a directory, file not found, or insufficient rights.
continue continue
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
## Upgrades Preferences to have the new version number. ## Upgrades Preferences to have the new version number.
# #
# This renames the renamed settings in the list of visible settings. # This renames the renamed settings in the list of visible settings.

View file

@ -10,14 +10,8 @@ _removed_settings = {
"machine_filament_park_distance", "machine_filament_park_distance",
} }
class VersionUpgrade45to46(VersionUpgrade):
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
class VersionUpgrade45to46(VersionUpgrade):
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
""" """
Upgrades preferences to have the new version number. Upgrades preferences to have the new version number.

View file

@ -6,14 +6,8 @@ from typing import Tuple, List
import io import io
from UM.VersionUpgrade import VersionUpgrade from UM.VersionUpgrade import VersionUpgrade
class VersionUpgrade46to47(VersionUpgrade):
def getCfgVersion(self, serialised: str) -> int:
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) # Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = "0"))
return format_version * 1000000 + setting_version
class VersionUpgrade46to47(VersionUpgrade):
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]: def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
""" """
Upgrades preferences to have the new version number. Upgrades preferences to have the new version number.

View file

@ -4,7 +4,7 @@
"inherits": "creality_cr10", "inherits": "creality_cr10",
"overrides": { "overrides": {
"machine_name": { "default_value": "Creality CR-10S Pro" }, "machine_name": { "default_value": "Creality CR-10S Pro" },
"machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nM420 S1 Z2 ;Enable ABL using saved Mesh and Fade Height\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n"}, "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nG29 ;Auto bed Level\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n"},
"machine_head_with_fans_polygon": { "default_value": [ "machine_head_with_fans_polygon": { "default_value": [
[-44, 34], [-44, 34],
[-44, -34], [-44, -34],
@ -21,4 +21,4 @@
"platform": "creality_cr10spro.stl", "platform": "creality_cr10spro.stl",
"platform_offset": [ -150, 0, 150] "platform_offset": [ -150, 0, 150]
} }
} }

View file

@ -9,8 +9,8 @@
}, },
"overrides": { "overrides": {
"machine_name": { "default_value": "Creality Ender-3 Pro" }, "machine_name": { "default_value": "Creality Ender-3 Pro" },
"machine_width": { "default_value": 235 }, "machine_width": { "default_value": 220 },
"machine_depth": { "default_value": 235 }, "machine_depth": { "default_value": 220 },
"machine_height": { "default_value": 250 }, "machine_height": { "default_value": 250 },
"machine_head_with_fans_polygon": { "default_value": [ "machine_head_with_fans_polygon": { "default_value": [
[-26, 34], [-26, 34],

View file

@ -43,7 +43,7 @@
"default_value": 1.75 "default_value": 1.75
}, },
"machine_start_gcode": { "machine_start_gcode": {
"default_value": "G21\nG90\nM82\nM107 T0\nM190 S{material_bed_temperature}\nM109 S{material_print_temperature} T0\nG28\nG92 E0\nG0 E3 F200\nG92 E0\n" "default_value": "G21\nG90\nM82\nM107 T0\nM190 S{material_bed_temperature_layer_0}\nM109 S{material_print_temperature_layer_0} T0\nG28\nG92 E0\nG0 E3 F200\nG92 E0\n"
}, },
"machine_end_gcode": { "machine_end_gcode": {
"default_value": "M107 T0\nM104 S0\nM104 S0 T1\nM140 S0\nG92 E0\nG91\nG1 E-1 F300 \nG1 Z+0.5 E-5 X-20 Y-20 F9000\nG28 X0 Y0\nM84 ;steppers off\nG90 ;absolute positioning\n" "default_value": "M107 T0\nM104 S0\nM104 S0 T1\nM140 S0\nG92 E0\nG91\nG1 E-1 F300 \nG1 Z+0.5 E-5 X-20 Y-20 F9000\nG28 X0 Y0\nM84 ;steppers off\nG90 ;absolute positioning\n"

View file

@ -143,8 +143,9 @@ Item
const networkPrinterItem = addNetworkPrinterDropDown.contentItem.currentItem const networkPrinterItem = addNetworkPrinterDropDown.contentItem.currentItem
CuraApplication.getDiscoveredPrintersModel().createMachineFromDiscoveredPrinter(networkPrinterItem) CuraApplication.getDiscoveredPrintersModel().createMachineFromDiscoveredPrinter(networkPrinterItem)
// If we have created a machine, go to the last page, which is the "cloud" page. // If we have created a machine, end the wizard (since this is the last page)
base.goToPage("cloud") base.endWizard()
} }
else else
{ {

View file

@ -130,7 +130,7 @@ Item
onTextEdited: invalidInputLabel.visible = false onTextEdited: invalidInputLabel.visible = false
placeholderText: catalog.i18nc("@text", "Place enter your printer's IP address.") placeholderText: catalog.i18nc("@text", "Enter your printer's IP address.")
enabled: { ! (addPrinterByIpScreen.hasRequestInProgress || addPrinterByIpScreen.isPrinterDiscovered) } enabled: { ! (addPrinterByIpScreen.hasRequestInProgress || addPrinterByIpScreen.isPrinterDiscovered) }
onAccepted: addPrinterButton.clicked() onAccepted: addPrinterButton.clicked()

View file

@ -15,14 +15,18 @@ Item
{ {
UM.I18nCatalog { id: catalog; name: "cura" } UM.I18nCatalog { id: catalog; name: "cura" }
property bool isLoggedIn: Cura.API.account.isLoggedIn property bool newCloudPrintersDetected: Cura.API.account.newCloudPrintersDetected
onIsLoggedInChanged: onNewCloudPrintersDetectedChanged:
{ {
if(isLoggedIn) // When the user signs in successfully, it will be checked whether he/she has cloud printers connected to
// the account. If he/she does, then the welcome wizard can close. If not, then proceed to the next page (if any)
if(newCloudPrintersDetected)
{
base.endWizard()
}
else
{ {
// If the user created an account or logged in by pressing any button on this page, all the actions that
// need / can be done by this page are completed, so we can just go to the next (if any).
base.showNextPage() base.showNextPage()
} }
} }
@ -46,7 +50,7 @@ Item
anchors anchors
{ {
top: titleLabel.bottom top: titleLabel.bottom
bottom: finishButton.top bottom: skipButton.top
left: parent.left left: parent.left
right: parent.right right: parent.right
topMargin: UM.Theme.getSize("default_margin").height topMargin: UM.Theme.getSize("default_margin").height
@ -107,35 +111,47 @@ Item
color: UM.Theme.getColor("text") color: UM.Theme.getColor("text")
renderType: Text.NativeRendering renderType: Text.NativeRendering
} }
// "Sign in" and "Create an account" exist inside the column
Cura.PrimaryButton
{
id: signInButton
height: createAccountButton.height
width: createAccountButton.width
anchors.horizontalCenter: parent.horizontalCenter
text: catalog.i18nc("@button", "Sign in")
onClicked: Cura.API.account.login()
// Content Item is used in order to align the text inside the button. Without it, when resizing the
// button, the text will be aligned on the left
contentItem: Text {
text: signInButton.text
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("primary_text")
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
Cura.SecondaryButton
{
id: createAccountButton
anchors.horizontalCenter: parent.horizontalCenter
text: catalog.i18nc("@button","Create account")
onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create")
}
} }
} }
// Bottom buttons go here // The "Skip" button exists on the bottom right
Cura.PrimaryButton
{
id: finishButton
anchors.right: parent.right
anchors.bottom: parent.bottom
text: catalog.i18nc("@button", "Finish")
onClicked: base.showNextPage()
}
Cura.SecondaryButton
{
id: createAccountButton
anchors.left: parent.left
anchors.verticalCenter: finishButton.verticalCenter
text: catalog.i18nc("@button", "Create an account")
onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create")
}
Label Label
{ {
id: signInButton id: skipButton
anchors.left: createAccountButton.right anchors.right: parent.right
anchors.verticalCenter: finishButton.verticalCenter anchors.bottom: parent.bottom
anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.leftMargin: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@button", "Sign in") text: catalog.i18nc("@button", "Skip")
color: UM.Theme.getColor("secondary_button_text") color: UM.Theme.getColor("secondary_button_text")
font: UM.Theme.getFont("medium") font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering renderType: Text.NativeRendering
@ -144,7 +160,7 @@ Item
{ {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: Cura.API.account.login() onClicked: base.showNextPage()
onEntered: parent.font.underline = true onEntered: parent.font.underline = true
onExited: parent.font.underline = false onExited: parent.font.underline = false
} }

View file

@ -68,11 +68,9 @@ fragment =
finalColor = (-normal.y > u_overhangAngle) ? u_overhangColor : finalColor; finalColor = (-normal.y > u_overhangAngle) ? u_overhangColor : finalColor;
if(u_renderError > 0.5) vec3 grid = vec3(f_vertex.x - floor(f_vertex.x - 0.5), f_vertex.y - floor(f_vertex.y - 0.5), f_vertex.z - floor(f_vertex.z - 0.5));
{ finalColor.a = (u_renderError > 0.5) && dot(grid, grid) < 0.245 ? 0.667 : 1.0;
vec3 grid = vec3(f_vertex.x - round(f_vertex.x), f_vertex.y - round(f_vertex.y), f_vertex.z - round(f_vertex.z));
finalColor.a = dot(grid, grid) < 0.245 ? 0.667 : 1.0;
}
gl_FragColor = finalColor; gl_FragColor = finalColor;
} }
@ -144,11 +142,8 @@ fragment41core =
finalColor = (u_faceId != gl_PrimitiveID) ? ((-normal.y > u_overhangAngle) ? u_overhangColor : finalColor) : u_faceColor; finalColor = (u_faceId != gl_PrimitiveID) ? ((-normal.y > u_overhangAngle) ? u_overhangColor : finalColor) : u_faceColor;
frag_color = finalColor; frag_color = finalColor;
if(u_renderError > 0.5) vec3 grid = f_vertex - round(f_vertex);
{ frag_color.a = (u_renderError > 0.5) && dot(grid, grid) < 0.245 ? 0.667 : 1.0;
vec3 grid = f_vertex - round(f_vertex);
frag_color.a = dot(grid, grid) < 0.245 ? 0.667 : 1.0;
}
} }
[defaults] [defaults]

View file

@ -0,0 +1,12 @@
[general]
name = 0.2mm Nozzle
version = 4
definition = creality_ender3pro
[metadata]
setting_version = 13
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.2

View file

@ -0,0 +1,12 @@
[general]
name = 0.3mm Nozzle
version = 4
definition = creality_ender3pro
[metadata]
setting_version = 13
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.3

View file

@ -0,0 +1,12 @@
[general]
name = 0.4mm Nozzle
version = 4
definition = creality_ender3pro
[metadata]
setting_version = 13
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.4

View file

@ -0,0 +1,12 @@
[general]
name = 0.5mm Nozzle
version = 4
definition = creality_ender3pro
[metadata]
setting_version = 13
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.5

View file

@ -0,0 +1,12 @@
[general]
name = 0.6mm Nozzle
version = 4
definition = creality_ender3pro
[metadata]
setting_version = 13
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.6

View file

@ -0,0 +1,12 @@
[general]
name = 0.8mm Nozzle
version = 4
definition = creality_ender3pro
[metadata]
setting_version = 13
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.8

View file

@ -0,0 +1,12 @@
[general]
name = 1.0mm Nozzle
version = 4
definition = creality_ender3pro
[metadata]
setting_version = 13
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 1.0