Add Install Pending Updates button to Account popup

CURA-7473
This commit is contained in:
Nino van Hooff 2020-06-26 11:37:01 +02:00
parent f35ca0eb7d
commit 4f1a18f102
3 changed files with 64 additions and 12 deletions

View file

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from datetime import datetime
from typing import Optional, Dict, TYPE_CHECKING, Union
from typing import Optional, Dict, TYPE_CHECKING, Callable
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty, QTimer, Q_ENUMS
@ -56,6 +56,7 @@ class Account(QObject):
lastSyncDateTimeChanged = pyqtSignal()
syncStateChanged = pyqtSignal(int) # because SyncState is an int Enum
manualSyncEnabledChanged = pyqtSignal(bool)
updatePackagesEnabledChanged = pyqtSignal(bool)
def __init__(self, application: "CuraApplication", parent = None) -> None:
super().__init__(parent)
@ -66,6 +67,8 @@ class Account(QObject):
self._logged_in = False
self._sync_state = SyncState.IDLE
self._manual_sync_enabled = False
self._update_packages_enabled = False
self._update_packages_action = None # type: Callable
self._last_sync_str = "-"
self._callback_port = 32118
@ -143,6 +146,18 @@ class Account(QObject):
if not self._update_timer.isActive():
self._update_timer.start()
def setUpdatePackagesAction(self, action: Callable):
""" Set the callback which will be invoked when the user clicks the update packages button
Should be invoked after your service sets the sync state to SYNCING and before setting the
sync state to SUCCESS.
Action will be reset to None when the next sync starts
"""
self._update_packages_action = action
self._update_packages_enabled = True
self.updatePackagesEnabledChanged.emit(self._update_packages_enabled)
def _onAccessTokenChanged(self):
self.accessTokenChanged.emit()
@ -185,6 +200,9 @@ class Account(QObject):
sync is currently running, a sync will be requested.
"""
self._update_packages_action = None
self._update_packages_enabled = False
self.updatePackagesEnabledChanged.emit(self._update_packages_enabled)
if self._update_timer.isActive():
self._update_timer.stop()
elif self._sync_state == SyncState.SYNCING:
@ -251,6 +269,10 @@ class Account(QObject):
def manualSyncEnabled(self) -> bool:
return self._manual_sync_enabled
@pyqtProperty(bool, notify=updatePackagesEnabledChanged)
def updatePackagesEnabled(self) -> bool:
return self._update_packages_enabled
@pyqtSlot()
@pyqtSlot(bool)
def sync(self, user_initiated: bool = False) -> None:
@ -259,11 +281,14 @@ class Account(QObject):
self._sync()
@pyqtSlot()
def update_packages(self):
if self._update_packages_action is not None:
self._update_packages_action()
@pyqtSlot()
def popupOpened(self) -> None:
self._setManualSyncEnabled(True)
self._sync_state = SyncState.IDLE
self.syncStateChanged.emit(self._sync_state)
@pyqtSlot()
def logout(self) -> None:

View file

@ -95,10 +95,6 @@ class CloudPackageChecker(QObject):
user_subscribed_packages = {plugin["package_id"] for plugin in subscribed_packages_payload}
user_installed_packages = self._package_manager.getAllInstalledPackageIDs()
if user_subscribed_packages == self._last_notified_packages:
# already notified user about these
return
# We need to re-evaluate the dismissed packages
# (i.e. some package might got updated to the correct SDK version in the meantime,
# hence remove them from the Dismissed Incompatible list)
@ -109,7 +105,15 @@ class CloudPackageChecker(QObject):
# We check if there are packages installed in Web Marketplace but not in Cura marketplace
package_discrepancy = list(user_subscribed_packages.difference(user_installed_packages))
if package_discrepancy:
account = self._application.getCuraAPI().account
account.setUpdatePackagesAction(lambda: self._onSyncButtonClicked(None, None))
if user_subscribed_packages == self._last_notified_packages:
# already notified user about these
return
Logger.log("d", "Discrepancy found between Cloud subscribed packages and Cura installed packages")
self._model.addDiscrepancies(package_discrepancy)
self._model.initialize(self._package_manager, subscribed_packages_payload)
@ -144,7 +148,8 @@ class CloudPackageChecker(QObject):
self._message.hide()
self._message = None
def _onSyncButtonClicked(self, sync_message: Message, sync_message_action: str) -> None:
def _onSyncButtonClicked(self, sync_message: Optional[Message], sync_message_action: Optional[str]) -> None:
if sync_message is not None:
sync_message.hide()
self._hideSyncMessage() # Should be the same message, but also sets _message to None
self.discrepancies.emit(self._model)

View file

@ -49,7 +49,7 @@ Row // Sync state icon + message
width: 20 * screenScaleFactor
height: width
source: Cura.API.account.manualSyncEnabled ? UM.Theme.getIcon("update") : UM.Theme.getIcon("checked")
// source is determined by State
color: UM.Theme.getColor("account_sync_state_icon")
RotationAnimator
@ -80,14 +80,36 @@ Row // Sync state icon + message
Label
{
id: stateLabel
text: catalog.i18nc("@state", catalog.i18nc("@label", "Account synced"))
// text is determined by State
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
width: contentWidth + UM.Theme.getSize("default_margin").height
height: contentHeight
verticalAlignment: Text.AlignVCenter
visible: !Cura.API.account.manualSyncEnabled
visible: !Cura.API.account.manualSyncEnabled && !Cura.API.account.updatePackagesEnabled
}
Label
{
id: updatePackagesButton
text: catalog.i18nc("@button", "Install pending updates")
color: UM.Theme.getColor("secondary_button_text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
height: contentHeight
width: contentWidth + UM.Theme.getSize("default_margin").height
visible: Cura.API.account.updatePackagesEnabled
MouseArea
{
anchors.fill: parent
onClicked: Cura.API.account.update_packages()
hoverEnabled: true
onEntered: updatePackagesButton.font.underline = true
onExited: updatePackagesButton.font.underline = false
}
}
Label