Merge branch 'master' of github.com:Ultimaker/Cura into CURA-7418-update-profile-window

This commit is contained in:
Jaime van Kessel 2020-06-15 14:10:20 +02:00
commit f6e9bc7c3c
No known key found for this signature in database
GPG Key ID: 3710727397403C91
51 changed files with 697 additions and 296 deletions

View File

@ -10,7 +10,7 @@ from UM.Message import Message
from UM.i18n import i18nCatalog
from cura.OAuth2.AuthorizationService import AuthorizationService
from cura.OAuth2.Models import OAuth2Settings
from cura.UltimakerCloud import UltimakerCloudAuthentication
from cura.UltimakerCloud import UltimakerCloudConstants
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
@ -69,7 +69,7 @@ class Account(QObject):
self._last_sync_str = "-"
self._callback_port = 32118
self._oauth_root = UltimakerCloudAuthentication.CuraCloudAccountAPIRoot
self._oauth_root = UltimakerCloudConstants.CuraCloudAccountAPIRoot
self._oauth_settings = OAuth2Settings(
OAUTH_SERVER_URL= self._oauth_root,

View File

@ -4,14 +4,14 @@ from PyQt5.QtCore import QObject, pyqtSignal, QTimer, pyqtProperty
from PyQt5.QtNetwork import QNetworkReply
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
from cura.UltimakerCloud import UltimakerCloudAuthentication
from cura.UltimakerCloud import UltimakerCloudConstants
class ConnectionStatus(QObject):
"""Status info for some web services"""
UPDATE_INTERVAL = 10.0 # seconds
ULTIMAKER_CLOUD_STATUS_URL = UltimakerCloudAuthentication.CuraCloudAPIRoot + "/connect/v1/"
ULTIMAKER_CLOUD_STATUS_URL = UltimakerCloudConstants.CuraCloudAPIRoot + "/connect/v1/"
__instance = None # type: Optional[ConnectionStatus]

View File

@ -106,7 +106,7 @@ from cura.UI.RecommendedMode import RecommendedMode
from cura.UI.TextManager import TextManager
from cura.UI.WelcomePagesModel import WelcomePagesModel
from cura.UI.WhatsNewPagesModel import WhatsNewPagesModel
from cura.UltimakerCloud import UltimakerCloudAuthentication
from cura.UltimakerCloud import UltimakerCloudConstants
from cura.Utils.NetworkingUtil import NetworkingUtil
from . import BuildVolume
from . import CameraAnimation
@ -207,6 +207,7 @@ class CuraApplication(QtApplication):
self._first_start_machine_actions_model = None
self._welcome_pages_model = WelcomePagesModel(self, parent = self)
self._add_printer_pages_model = AddPrinterPagesModel(self, parent = self)
self._add_printer_pages_model_without_cancel = AddPrinterPagesModel(self, parent = self)
self._whats_new_pages_model = WhatsNewPagesModel(self, parent = self)
self._text_manager = TextManager(parent = self)
@ -255,11 +256,11 @@ class CuraApplication(QtApplication):
@pyqtProperty(str, constant=True)
def ultimakerCloudApiRootUrl(self) -> str:
return UltimakerCloudAuthentication.CuraCloudAPIRoot
return UltimakerCloudConstants.CuraCloudAPIRoot
@pyqtProperty(str, constant = True)
def ultimakerCloudAccountRootUrl(self) -> str:
return UltimakerCloudAuthentication.CuraCloudAccountAPIRoot
return UltimakerCloudConstants.CuraCloudAccountAPIRoot
@pyqtProperty(str, constant=True)
def ultimakerDigitalFactoryUrl(self) -> str:
@ -651,7 +652,7 @@ class CuraApplication(QtApplication):
return self._global_container_stack
@override(Application)
def setGlobalContainerStack(self, stack: "GlobalStack") -> None:
def setGlobalContainerStack(self, stack: Optional["GlobalStack"]) -> None:
self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing Active Machine..."))
super().setGlobalContainerStack(stack)
@ -816,6 +817,7 @@ class CuraApplication(QtApplication):
self._output_device_manager.start()
self._welcome_pages_model.initialize()
self._add_printer_pages_model.initialize()
self._add_printer_pages_model_without_cancel.initialize(cancellable = False)
self._whats_new_pages_model.initialize()
# Detect in which mode to run and execute that mode
@ -853,6 +855,7 @@ class CuraApplication(QtApplication):
self.callLater(self._openFile, file_name)
initializationFinished = pyqtSignal()
showAddPrintersUncancellableDialog = pyqtSignal() # Used to show the add printers dialog with a greyed background
def runWithoutGUI(self):
"""Run Cura without GUI elements and interaction (server mode)."""
@ -943,6 +946,10 @@ class CuraApplication(QtApplication):
def getAddPrinterPagesModel(self, *args) -> "AddPrinterPagesModel":
return self._add_printer_pages_model
@pyqtSlot(result = QObject)
def getAddPrinterPagesModelWithoutCancel(self, *args) -> "AddPrinterPagesModel":
return self._add_printer_pages_model_without_cancel
@pyqtSlot(result = QObject)
def getWhatsNewPagesModel(self, *args) -> "WhatsNewPagesModel":
return self._whats_new_pages_model

View File

@ -154,7 +154,7 @@ class BaseMaterialsModel(ListModel):
# Update the available materials (ContainerNode) for the current active machine and extruder setup.
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
if not global_stack.hasMaterials:
if not global_stack or not global_stack.hasMaterials:
return # There are no materials for this machine, so nothing to do.
extruder_list = global_stack.extruderList
if self._extruder_position > len(extruder_list):

View File

@ -2,6 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher.
from http.server import HTTPServer
from socketserver import ThreadingMixIn
from typing import Callable, Any, TYPE_CHECKING
if TYPE_CHECKING:
@ -9,7 +10,7 @@ if TYPE_CHECKING:
from cura.OAuth2.AuthorizationHelpers import AuthorizationHelpers
class AuthorizationRequestServer(HTTPServer):
class AuthorizationRequestServer(ThreadingMixIn, HTTPServer):
"""The authorization request callback handler server.
This subclass is needed to be able to pass some data to the request handler. This cannot be done on the request

View File

@ -81,7 +81,7 @@ class LocalAuthorizationServer:
if self._web_server:
try:
self._web_server.server_close()
self._web_server.shutdown()
except OSError:
# OS error can happen if the socket was already closed. We really don't care about that case.
pass

View File

@ -22,6 +22,7 @@ from UM.Settings.SettingFunction import SettingFunction
from UM.Signal import postponeSignals, CompressTechnique
import cura.CuraApplication # Imported like this to prevent circular references.
from UM.Util import parseBool
from cura.Machines.ContainerNode import ContainerNode
from cura.Machines.ContainerTree import ContainerTree
@ -37,6 +38,7 @@ from cura.Settings.ExtruderStack import ExtruderStack
from cura.Settings.cura_empty_instance_containers import (empty_definition_changes_container, empty_variant_container,
empty_material_container, empty_quality_container,
empty_quality_changes_container, empty_intent_container)
from cura.UltimakerCloud.UltimakerCloudConstants import META_UM_LINKED_TO_ACCOUNT
from .CuraStackBuilder import CuraStackBuilder
@ -288,9 +290,15 @@ class MachineManager(QObject):
self.activeStackValueChanged.emit()
@pyqtSlot(str)
def setActiveMachine(self, stack_id: str) -> None:
def setActiveMachine(self, stack_id: Optional[str]) -> None:
self.blurSettings.emit() # Ensure no-one has focus.
if not stack_id:
self._application.setGlobalContainerStack(None)
self.globalContainerChanged.emit()
self._application.showAddPrintersUncancellableDialog.emit()
return
container_registry = CuraContainerRegistry.getInstance()
containers = container_registry.findContainerStacks(id = stack_id)
if not containers:
@ -494,6 +502,10 @@ class MachineManager(QObject):
group_size = int(self.activeMachine.getMetaDataEntry("group_size", "-1"))
return group_size > 1
@pyqtProperty(bool, notify = printerConnectedStatusChanged)
def activeMachineIsLinkedToCurrentAccount(self) -> bool:
return parseBool(self.activeMachine.getMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, "True"))
@pyqtProperty(bool, notify = printerConnectedStatusChanged)
def activeMachineHasNetworkConnection(self) -> bool:
# A network connection is only available if any output device is actually a network connected device.
@ -715,6 +727,8 @@ class MachineManager(QObject):
other_machine_stacks = [s for s in machine_stacks if s["id"] != machine_id]
if other_machine_stacks:
self.setActiveMachine(other_machine_stacks[0]["id"])
else:
self.setActiveMachine(None)
metadatas = CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)
if not metadatas:

View File

@ -10,12 +10,11 @@ from .WelcomePagesModel import WelcomePagesModel
#
class AddPrinterPagesModel(WelcomePagesModel):
def initialize(self) -> None:
def initialize(self, cancellable: bool = True) -> None:
self._pages.append({"id": "add_network_or_local_printer",
"page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
"next_page_id": "machine_actions",
"next_page_button_text": self._catalog.i18nc("@action:button", "Add"),
"previous_page_button_text": self._catalog.i18nc("@action:button", "Cancel"),
})
self._pages.append({"id": "add_printer_by_ip",
"page_url": self._getBuiltinWelcomePagePath("AddPrinterByIpContent.qml"),
@ -30,6 +29,9 @@ class AddPrinterPagesModel(WelcomePagesModel):
"page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
"should_show_function": self.shouldShowMachineActions,
})
if cancellable:
self._pages[0]["previous_page_button_text"] = self._catalog.i18nc("@action:button", "Cancel")
self.setItems(self._pages)

View File

@ -9,6 +9,10 @@ DEFAULT_CLOUD_API_VERSION = "1" # type: str
DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str
DEFAULT_DIGITAL_FACTORY_URL = "https://digitalfactory.ultimaker.com" # type: str
# Container Metadata keys
META_UM_LINKED_TO_ACCOUNT = "um_linked_to_account"
"""(bool) Whether a cloud printer is linked to an Ultimaker account"""
try:
from cura.CuraVersion import CuraCloudAPIRoot # type: ignore
if CuraCloudAPIRoot == "":

View File

@ -1,13 +1,13 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from cura.UltimakerCloud import UltimakerCloudAuthentication
from cura.UltimakerCloud import UltimakerCloudConstants
class Settings:
# Keeps the plugin settings.
DRIVE_API_VERSION = 1
DRIVE_API_URL = "{}/cura-drive/v{}".format(UltimakerCloudAuthentication.CuraCloudAPIRoot, str(DRIVE_API_VERSION))
DRIVE_API_URL = "{}/cura-drive/v{}".format(UltimakerCloudConstants.CuraCloudAPIRoot, str(DRIVE_API_VERSION))
AUTO_BACKUP_ENABLED_PREFERENCE_KEY = "cura_drive/auto_backup_enabled"
AUTO_BACKUP_LAST_DATE_PREFERENCE_KEY = "cura_drive/auto_backup_date"

View File

@ -289,6 +289,13 @@ class Stretcher:
self.layergcode = self.layergcode + sout + "\n"
ipos = ipos + 1
else:
# The command is intended to be passed through unmodified via
# the comment field. In the case of an extruder only move, though,
# the extruder and potentially the feed rate are modified.
# We need to update self.outpos accordingly so that subsequent calls
# to stepToGcode() knows about the extruder and feed rate change.
self.outpos.step_e = layer_steps[i].step_e
self.outpos.step_f = layer_steps[i].step_f
self.layergcode = self.layergcode + layer_steps[i].comment + "\n"
def workOnSequence(self, orig_seq, modif_seq):

View File

@ -1,13 +1,13 @@
from typing import Union
from cura import ApplicationMetadata
from cura.UltimakerCloud import UltimakerCloudAuthentication
from cura.UltimakerCloud import UltimakerCloudConstants
class CloudApiModel:
sdk_version = ApplicationMetadata.CuraSDKVersion # type: Union[str, int]
cloud_api_version = UltimakerCloudAuthentication.CuraCloudAPIVersion # type: str
cloud_api_root = UltimakerCloudAuthentication.CuraCloudAPIRoot # type: str
cloud_api_version = UltimakerCloudConstants.CuraCloudAPIVersion # type: str
cloud_api_root = UltimakerCloudConstants.CuraCloudAPIRoot # type: str
api_url = "{cloud_api_root}/cura-packages/v{cloud_api_version}/cura/v{sdk_version}".format(
cloud_api_root = cloud_api_root,
cloud_api_version = cloud_api_version,

View File

@ -13,7 +13,7 @@ from UM.TaskManagement.HttpRequestManager import HttpRequestManager
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
from cura.API import Account
from cura.CuraApplication import CuraApplication
from cura.UltimakerCloud import UltimakerCloudAuthentication
from cura.UltimakerCloud import UltimakerCloudConstants
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
from .ToolPathUploader import ToolPathUploader
from ..Models.BaseModel import BaseModel
@ -35,7 +35,7 @@ class CloudApiClient:
"""
# The cloud URL to use for this remote cluster.
ROOT_PATH = UltimakerCloudAuthentication.CuraCloudAPIRoot
ROOT_PATH = UltimakerCloudConstants.CuraCloudAPIRoot
CLUSTER_API_ROOT = "{}/connect/v1".format(ROOT_PATH)
CURA_API_ROOT = "{}/cura/v1".format(ROOT_PATH)

View File

@ -1,21 +1,23 @@
# Copyright (c) 2019 Ultimaker B.V.
# 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, Set
from PyQt5.QtCore import QTimer
from PyQt5.QtNetwork import QNetworkReply
from PyQt5.QtWidgets import QMessageBox
from UM import i18nCatalog
from UM.Logger import Logger # To log errors talking to the API.
from UM.Message import Message
from UM.Settings.Interfaces import ContainerInterface
from UM.Signal import Signal
from UM.Util import parseBool
from cura.API import Account
from cura.API.Account import SyncState
from cura.CuraApplication import CuraApplication
from cura.Settings.CuraStackBuilder import CuraStackBuilder
from cura.Settings.GlobalStack import GlobalStack
from cura.UltimakerCloud.UltimakerCloudConstants import META_UM_LINKED_TO_ACCOUNT
from .CloudApiClient import CloudApiClient
from .CloudOutputDevice import CloudOutputDevice
from ..Models.Http.CloudClusterResponse import CloudClusterResponse
@ -30,6 +32,7 @@ class CloudOutputDeviceManager:
META_CLUSTER_ID = "um_cloud_cluster_id"
META_NETWORK_KEY = "um_network_key"
SYNC_SERVICE_NAME = "CloudOutputDeviceManager"
# The translation catalog for this device.
@ -41,9 +44,14 @@ class CloudOutputDeviceManager:
def __init__(self) -> None:
# Persistent dict containing the remote clusters for the authenticated user.
self._remote_clusters = {} # type: Dict[str, CloudOutputDevice]
# Dictionary containing all the cloud printers loaded in Cura
self._um_cloud_printers = {} # type: Dict[str, GlobalStack]
self._account = CuraApplication.getInstance().getCuraAPI().account # type: Account
self._api = CloudApiClient(CuraApplication.getInstance(), on_error = lambda error: Logger.log("e", str(error)))
self._account.loginStateChanged.connect(self._onLoginStateChanged)
self._removed_printers_message = None # type: Optional[Message]
# Ensure we don't start twice.
self._running = False
@ -98,23 +106,41 @@ class CloudOutputDeviceManager:
def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None:
"""Callback for when the request for getting the clusters is finished."""
self._um_cloud_printers = {m.getMetaDataEntry(self.META_CLUSTER_ID): m for m in
CuraApplication.getInstance().getContainerRegistry().findContainerStacks(
type = "machine") if m.getMetaDataEntry(self.META_CLUSTER_ID, None)}
new_clusters = []
all_clusters = {c.cluster_id: c for c in clusters} # type: Dict[str, CloudClusterResponse]
online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse]
# Add the new printers in Cura. If a printer was previously added and is rediscovered, set its metadata to
# reflect that and mark the printer not removed from the account
for device_id, cluster_data in all_clusters.items():
if device_id not in self._remote_clusters:
new_clusters.append(cluster_data)
if device_id in self._um_cloud_printers and not parseBool(self._um_cloud_printers[device_id].getMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, "true")):
self._um_cloud_printers[device_id].setMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, True)
self._onDevicesDiscovered(new_clusters)
removed_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys())
for device_id in removed_device_keys:
# Hide the current removed_printers_message, if there is any
if self._removed_printers_message:
self._removed_printers_message.actionTriggered.disconnect(self._onRemovedPrintersMessageActionTriggered)
self._removed_printers_message.hide()
# Remove the CloudOutput device for offline printers
offline_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys())
for device_id in offline_device_keys:
self._onDiscoveredDeviceRemoved(device_id)
if new_clusters or removed_device_keys:
self.discoveredDevicesChanged.emit()
# Handle devices that were previously added in Cura but do not exist in the account anymore (i.e. they were
# removed from the account)
removed_device_keys = set(self._um_cloud_printers.keys()) - set(all_clusters.keys())
if removed_device_keys:
self._devicesRemovedFromAccount(removed_device_keys)
if new_clusters or offline_device_keys or removed_device_keys:
self.discoveredDevicesChanged.emit()
if offline_device_keys:
# If the removed device was active we should connect to the new active device
self._connectToActiveMachine()
@ -144,10 +170,13 @@ class CloudOutputDeviceManager:
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 a printer that was removed from the account is re-added, change its metadata to mark it not removed
# from the account
elif not parseBool(self._um_cloud_printers[device.key].getMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, "true")):
self._um_cloud_printers[device.key].setMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, True)
# Inform the Cloud printers model about new devices.
new_devices_list_of_dicts = [{
@ -163,7 +192,11 @@ class CloudOutputDeviceManager:
self._connectToActiveMachine()
return
new_devices.sort(key = lambda x: x.name.lower())
# Sort new_devices on online status first, alphabetical second.
# Since the first device might be activated in case there is no active printer yet,
# it would be nice to prioritize online devices
online_cluster_names = {c.friendly_name.lower() for c in clusters if c.is_online and not c.friendly_name is None}
new_devices.sort(key = lambda x: ("a{}" if x.name.lower() in online_cluster_names else "b{}").format(x.name.lower()))
image_path = os.path.join(
CuraApplication.getInstance().getPluginRegistry().getPluginPath("UM3NetworkPrinting") or "",
@ -204,19 +237,97 @@ class CloudOutputDeviceManager:
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_name_list = ["<li>{} ({})</li>".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", "<li>... and {} others</li>", num_hidden))
device_names = "\n".join(device_name_list)
else:
device_names = "\n".join(["- {} ({})".format(device.name, device.printerTypeName) for device in new_devices])
device_names = "\n".join(["<li>{} ({})</li>".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{}",
"Cloud printers added from your account:\n<ul>{}</ul>",
device_names
)
message.setText(message_text)
def _devicesRemovedFromAccount(self, removed_device_ids: Set[str]) -> None:
"""
Removes the CloudOutputDevice from the received device ids and marks the specific printers as "removed from
account". In addition, it generates a message to inform the user about the printers that are no longer linked to
his/her account. The message is not generated if all the printers have been previously reported as not linked
to the account.
:param removed_device_ids: Set of device ids, whose CloudOutputDevice needs to be removed
:return: None
"""
if not CuraApplication.getInstance().getCuraAPI().account.isLoggedIn:
return
# Do not report device ids which have been previously marked as non-linked to the account
ignored_device_ids = set()
for device_id in removed_device_ids:
if not parseBool(self._um_cloud_printers[device_id].getMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, "true")):
ignored_device_ids.add(device_id)
# Keep the reported_device_ids list in a class variable, so that the message button actions can access it and
# take the necessary steps to fulfill their purpose.
self.reported_device_ids = removed_device_ids - ignored_device_ids
if not self.reported_device_ids:
return
# Generate message
self._removed_printers_message = Message(
title = self.I18N_CATALOG.i18ncp(
"info:status",
"Cloud connection is not available for a printer",
"Cloud connection is not available for some printers",
len(self.reported_device_ids)
)
)
device_names = "\n".join(["<li>{} ({})</li>".format(self._um_cloud_printers[device].name, self._um_cloud_printers[device].definition.name) for device in self.reported_device_ids])
message_text = self.I18N_CATALOG.i18ncp(
"info:status",
"The following cloud printer is not linked to your account:\n",
"The following cloud printers are not linked to your account:\n",
len(self.reported_device_ids)
)
message_text += self.I18N_CATALOG.i18nc(
"info:status",
"<ul>{}</ul>\nTo establish a connection, please visit the "
"<a href='https://mycloud.ultimaker.com/'>Ultimaker Digital Factory</a>.",
device_names
)
self._removed_printers_message.setText(message_text)
self._removed_printers_message.addAction("keep_printer_configurations_action",
name = self.I18N_CATALOG.i18nc("@action:button", "Keep printer configurations"),
icon = "",
description = "Keep the configuration of the cloud printer(s) synced with Cura which are not linked to your account.",
button_align = Message.ActionButtonAlignment.ALIGN_RIGHT)
self._removed_printers_message.addAction("remove_printers_action",
name = self.I18N_CATALOG.i18nc("@action:button", "Remove printers"),
icon = "",
description = "Remove the cloud printer(s) which are not linked to your account.",
button_style = Message.ActionButtonStyle.SECONDARY,
button_align = Message.ActionButtonAlignment.ALIGN_LEFT)
self._removed_printers_message.actionTriggered.connect(self._onRemovedPrintersMessageActionTriggered)
output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
# Remove the output device from the printers
for device_id in removed_device_ids:
device = self._um_cloud_printers.get(device_id, None) # type: Optional[GlobalStack]
if not device:
continue
if device_id in output_device_manager.getOutputDeviceIds():
output_device_manager.removeOutputDevice(device_id)
if device_id in self._remote_clusters:
del self._remote_clusters[device_id]
# Update the printer's metadata to mark it as not linked to the account
device.setMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, False)
self._removed_printers_message.show()
def _onDiscoveredDeviceRemoved(self, device_id: str) -> None:
device = self._remote_clusters.pop(device_id, None) # type: Optional[CloudOutputDevice]
if not device:
@ -302,3 +413,24 @@ class CloudOutputDeviceManager:
container_cluster_id = container.getMetaDataEntry(self.META_CLUSTER_ID, None)
if container_cluster_id in self._remote_clusters.keys():
del self._remote_clusters[container_cluster_id]
def _onRemovedPrintersMessageActionTriggered(self, removed_printers_message: Message, action: str) -> None:
if action == "keep_printer_configurations_action":
removed_printers_message.hide()
elif action == "remove_printers_action":
machine_manager = CuraApplication.getInstance().getMachineManager()
remove_printers_ids = {self._um_cloud_printers[i].getId() for i in self.reported_device_ids}
all_ids = {m.getId() for m in CuraApplication.getInstance().getContainerRegistry().findContainerStacks(type = "machine")}
question_title = self.I18N_CATALOG.i18nc("@title:window", "Remove printers?")
question_content = self.I18N_CATALOG.i18nc("@label", "You are about to remove {} printer(s) from Cura. This action cannot be undone. \nAre you sure you want to continue?".format(len(remove_printers_ids)))
if remove_printers_ids == all_ids:
question_content = self.I18N_CATALOG.i18nc("@label", "You are about to remove all printers from Cura. This action cannot be undone. \nAre you sure you want to continue?")
result = QMessageBox.question(None, question_title, question_content)
if result == QMessageBox.No:
return
for machine_cloud_id in self.reported_device_ids:
machine_manager.setActiveMachine(self._um_cloud_printers[machine_cloud_id].getId())
machine_manager.removeMachine(self._um_cloud_printers[machine_cloud_id].getId())
removed_printers_message.hide()

View File

@ -465,7 +465,7 @@ class XmlMaterialProfile(InstanceContainer):
return "materials"
@classmethod
def getVersionFromSerialized(cls, serialized: str) -> Optional[int]:
def getVersionFromSerialized(cls, serialized: str) -> int:
data = ET.fromstring(serialized)
version = XmlMaterialProfile.Version

View File

@ -0,0 +1,68 @@
{
"name": "Dagoma Delta",
"version": 2,
"inherits": "fdmprinter",
"metadata": {
"visible": false,
"author": "Dagoma",
"manufacturer": "Dagoma"
},
"overrides": {
"machine_width": {
"default_value": 195.55
},
"machine_height": {
"default_value": 205
},
"machine_depth": {
"default_value": 195.55
},
"machine_center_is_zero": {
"default_value": true
},
"machine_head_with_fans_polygon": {
"default_value": [
[-36, -42],
[-36, 42],
[36, 42],
[36, -42]
]
},
"gantry_height": {
"value": "0"
},
"machine_shape": {
"default_value": "elliptic"
},
"machine_start_gcode": {
"default_value": ";Gcode by Cura\nG90\nG28\nM107\nM109 R100\nG29\nM109 S{material_print_temperature_layer_0} U-55 X55 V-85 Y-85 W0.26 Z0.26\nM82\nG92 E0\nG1 F200 E6\nG92 E0\nG1 F200 E-3.5\nG0 Z0.15\nG0 X10\nG0 Z3\nG1 F6000\n"
},
"machine_end_gcode": {
"default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 E-2 F9000\nG90\nG28\n"
},
"default_material_print_temperature": {
"default_value": 205
},
"speed_print": {
"default_value": 40
},
"retraction_amount": {
"default_value": 3.8
},
"retraction_speed": {
"default_value": 60
},
"adhesion_type": {
"default_value": "skirt"
},
"skirt_line_count": {
"default_value": 2
},
"layer_height_0": {
"default_value": 0.26
},
"top_bottom_thickness": {
"default_value": 1
}
}
}

View File

@ -0,0 +1,62 @@
{
"name": "Dagoma Disco",
"version": 2,
"inherits": "fdmprinter",
"metadata": {
"visible": false,
"author": "Dagoma",
"manufacturer": "Dagoma"
},
"overrides": {
"machine_width": {
"default_value": 205
},
"machine_height": {
"default_value": 205
},
"machine_depth": {
"default_value": 205
},
"machine_center_is_zero": {
"default_value": false
},
"machine_head_with_fans_polygon": {
"default_value": [
[-17, -70],
[-17, 40],
[17, 40],
[17, -70]
]
},
"gantry_height": {
"value": "10"
},
"default_material_print_temperature": {
"default_value": 205
},
"material_standby_temperature": {
"default_value": 90
},
"speed_print": {
"default_value": 60
},
"retraction_amount": {
"default_value": 3.5
},
"retraction_speed": {
"default_value": 50
},
"adhesion_type": {
"default_value": "skirt"
},
"skirt_line_count": {
"default_value": 2
},
"layer_height_0": {
"default_value": 0.26
},
"top_bottom_thickness": {
"default_value": 1
}
}
}

View File

@ -1,82 +1,34 @@
{
"name": "Dagoma DiscoEasy200",
"version": 2,
"inherits": "fdmprinter",
"inherits": "dagoma_disco",
"metadata": {
"visible": true,
"author": "Dagoma",
"manufacturer": "Dagoma",
"file_formats": "text/x-gcode",
"platform": "dagoma_discoeasy200.3mf",
"platform_offset": [0, -57.3, -11],
"platform_offset": [0, -57, -39],
"has_machine_quality": true,
"has_materials": true,
"preferred_material": "chromatik_pla",
"machine_extruder_trains":
{
"0": "dagoma_discoeasy200_extruder_0",
"1": "dagoma_discoeasy200_extruder_1"
"0": "dagoma_discoeasy200_extruder"
}
},
"overrides": {
"machine_name": {
"default_value": "Dagoma DiscoEasy200"
},
"machine_extruder_count": {
"default_value": 2
},
"machine_extruders_share_heater": {
"default_value": true
},
"machine_width": {
"default_value": 205
},
"machine_height": {
"default_value": 205
},
"machine_depth": {
"default_value": 205
},
"machine_center_is_zero": {
"default_value": false
},
"machine_head_with_fans_polygon": {
"default_value": [
[-17, -70],
[-17, 40],
[17, 40],
[17, -70]
]
},
"gantry_height": {
"value": "10"
"default_value": 1
},
"machine_start_gcode": {
"default_value": ";Gcode by Cura\nG90\nM106 S255\nG28 X Y\nG1 X50\nM109 R90\nG28\nM104 S{material_print_temperature_layer_0}\nG29\nM107\nG1 X100 Y20 F3000\nG1 Z0.5\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E10\nG92 E0\nG1 Z3\nG1 F6000\n"
"default_value": ";Begin Start Gcode for Dagoma DiscoEasy 200\n;Sliced: {date} {time}\n;Initial extruder: {initial_extruder_nr}\n\nG90 ;Absolute positioning\nM106 S255 ;Fan on full\nG28 X Y ;Home stop X Y\nG1 X100 ;Centre back during cooldown in case of oozing\nM109 R{material_standby_temperature} ;Cooldown in case too hot\nG28 ;Centre\nG29 ;Auto-level\nM104 S{material_print_temperature_layer_0} ;Pre-heat\nM107 ;Fan off\nG0 X100 Y5 Z0.5 ;Front centre for degunk\nM109 S{material_print_temperature_layer_0} ;Wait for initial temp\nM83 ;E Relative\nG1 E10 F200 ;Degunk\nG1 E-3 F5000 ;Retract\nG0 Z3 ;Withdraw\nM82 ;E absolute\nG92 E0 ;E reset\nG1 F6000 ;Set feedrate\n\n;Finish Start Gcode for Dagoma DiscoEasy 200\n"
},
"machine_end_gcode": {
"default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 F3000\nG90\nG28 X Y\nM107\nM84\n"
},
"default_material_print_temperature": {
"default_value": 205
},
"speed_print": {
"default_value": 60
},
"retraction_amount": {
"default_value": 3.5
},
"retraction_speed": {
"default_value": 50
},
"adhesion_type": {
"default_value": "skirt"
},
"skirt_line_count": {
"default_value": 2
},
"layer_height_0": {
"default_value": 0.26
},
"top_bottom_thickness": {
"default_value": 1
"default_value": ";Begin End Gcode for Dagoma DiscoEasy 200\n\nM106 S255 ;Fan on full\nM104 S0 ;Cool hotend\nM140 S0 ;Cool heated bed\nG91 ;Relative positioning\nG1 E-3 F5000 ;Retract filament to stop oozing\nG0 Z+3 ;Withdraw\nG90 ;Absolute positioning\nG28 X Y ;Home\nM109 R{material_standby_temperature} ;Wait until head has cooled to standby temp\nM107 ;Fan off\nM18 ;Stepper motors off\n\n;Finish End Gcode for Dagoma DiscoEasy 200\n"
}
}
}

View File

@ -0,0 +1,38 @@
{
"name": "Dagoma DiscoEasy200 Bicolor",
"version": 2,
"inherits": "dagoma_disco",
"metadata": {
"visible": true,
"author": "Dagoma",
"manufacturer": "Dagoma",
"file_formats": "text/x-gcode",
"platform": "dagoma_discoeasy200_bicolor.3mf",
"platform_offset": [0, -57.3, -11],
"has_machine_quality": true,
"has_materials": true,
"preferred_material": "chromatik_pla",
"machine_extruder_trains":
{
"0": "dagoma_discoeasy200_extruder_0",
"1": "dagoma_discoeasy200_extruder_1"
}
},
"overrides": {
"machine_name": {
"default_value": "Dagoma DiscoEasy200 Bicolor"
},
"machine_extruder_count": {
"default_value": 2
},
"machine_extruders_share_heater": {
"default_value": true
},
"machine_start_gcode": {
"default_value": ";Begin Start Gcode for Dagoma DiscoEasy 200 Bicolor\n;Sliced: {date} {time}\n;Initial extruder: {initial_extruder_nr}\n\nG90 ;Absolute positioning\nM106 S255 ;Fan on full\nG28 X Y ;Home stop X Y\nG1 X100 ;Centre back during cooldown in case of oozing\nM109 R{material_standby_temperature} ;Cooldown in case too hot\nG28 ;Centre\nG29 ;Auto-level\nM104 S{material_print_temperature_layer_0} ;Pre-heat\nM107 ;Fan off\nG0 X100 Y5 Z0.5 ;Front centre for degunk\nM109 S{material_print_temperature_layer_0} ;Wait for initial temp\n;M83 ;E Relative\n;G1 E60 F3000 ;Reverse multi-extruder retract\n;G1 E10 F200 ;Degunk\n;G1 E-3 F5000 ;Retract\nG0 Z3 ;Withdraw\n;M82 ;E absolute\n;G92 E0 ;E reset\n;G1 F6000 ;Set feedrate\n\n;Finish Start Gcode for Dagoma DiscoEasy 200 Bicolor\n"
},
"machine_end_gcode": {
"default_value": ";Begin End Gcode for Dagoma DiscoEasy 200 Bicolor\n\nM106 S255 ;Fan on full\nM104 S0 ;Cool hotend\nM140 S0 ;Cool heated bed\nG91 ;Relative positioning\nG1 E-3 F5000 ;Retract filament to stop oozing\nG1 E-60 F5000 ;Retract filament multi-extruder\nG0 Z+3 ;Withdraw\nG90 ; Absolute positioning\nG28 X Y ;Home\nM109 R{material_standby_temperature} ;Wait until head has cooled to standby temp\nM107 ;Fan off\nM18 ;Stepper motors off\n\n;Finish End Gcode for Dagoma DiscoEasy 200 Bicolor\n"
}
}
}

View File

@ -1,82 +1,34 @@
{
"name": "Dagoma DiscoUltimate",
"version": 2,
"inherits": "fdmprinter",
"inherits": "dagoma_disco",
"metadata": {
"visible": true,
"author": "Dagoma",
"manufacturer": "Dagoma",
"file_formats": "text/x-gcode",
"platform": "dagoma_discoultimate.3mf",
"platform_offset": [0, -58.5, -11],
"platform_offset": [0, -58.5, -39.5],
"has_machine_quality": true,
"has_materials": true,
"preferred_material": "chromatik_pla",
"machine_extruder_trains":
{
"0": "dagoma_discoultimate_extruder_0",
"1": "dagoma_discoultimate_extruder_1"
"0": "dagoma_discoultimate_extruder"
}
},
"overrides": {
"machine_name": {
"default_value": "Dagoma DiscoUltimate"
},
"machine_extruder_count": {
"default_value": 2
},
"machine_extruders_share_heater": {
"default_value": true
},
"machine_width": {
"default_value": 205
},
"machine_height": {
"default_value": 205
},
"machine_depth": {
"default_value": 205
},
"machine_center_is_zero": {
"default_value": false
},
"machine_head_with_fans_polygon": {
"default_value": [
[-17, -70],
[-17, 40],
[17, 40],
[17, -70]
]
},
"gantry_height": {
"value": "10"
"default_value": 1
},
"machine_start_gcode": {
"default_value": ";Gcode by Cura\nG90\nM106 S255\nG28 X Y\nG1 X50\nM109 R90\nG28\nM104 S{material_print_temperature_layer_0}\nG29\nM107\nG1 X100 Y20 F3000\nG1 Z0.5\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E10\nG92 E0\nG1 Z3\nG1 F6000\n"
"default_value": ";Begin Start Gcode for Dagoma DiscoUltimate\n;Sliced: {date} {time}\n;Initial extruder: {initial_extruder_nr}\n\nG90 ;Absolute positioning\nM106 S255 ;Fan on full\nG28 X Y ;Home stop X Y\nG1 X100 ;Centre back during cooldown in case of oozing\nM109 R{material_standby_temperature} ;Cooldown in case too hot\nG28 ;Centre\nG29 ;Auto-level\nM104 S{material_print_temperature_layer_0} ;Pre-heat\nM107 ;Fan off\nG0 X100 Y5 Z0.5 ;Front centre for degunk\nM109 S{material_print_temperature_layer_0} ;Wait for initial temp\nM83 ;E Relative\nG1 E10 F200 ;Degunk\nG1 E-3 F5000 ;Retract\nG0 Z3 ;Withdraw\nM82 ;E absolute\nG92 E0 ;E reset\nG1 F6000 ;Set feedrate\n\n;Finish Start Gcode for Dagoma DiscoUltimate\n"
},
"machine_end_gcode": {
"default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 F3000\nG90\nG28 X Y\nM107\nM84\n"
},
"default_material_print_temperature": {
"default_value": 205
},
"speed_print": {
"default_value": 60
},
"retraction_amount": {
"default_value": 3.5
},
"retraction_speed": {
"default_value": 50
},
"adhesion_type": {
"default_value": "skirt"
},
"skirt_line_count": {
"default_value": 2
},
"layer_height_0": {
"default_value": 0.26
},
"top_bottom_thickness": {
"default_value": 1
"default_value": ";Begin End Gcode for Dagoma DiscoUltimate\n\nM106 S255 ;Fan on full\nM104 S0 ;Cool hotend\nM140 S0 ;Cool heated bed\nG91 ;Relative positioning\nG1 E-3 F5000 ;Retract filament to stop oozing\nG0 Z+3 ;Withdraw\nG90 ;Absolute positioning\nG28 X Y ;Home\nM109 R{material_standby_temperature} ;Wait until head has cooled to standby temp\nM107 ;Fan off\nM18 ;Stepper motors off\n\n;Finish End Gcode for Dagoma DiscoUltimate\n"
}
}
}

View File

@ -0,0 +1,38 @@
{
"name": "Dagoma DiscoUltimate Bicolor",
"version": 2,
"inherits": "dagoma_disco",
"metadata": {
"visible": true,
"author": "Dagoma",
"manufacturer": "Dagoma",
"file_formats": "text/x-gcode",
"platform": "dagoma_discoultimate_bicolor.3mf",
"platform_offset": [0, -58.5, -11],
"has_machine_quality": true,
"has_materials": true,
"preferred_material": "chromatik_pla",
"machine_extruder_trains":
{
"0": "dagoma_discoultimate_extruder_0",
"1": "dagoma_discoultimate_extruder_1"
}
},
"overrides": {
"machine_name": {
"default_value": "Dagoma DiscoUltimate Bicolor"
},
"machine_extruder_count": {
"default_value": 2
},
"machine_extruders_share_heater": {
"default_value": true
},
"machine_start_gcode": {
"default_value": ";Begin Start Gcode for Dagoma DiscoUltimate Bicolor\n;Sliced: {date} {time}\n;Initial extruder: {initial_extruder_nr}\n\nG90 ;Absolute positioning\nM106 S255 ;Fan on full\nG28 X Y ;Home stop X Y\nG1 X100 ;Centre back during cooldown in case of oozing\nM109 R{material_standby_temperature} ;Cooldown in case too hot\nG28 ;Centre\nG29 ;Auto-level\nM104 S{material_print_temperature_layer_0} ;Pre-heat\nM107 ;Fan off\nG0 X100 Y5 Z0.5 ;Front centre for degunk\nM109 S{material_print_temperature_layer_0} ;Wait for initial temp\n;M83 ;E Relative\n;G1 E60 F3000 ;Reverse multi-extruder retract\n;G1 E10 F200 ;Degunk\n;G1 E-3 F5000 ;Retract\nG0 Z3 ;Withdraw\n;M82 ;E absolute\n;G92 E0 ;E reset\n;G1 F6000 ;Set feedrate\n\n;Finish Start Gcode for Dagoma DiscoUltimate Bicolor\n"
},
"machine_end_gcode": {
"default_value": ";Begin End Gcode for Dagoma DiscoUltimate Bicolor\n\nM106 S255 ;Fan on full\nM104 S0 ;Cool hotend\nM140 S0 ;Cool heated bed\nG91 ;Relative positioning\nG1 E-3 F5000 ;Retract filament to stop oozing\nG1 E-60 F5000 ;Retract filament multi-extruder\nG0 Z+3 ;Withdraw\nG90 ; Absolute positioning\nG28 X Y ;Home\nM109 R{material_standby_temperature} ;Wait until head has cooled to standby temp\nM107 ;Fan off\nM18 ;Stepper motors off\n\n;Finish End Gcode for Dagoma DiscoUltimate Bicolor\n"
}
}
}

View File

@ -1,7 +1,7 @@
{
"name": "Dagoma Magis",
"version": 2,
"inherits": "fdmprinter",
"inherits": "dagoma_delta",
"metadata": {
"visible": true,
"author": "Dagoma",
@ -14,65 +14,12 @@
"preferred_material": "chromatik_pla",
"machine_extruder_trains":
{
"0": "dagoma_magis_extruder_0"
"0": "dagoma_magis_extruder"
}
},
"overrides": {
"machine_width": {
"default_value": 195.55
},
"machine_height": {
"default_value": 205
},
"machine_depth": {
"default_value": 195.55
},
"machine_center_is_zero": {
"default_value": true
},
"machine_head_with_fans_polygon": {
"default_value": [
[-36, -42],
[-36, 42],
[36, 42],
[36, -42]
]
},
"gantry_height": {
"value": "0"
},
"machine_shape": {
"default_value": "elliptic"
},
"machine_start_gcode": {
"default_value": ";Gcode by Cura\nG90\nG28\nM107\nM109 R100\nG29\nM109 S{material_print_temperature_layer_0} U-55 X55 V-85 Y-85 W0.26 Z0.26\nM82\nG92 E0\nG1 F200 E6\nG92 E0\nG1 F200 E-3.5\nG0 Z0.15\nG0 X10\nG0 Z3\nG1 F6000\n"
},
"machine_end_gcode": {
"default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 E-2 F9000\nG90\nG28\n"
},
"default_material_print_temperature": {
"default_value": 205
},
"speed_print": {
"default_value": 40
},
"retraction_amount": {
"default_value": 3.8
},
"retraction_speed": {
"default_value": 60
},
"adhesion_type": {
"default_value": "skirt"
},
"skirt_line_count": {
"default_value": 2
},
"layer_height_0": {
"default_value": 0.26
},
"top_bottom_thickness": {
"default_value": 1
"machine_name": {
"default_value": "Dagoma Magis"
}
}
}

View File

@ -1,7 +1,7 @@
{
"name": "Dagoma NEVA",
"name": "Dagoma Neva",
"version": 2,
"inherits": "fdmprinter",
"inherits": "dagoma_delta",
"metadata": {
"visible": true,
"author": "Dagoma",
@ -14,65 +14,12 @@
"preferred_material": "chromatik_pla",
"machine_extruder_trains":
{
"0": "dagoma_neva_extruder_0"
"0": "dagoma_neva_extruder"
}
},
"overrides": {
"machine_width": {
"default_value": 195.55
},
"machine_height": {
"default_value": 205
},
"machine_depth": {
"default_value": 195.55
},
"machine_center_is_zero": {
"default_value": true
},
"machine_head_with_fans_polygon": {
"default_value": [
[-36, -42],
[-36, 42],
[36, 42],
[36, -42]
]
},
"gantry_height": {
"value": "0"
},
"machine_shape": {
"default_value": "elliptic"
},
"machine_start_gcode": {
"default_value": ";Gcode by Cura\nG90\nG28\nM107\nM109 R100\nG29\nM109 S{material_print_temperature_layer_0} U-55 X55 V-85 Y-85 W0.26 Z0.26\nM82\nG92 E0\nG1 F200 E6\nG92 E0\nG1 F200 E-3.5\nG0 Z0.15\nG0 X10\nG0 Z3\nG1 F6000\n"
},
"machine_end_gcode": {
"default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 E-2 F9000\nG90\nG28\n"
},
"default_material_print_temperature": {
"default_value": 205
},
"speed_print": {
"default_value": 40
},
"retraction_amount": {
"default_value": 3.8
},
"retraction_speed": {
"default_value": 60
},
"adhesion_type": {
"default_value": "skirt"
},
"skirt_line_count": {
"default_value": 2
},
"layer_height_0": {
"default_value": 0.26
},
"top_bottom_thickness": {
"default_value": 1
"machine_name": {
"default_value": "Dagoma Neva"
}
}
}

View File

@ -2082,7 +2082,7 @@
"description": "Skin areas narrower than this are not expanded. This avoids expanding the narrow skin areas that are created when the model surface has a slope close to the vertical.",
"unit": "mm",
"type": "float",
"default_value": 2.24,
"default_value": 0,
"value": "top_layers * layer_height / math.tan(math.radians(max_skin_angle_for_expansion))",
"minimum_value": "0",
"enabled": "(top_layers > 0 or bottom_layers > 0) and (top_skin_expand_distance > 0 or bottom_skin_expand_distance > 0)",

View File

@ -55,7 +55,7 @@
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
"default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."
"default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 Y50 F9000\n;Put printing message on LCD screen\nM117 Printing..."
},
"machine_end_gcode": {
"value": "'M104 S0 ;extruder heater off' + ('\\nM140 S0 ;heated bed heater off' if machine_heated_bed else '') + '\\nG91 ;relative positioning\\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\\nM84 ;steppers off\\nG90 ;absolute positioning'"

View File

@ -0,0 +1,21 @@
{
"version": 2,
"name": "Extruder",
"inherits": "fdmextruder",
"metadata": {
"machine": "dagoma_discoeasy200",
"position": "0"
},
"overrides": {
"extruder_nr": {
"default_value": 0
},
"machine_nozzle_size": {
"default_value": 0.4
},
"material_diameter": {
"default_value": 1.75
}
}
}

View File

@ -3,7 +3,7 @@
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
"machine": "dagoma_discoeasy200",
"machine": "dagoma_discoeasy200_bicolor",
"position": "0"
},
@ -18,10 +18,10 @@
"default_value": 1.75
},
"machine_extruder_start_code": {
"default_value": "\n;Start T0\nG92 E0\nG1 E-{retraction_amount} F10000\nG92 E0G1 E1.5 F3000\nG1 E-60 F10000\nG92 E0\n"
"default_value": ";Start T0\nM83\nG1 E{retraction_amount} F3000\nG1 E60 F3000\nG1 E-{retraction_amount} F5000\nM82\nG92 E0"
},
"machine_extruder_end_code": {
"default_value": "\nG92 E0\nG1 E{retraction_amount} F3000\nG92 E0\nG1 E60 F3000\nG92 E0\nG1 E-{retraction_amount} F5000\n;End T0\n\n"
"default_value": "M83\nG1 E-{retraction_amount} F10000\nG1 E1.5 F3000\nG1 E-60 F10000\nM82\nG92 E0\n;End T0"
}
}
}

View File

@ -3,7 +3,7 @@
"name": "Extruder 2",
"inherits": "fdmextruder",
"metadata": {
"machine": "dagoma_discoeasy200",
"machine": "dagoma_discoeasy200_bicolor",
"position": "1"
},
@ -18,10 +18,10 @@
"default_value": 1.75
},
"machine_extruder_start_code": {
"default_value": "\n;Start T1\nG92 E0\nG1 E-{retraction_amount} F10000\nG92 E0G1 E1.5 F3000\nG1 E-60 F10000\nG92 E0\n"
"default_value": ";Start T1\nM83\nG1 E{retraction_amount} F3000\nG1 E60 F3000\nG1 E-{retraction_amount} F5000\nM82\nG92 E0"
},
"machine_extruder_end_code": {
"default_value": "\nG92 E0\nG1 E{retraction_amount} F3000\nG92 E0\nG1 E60 F3000\nG92 E0\nG1 E-{retraction_amount} F5000\n;End T1\n\n"
"default_value": "M83\nG1 E-{retraction_amount} F10000\nG1 E1.5 F3000\nG1 E-60 F10000\nM82\nG92 E0\n;End T1"
}
}
}

View File

@ -0,0 +1,21 @@
{
"version": 2,
"name": "Extruder",
"inherits": "fdmextruder",
"metadata": {
"machine": "dagoma_discoultimate",
"position": "0"
},
"overrides": {
"extruder_nr": {
"default_value": 0
},
"machine_nozzle_size": {
"default_value": 0.4
},
"material_diameter": {
"default_value": 1.75
}
}
}

View File

@ -3,7 +3,7 @@
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
"machine": "dagoma_discoultimate",
"machine": "dagoma_discoultimate_bicolor",
"position": "0"
},
@ -18,10 +18,10 @@
"default_value": 1.75
},
"machine_extruder_start_code": {
"default_value": "\n;Start T0\nG92 E0\nG1 E-{retraction_amount} F10000\nG92 E0G1 E1.5 F3000\nG1 E-60 F10000\nG92 E0\n"
"default_value": ";Start T0\nM83\nG1 E{retraction_amount} F3000\nG1 E60 F3000\nG1 E-{retraction_amount} F5000\nM82\nG92 E0"
},
"machine_extruder_end_code": {
"default_value": "\nG92 E0\nG1 E{retraction_amount} F3000\nG92 E0\nG1 E60 F3000\nG92 E0\nG1 E-{retraction_amount} F5000\n;End T0\n\n"
"default_value": "M83\nG1 E-{retraction_amount} F10000\nG1 E1.5 F3000\nG1 E-60 F10000\nM82\nG92 E0\n;End T0"
}
}
}

View File

@ -3,7 +3,7 @@
"name": "Extruder 2",
"inherits": "fdmextruder",
"metadata": {
"machine": "dagoma_discoultimate",
"machine": "dagoma_discoultimate_bicolor",
"position": "1"
},
@ -18,10 +18,10 @@
"default_value": 1.75
},
"machine_extruder_start_code": {
"default_value": "\n;Start T1\nG92 E0\nG1 E-{retraction_amount} F10000\nG92 E0G1 E1.5 F3000\nG1 E-60 F10000\nG92 E0\n"
"default_value": ";Start T1\nM83\nG1 E{retraction_amount} F3000\nG1 E60 F3000\nG1 E-{retraction_amount} F5000\nM82\nG92 E0"
},
"machine_extruder_end_code": {
"default_value": "\nG92 E0\nG1 E{retraction_amount} F3000\nG92 E0\nG1 E60 F3000\nG92 E0\nG1 E-{retraction_amount} F5000\n;End T1\n\n"
"default_value": "M83\nG1 E-{retraction_amount} F10000\nG1 E1.5 F3000\nG1 E-60 F10000\nM82\nG92 E0\n;End T1"
}
}
}

View File

@ -1,6 +1,6 @@
{
"version": 2,
"name": "Extruder 1",
"name": "Extruder",
"inherits": "fdmextruder",
"metadata": {
"machine": "dagoma_magis",

View File

@ -1,6 +1,6 @@
{
"version": 2,
"name": "Extruder 1",
"name": "Extruder",
"inherits": "fdmextruder",
"metadata": {
"machine": "dagoma_neva",

Binary file not shown.

Binary file not shown.

View File

@ -84,6 +84,21 @@ UM.MainWindow
CuraApplication.purgeWindows()
}
Connections
{
// This connection is used when there is no ActiveMachine and the user is logged in
target: CuraApplication
onShowAddPrintersUncancellableDialog:
{
Cura.Actions.parent = backgroundItem
// Reuse the welcome dialog item to show "Add a printer" only.
welcomeDialogItem.model = CuraApplication.getAddPrinterPagesModelWithoutCancel()
welcomeDialogItem.progressBarVisible = false
welcomeDialogItem.visible = true
}
}
Connections
{
target: CuraApplication
@ -117,6 +132,15 @@ UM.MainWindow
welcomeDialogItem.progressBarVisible = false
welcomeDialogItem.visible = true
}
// Reuse the welcome dialog item to show the "Add printers" dialog. Triggered when there is no active
// machine and the user is logged in.
if (!Cura.MachineManager.activeMachine && Cura.API.account.isLoggedIn)
{
welcomeDialogItem.model = CuraApplication.getAddPrinterPagesModelWithoutCancel()
welcomeDialogItem.progressBarVisible = false
welcomeDialogItem.visible = true
}
}
}

View File

@ -14,8 +14,8 @@ UM.Dialog
id: base
title: catalog.i18nc("@title:window", "Discard or Keep changes")
width: UM.Theme.getSize("popup_dialog").width
height: UM.Theme.getSize("popup_dialog").height
minimumWidth: UM.Theme.getSize("popup_dialog").width
minimumHeight: UM.Theme.getSize("popup_dialog").height
property var changesModel: Cura.UserChangesModel{ id: userChangesModel}
onVisibilityChanged:
{
@ -80,6 +80,8 @@ UM.Dialog
property var extruder_name: userChangesModel.getItem(styleData.row).extruder
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
elide: Text.ElideRight
font: UM.Theme.getFont("system")
text:
{

View File

@ -143,7 +143,7 @@ UM.Dialog
{
width: parent.width
height: childrenRect.height
model: Cura.MachineManager.activeMachine.extruderList
model: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.extruderList : null
delegate: Column
{
height: childrenRect.height

View File

@ -33,7 +33,7 @@ Cura.ExpandablePopup
}
contentPadding: UM.Theme.getSize("default_lining").width
enabled: Cura.MachineManager.activeMachine.hasMaterials || Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates; //Only let it drop down if there is any configuration that you could change.
enabled: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials || Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates : false; //Only let it drop down if there is any configuration that you could change.
headerItem: Item
{
@ -46,7 +46,7 @@ Cura.ExpandablePopup
model: extrudersModel
delegate: Item
{
Layout.fillWidth: true
Layout.preferredWidth: Math.round(parent.width / extrudersModel.count)
Layout.fillHeight: true
// Extruder icon. Shows extruder index and has the same color as the active material.
@ -84,7 +84,7 @@ Cura.ExpandablePopup
{
id: variantLabel
visible: Cura.MachineManager.activeMachine.hasVariants
visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasVariants : false
text: model.variant
elide: Text.ElideRight
@ -114,7 +114,7 @@ Cura.ExpandablePopup
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
visible: !Cura.MachineManager.activeMachine.hasMaterials && (Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates)
visible: Cura.MachineManager.activeMachine ? !Cura.MachineManager.activeMachine.hasMaterials && (Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates) : false
anchors
{

View File

@ -244,7 +244,7 @@ Item
Row
{
height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
visible: Cura.MachineManager.activeMachine.hasMaterials
visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials : false
Label
{
@ -305,7 +305,7 @@ Item
Row
{
height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
visible: Cura.MachineManager.activeMachine.hasVariants
visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasVariants : false
Label
{

View File

@ -130,7 +130,11 @@ Item
target: extruderModel
onModelChanged:
{
supportExtruderCombobox.color = supportExtruderCombobox.model.getItem(supportExtruderCombobox.currentIndex).color
var maybeColor = supportExtruderCombobox.model.getItem(supportExtruderCombobox.currentIndex).color
if (maybeColor)
{
supportExtruderCombobox.color = maybeColor
}
}
}
onCurrentIndexChanged:

View File

@ -35,14 +35,21 @@ Cura.ExpandablePopup
}
}
readonly property string connectionStatusMessage: {
function getConnectionStatusMessage() {
if (connectionStatus == "printer_cloud_not_available")
{
if(Cura.API.connectionStatus.isInternetReachable)
{
if (Cura.API.account.isLoggedIn)
{
return catalog.i18nc("@status", "The cloud printer is offline. Please check if the printer is turned on and connected to the internet.")
if (Cura.MachineManager.activeMachineIsLinkedToCurrentAccount)
{
return catalog.i18nc("@status", "The cloud printer is offline. Please check if the printer is turned on and connected to the internet.")
}
else
{
return catalog.i18nc("@status", "This printer is not linked to your account. Please visit the Ultimaker Digital Factory to establish a connection.")
}
}
else
{
@ -139,12 +146,13 @@ Cura.ExpandablePopup
{
id: connectionStatusTooltipHoverArea
anchors.fill: parent
hoverEnabled: connectionStatusMessage !== ""
hoverEnabled: getConnectionStatusMessage() !== ""
acceptedButtons: Qt.NoButton // react to hover only, don't steal clicks
onEntered:
{
machineSelector.mouseArea.entered() // we want both this and the outer area to be entered
tooltip.tooltipText = getConnectionStatusMessage()
tooltip.show()
}
onExited: { tooltip.hide() }
@ -155,7 +163,7 @@ Cura.ExpandablePopup
id: tooltip
width: 250 * screenScaleFactor
tooltipText: connectionStatusMessage
tooltipText: getConnectionStatusMessage()
arrowSize: UM.Theme.getSize("button_tooltip_arrow").width
x: connectionStatusImage.x - UM.Theme.getSize("narrow_margin").width
y: connectionStatusImage.y + connectionStatusImage.height + UM.Theme.getSize("narrow_margin").height

View File

@ -28,11 +28,11 @@ ListView
delegate: MachineSelectorButton
{
text: model.name
text: model.name ? model.name : ""
width: listView.width
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
checked: Cura.MachineManager.activeMachine.id == model.id
checked: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.id == model.id : false
onClicked:
{

View File

@ -0,0 +1,26 @@
[general]
version = 4
name = Fast
definition = dagoma_discoeasy200_bicolor
[metadata]
setting_version = 15
type = quality
quality_type = draft
weight = -2
material = chromatik_pla
[values]
layer_height = 0.2
line_width = =machine_nozzle_size * 0.875
material_print_temperature = =default_material_print_temperature + 10
material_bed_temperature_layer_0 = =default_material_bed_temperature + 10
speed_print = 60
speed_travel = 75
speed_layer_0 = 17
speed_infill = 60
speed_wall_0 = 50
speed_wall_x = 60
speed_topbottom = 60

View File

@ -0,0 +1,23 @@
[general]
version = 4
name = Fine
definition = dagoma_discoeasy200_bicolor
[metadata]
setting_version = 15
type = quality
quality_type = normal
weight = 0
material = chromatik_pla
[values]
layer_height = 0.1
line_width = =machine_nozzle_size * 0.875
speed_print = 35
speed_travel = 50
speed_layer_0 = 15
speed_infill = 40
speed_wall_0 = 25
speed_wall_x = 35
speed_topbottom = 35

View File

@ -0,0 +1,26 @@
[general]
version = 4
name = Standard
definition = dagoma_discoeasy200_bicolor
[metadata]
setting_version = 15
type = quality
quality_type = fast
weight = -1
material = chromatik_pla
[values]
layer_height = 0.15
line_width = =machine_nozzle_size * 0.875
material_print_temperature = =default_material_print_temperature + 5
material_bed_temperature_layer_0 = =default_material_bed_temperature + 5
speed_print = 50
speed_travel = 60
speed_layer_0 = 17
speed_infill = 50
speed_wall_0 = 40
speed_wall_x = 45
speed_topbottom = 50

View File

@ -0,0 +1,26 @@
[general]
version = 4
name = Fast
definition = dagoma_discoultimate_bicolor
[metadata]
setting_version = 15
type = quality
quality_type = draft
weight = -2
material = chromatik_pla
[values]
layer_height = 0.2
line_width = =machine_nozzle_size * 0.875
material_print_temperature = =default_material_print_temperature + 10
material_bed_temperature_layer_0 = =default_material_bed_temperature + 10
speed_print = 60
speed_travel = 75
speed_layer_0 = 17
speed_infill = 60
speed_wall_0 = 50
speed_wall_x = 60
speed_topbottom = 60

View File

@ -0,0 +1,23 @@
[general]
version = 4
name = Fine
definition = dagoma_discoultimate_bicolor
[metadata]
setting_version = 15
type = quality
quality_type = normal
weight = 0
material = chromatik_pla
[values]
layer_height = 0.1
line_width = =machine_nozzle_size * 0.875
speed_print = 35
speed_travel = 50
speed_layer_0 = 15
speed_infill = 40
speed_wall_0 = 25
speed_wall_x = 35
speed_topbottom = 35

View File

@ -0,0 +1,26 @@
[general]
version = 4
name = Standard
definition = dagoma_discoultimate_bicolor
[metadata]
setting_version = 15
type = quality
quality_type = fast
weight = -1
material = chromatik_pla
[values]
layer_height = 0.15
line_width = =machine_nozzle_size * 0.875
material_print_temperature = =default_material_print_temperature + 5
material_bed_temperature_layer_0 = =default_material_bed_temperature + 5
speed_print = 50
speed_travel = 60
speed_layer_0 = 17
speed_infill = 50
speed_wall_0 = 40
speed_wall_x = 45
speed_topbottom = 50