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 == "":